# TP1: problème du choix distant Familiarisez vous avec l’outil UPPAAL. Le point fort d’Uppaal c’est le temps; ici on ne l’utilise que pour simuler/vérifier des _produits d’automates asynchrone_ (vous verrez le temps l’an prochain). Ce TP est facile; il faut avoir commencé le TP2 avant la fin de la première séance. ## Étudiez les différents onglets de l’éditeur graphiques * `editor` qui permet de modifier les _déclarations_; les _templates_ de processus; et la _déclaration du système_ * `simulator` affiche le _système instancié_ et permet d’explorer les états du système * `verifier` le model-checker intégré à UPPAAL ## Il y a trois types de fichiers (extensions) * `.xta` format textuel pour définir des _process_ ; déclarer de nouveaux types et constantes; et déclarer le _system_. Vous pouvez écrire directement dans ce format. * `.ugi` format de déclaration des propriétés graphiques (couleur et emplacement des états, … ). Utilisé en interne par l’outil. * `.q` format _query_, pour déclarer de nouvelles propriétés * il y a aussi possibilité d’utiliser un langage `XML` ## Synchronisation en UPPAAL Les transitions d’un _template_/_process_ UPPAAL peuvent avoir quatre types de propriétés
Edit edge in UPPAAL
Fig. 1: edit edge in UPPAAL
* `select` choix “non-déterministe” d’une valeur * `guard` (condition) sur les données * `sync` synchronisation sur un canal * `update` mis à jour des données Une transition sans `sync` est dite interne. Elle peut se déclencher indépendamment des autres instances de process. Il y a deux _polarités_ sur les canaux `!` (émettre) et `?` recevoir. On peut émettre sur un canal `a` (noté `a!`) ou recevoir (noté `a?`). > __Convention:__ on dit que le message transite de `a!` vers `a?`   > __Convention:__ on exécute toujours l’update de l’émetteur avant celui du récepteur (utile seulement si on a des données) ## Espace d’état d’un système On peut explorer les états du système en construisant un graphe qui énumère toutes les transitions/synchronisations possibles depuis un état; en partant de __l’état initial__. C’est ce qu’on appelle la __sémantique__ du système. Le _model-checking_, c’est utilisé des formules de logique temporelle pour “poser des questions” sur le graphe, par exemple pour découvrir la présence de _deadlock_ (états sans transitions sortantes); savoir si le système est _vivant_ et/ou ré-initialisable; …
State space for the first example
Fig. 2: espace d'état pour l'exemple de la question 1
## Rappel sur les formules de logique temporelle en UPPAAL Il existe des formules qui parlent de “l’état courant” du système: conjonction, notée `and`; disjonction, notée `or`; et négation, notée `not`, de _propriétés atomiques_. * l’instance `gauche` est dans l’état `a` s’écrit `gauche.a` * la valeur de la variable `cpt` de l’instance `FifoRI` est inférieure à 2 s’écrit `FifoRI.cpt <=2` Il y a des modalités * deux _modifiers_ de contexte: `A` (All, ∀) et `E` (Exists, ∃) * deux modalités temporelles: `[]` (partout, tout le temps) et `<>` (éventuellement) * donnent 4 possibilités (`A[]`, `E[]`, `A<>`, `E<>`) + une formule spéciale (_leadsto_) `.. –> ..` Il est impossible d’imbriquer (d’utiliser) une formule à l’intérieur d’une autre: `E<> gauche.a` est correct, mais pas `(E<> gauche.a) –> gauche.b` Les formules parlent et quantifient des __chemin maximaux__ dans le __graphe/espace d’état__ du système. | | `[]` | `<>` | |:----:|:--------------------------------:|:----------------:| | `A` | __always__ | __inevitably__ | | `E` | __potentially__
__always__ | __reachable__ | > __Exemple de formules classiques:__ > > * `A[] not deadlock` (invariant) toujours l’état n’est pas un deadlock ## Données et expressions en UPPAAL On peut définir des variables, en plus des canaux, en utilisant une syntaxe “à la C” avec différents types de données possible * `int[0,3] x;` déclare une variable `x` qui peut prendre comme valeur 0, 1, 2 ou 3 * `int y;` domaine par défaut * `int tab[n];` tableau de `n` valeurs, de `tab[0]` à `tab[n-1]` On peut aussi définir des constantes `const bool KO = false;` Ces valeurs peuvent être utilisées pour instancier des paramètres, et donc pouvoir définir deux instances d’un même _template_ qui ont des comportements différents.
Fig. 3: exemple d'utilisation de paramètres et déclarations locales dans un template
```uppaal gauche = Agent(0); droit = Agent(1); system gauche, droit; ``` ## Format textuel On peut également écrire un modèle UPPAAL directement dans le format XTA (textuel) ```uppaal int[0,1] vp; chan s, a, b ; process Agent(int kind) { int lkind := kind; state idle, choice, before_a, before_b; init idle; trans before_b -> idle { guard lkind==1; sync b!; }, before_a -> idle { guard lkind==1; sync a?; assign lkind := 1 - lkind; }, idle -> choice { guard lkind==1; sync s?; }, idle -> choice { select p : int[0,1]; guard lkind==0; sync s!; assign vp := p; }, choice -> before_a { guard (vp == 1); }, choice -> before_b { guard vp == 0; }, before_a -> idle { guard lkind==0; sync a!; assign lkind := 1 - lkind; }, before_b -> idle { guard lkind==0; sync b?; }; } gauche = Agent(0); droit = Agent(1); system gauche, droit; ```