// totally ordered set of integers public type Ordered : empty, ordered(Ordered,Int,Ordered). // automagically generated public type Ordered_accu($T) : accu ( $T->$T empty, (Int,$T) -> $T cons, ). // automagically generated public define $T accu (Ordered t,$T acc,Ordered_accu($T) d) = if t is { empty then empty(d)(acc), ordered(l,i,r) then accu(l,cons(d)(i,accu(r,acc,d)),d) }. // automagically generated public type Ordered_fold($T) : fold ( $T empty, ($T,Int,$T) -> $T ordered ). // automagically generated public define $T fold (Ordered s,Ordered_fold($T) d) = if s is { empty then empty(d), ordered(l,i,r) then ordered(d)(fold(l,d),i,fold(r,d)) }. // automagically generated public type Ordered_cata($T) : cata ( $T empty, (One->$T,Int,One->$T) -> $T ordered ). // automagically generated public define $T cata (Ordered s,Ordered_cata($T) d,One _) = if s is { empty then empty(d), ordered(l,i,r) then ordered(d) ((One u)|->cata(l,d,u),i,(One u)|->cata(r,d,u)) }. // automagically generated public type Ordered_recu($T) : recu ( $T empty, (Ordered,$T,Int,Ordered,$T) -> $T ordered ). // automagically generated public define $T recu (Ordered s,Ordered_recu($T) d) = if s is { empty then empty(d), ordered(l,i,r) then ordered(d)(l,recu(l,d),i,r,recu(r,d)) }. // automagically generated public type Ordered_para($T) : para ( $T empty, (Ordered,One->$T,Int,Ordered,One->$T) -> $T ordered ). // automagically generated public define $T para (Ordered s,Ordered_para($T) d,One _) = if s is { empty then empty(d), ordered(l,i,r) then ordered(d) (l,(One u)|->para(l,d,u),i,r,(One u)|->para(r,d,u)) }. public define Word32 cardinal (Ordered s) = fold ( s, fold ( 0, (Word32 l,Int _,Word32 r) |-> l + 1 + r ) ). // an alternative cardinal using 'accu' instead of 'fold' public define Word32 cardinal (Ordered s) = accu ( s, 0, accu ( (Word32 n) |-> n, (Int _,Word32 n) |-> n + 1 ) ). public define Bool member (Ordered s,Int n) = cata ( s, cata ( false, (One->Bool l,Int i,One->Bool r) |-> if n < i then l(unique) else if n > i then r(unique) else true ), unique ). public define Bool forall (Ordered s,(Int)->Bool cond) = cata ( s, cata ( true, (One->Bool l,Int i,One->Bool r) |-> cond(i) & l(unique) & r(unique) ), unique ). public define Ordered insert (Ordered s,Int n) = para ( s, para ( ordered(empty,n,empty), (Ordered l,One->Ordered dl,Int i,Ordered r,One->Ordered dr) |-> if n < i then ordered(dl(unique),i,r) else if n > i then ordered(l,i,dr(unique)) else s ), unique ). public define Ordered Ordered s + Int n = insert(s,n). public define Int minimum (Ordered s,Int n) = para ( s, para ( n, (Ordered l,One->Int dl,Int i,Ordered r,One->Int _) |-> if l is empty then i else dl(unique) ), unique ). public define Ordered remove_minimum (Ordered sl,Int n,Ordered sr) = if sl is empty then sr else ordered ( para ( sl, para ( empty, (Ordered l,One->Ordered dl,Int i,Ordered r,One->Ordered _) |-> if l is empty then r else ordered(dl(unique),i,r) ), unique ), n, sr ). // concatenation of sa + sb where max(sa) < min(sb) public define Ordered concat (Ordered sa,Ordered sb) = if sa is empty then sb else if sb is { empty then sa ordered(lb,nb,rb) then ordered(sa,minimum(lb,nb),remove_minimum(lb,nb,rb)) }. public define Ordered remove (Ordered s,Int n) = para ( s, para ( empty, (Ordered l,One->Ordered dl,Int i,Ordered r,One->Ordered dr) |-> if n < i then ordered(dl(unique),i,r) else if n > i then ordered(l,i,dr(unique)) else concat(l,r) ), unique ). // returns (sa,b,sb) where max(sa) < n < min(sb) and b = member(s,n) public define (Ordered,Bool,Ordered) split (Ordered s,Int n) = para ( s, para ( (empty,false,empty), (Ordered l,One->(Ordered,Bool,Ordered) dl,Int i,Ordered r,One->(Ordered,Bool,Ordered) dr) |-> if n < i then (if dl(unique) is (a,b,c) then (a,b,ordered(c,i,r))) else if n > i then (if dr(unique) is (a,b,c) then (ordered(l,i,a),b,c)) else (l,true,r) ), unique ). public define Ordered filter (Ordered s,Int->Bool cond) = fold ( s, fold ( empty, (Ordered l,Int i,Ordered r) |-> if cond(i) then ordered(l,i,r) else concat(l,r) ) ). public define Ordered union (Ordered sa,Ordered sb) = fold ( sa, fold ( (Ordered s) |-> s, (Ordered->Ordered l,Int i,Ordered->Ordered r) |-> (Ordered s) |-> if s is { empty then empty, ordered(sl,si,sr) then if split(s,i) is (a,b,c) then ordered(l(a),i,r(c)) } ) ) (sb). public define Ordered Ordered sa + Ordered sb = union(sa,sb). public define Ordered intersection (Ordered sa,Ordered sb) = fold ( sa, fold ( (Ordered s) |-> empty, (Ordered->Ordered l,Int i,Ordered->Ordered r) |-> (Ordered s) |-> if s is { empty then empty, ordered(sl,si,sr) then if split(s,i) is (a,b,c) then if b then ordered(l(a),i,r(c)) else concat(l(a),r(c)) } ) ) (sb). public define Ordered difference (Ordered sa,Ordered sb) = recu ( sa, recu ( (Ordered s) |-> empty, (Ordered l,Ordered->Ordered dl,Int i,Ordered r,Ordered->Ordered dr) |-> (Ordered s) |-> if s is { empty then ordered(l,i,r), ordered(sl,si,sr) then if split(s,i) is (a,b,c) then if b then concat(dl(a),dr(c)) else ordered(dl(a),i,dr(c)) } ) ) (sb). public define Ordered Ordered sa - Ordered sb = difference(sa,sb). public define Bool subset (Ordered sa,Ordered sb) = fold ( sa, fold ( (Ordered s) |-> true, (Ordered->Bool l,Int i,Ordered->Bool r) |-> (Ordered s) |-> if s is { empty then true, ordered(sl,si,sr) then if i < si then l(sl) & member(sl,i) & r(s) else if i > si then l(s) & member(sr,i) & r(sr) else l(sl) & r(sr) } ) ) (sb). public define Bool Ordered sa = Ordered sb = subset(sa,sb) & subset(sb,sa). public define List(Int) to_ordered_list(Ordered t) = accu ( t, [], accu ( (List(Int) l) |-> l, (Int i,List(Int) l) |-> [i . l] ) ).
Ertaï il y a plus de 10 ans