From Coq Require Import Arith.PeanoNat.
Import Nat(add_0_l, add_0_r, add_succ_l, add_succ_r, add_comm, add_assoc).
Import Nat(add_0_l, add_0_r, add_succ_l, add_succ_r, add_comm, add_assoc).
Consignes
- Partie 1 : calcul des propositions. Cette partie revient sur le contenu du premier TP pour s'assurer que vous avez des bases suffisantes en logique.
- Partie 2 : sur un type clock à deux valeurs, on s'amuse à faire tic-tac-tic-tac..., ceci permet de revenir sur la partie calculatoire de Coq (discriminate et simpl) et l'induction. Les entiers naturels ramènent leur fraise à la fin, avec un dernier exercice dur.
- intros
- unfold
- exact
- split
- destruct pour : un ∧, un ∨, une preuve de False ou une preuve par cas (sur les entiers naturels ou tout ou autre type inductif)
- left/right
- exfalso
- reflexivity
- apply et apply ... in
- rewrite, rewrite <-, rewrite ... in et rewrite <- ... in
- discriminate
- induction
- specialize
- simpl est autorisé et indispensable dans certains cas très faciles, mais on est toujours content de s'en passer
- add_0_l : ∀ n : nat, 0 + n = n
- add_0_r : ∀ n : nat, n + 0 = n
- add_1_l : ∀ n : nat, 1 + n = S n
- add_1_r : ∀ n : nat, n + 1 = S n
- add_succ_l : ∀ n m : nat, S n + m = S (n + m)
- add_succ_r : ∀ n m : nat, n + S m = S (n + m)
- add_comm : ∀ n m : nat, n + m = m + n
- add_assoc : ∀ n m p : nat, n + (m + p) = (n + m) + p
Partie 1 : logique de base
Theorem P1_ex1 : ∀ (P Q R : Prop), (P → Q) → (Q → R) → (P → R).
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Theorem P1_ex2 : ∀ (P Q : Prop), ~(P ∨ Q) ↔ ¬P ∧ ¬Q.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Theorem P1_ex3 : ∀ (P Q : Prop), ¬P ∨ ¬Q → ~(P ∧ Q).
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Theorem P1_ex4 : ∀ (P : Prop), (((P ∨ ¬P) → False) ↔ False).
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
End LogiqueBase.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
End LogiqueBase.
On considère un type clock avec seulement deux valeurs distinctes: tic
et tac:
C'est un type à deux constructeurs tout comme nat mais il n'y a ici
aucune auto-référence, donc il y a seulement deux valeurs.
On peut utiliser discriminate pour réfuter une égalité entre constructeurs
distincts et destruct c pour faire une preuve par disjonction de cas
sur une variable c de type clock.
Exercice : Prouver le théorème suivant, difficulté 05.
Lemma tic_not_tac : ~(tic = tac).
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Lemma tic_or_tac : ∀ (c : clock), c = tic ∨ c = tac.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Après tic, c'est tac, après tac, c'est tic.
Lemma next_tic : next tic = tac.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Lemma next_tac : next tac = tic.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Lemma next_involutive : ∀ (c : clock), next (next c) = c.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Maintenant, on itère l'opération next, intuitivement
next_iter c n = next (next (next ... c)), où l'opération next est
répétée n fois.
Fixpoint next_iter (c : clock) (n : nat) :=
match n with
| 0 ⇒ c
| (S p) ⇒ next (next_iter c p)
end.
match n with
| 0 ⇒ c
| (S p) ⇒ next (next_iter c p)
end.
On va utiliser la notation c + n, où c vaut tic ou tac et n est un entier
à la place de next_iter c n.
Par exemple, on a
- c + 0 = c
- c + 1 = next c
- c + 2 = next (next c)
Lemma next_iter_0 (c : clock) : c + 0 = c.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Lemma next_iter_succ (c : clock) (n : nat) :
c + (S n) = next (c + n).
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
c + (S n) = next (c + n).
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Lemma next_iter_assoc (c : clock) (n m : nat) :
(c + n) + m = c + (n + m).
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
(c + n) + m = c + (n + m).
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
On s'intéresse maintenant à la parité des entiers.
On crée un nouveau type à deux éléments :
Tout ce qui a été dit sur le type clock est évidemment encore vrai sur
pair_ou_impair.
On calcule maintenant par récurrence la parité d'un entier naturel n :
- la parité de 0 est "pair"
- la parité de 1 est "impair"
- la parité de n + 2 est la même que la parité de n.
Lemma parité_0 : parité 0 = pair.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Lemma parité_1 : parité 1 = impair.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Lemma parité_succ_succ (n : nat) : parité (S (S n)) = parité n.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Pour énoncer des résultats sur la parité des entiers, on définit l'opération
autre :
Lemma autre_pair : autre pair = impair.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Lemma autre_impair : autre impair = pair.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Lemma autre_involutive (e : pair_ou_impair) : autre (autre e) = e.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Lemma autre_eq (e f : pair_ou_impair) : autre e = f → e = autre f.
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Proof.
(* Remplir la preuve ici *)
Admitted. (* Remplacer cette ligne par Qed. *)
Maintenant que les lemmes évidents sur autre sont prouvés, on peut
s'attaquer aux résultats intéressants sur parité et next_iter.