Intégrateur
node itgr(y, delta, x0 : float :: .) returns (o : float :: .) (* :: . est inféré par le compilo *)
var area : float;
let
area = delta *. y;
o = (x0 fby o) +. area;
tel
(* là on integre quand meme dans itgr donc on va garder le calcul qu'on veut pas *)
node itgr_enable_bad(y, delta, x0 : float; enable : bool) returns (o : float)
var oi : float;
let
oi = itgr(y, delta, x0) when enable; (*= j'integre tout, tout le temps *)
o = merge enable oi ((x0 fby o) whenot enable); (* maintenant je filtre *)
tel
(* on appelle l'intégrateur uniquement au besoin *)
node itgr_enable(y, delta, x0 : float; enable : bool) returns (o : float)
var oi : float;
let
(* on faite la on décide de notre horloge de base, ici cest when enable *)
oi = itgr(y when enable, delta when enable, x0 when enable);
o = merge enable oi ((x0 fby o) whenot enable); (* grâce au merge on a un o propre *)
tel
Automates
Construction de contrôle.
Grammaire
block = eq
| block; block
| reset block every expression
| automaton ... end
Automate : plusieurs états avec chacun un bloc d’équations, avec un état “éveillé” et les autres “dormants”.
type lettre = A | B | C
node p(l : lettre) returns (accept : bool)
let
automaton
state X (* état initial pcq c'est le premier *)
do accept = false
unless l = A then Y
state Y
do accept = false
unless l = B then Y (* tester dans l'ordre d'apparition *)
| l = C then Z
state Z
do accept = true
unless l = A then Y
end
tel
Il faut rajouter l’état Dead
qui gère quand on sors de l’automate
type lettre = A | B | C
node p(l : lettre) returns (accept : bool)
let
automaton
state X (* état initial pcq c'est le premier *)
do accept = false
unless l = A then Y
| true then Dead
state Y
do accept = false
unless l = B then Y (* tester dans l'ordre d'apparition *)
| l = C then Z
| true then Dead
state Z
do accept = true
unless l = A then Y
| true then Dead
state Dead
do accept = false
end
tel
Transitions fortes/faibles
unless c_{1} then s_{1} | \dots | s_{n} then s_{n}
- unless est une transition fortes
node a0() returns (o : bool)
let
automaton
state A
do o = true
unless true then B
state B
do o = false
end
tel
until c_{1} then s_{1} | \dots | s_{n} then s_{n}
- until est une transition faible
node a1() returns (o : bool)
let
automaton
state A
do o = true
until true then B
state B
do o = false
end
tel
node a3() returns (o : int)
let
automaton
state A
do o = 1
unless true then B
state B
do o = 2
until true then C
state C
do o = 3
end
tel
(* seul cas avec un *cas transitoire* *)
node a4() returns (o : int)
let
automaton
state A
do o = 1
until true then B
(* skipped *)
state B
do o = 2
unless true then C
state C
do o = 3
end
tel
Transitions réinitialisante/continuante
- Réinitialisante : then
node f0() returns (o : int)
let
automaton
state X
do o = 0 fby (o + 1)
until (o >= 3) then Y
state Y
do o = 42
until true then X (* a chaque fois qu'on envoie 42, on reviens sur X *)
end
tel
On réinitialise quand on arrive dans l’état.
node f0() returns (o : int)
let
automaton
state X
do o = 0 fby (o + 1)
until (o >= 3) then Y
state Y
do o = 42
unless true then X (* on regarde le unless qui est tjrs true alors le 42 sert à rien *)
end
tel
node f0() returns (o : int)
let
automaton
state X
do o = 0 fby (o + 1)
until (o >= 3) then X (* reinitialisation de l'état X, sans Y *)
end
tel
- Continuante : continue
node f0() returns (o : int)
let
automaton
state X
do o = 0 fby (o + 1)
until (o >= 3) continue X (* on reviens à X sans réinitialiser, donc ça fais rien *)
end
tel
node f0() returns (o : int)
let
automaton
state X
do o = 0 fby (o + 1)
until (o >= 3) continue Y (* quand on va revenir apres Y, on a pas réinitalisé
* alors part direct après l'entier *)
state Y
do o = 42
until true continue X (* a chaque fois qu'on envoie 42, on reviens sur X *)
end
tel
Exemple du bouton
Ce cas illustre que la valeur précédente de
o
est relative à la définition de l’état, pas auo
global.
node switch3bad(b : bool; s : int) returns (o : int)
let
automaton
state Idle
do o = 0 -> (pre o);
unless b continue Increment
state Increment
do o = (0 -> pre o) + s
unless b continue Multiply
state Multiply
do o = (0 -> pre o) * s
unless b continue Idle
end
tel
On peut utiliser le mot clé
last
node switch3(b : bool; s : int) returns (last o : int = 0)
let
automaton
state Idle
do (* o = last o; *) (* ne sert à rien car conserve le dernier état *)
unless b continue Increment
state Increment
do o = last o + s
unless b continue Multiply
state Multiply
do o = last o * s
unless b continue Idle
end
tel
- Variable
last
est tout le temps défini. last
ne s’applique qu’à une variable définie parlast
last
conserve son état