TD9: Enigme de MU: Définitions inductives de prédicats et analyse par cas
TD9 : Définitions inductives de prédicats et analyse par cas
M1 Informatique - Preuves Assistées par Ordinateur
Pierre Letouzey (d’après A. Miquel)
L’énigme de MU (Hofstadter 1986)
Sur l’alphabet à trois lettres {M;I;U}
, on considère le
langage L
défini à partir de l’axiome et des règles suivantes:
- Axiome:
MI ∈ L
- Règle 1: Si
xI ∈ L
, alorsxIU ∈ L
(avecx ∈ {M;I;U}*
) - Règle 2: Si
Mx ∈ L
, alorsMxx ∈ L
(avecx ∈ {M;I;U}*
) - Règle 3: Si
xIIIy ∈ L
, alorsxUy ∈ L
(avecx,y ∈ {M;I;U}*
) - Règle 4: Si
xUUy ∈ L
, alorsxy ∈ L
(avecx,y ∈ {M;I;U}*
)
La question est alors de savoir si le mot MU
fait partie du langage
L
ou non.
Modélisation en Coq
On se propose de formaliser ce problème en Coq. Pour cela, on introduit les définitions suivantes :
Require Import List.
Import ListNotations.
Inductive alpha := M | I | U.
Definition word := list alpha.
Inductive lang : word -> Prop :=
| axiom : lang [M;I]
| rule1 x : lang (x ++ [I]) -> lang (x ++ [I;U])
| rule2 x : lang ([M] ++ x) -> lang ([M] ++ x ++ x)
| rule3 x y : lang (x ++ [I;I;I] ++ y) -> lang (x ++ [U] ++ y)
| rule4 x y : lang (x ++ [U;U] ++ y) -> lang (x ++ y).
Un mot sur l’alphabet {M;U;I}
est donc représenté en Coq par une
liste de lettres. Par exemple, le mot MI
correspond ainsi à la liste
[M;I]
, cette syntaxe étant un raccourci pour M::I::nil
, lui même
correspondant à cons M (cons I nil)
. Et la concaténation de
mots est ici la concaténation de listes ++
(nommée app
en
Coq). Pour plus d’explications sur le type des listes, revoir le TD6.
Enfin, l’appartenance au langage L
est modélisé en Coq
sous la forme du prédicat lang : word->Prop
.
1. Comme échauffement, montrer en Coq que tous les mots du langage L
commencent par la lettre M
.
Attention, il y a au moins deux formulations Coq possibles possibles pour cet énoncé (en utilisant exists
ou match
), prouver la plus facile, puis l’autre par équivalence.
Theorem beginning_M_match: forall w: word, lang w ->
(match w with
| [] => False
| x :: l => x = M
end).
Proof.
intros.
induction H.
- reflexivity.
- destruct x; now simpl in *.
- destruct x; now simpl in *.
- destruct x; now simpl in *.
- destruct x; now simpl in *.
Qed.
Theorem beginning_M_exists: forall w: word, lang w -> exists w': word, w = [M] ++ w'.
Proof.
intros.
assert (H' := beginning_M_match w).
apply H' in H.
destruct w.
contradiction.
exists w.
simpl.
now rewrite H.
Qed.
Arithmétique ternaire
On cherche maintenant à établir que tous les mots du langage ont un
nombre d’occurrences de la lettre I
qui n’est pas un multiple de
trois. Pour cela, on formalise d’abord l’arithmétique modulo 3 en
Coq à partir de la définition inductive suivante:
Inductive Z3 := Z0 | Z1 | Z2.
1. Définir les fonctions succ:Z3->Z3
et add:Z3->Z3->Z3
qui implémentent le successeur et l’addition modulo 3.
Ajouter une notation pour add
via Infix "+" := add
.
Fixpoint succ (n : Z3) : Z3 :=
match n with
| Z0 => Z1
| Z1 => Z2
| Z2 => Z0
end.
Fixpoint add (n : Z3) : Z3 -> Z3 :=
match n with
| Z0 => (fun m => m)
| Z1 => succ
| Z2 => (fun m => succ (succ m))
end.
Infix "+" := add.
2. Montrer que add
est commutative, associative, et qu’elle admet Z0
pour élément neutre.
3. Montrer que pour tout z:Z3
, on a z<>Z0 -> z+z <> Z0
4. Définir une fonction occurI3 : word -> Z3
qu à chaque mot w:word
associe le nombre d’occurrences de la lettre I
modulo 3 dans w
.
5. Montrer que pour tous mots v
et w
on a occurI3 (v ++ w) = (occurI3 v)+(occurI3 w)
.
6. Montrer que pour tout mot w
dans le langage L
, on a occurI3 w <> Z0
.
7. En déduire que ~(lang [M;U])
.
Tactiques utiles: induction
, inversion
, destruct
, discriminate
, injection
.
head: list A -> A -> A
head2: list A -> option A
Inductive Head (A: Type): list A -> A -> Prop :=
Hd: forall w x, Head (x::w) x
Head l x := exists w, l = x :: w
Inductive ord : Type :=
| 0o : ord
| So : ord -> ord
| Lim : (nat -> ord) -> ord
inj_nat n := match n with
| 0 => 0o
| S x => So (inj_nat n)
ω = Lim (inj_nat)
Leave a comment