Quelques commentaires au fil de l’eau.
Une fois le comportement définit, la compilation du langage source vers le langage cible devrait être faite correctement en procédant ainsi : <description informelle du compilateur naif>
Je trouve cette phrase peu claire, car elle donne l’impression que c’est le seul choix de compilation possible. En particulier, un lecteur inattentif pourrait prouver la correction du compilateur, c’est prouver cela (que Add n
génère n instructions Incr
, etc.).
Je pense qu’il y aurait deux manières d’éviter cette confusion, qui amélioreraient toutes les deux le tutoriel:
- Ne pas mélanger le paragraphe où tu parles du compilateur (ici) et celui où tu parles de la spécification du compilateur (avec la remarque sur le fait que la définition n’est pas assez fine, tout ça); parler de la spécification avant de faire la preuve mais pas trop tôt.
- Clarifier le fait qu’il existe plusieurs choix de traduction possible, et que tu fais ici le choix le plus naïf. Il suffit peut-être de préciser qu’on pourrait imaginer un compilateur optimisant qui pour
[Add 2; Sub 3]
renvoie directement [Decr]
.
Example compile_ex:
compile [Add 2; Sub 3] = [Incr; Incr; Decr; Decr; Decr].
Proof.
Je ne trouve pas très clair de mélanger la notion de test et la notion de preuve. Certes, on peut voir un test comme un énoncé formel avec une preuve triviale, c’est intéressant mais un débutant peut s’y perdre. Pourquoi ne pas montrer une ligne du style Compute
et montrer la forme normale affichée par Coq ?
Signification des programmes
Pourquoi ne pas utiliser le terme habituel, "sémantique" ? Il me semble utile d’utiliser le terme des gens du domaine, pour qu’une personne qui a lu ton introduction s’y retrouve ensuute dans des documents plus avancés.
exec_instr_s a (exec_s prog)
J’ai l’impression qu’il y a une incohérence, au-dessus tu définis exec_instr : counter -> counter
, et là tu prends deux arguments.
Il faut faire un choix entre donner une sémantique où chaque instruction renvoie un nombre, et les nombres du programme sont additionnés, et une sémantique où chaque instruction transforme un nombre, et le programme est une composition de tous ces transformateurs d’état. Je n’ai pas de préférence forte.
P.S.: Ce n’est pas normal que tu doives utiliser la commutatitivé dans ta preuve, il doit y avoir une définition à l’envers.
destruct i ; induction n ;
trivial ; simpl in IHn ; unfold compile_instr ; simpl repeat ;
unfold exec_t ; fold exec_t ; rewrite <- IHn ; unfold exec_instr_s ;
unfold exec_instr_t ; rewrite Nat2Z.inj_succ ; ring.
caca.