Pascal Raymond, Verimag-CNRS
Compilation des langages synchrones 2 Problème général Passage d une description parrallèle à un programme séquentiel simple. E S E f M S Compilateur g Compilation des langages synchrones
Implémentation d un programme réactif P 3 var E, S, M; M := m0; proc P step()...; foreach step do read(e); P step(); // combine : S := f(m, E); M := g(m, E); write(s); end foreach Rôle du compilateur Identifier la mémoire et sa valeur initiale m0 Fournir le corps de la boucle (procédure P step ) Implémentation efficace (si possible) Compilation des langages synchrones
Compilation modulaire? 4 Démarche naturelle Un nœud Lustre une procédure. F P X var A, X, Y, S; proc F step() begin X :=... end proc G step() begin Y :=... end A G Y + S Compilation proc P step() begin F step(); G step(); S := X + Y; end Compilation modulaire?
Problème 5 Utilisation bouclée de certains nœuds. P A F * X Boucle combinatoire? B - Y Non! X = A * (2 - A) + 2 Le programme correct (pas de vrai court-circuit), mais aucune procédure F step ne peut marcher! Compilation modulaire?
Solution(s) 6 Lustre : expansion des appels de nœuds Respecte strictement le principe de substitution. Interdit la compilation modulaire. Scade : interdiction des appels bouclés Entorse au principe de substitution. Permet la compilation modulaire. Même règle que pour les opérateurs prédéfinis. Raisonnable dans un cadre industriel. Compilation modulaire?
Compilation de Lustre 7 Exemple : un compteur avec entrées filtrées compte les fronts de X (F), remise à zéro avec un ycle de retard (R). node CptF(X,reset: bool) returns (cpt: int); var F, R : bool; let tel cpt = if R then 0 else if F then pre cpt + 1 else pre cpt; R = true -> pre reset; F = X -> (X and not pre X); Compilation de Lustre
Compilation en boucle simple 8 Idée : remplacer les définitions par des affectations. Traduction des opérateurs classiques triviale. Traduction des pre et -> par des mémoires. Séquentialisation. Compilation de Lustre
Identification de la mémoire 9 Les opérateurs pre : pcpt = pre cpt, preset = pre reset, px = pre X La mémoire implicite init (opérateur ->) : x -> y devient if init then x else y (init true -> false) Programme Lustre équivalent cpt = if R then 0 else if F then pcpt + 1 else pcpt; R = if init then true else preset; F = if init then X else (X and not px); Compilation de Lustre
Séquentialisation 10 Dépendances instantanées entre variables Ordonnancement des définitions N.B. Pas de boucle instantanée un ordre existe Exemple : R et F avant cpt Mémorisations En vrac (pas de dépendance) à la fin Compilation de Lustre
Implémentation en boucle simple (en pseudo C) 11 Les opérateurs arithmétique et logiques sont littéralement traduits (ex. and devient &&, if..then..else devient..?..:..) Les pre sont remplacés par des mémoires Les -> sont remplacées par init?...:... Les entrées/sorties (par exemple) sont des variables globales Compilation de Lustre
12 int cpt; bool X, reset; /* E/S globales (par exemple) */ int pcpt; bool px, preset; /* mémoires non initialisées */ bool init = true; /* seule initialisation nécessaire */ void CptFiltre step() { } bool R, F; /* variables locales */ R = init? true : preset; F = init? X : (X &&! px); cpt = R? 0 : F? pcpt + 1 : pcpt; pcpt = cpt; px = X; preset = reset; init = false; Compilation de Lustre
Optimisations 13 Structure de contrôle :? devient if Factoriser les conditions Éliminer les variables locales inutiles if (init) { cpt = 0; init = false; } else { F = (X &&! px); cpt = preset? 0 : F? (pcpt+1) : pcpt; } pcpt = cpt; px = X; preset = reset; Compilation de Lustre
Compilation en automate 14 L automate (réactif) suivant : on on off N := 0 N := N + 1 off implémente le programme : node Chrono(on, off : var R : bool; let tel bool) returns (N : int); R = false -> pre(if R then not off else on); N = if R then (pre N + 1) else 0; Idée/problème : construire l automate à partir du programme? Compilation en automate
Objectif 15 Construire un automate réactif à partir d un programme Lustre Idée : un état une configuration de la mémoire N.B. Nombre fini d états mémoire finie (booléenne) Exemple de CptF S1 = État initial = init vrai, les autres indéfinies code simplifié : cpt = 0 mémorisation des entiers : toujours pareil mémorisation des booléens : changement d état! Compilation en automate
Transitions 16 Dans l état S1 (initial) on a : init = false; px = X; preset = reset; Suivant les valeurs de X et reset, 4 états possibles : X reset S2 init px preset X reset S3 init px preset X reset S4 init px preset X reset S5 init px preset Compilation en automate
17 X reset X reset S1 cpt = 0 X reset X reset S2 S3 S4 S5???? Code pour les autres états : S2 cpt = 0 S3 cpt = pcpt S4 cpt = 0 S5 F = X donc cpt = X? (pcpt + 1) : pcpt Transitions pour les autres états : pareil que pour S1 (ne dépendent que des entrées) Compilation en automate
En bref... S1 cpt = 0; 18 S2 cpt = 0; S3 cpt = pcpt; S4 cpt = 0; S5 cpt = X? (pcpt + 1) : pcpt; problème : taille de l automate! Compilation en automate
Remarques sur la taille de l automate 19 n mémoires (pire des cas) 2 n états, 2 2n transitions Explosion combinatoire Pas toujours : États inaccessibles Exemple : ( pre X, pre(x or Y)) seulement 3 états Contre-exemple : CPtF! États équivalents Exemple de CPtF : S1, S2 et S4 font la même chose Important de produire un automate minimal Compilation en automate
Automate minimal de CptF X reset M2 cpt = pcpt; X reset 20 reset M1 cpt = 0; reset X reset X reset X reset reset M3 cpt = X? (pcpt + 1) : pcpt; X reset Compilation en automate
Implémentation en C (par exemple) 21 typedef enum {M1, M2, M3} TState; TState state = M1; void CptFiltre step(){ switch (state) { case M1: cpt = 0; break; case M2: cpt = pcpt; break; case M3: cpt = X? (pcpt + 1):pcpt; break; } pcpt = cpt; if (reset) state = M1; else if (X) state = M2; else state = M3; } Compilation en automate
Boucle simple ou automate? 22 Automate Idéalement rapide Code (potentiellement) énorme Boucle simple Moins rapide Taille du code linéaire Seule solution viable du point de vue industriel Intérêt de l automate? Modèle précieux pour la validation Boucle simple ou automate?