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”.
rappel_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
        
    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
automate_enum

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}

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}

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

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
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 au o 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