Message de test de la coloration du code Anubis.
Commençons par un petit dérivateur formel en Anubis :
// a simple formal derivator
// functions from R to R
public type RtoR :
x,
cst(Int),
~ RtoR,
RtoR + RtoR,
RtoR * RtoR,
sin(RtoR),
cos(RtoR),
exp(RtoR).
// automagically generated
public type RtoR_recu($T) :
recu
(
$T x,
$T cst,
($T) -> $T neg,
($T,$T) -> $T add,
(RtoR,$T,RtoR,$T) -> $T mul,
(RtoR,$T) -> $T sin,
(RtoR,$T) -> $T cos,
(RtoR,$T) -> $T exp
).
// automagically generated
public define $T recu (RtoR f,RtoR_recu($T) d)
=
if f is
{
x then x(d),
cst(z) then cst(d),
~ u then neg(d)(recu(u,d)),
u + v then add(d)(recu(u,d),recu(v,d)),
u * v then mul(d)(u,recu(u,d),v,recu(v,d)),
sin(u) then sin(d)(u,recu(u,d)),
cos(u) then cos(d)(u,recu(u,d)),
exp(u) then exp(d)(u,recu(u,d))
}.
public define RtoR deriv (RtoR f)
=
recu
(
f,
recu
(
cst(0),
cst(1),
(RtoR du) |-> ~ du,
(RtoR du,RtoR dv) |-> du + dv,
(RtoR u,RtoR du,RtoR v,RtoR dv) |-> du * v + u * dv,
(RtoR u,RtoR du) |-> du * cos(u),
(RtoR u,RtoR du) |-> ~ du * sin(u),
(RtoR u,RtoR du) |-> du * exp(u)
)
).J'attire l'attention du lecteur sur le fait que la fonction deriv n'est pas directement récursive, nulle part dans son corps elle appelle la fonction deriv !
En effet, toute la récursion est encapsulée dans le récurseur recu.
Le second exemple, à savoir les ensembles totalement ordonnés, illustre un ensemble plus complet de récurseurs : accu, fold, cata, recu et para.
Spoiler (Sélectionnez le texte dans le cadre pointillé pour le faire apparaître)
// 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]
)
).
fuse.
Spoiler (Sélectionnez le texte dans le cadre pointillé pour le faire apparaître)
// skew max-heap
public type Skew :
empty,
skew(Skew,Int,Skew).
// automagically generated
public type Skew_fuse :
fuse
(
(Skew,Skew,(Skew,Skew)->Skew,(Skew,Skew)->Skew) -> Skew both_not_empty
).
// automagically generated
public define Skew fuse(Skew sa,Skew sb,Skew_fuse d)
=
if sa is {
empty then sb
skew(_,_,_) then
if sb is
{
empty then sa
skew(_,_,_) then both_not_empty(d)
(sa,sb,(Skew u,Skew v)|->fuse(u,v,d),(Skew u,Skew v)|->fuse(u,v,d))
}
}.
public define Skew join(Skew s1,Skew s2)
=
fuse
(
s1,
s2,
fuse
(
(Skew sa,Skew sb,(Skew,Skew)->Skew fa,(Skew,Skew)->Skew fb) |->
if sa is {empty then alert,skew(la,na,ra) then
if sb is {empty then alert,skew(lb,nb,rb) then
if na > nb then skew(la,na,fa(ra,sb))
else skew(fb(sa,lb),nb,rb)}}
)
).
public define Skew insert(Skew s,Int n)
=
join(s,skew(empty,n,empty)).
public define Skew remove(Skew l,Skew r)
=
join(l,r).
Je laisse le soin au lecteur de vérifier que les fonctions (assez avancées) de ces deux derniers exemples ne font appel à aucune récursion ni aucune itération.


au talentueux webmaster qui a implémenté la coloration OCaml, Anubis, Coq ainsi que la citation de code dans le texte, sur ma simple demande.
Je comprends encore moins que le Coq, mais c'est très joli