feat: a LOT of stuff (final report, examples, simulation of a single assert, move from node instances to node definitions, etc.)

This commit is contained in:
Henri Saudubray 2025-08-20 18:20:46 +02:00
parent ba5db5bd99
commit f2c545ce2c
Signed by: hms
GPG key ID: 7065F57ED8856128
49 changed files with 12377 additions and 1898 deletions

View file

@ -1,3 +1,7 @@
#set par(justify: true)
= Version 1.
La phrase "it is less computationally intensive... the compiler". est mal dite;
tu peux dire que c'est la methode classique, par exemple, implementee pour
simulink et aussi Zelus.
@ -224,5 +228,121 @@ phases d'integration (le temps ronronne) et des pas discrets (reactions
instantanees).
Super. Continue ! --Marc
#pagebreak()
= Version 2.
*L.230 - 235*. Le discours peut donner l'impression de confondre simuation et
modèle mathématique. Tu écris un modèle mathématique idéalisé, c.à.d. avec un
choc élastique la vitesse change instantanément de direction. Pour cela, la
manière de simuler doit changer. La, tu peux garder le discours.
"_Since time is logical in discrete nodes_". Tu veux dire plutôt que l'on
choisit de décrire des réactions en temps zéro (ou instantanées), c'est bien
ça ? "_Since time is logical in discrete nodes, nothing tells us when, in
continuous time, we should perform discrete steps._" Je ne comprends pas cette
phrase !
*L. 242-245*. Si tu veux définir le zéro-crossing, ne faudrait-il pas plutôt le
faire avec une définition d'analyse d'abord et décrire ensuite, si besoin
l'algorithme (mais informellement) ? L'intuition, c'est qu'il y a un
zéro-crossing de $z$ en $t_0$, entre $t_"left"$ et $t_"right"$ lorsque il existe
une boule d'épaisseur non nulle autour de $t_0$ (d'épaisseur $epsilon$) telle
que pour tous les points a gauche de t0 (notons
$t_0^- = { t | t <= t_0 and |t_0 - t| <= epsilon }$), $z(t_0^-) <= 0$ et tous
les points a droite, $z(t_0^+) > 0$. Tim t'as donné l'article qui décrit l'algo.
Illinois. Je ne l'ai pas sur moi. Le signal $z: [t_"left", t_"right"]$ a un
zéro-crossing en t0 lorsque il existe un $epsilon > 0$ tq pour tout
$alpha < epsilon$: ... . Qu'en penses-tu ?
*Listing 5*. Tu n'expliques pas `last y'`.
*P.10*. Tu devrais d'abord expliquer le modele mathématique, ce dont tu as
besoin, puis l'exemple; ou bien l'inverse, expliquer d'abord intuitivement
l'exemple, les ingrédients dont tu as besoin et que tu introduits, plus le
modèle mathématique. Et ensuite, les choses dont tu as besoin pour simuler.
E.g., connaitre $f_"der"$, $f_"zero"$, l'état initial continu, l'état discret,
etc.
*L.302*.
Je trouve l'écriture $h in [0, v.h]$ un peu troublante. Est-ce qu'une notation
$v\#h$ ou autre ne serait pas mieux ? Ou alors, utiliser plutôt un champ
"horizon" que h, dans la notation en point. Ou "right" ?
"_Multiple methods exist (Zélus uses the Illinois method [Sny53])_". La méthode
Illinois est la plus connue et utilisée. C'est mal formulé. Multiple methods
exist; one of the oldest and most-used method is the Illinois method. It is
used, for example, in the Sundials CVODE suite (donner la référence; regarde
le manuel). Simulink also used this method by default. Zelus also implements
this method.
*L.305-309*.
C'est un peu confus. Dis simplement ce que fait une méthode de zéro-crossing et
des ingrédients dont elle a besoin, avant d'expliquer, plus tard, comment on
s'en sert dans la simulation.
Tu as besoin de $g: T i m e -> X -> Z_o$; de $x_0: X$; de $t_"left"$, de
$t_"right"$ et de $d e n s e: T i m e -> X$, défini sur cet intervalle. La
fonction de zéro-crossing indique qui, sur le vecteur $Z_o$, traverse zéro. Tu
peux signaler les difficultés éventuelles (on peut rater un événement, c'est
sensible a la largeur de l'intervalle de détection, au fait que le nombre de
traversées peut être paire et on rate l'événement, etc.). Et dire que on ne fait
rien dessus (pas plus que Simulink, Modelica, et les autres d'ailleurs).
*L. 322-324*. Je ne comprends pas la définition entre la ligne 322 et 324 et pas
bien le paragraphe précédent.
*L. 418*. Tu veux plutôt dire que tu voudrais pouvoir agréger les solutions
denses successives ($d k y$). Les solveurs classiques sont impératifs,
c'est-à-dire qu'ils ont un état interne et que chaque appel à "step" le modifie
physiquement. Pour pouvoir agréger plusieurs solutions successives, il faut
qu'il fournisse un moyen de le faire. (Rmq: ce n'est pas forcément une "copie
d'état" dont on a besoin. Pour RK, je l'ai fait en fournissant un moyen d'avoir
une copie de $d k y$. Ça suffit.)
*L. 459*. Si tu parles d'assertions dans les programmes, cite/lis les articles
classiques car c'est une construction très ancienne des langages de
programmation. Je ne suis pas spécialiste mais j'en ai lu deux vieux (de
mémoire, un de Hoare; un de Dijsktra). Je suis sûr qu'il doit y avoir un article
de survey que tout le monde cite la dessus. Je regarderai en rentrant. En somme,
dis aussi pourquoi c'est intéressant/utile de pouvoir écrire des assertions et
les difficultés que cela pose dans le cas présent.
"_An important property of assertions is that they are transparent: their
presence does not affect the result of the computation._" An expected feature of
run-time assertions is that they should not affect the rest of the computation
(except stopping execution when they are not fulfilled). We call them
"transparent", in the sense that, running the program with or without, if no
error is raised, should produce the same result.
*Figure 9*. Je ne comprends pas la figure 9. Tu veux dire que, en Lustre, cela
correspond à avoir un seul noeud qui calcule les deux en parallèle ? On n'écrira
jamais le code de la partie droite. Relis l'article sur les assertions de Lustre
(de memoire, AMAST 93). En Lustre, les assertions ont un role qui consiste à
contraindre l'environnement, avant tout. C'est utile quand on veut vérifier des
propriétes. En fait, une assertion se decompose en deux parties, une hypothèse
(qui parle des entrées, incontrolâbles), et une conclusion (assume/guarantee).
Dans notre cas, comme on veut s'en servir d'abord comme on le fait dans un
langage généraliste et, pour le moment, pas pour faire de la vérification, on ne
distingue pas les deux. Le programme de gauche est equivalent à
```
let node f (x) =
let v = ... in
let assertion = (let p = integr(0.0, v) in p >= 0.0) in
(v, assertion)
```
c.à.d. que assertion est un flot comme les autres. Est-ce autre chose que cela
que tu veux dire ?
*L. 477*.
Pas vraiment. Un noeud Lustre avec une assertion a vérifier dynamiquement,
s'implémente en calculant un flot supplementaire et en vérifiant qu'il est vrai
à chaque instant. On le calcule donc avec le reste du code, comme on le fait
habituellement pour les assertions dans les langages classiques. Attention: je
ne parle pas ici de vérification formelle. On traite de manière particulière les
assertions quand on cherche a vérifier une propriété. En Lustre, on considère
que les assertions sont vraies et on vérifie qu'elles ne dépendent pas des
sorties; sinon, elle ne sont pas causales. C'est pour cela, qu'il faut
distinguer les hypothèses (assume) des résultats attendus (guarantee).
Il n'y a aucun exemple ?