field:BinRel -> setofnat1
field(R) ==
domain(R) union range(R);
inverse_rel:BinRel -> BinRel
inverse_rel(R) ==
{mk_(y,x)|mk_(x,y) inset R}; -- or x in set domain(R),y in set range(R) & mk_(x,y) in set R};
id_rel: BinRel -> BinRel -- Returns the identity relation of R
id_rel(R) ==
{mk_(x,x)| x inset field(R)};
Composition:BinRel * BinRel -> BinRel
Composition(R,Q) ==
{mk_(a,c)|mk_(a,b1) inset R,
mk_(b2,c) inset Q & b1=b2}; -- or{mk_(a,c)| a in set domain(R), c in set range(Q) & -- exists b in set (range(R) inter domain(Q)) & -- mk_(a,b) in set R and mk_(b,c) in set Q};
power_of:BinRel * nat1 -> BinRel --returns the xth power of R
power_of(R,x) == if (x = 1) then R else Composition(R, power_of(R, x-1)) pre x>0;
Power_rel: BinRel * nat -> BinRel -- Returns the kth power of R.
Power_rel(R,k) == if k=0 then id_rel(R) elseif k=1 then R else Composition(R,Power_rel(R, k-1));
-- RELATIONAL CLOSURES
Reflexive_cl: BinRel -> BinRel -- Returns the reflexive closure of R
Reflexive_cl(R) ==
(R union id_rel(R));
Symmetric_cl: BinRel -> BinRel -- Returns the symmetric closure of R
Symmetric_cl(R) ==
R union inverse_rel(R);
Transitive_cl: BinRel -> BinRel -- Returns the transitive irreflexive closure of R -- Identical to formal definition of closure. -- Very inefficient interpretation: for every k,k>1, ALL -- lower powers of R are computed from scratch
Transitive_cl(R) == dunion{Power_rel(R,k) | k inset {1,...,card field(R)}};
TransitiveRefl_cl: BinRel -> BinRel -- Returns the transitive reflexive closure of R
TransitiveRefl_cl(R) == dunion{Power_rel(R,k) | k inset {0,...,card field(R)}};
BuildList: BinRel * nat1 -> seqof BinRel -- BuildList(R,n) == sequence of powers of relation R, of maximal length n, -- i.e. RESULT = [Power_rel(R,1),...,Power_rel(R,n)], n>0. -- Thus RESULT(i)=Power_rel(R,i), 0<i<=n. -- For ACYCLIC R, only NONEMPTY powers of R are computed, i.e. -- in that case the length of the result list may be less than n. -- If R = {} the result is [{}] for any n>0. -- The function derives each power of R only once.
BuildList(R,n) == if n=1 then [R] elselet M= BuildList(R,n-1), C=Composition(M(len M),R) in if C={} --empty higher powers of R then M else M ^ [C] pre n>0;
maxset: set1 ofint -> int -- returns maximum of set
maxset(S) == let x inset S in ifcard S = 1 then x else max2(x,maxset(S\ {x}));
max2: int * int -> int
max2(a,b) == if a>= b then a else b;
R := Q; let n = maxset (field(R)) in for k = 1 to n do for i = 1 to n do for j = 1 to n do if mk_(i,j) notinset R thenif mk_(i,k) inset R and mk_(k,j) inset R then R := R union {mk_(i,j)}; return R;
);
-- Testing functions&operations
functions
test_PowerList: BinRel -> bool -- tests PowerList using a simpler albeit inefficient -- Power_Rel as an automatic test oracle, to avoid manual test evaluation
test_PowerList(R)== let L = PowerList(R),
n = card field(R) in
(forall i insetinds L & L(i)=Power_rel(R,i)) andlen L<n => Power_rel(R, len L +1) ={}; -- For "normal" applications pre_PowerList(R) <=> R<>{} should be observed. -- However, PowerList should also be tested for R={}. -- Such a STRESS TEST shows the function's behaviour for invalid data.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.