Test de coloration du code Anubis

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]
   )
).

Le dernier exemple, à savoir un tax-maximum fusionnable, illustre le récurseur 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.  

Laissez un commentaire

1 Commentaire

Laissez un commentaire

Vous devez être connecté pour commenter sur le Refuge. Identifiez-vous maintenant ou inscrivez-vous !