Continuation du DM et deuxième TP.
This commit is contained in:
parent
6424326014
commit
3ef408bcac
378
dm1-AVRILLON.v
378
dm1-AVRILLON.v
@ -99,30 +99,142 @@ Check Nat.eq_dec.
|
|||||||
Search sumbool lt.
|
Search sumbool lt.
|
||||||
(* pour voir l'ensemble des lemmes que connaît Coq faisant intervenir lt et sumbool. *)
|
(* pour voir l'ensemble des lemmes que connaît Coq faisant intervenir lt et sumbool. *)
|
||||||
|
|
||||||
|
Lemma compare_lists_cons_nil : forall (a: nat) (l: list nat), compare_lists (a::l) [] = false.
|
||||||
|
intros.
|
||||||
|
simpl.
|
||||||
|
reflexivity.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Lemma compare_lists_cons_nil_r : forall (a: nat) (l: list nat), compare_lists [] (a::l) = false.
|
||||||
|
intros.
|
||||||
|
simpl.
|
||||||
|
reflexivity.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
|
||||||
|
Lemma compare_lists_nil : forall (l: list nat), compare_lists l [] = true -> l=[].
|
||||||
|
induction l.
|
||||||
|
simpl.
|
||||||
|
trivial.
|
||||||
|
intro HH.
|
||||||
|
rewrite (compare_lists_cons_nil a l) in HH.
|
||||||
|
inversion HH.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Lemma compare_lists_nil_r : forall (l: list nat), compare_lists [] l = true -> l=[].
|
||||||
|
induction l.
|
||||||
|
simpl.
|
||||||
|
trivial.
|
||||||
|
intro HH.
|
||||||
|
rewrite (compare_lists_cons_nil_r a l) in HH.
|
||||||
|
inversion HH.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Check IF_then_else.
|
||||||
|
Check (Nat.eq_dec 0 1).
|
||||||
|
Check sumbool.
|
||||||
|
|
||||||
|
Lemma compare_lists_ind : forall l l' a b,
|
||||||
|
(compare_lists (a::l) (b::l')) = true -> ((a=b) /\ (compare_lists l l')=true).
|
||||||
|
intros.
|
||||||
|
unfold compare_lists in H; fold compare_lists in H.
|
||||||
|
destruct (Nat.eq_dec a b).
|
||||||
|
split.
|
||||||
|
assumption.
|
||||||
|
assumption.
|
||||||
|
inversion H.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Lemma compare_lists_tt : forall l' l l'',
|
||||||
|
compare_lists l l' = true -> compare_lists l' l'' = true ->
|
||||||
|
compare_lists l l'' = true.
|
||||||
|
induction l' as [ | b lb ].
|
||||||
|
intros.
|
||||||
|
apply (compare_lists_nil l) in H.
|
||||||
|
apply (compare_lists_nil_r l'') in H0.
|
||||||
|
rewrite H.
|
||||||
|
rewrite H0.
|
||||||
|
simpl.
|
||||||
|
reflexivity.
|
||||||
|
intro.
|
||||||
|
|
||||||
|
case l as [ | a la].
|
||||||
|
intros.
|
||||||
|
rewrite compare_lists_cons_nil_r in H.
|
||||||
|
inversion H.
|
||||||
|
|
||||||
|
case l'' as [ | c lc ].
|
||||||
|
intros.
|
||||||
|
inversion H0.
|
||||||
|
|
||||||
|
intros H1 H2.
|
||||||
|
|
||||||
|
apply compare_lists_ind in H1.
|
||||||
|
apply compare_lists_ind in H2.
|
||||||
|
destruct H1.
|
||||||
|
destruct H2.
|
||||||
|
subst a c.
|
||||||
|
|
||||||
|
simpl.
|
||||||
|
|
||||||
|
destruct (Nat.eq_dec b b).
|
||||||
|
apply IHlb.
|
||||||
|
assumption.
|
||||||
|
assumption.
|
||||||
|
destruct n.
|
||||||
|
reflexivity.
|
||||||
|
Qed.
|
||||||
|
|
||||||
(* transitivité *)
|
|
||||||
(* Pour prouver ce lemme, vous pouvez utiliser une seule induction, et pas mal
|
|
||||||
de "destruct". À noter que destruct peut être utilisé sur une liste, mais on
|
|
||||||
peut aussi faire destruct (Nat.eq_dec k k'), où k et k' sont des nat. *)
|
|
||||||
Lemma compare_lists_t : forall l1 l2 l3,
|
Lemma compare_lists_t : forall l1 l2 l3,
|
||||||
compare_lists l1 l2 = true -> compare_lists l2 l3 = true ->
|
compare_lists l1 l2 = true -> compare_lists l2 l3 = true ->
|
||||||
compare_lists l1 l3 = true.
|
compare_lists l1 l3 = true.
|
||||||
[...]
|
intros.
|
||||||
|
apply (compare_lists_tt l2 l1 l3).
|
||||||
|
assumption.
|
||||||
|
assumption.
|
||||||
Qed.
|
Qed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(* symétrie *)
|
(* symétrie *)
|
||||||
Lemma compare_lists_s : forall l1 l2,
|
Lemma compare_lists_s : forall l1 l2,
|
||||||
compare_lists l1 l2 = true -> compare_lists l2 l1 = true.
|
compare_lists l1 l2 = true -> compare_lists l2 l1 = true.
|
||||||
[...]
|
induction l1.
|
||||||
|
intros.
|
||||||
|
apply compare_lists_nil_r in H.
|
||||||
|
rewrite H.
|
||||||
|
simpl.
|
||||||
|
reflexivity.
|
||||||
|
|
||||||
|
induction l2.
|
||||||
|
intro HH.
|
||||||
|
rewrite compare_lists_cons_nil in HH.
|
||||||
|
inversion HH.
|
||||||
|
|
||||||
|
intro H.
|
||||||
|
apply compare_lists_ind in H.
|
||||||
|
destruct H.
|
||||||
|
subst a0.
|
||||||
|
|
||||||
|
destruct (Nat.eq_dec a a).
|
||||||
|
simpl.
|
||||||
|
destruct (Nat.eq_dec a a).
|
||||||
|
apply IHl1.
|
||||||
|
assumption.
|
||||||
|
apply n in e.
|
||||||
|
inversion e.
|
||||||
|
|
||||||
|
contradiction.
|
||||||
Qed.
|
Qed.
|
||||||
|
|
||||||
(* reflexivité *)
|
(* reflexivité *)
|
||||||
Lemma compare_lists_r : forall l, compare_lists l l = true.
|
Lemma compare_lists_r : forall l, compare_lists l l = true.
|
||||||
[...]
|
induction l.
|
||||||
|
simpl. reflexivity.
|
||||||
|
simpl. destruct (Nat.eq_dec a a).
|
||||||
|
assumption.
|
||||||
|
contradiction.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -130,34 +242,132 @@ Definition compare_dl : dl -> dl -> bool :=
|
|||||||
fun d1 d2 => compare_lists (two2one d1) (two2one d2).
|
fun d1 d2 => compare_lists (two2one d1) (two2one d2).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(* Sans surprise, le calcul qui est effectué par compare_lists en renvoyant
|
(* Sans surprise, le calcul qui est effectué par compare_lists en renvoyant
|
||||||
un bool correspond à l'égalité sur les list nat : c'est prouvé par les deux
|
un bool correspond à l'égalité sur les list nat : c'est prouvé par les deux
|
||||||
lemmes suivants. *)
|
lemmes suivants. *)
|
||||||
Lemma compare_bool_Prop : forall l1 l2, compare_lists l1 l2 = true -> l1=l2.
|
Lemma compare_bool_Prop : forall l1 l2, compare_lists l1 l2 = true -> l1=l2.
|
||||||
[...]
|
induction l1.
|
||||||
|
intro l2.
|
||||||
|
case l2.
|
||||||
|
simpl. reflexivity.
|
||||||
|
intros.
|
||||||
|
rewrite compare_lists_cons_nil_r in H.
|
||||||
|
inversion H.
|
||||||
|
|
||||||
|
induction l2.
|
||||||
|
intro HH.
|
||||||
|
rewrite compare_lists_cons_nil in HH.
|
||||||
|
inversion HH.
|
||||||
|
|
||||||
|
intro H.
|
||||||
|
apply compare_lists_ind in H.
|
||||||
|
destruct H.
|
||||||
|
subst a0.
|
||||||
|
apply IHl1 in H0.
|
||||||
|
subst l2.
|
||||||
|
reflexivity.
|
||||||
Qed.
|
Qed.
|
||||||
|
|
||||||
|
|
||||||
Lemma compare_Prop_bool : forall l1 l2, l1=l2 -> compare_lists l1 l2 = true.
|
Lemma compare_Prop_bool : forall l1 l2, l1=l2 -> compare_lists l1 l2 = true.
|
||||||
[...]
|
induction l1.
|
||||||
|
intros.
|
||||||
|
subst l2.
|
||||||
|
simpl. reflexivity.
|
||||||
|
|
||||||
|
induction l2.
|
||||||
|
intro H. inversion H.
|
||||||
|
|
||||||
|
intros.
|
||||||
|
inversion H.
|
||||||
|
apply IHl1 in H2.
|
||||||
|
subst a0.
|
||||||
|
simpl.
|
||||||
|
|
||||||
|
destruct (Nat.eq_dec a a).
|
||||||
|
apply compare_lists_r.
|
||||||
|
contradiction.
|
||||||
Qed.
|
Qed.
|
||||||
|
|
||||||
|
|
||||||
(* Définissez une fonction qui calcule le retournement d'une liste. *)
|
(* Définissez une fonction qui calcule le retournement d'une liste. *)
|
||||||
Definition rev2 : dl -> dl := [...].
|
Definition rev2 : dl -> dl := fun dd => match dd with
|
||||||
|
| (lg, ld) => (ld,lg)
|
||||||
|
end.
|
||||||
|
|
||||||
|
Lemma petit_cons : forall (a:nat) (l:list nat), (a::l) = ([a] ++ l).
|
||||||
|
intros.
|
||||||
|
simpl.
|
||||||
|
reflexivity.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Lemma dl_def : forall lg ld, (t2o lg ld) = (List.rev lg ++ ld).
|
||||||
|
induction lg.
|
||||||
|
simpl. reflexivity.
|
||||||
|
simpl. intro ld.
|
||||||
|
rewrite IHlg.
|
||||||
|
rewrite app_ass.
|
||||||
|
rewrite petit_cons.
|
||||||
|
reflexivity.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Lemma rev2_two2one_ll : forall lg ld,
|
||||||
|
compare_lists (List.rev (t2o lg ld)) (two2one (rev2 ((lg,ld))))=true.
|
||||||
|
simpl.
|
||||||
|
induction lg.
|
||||||
|
simpl.
|
||||||
|
induction ld.
|
||||||
|
simpl. reflexivity.
|
||||||
|
simpl. rewrite dl_def. apply compare_lists_r.
|
||||||
|
|
||||||
|
induction ld.
|
||||||
|
simpl.
|
||||||
|
rewrite dl_def.
|
||||||
|
apply (compare_Prop_bool (rev (rev lg ++ [a])) (a::lg)).
|
||||||
|
cut ([a] = rev [a]).
|
||||||
|
intro H.
|
||||||
|
rewrite H.
|
||||||
|
rewrite distr_rev.
|
||||||
|
rewrite rev_involutive.
|
||||||
|
rewrite rev_involutive.
|
||||||
|
simpl. reflexivity.
|
||||||
|
simpl. reflexivity.
|
||||||
|
|
||||||
|
apply compare_Prop_bool.
|
||||||
|
apply compare_bool_Prop in IHld.
|
||||||
|
|
||||||
|
rewrite dl_def.
|
||||||
|
rewrite dl_def.
|
||||||
|
rewrite dl_def in IHld.
|
||||||
|
rewrite dl_def in IHld.
|
||||||
|
|
||||||
|
rewrite <- (rev_involutive (a0::ld)).
|
||||||
|
rewrite distr_rev.
|
||||||
|
rewrite rev_involutive.
|
||||||
|
rewrite rev_involutive.
|
||||||
|
|
||||||
|
rewrite <- (rev_involutive ld) in IHld.
|
||||||
|
rewrite <- (distr_rev (rev ld) (a::lg)) in IHld.
|
||||||
|
rewrite rev_involutive in IHld.
|
||||||
|
rewrite rev_involutive in IHld.
|
||||||
|
reflexivity.
|
||||||
|
Qed.
|
||||||
|
|
||||||
[...]
|
|
||||||
|
|
||||||
(* Pour prouver le lemme suivant, vous pouvez introduire des lemmes
|
(* Pour prouver le lemme suivant, vous pouvez introduire des lemmes
|
||||||
intermédiaires, et aussi vous appuyer sur la librairie List de Coq
|
intermédiaires, et aussi vous appuyer sur la librairie List de Coq
|
||||||
(n'oubliez pas que ++ est une notation pour la fonction app). *)
|
(n'oubliez pas que ++ est une notation pour la fonction app). *)
|
||||||
Lemma rev2_two2one : forall d,
|
Lemma rev2_two2one : forall d,
|
||||||
compare_lists (List.rev (two2one d)) (two2one (rev2 d))=true.
|
compare_lists (List.rev (two2one d)) (two2one (rev2 d))=true.
|
||||||
[...]
|
|
||||||
|
induction d as [ lg ld ].
|
||||||
|
apply rev2_two2one_ll.
|
||||||
Qed.
|
Qed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(* Retirer un élément d'une liste *)
|
(* Retirer un élément d'une liste *)
|
||||||
|
|
||||||
(*
|
(*
|
||||||
@ -169,15 +379,38 @@ Veillez à prendre en compte les recommandations ci-dessus à propos du fait que
|
|||||||
évite de parcourir inutilement des bouts de liste, et que l'on préfère que
|
évite de parcourir inutilement des bouts de liste, et que l'on préfère que
|
||||||
"ça penche à droite" plutôt qu'à gauche.
|
"ça penche à droite" plutôt qu'à gauche.
|
||||||
*)
|
*)
|
||||||
|
Fixpoint ridelle l n := match l with
|
||||||
|
| nil => (nil, false)
|
||||||
|
| e::s => if Nat.eq_dec n e then (s, true) else
|
||||||
|
match (ridelle s n) with
|
||||||
|
| (ss, b) => (e::ss, b)
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
[...]
|
Definition rid ll n := match ll with
|
||||||
|
| (lg, ld) => match (ridelle lg n) with
|
||||||
|
| (sg, b) => if Bool.bool_dec b true then (sg,ld) else
|
||||||
|
match (ridelle ld n) with
|
||||||
|
| (sd, bb) => (sg,sd)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
Definition fst (ll: list nat * bool) := match ll with
|
||||||
|
| (lg, ld) => lg
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
(*
|
(*
|
||||||
Définir une fonction rid_sorted : dl -> nat -> dl, qui fait comme rid2, à ceci près
|
Définir une fonction rid_sorted : dl -> nat -> dl, qui fait comme rid2, à ceci près
|
||||||
que l'on suppose que la liste passée en argument (et représentée avec un dl) est triée.*)
|
que l'on suppose que la liste passée en argument (et représentée avec un dl) est triée.*)
|
||||||
|
|
||||||
[...]
|
Definition rid_sorted ll n := match ll with
|
||||||
|
| (lg, ld) => match lg with
|
||||||
|
| nil => (nil, fst (ridelle ld n))
|
||||||
|
| e::s => if Bool.bool_dec (e<?n) true then (lg, fst (ridelle ld n)) else (fst (ridelle lg n), ld)
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -186,28 +419,131 @@ que l'on suppose que la liste passée en argument (et représentée avec un dl)
|
|||||||
(* Définir une relation inductive dont l'intention est qu'elle coïncide avec compare_dl.
|
(* Définir une relation inductive dont l'intention est qu'elle coïncide avec compare_dl.
|
||||||
Il n'est pas autorisé de faire appel à des fonctions définies ci-dessus dans la
|
Il n'est pas autorisé de faire appel à des fonctions définies ci-dessus dans la
|
||||||
définition de same. *)
|
définition de same. *)
|
||||||
Inductive same : dl -> dl -> Prop := [...].
|
Inductive same : dl -> dl -> Prop :=
|
||||||
[...]
|
| same_nil : same ([],[]) ([],[])
|
||||||
|
| same_decale : forall lg ld a dd, same (a::lg,ld) dd -> same (lg, a::ld) dd
|
||||||
|
| same_cons : forall lg ld lg' ld' a, same (lg, ld) (lg',ld') -> same (lg, a::ld) (lg', a::lg)
|
||||||
|
| same_s : forall dd dd', same dd dd' -> same dd' dd.
|
||||||
|
|
||||||
|
Lemma cons_toi_meme : forall (l:list nat) (a:nat), l=(a::l) -> False.
|
||||||
|
intros.
|
||||||
|
induction l.
|
||||||
|
inversion H.
|
||||||
|
inversion H.
|
||||||
|
subst.
|
||||||
|
apply IHl in H2.
|
||||||
|
apply H2.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Lemma same_nil_plus : forall ld ld', same ([], ld) ([], ld') -> ld=ld'.
|
||||||
|
Abort.
|
||||||
|
(*
|
||||||
|
induction ld.
|
||||||
|
intro ld'.
|
||||||
|
induction ld'.
|
||||||
|
reflexivity.
|
||||||
|
intro H.
|
||||||
|
inversion H.
|
||||||
|
subst.
|
||||||
|
reflexivity.
|
||||||
|
subst.
|
||||||
|
case ld'.
|
||||||
|
reflexivity.
|
||||||
|
intros.
|
||||||
|
intro H.
|
||||||
|
inversion H.
|
||||||
|
intros.
|
||||||
|
inversion H.
|
||||||
|
subst. reflexivity.
|
||||||
|
subst. apply IHld in H1. subst. reflexivity.
|
||||||
|
Qed.*)
|
||||||
|
|
||||||
|
Lemma same_left : forall l l', same ([],l) ([],l') -> l=l'.
|
||||||
|
Abort.
|
||||||
|
|
||||||
(* On prouve ensuite que compare_dl et same coïncident. *)
|
(* On prouve ensuite que compare_dl et same coïncident. *)
|
||||||
|
Lemma same_first_equal : forall lg ld lg' ld', same (lg,ld) (lg',ld') -> lg=lg' -> ld=ld'.
|
||||||
|
intros lg.
|
||||||
|
induction ld.
|
||||||
|
intro lg'.
|
||||||
|
induction ld'.
|
||||||
|
reflexivity.
|
||||||
|
intros. subst.
|
||||||
|
induction lg'.
|
||||||
|
induction ld'.
|
||||||
|
exfalso. inversion H. subst.
|
||||||
|
inversion H.
|
||||||
|
subst. reflexivity.
|
||||||
|
subst.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
apply cons_toi_meme in H4. exfalso. apply H4.
|
||||||
|
subst. induction lg'.
|
||||||
|
inversion H2.
|
||||||
|
subst. reflexivity.
|
||||||
|
subst. apply same_nil in H1.
|
||||||
|
subst. reflexivity.
|
||||||
|
inversion H
|
||||||
|
Qed.
|
||||||
|
|
||||||
Theorem same_compare :
|
Theorem same_compare :
|
||||||
forall d1 d2, same d1 d2 -> compare_dl d1 d2 = true.
|
forall d1 d2, same d1 d2 -> compare_dl d1 d2 = true.
|
||||||
[...]
|
induction d1 as [lg ld].
|
||||||
|
induction lg.
|
||||||
|
intros.
|
||||||
|
unfold compare_dl.
|
||||||
|
simpl.
|
||||||
|
induction d2 as [lg' ld'].
|
||||||
|
simpl.
|
||||||
|
induction lg'.
|
||||||
|
simpl.
|
||||||
|
apply same_first_equal in H.
|
||||||
|
apply compare_Prop_bool.
|
||||||
|
assumption.
|
||||||
|
reflexivity.
|
||||||
|
simpl.
|
||||||
|
inversion H.
|
||||||
|
intro d2.
|
||||||
|
induction d2 as [ lg' ld' ].
|
||||||
|
induction lg'.
|
||||||
|
intro H.
|
||||||
|
inversion H. subst.
|
||||||
|
unfold compare_dl.
|
||||||
|
simpl.
|
||||||
|
destruct (Nat.eq_dec a a).
|
||||||
|
apply compare_lists_r.
|
||||||
|
contradiction.
|
||||||
|
intro H.
|
||||||
|
inversion H. subst lg' ld' a0 ld0 lg0.
|
||||||
|
unfold compare_dl.
|
||||||
|
apply compare_lists_r.
|
||||||
|
subst ld' lg lg0 ld0 a1.
|
||||||
|
rename a0 into b; rename lg' into lg.
|
||||||
|
unfold compare_dl.
|
||||||
|
unfold two2one.
|
||||||
|
simpl.
|
||||||
|
apply compare_lists_r.
|
||||||
Qed.
|
Qed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[...]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Theorem compare_same :
|
Theorem compare_same :
|
||||||
forall d1 d2, compare_dl d1 d2 = true -> same d1 d2.
|
forall d1 d2, compare_dl d1 d2 = true -> same d1 d2.
|
||||||
[...]
|
induction d1 as [lg ld].
|
||||||
|
induction lg.
|
||||||
|
induction d2 as [lg' ld'].
|
||||||
|
intro H.
|
||||||
|
unfold compare_dl in H.
|
||||||
|
unfold two2one in H.
|
||||||
|
simpl in H.
|
||||||
|
apply compare_bool_Prop in H.
|
||||||
|
induction lg'.
|
||||||
|
simpl in H. subst. apply same_idem.
|
||||||
|
simpl in H. subst.
|
||||||
|
|
||||||
|
unfold t2o in H.
|
||||||
Qed.
|
Qed.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
561
tp2.v
Normal file
561
tp2.v
Normal file
@ -0,0 +1,561 @@
|
|||||||
|
(*** TP 2 : Loqique, booléens, propositions et IMP ***)
|
||||||
|
|
||||||
|
|
||||||
|
(** Note : si au bout d'une heure votre TP-man oublie de le dire, passez à la partie sur les listes !! *)
|
||||||
|
|
||||||
|
|
||||||
|
(** * Logique "avancée" et Coq : négation, booléens et Prop **)
|
||||||
|
|
||||||
|
(* Négation *)
|
||||||
|
(* On peut voir le faux, noté False, comme un connecteur logique, qui
|
||||||
|
peut être inséré dans le "tableau" où figuraient la conjonction et
|
||||||
|
l'existentielle dans l'énoncé du TP 1 :
|
||||||
|
|
||||||
|
connecteur | pour utiliser | pour construire
|
||||||
|
----------------|---------------|---------------------
|
||||||
|
P /\ Q | destruct H. | split.
|
||||||
|
P \/ Q | destruct H. | left. / right.
|
||||||
|
exists x:nat, P | destruct H. | exists 17.
|
||||||
|
False | destruct H. |
|
||||||
|
|
||||||
|
Devinez :
|
||||||
|
- pourquoi il n'y a pas de tactique dans la colonne "pour construire" de ce tableau.
|
||||||
|
- ce que fait "destruct H." si H est une hypothèse qui dit False. *)
|
||||||
|
|
||||||
|
(* A vous de jouer : prouvez les lemmes suivants *)
|
||||||
|
|
||||||
|
Lemma ex_falso: forall P : Prop, False -> P.
|
||||||
|
intros P H.
|
||||||
|
destruct H.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(* Si l'on a A:Prop, alors ~A, la négation de A, est une notation pour "A -> False". *)
|
||||||
|
(* Si la notation vous perturbe, vous pouvez toujours utiliser la tactique [unfold not.] *)
|
||||||
|
|
||||||
|
Lemma not_not : forall P : Prop, P -> ~~P.
|
||||||
|
intro P.
|
||||||
|
intros H.
|
||||||
|
unfold not.
|
||||||
|
intros H0.
|
||||||
|
apply H0.
|
||||||
|
apply H.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Lemma morgan1 : forall P Q : Prop, ~P \/ ~Q -> ~(P /\ Q).
|
||||||
|
intros P Q.
|
||||||
|
intro H.
|
||||||
|
unfold not.
|
||||||
|
intros HH.
|
||||||
|
destruct HH.
|
||||||
|
destruct H.
|
||||||
|
apply H.
|
||||||
|
apply H0.
|
||||||
|
apply H.
|
||||||
|
apply H1.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Lemma morgan2 : forall P Q : Prop, ~P /\ ~Q -> ~(P \/ Q).
|
||||||
|
intros P Q H.
|
||||||
|
destruct H.
|
||||||
|
intro HH.
|
||||||
|
destruct HH.
|
||||||
|
apply H.
|
||||||
|
apply H1.
|
||||||
|
apply H0.
|
||||||
|
apply H1.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
|
||||||
|
(* Pour la prochaine preuve, vous aurez besoin d'une nouvelle tactique :
|
||||||
|
[inversion H.]
|
||||||
|
Formellement, lorsque l'on appelle [inversion H], Coq essaye de
|
||||||
|
trouver les conditions nécessaires pour que l'hypothèse H soit vérifiée.
|
||||||
|
Coq fait aussi quelques simplifications lorsque l'on utilise inversion : si H est fausse, alors
|
||||||
|
il termine automatiquement la preuve, si H implique une égalité entre 2 expressions, il fait
|
||||||
|
parfois automatiquement le remplacement.
|
||||||
|
Essayez cette tactique sur les prochains lemmes pour comprendre comment elle marche en pratique *)
|
||||||
|
|
||||||
|
Lemma zero_un : ~(0=1).
|
||||||
|
intro H.
|
||||||
|
inversion H.
|
||||||
|
Qed.
|
||||||
|
(*Notez que "x <> y" est un raccourci de "x = y -> False".*)
|
||||||
|
|
||||||
|
(* Un autre exemple d'application de la tactique inversion, indépendamment de la négation *)
|
||||||
|
Lemma S_out : forall n m : nat, S n = S m -> n = m.
|
||||||
|
intros n m H.
|
||||||
|
inversion H.
|
||||||
|
reflexivity.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
|
||||||
|
(* Dans le même style, les différents constructeurs d'un type inductif ne peuvent pas renvoyer la même valeur.
|
||||||
|
Revenons sur la tentative de définition des entiers avec le successeur ET le prédécesseur, évoquée en cours. *)
|
||||||
|
Inductive t : Set :=
|
||||||
|
Ze : t | Pr : t -> t | Su : t -> t.
|
||||||
|
|
||||||
|
Lemma S_et_P : forall x y, Su x = Pr y -> False.
|
||||||
|
intros x y H.
|
||||||
|
inversion H.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(** Food for thought : à méditer après ce TP, ou si par hasard vous avez fini
|
||||||
|
le reste avant la fin. Avec la syntaxe au-dessus, il est évident que le
|
||||||
|
"prédécesseur" du "successeur" de "zéro" et "zéro" ne définissent pas le même
|
||||||
|
objet: *)
|
||||||
|
|
||||||
|
Lemma PSZ: Pr (Su Ze) = Ze -> False.
|
||||||
|
intros H. inversion H.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Require Export ZArith.
|
||||||
|
|
||||||
|
(** Sauriez-vous montrer la même chose en remplaçant "zéro" par un x (de type t)
|
||||||
|
quelconque ?
|
||||||
|
On insiste sur le fait que cette question est plutôt pour emmener à la maison
|
||||||
|
que pour pendant le TP. Nous serons par ailleurs ravis de recevoir des mails
|
||||||
|
si vous avez des questions là-dessus.
|
||||||
|
Un indice : souvenez-vous de vos cours de maths, où vous avez sûrement été déjà
|
||||||
|
amené.e.s à prouver des résultats plus forts et plus généraux pour parvenir à
|
||||||
|
vos fins.
|
||||||
|
Si besoin, vous pourrez vous servir de la tactique [omega] (chargée avec la
|
||||||
|
librairie ZArith au-dessus, pour résoudre de buts arithmétiques (notamment
|
||||||
|
obtenir faux à partir d'une hypothèse évidemment fausse comme x < x ou 2 < 0),
|
||||||
|
et vous pouvez aussi invoquer la tactique [Search bla] pour chercher des lemmes
|
||||||
|
contenant "bla", comme dans: *)
|
||||||
|
|
||||||
|
Search "<" "S".
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Lemma inj_PS: forall x, Pr (Su x) = x -> False.
|
||||||
|
induction x.
|
||||||
|
apply PSZ.
|
||||||
|
intro H.
|
||||||
|
inversion H.
|
||||||
|
apply IHx.
|
||||||
|
Abort.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(** * Les booléens et les propositions **)
|
||||||
|
|
||||||
|
(* Il y a en Coq deux moyens d'exprimer des affirmations logiques, avec des booléens (le type bool) ou
|
||||||
|
des propositions (le type prop *)
|
||||||
|
Check True.
|
||||||
|
Check False.
|
||||||
|
Check true.
|
||||||
|
Check false.
|
||||||
|
|
||||||
|
(*Un booléen est soit "true" soit "false". Ainsi, si on définit la fonction "and" suivante : *)
|
||||||
|
|
||||||
|
Definition Booland a b := match a,b with
|
||||||
|
| true,true => true
|
||||||
|
| true,false => false
|
||||||
|
| false,true => false
|
||||||
|
| false,false => false
|
||||||
|
end.
|
||||||
|
|
||||||
|
(* Et qu'on l'évalue, on obtient soit true, soit false *)
|
||||||
|
|
||||||
|
Eval compute in (Booland false true).
|
||||||
|
Eval compute in (Booland true true).
|
||||||
|
|
||||||
|
|
||||||
|
(* Il est important de garder à l'esprit que ceci est spécifique au type "bool".
|
||||||
|
En effet, un objet de type "Prop" n'est pas quelque chose que l'on peut
|
||||||
|
simplifier soit en True soit en False, mais plutôt un énoncé dont on peut
|
||||||
|
avoir une preuve (preuve que l'on peut construire en Coq à l'aide de tactiques).
|
||||||
|
*)
|
||||||
|
|
||||||
|
|
||||||
|
Eval compute in (False /\ True).
|
||||||
|
|
||||||
|
(* On va travailler un peu sur ces différences dans un exemple *)
|
||||||
|
(* On donne deux moyens de prouver qu'un entier est pair. *)
|
||||||
|
|
||||||
|
Definition not a := match a with
|
||||||
|
|false => true
|
||||||
|
|true => false
|
||||||
|
end.
|
||||||
|
|
||||||
|
Fixpoint evenb n := match n with
|
||||||
|
| 0 => true
|
||||||
|
| S n' => not (evenb n')
|
||||||
|
end.
|
||||||
|
|
||||||
|
Definition even_bool n := evenb n = true.
|
||||||
|
|
||||||
|
(* Prouvez que 42 est pair avec cette définition *)
|
||||||
|
|
||||||
|
Lemma even_42_bool : even_bool 42.
|
||||||
|
unfold even_bool.
|
||||||
|
unfold evenb.
|
||||||
|
simpl.
|
||||||
|
reflexivity.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(* Une seconde définition avec une fonction "double" *)
|
||||||
|
|
||||||
|
Fixpoint double n := match n with
|
||||||
|
|0 => 0
|
||||||
|
|S n' => S (S (double n'))
|
||||||
|
end.
|
||||||
|
|
||||||
|
Definition even_prop n := exists k, n = double k.
|
||||||
|
|
||||||
|
(* Prouvez une nouvelle fois que 42 est pair *)
|
||||||
|
|
||||||
|
Lemma even_42_prop : even_prop 42.
|
||||||
|
unfold even_prop.
|
||||||
|
exists 21.
|
||||||
|
unfold double.
|
||||||
|
reflexivity.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(* Et maintenant, on va prouvez que finalement, ces deux définitions sont équivalentes *)
|
||||||
|
(* On aura besoin pour cela de lemmes auxiliaires, prouvez les. *)
|
||||||
|
(* Indice : Vous pouvez utiliser la tactique [case a] quand "a" est un booléen pour traiter les deux cas "true" et "false".
|
||||||
|
Cela ne modifiera que dans l'objectif.*)
|
||||||
|
|
||||||
|
Lemma Not_invol : forall a, not (not a) = a.
|
||||||
|
intro a.
|
||||||
|
case a.
|
||||||
|
simpl. reflexivity.
|
||||||
|
simpl. reflexivity.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Lemma Not_false : forall a, not a = false -> a = true.
|
||||||
|
intro a.
|
||||||
|
case a.
|
||||||
|
simpl.
|
||||||
|
intro H. reflexivity.
|
||||||
|
simpl. intro H. inversion H.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Lemma Not_true : forall a, not a = true -> a = false.
|
||||||
|
intro a. case a.
|
||||||
|
intro H. inversion H.
|
||||||
|
intro H. reflexivity.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Lemma evenb_double : forall k, even_bool (double k).
|
||||||
|
intro k.
|
||||||
|
unfold even_bool.
|
||||||
|
induction k.
|
||||||
|
simpl. reflexivity.
|
||||||
|
simpl.
|
||||||
|
rewrite (Not_invol (evenb (double k))).
|
||||||
|
apply IHk.
|
||||||
|
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Lemma moinsDeuxParite : forall n, (even_bool (S (S n))) -> (even_bool n).
|
||||||
|
intro n.
|
||||||
|
intro H.
|
||||||
|
unfold even_bool in H.
|
||||||
|
unfold evenb in H.
|
||||||
|
fold evenb in H.
|
||||||
|
rewrite Not_invol in H.
|
||||||
|
trivial.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(*Tentez de prouver que la définition booléenne implique la définition propositionnelle*)
|
||||||
|
Lemma even_bool_to_prop : forall n, even_bool n -> even_prop n.
|
||||||
|
|
||||||
|
cut (forall n, (even_bool n -> even_prop n) /\ (even_bool (S n) -> even_prop (S n))).
|
||||||
|
intros.
|
||||||
|
destruct (H n).
|
||||||
|
apply H1.
|
||||||
|
apply H0.
|
||||||
|
|
||||||
|
induction n.
|
||||||
|
split.
|
||||||
|
|
||||||
|
intro H.
|
||||||
|
unfold even_prop.
|
||||||
|
exists 0.
|
||||||
|
simpl.
|
||||||
|
reflexivity.
|
||||||
|
|
||||||
|
intro H.
|
||||||
|
unfold even_bool in H.
|
||||||
|
unfold evenb in H.
|
||||||
|
apply Not_true in H.
|
||||||
|
inversion H.
|
||||||
|
|
||||||
|
destruct IHn.
|
||||||
|
split.
|
||||||
|
apply H0.
|
||||||
|
|
||||||
|
intro HH.
|
||||||
|
unfold even_prop.
|
||||||
|
unfold even_bool in HH.
|
||||||
|
apply moinsDeuxParite in HH.
|
||||||
|
apply H in HH.
|
||||||
|
unfold even_prop in HH.
|
||||||
|
destruct HH.
|
||||||
|
exists (S x).
|
||||||
|
simpl.
|
||||||
|
rewrite H1.
|
||||||
|
reflexivity.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(* Dans certains cas, on aura besoin d'une hypothèse d'induction plus forte que ce l'on souhaite prouver.
|
||||||
|
Note : Comme l'hypothèse d'induction 'est' notre objectif, "intro H. induction x" donnera une hypothèse d'induction
|
||||||
|
plus faible que "induction x" puis "intro H" dans les sous-cas.*)
|
||||||
|
(* Comprenez et completez la preuve à trous suivante: *)
|
||||||
|
|
||||||
|
Lemma evenb_double_conv : forall n,
|
||||||
|
(evenb n = true -> exists k, n = double k) /\ (evenb n = false -> exists k, n = S (double k)).
|
||||||
|
induction n.
|
||||||
|
(* Traitez le cas n = 0 de l'induction *)
|
||||||
|
split.
|
||||||
|
intro H.
|
||||||
|
exists 0.
|
||||||
|
simpl.
|
||||||
|
reflexivity.
|
||||||
|
intro H.
|
||||||
|
inversion H.
|
||||||
|
(* Début du cas successeur : *)
|
||||||
|
simpl. destruct IHn. split.
|
||||||
|
intros. destruct H0. (* Premier cas du split à traiter. Si vous avez du mal à lire l'intérface Coq, n'hésitez pas à demander de l'aide *)
|
||||||
|
apply Not_true in H1. assumption.
|
||||||
|
apply Not_true in H1. exists (S x). rewrite H0. simpl. reflexivity.
|
||||||
|
intros. destruct H. (* Deuxième cas du split à traiter *)
|
||||||
|
apply Not_false in H1. assumption.
|
||||||
|
exists x. rewrite H. reflexivity.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(* On peut maintenant prouver l'équivalence entre les deux *)
|
||||||
|
Lemma even_bool_prop : forall n, even_prop n <-> even_bool n.
|
||||||
|
intro n.
|
||||||
|
split.
|
||||||
|
intro H.
|
||||||
|
unfold even_prop in H.
|
||||||
|
destruct H.
|
||||||
|
rewrite H.
|
||||||
|
apply evenb_double.
|
||||||
|
|
||||||
|
apply even_bool_to_prop.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(* Sur cet exemple, vous avez normalement constaté qu'il est plus difficile de travailler sur
|
||||||
|
les preuves avec les booléens que les propositions.
|
||||||
|
En effet, on est passé assez facilement des propositions aux booléens (evenb_double) mais l'inverse était plus compliqué. *)
|
||||||
|
|
||||||
|
(* En revanche, sur la preuve que 42 est paire, sur les booléens il n'y a presque rien à faire, mais pour les propositions,
|
||||||
|
il faut au minimum donner l'entier correspondant à l'existentiel... *)
|
||||||
|
(* Ou bien, si on ne veut pas donner l'entier, on peut faire la preuve suivante... *)
|
||||||
|
|
||||||
|
Lemma even_42_prop_bis : even_prop 42.
|
||||||
|
apply even_bool_prop. reflexivity. Qed.
|
||||||
|
|
||||||
|
(* Sur cet exemple, on ne gagne pas vraiment à utiliser cette preuve. Mais sur certains cas, il peut être utile de connaitre cette
|
||||||
|
technique. Un exemple extreme serait la preuve en Coq du théorème des 4 couleurs,
|
||||||
|
dans laquelle ce procédé est utilisé pour qu'une preuve qui aurait eu besoin d'une analyse de centaines de cas soit
|
||||||
|
capturé par un calcul sur les booléens. *)
|
||||||
|
|
||||||
|
(* Un exemple plus simple serait le suivant. Prouvez ce lemme *)
|
||||||
|
|
||||||
|
Lemma not_even_1001 : ~(even_bool 1001).
|
||||||
|
intro H.
|
||||||
|
unfold even_bool in H.
|
||||||
|
unfold evenb in H.
|
||||||
|
repeat (apply Not_true in H;apply Not_false in H).
|
||||||
|
apply Not_true in H.
|
||||||
|
inversion H.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(* Et celui-ci ? Voyez-vous le problème ?*)
|
||||||
|
|
||||||
|
Lemma not_even_1001_bis : ~(even_prop 1001).
|
||||||
|
intro H.
|
||||||
|
Abort.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(* Petit bonus : La fin de cette partie permet de vous familiariser d'avantager aux équivalences bool/Prop.
|
||||||
|
Il n'est pas nécessaire de la faire en TP, particulièrement si vous avez l'impression d'être en retard.*)
|
||||||
|
(* Si Coq râle, n'hésitez à commenter les parties non faites *)
|
||||||
|
|
||||||
|
(* Prouvez le lemme suivant *)
|
||||||
|
|
||||||
|
Lemma andb_true_iff : forall a b, Booland a b = true <-> (a = true /\ b = true).
|
||||||
|
Abort.
|
||||||
|
|
||||||
|
(* Définissez la fonction "Boolor" pour les booléens *)
|
||||||
|
|
||||||
|
Fail Definition Boolor a b := 0.
|
||||||
|
|
||||||
|
(* Prouvez comme ci-dessus l'équivalence avec \/ *)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(* Fin du bonus. *)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(** * Prédicats inductifs, listes et relations **)
|
||||||
|
|
||||||
|
Require Import List.
|
||||||
|
|
||||||
|
(* On va définir des prédicats sur des listes. Pour simplifier, on supposera qu'il s'agit de listes d'entiers.*)
|
||||||
|
|
||||||
|
Definition listn := list nat.
|
||||||
|
|
||||||
|
(* Inspirez vous de ce que vous avez vu en cours pour écrire le prédicat inductif (is_size l n) qui signifie que l est de taille n *)
|
||||||
|
Inductive is_size :listn -> nat -> Prop :=
|
||||||
|
| size_nil : is_size nil 0
|
||||||
|
| size_cons : forall (x:nat) (l:list nat) (n:nat), (is_size l n) -> (is_size (x::l) (S n)).
|
||||||
|
|
||||||
|
(* La tactique [inversion H] ne sert pas que dans les égalités, en fait, elle fonctionne aussi sur tous les prédicats inductifs.
|
||||||
|
Elle va vérifier quels cas sont possibles. Cela se voit dans le lemme suivant: *)
|
||||||
|
|
||||||
|
Lemma non_empty_size : forall p l n, is_size (p::l) n -> n <> 0.
|
||||||
|
intros p l n.
|
||||||
|
intro H.
|
||||||
|
inversion H.
|
||||||
|
intro HH.
|
||||||
|
inversion HH.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(* Définissez un prédicat (mem l x) qui signifie que x ∈ l *)
|
||||||
|
Inductive mem : listn -> nat -> Prop :=
|
||||||
|
| mem_in : forall x l, mem (x::l) x
|
||||||
|
| mem_cons : forall a x l, mem l x -> mem (a::l) x.
|
||||||
|
|
||||||
|
(* Le prédicat (update l x y l') signifie que l' est obtenu en
|
||||||
|
remplaçant la première occurence de x dans l par y. *)
|
||||||
|
|
||||||
|
(* On vous donne un des cas :
|
||||||
|
|
||||||
|
──────────────────────────────── head
|
||||||
|
update (x::l) x y (y::l)
|
||||||
|
|
||||||
|
*)
|
||||||
|
|
||||||
|
(* Ecrivez ce prédicat *)
|
||||||
|
Inductive update : listn -> nat -> nat -> listn -> Prop :=
|
||||||
|
| update_yep : forall x y l, update (x::l) x y (y::l)
|
||||||
|
| update_end : forall x y z l l', update l x y l' -> z<>x -> update (z::l) x y (z::l').
|
||||||
|
(* update_nil : forall x y, update nil x y nil *)
|
||||||
|
|
||||||
|
|
||||||
|
(* Pour montrer une cohérence entre les deux prédicats, prouvez le lemme suivant *)
|
||||||
|
Lemma update_mem : forall l x y l', update l x y l' -> mem l x.
|
||||||
|
induction l.
|
||||||
|
intros.
|
||||||
|
inversion H.
|
||||||
|
intros x y.
|
||||||
|
intro l'.
|
||||||
|
case l'.
|
||||||
|
intro HH.
|
||||||
|
inversion HH.
|
||||||
|
intros n ll.
|
||||||
|
intro HH.
|
||||||
|
inversion HH.
|
||||||
|
subst.
|
||||||
|
apply mem_in.
|
||||||
|
subst.
|
||||||
|
apply mem_cons.
|
||||||
|
apply (IHl x y ll).
|
||||||
|
assumption.
|
||||||
|
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(* On pourrait prouver de manière similaire "forall l' l x y, update l x y l' -> mem l' y." *)
|
||||||
|
|
||||||
|
(* Petit bonus *)
|
||||||
|
(* Pour prouver une implication dans l'autre sens, vous pourrez avoir besoin du lemme suivant: *)
|
||||||
|
Lemma eq_dec : forall n m : nat, n = m \/ n <> m.
|
||||||
|
induction n.
|
||||||
|
intro m.
|
||||||
|
case m.
|
||||||
|
left. reflexivity.
|
||||||
|
intro mm.
|
||||||
|
right. intro HH. inversion HH.
|
||||||
|
|
||||||
|
intro m.
|
||||||
|
destruct (IHn (S m)).
|
||||||
|
right.
|
||||||
|
intro.
|
||||||
|
rewrite H in H0.
|
||||||
|
inversion H0.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Lemma mem_update : forall l x, mem l x -> forall y, exists l', update l x y l'.
|
||||||
|
[...]
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(* P.S : Si vous avez réussi à le prouver sans utiliser le lemme au-dessus,
|
||||||
|
votre définition de mem aurait probablement pu être plus simple. *)
|
||||||
|
|
||||||
|
(* Fin du petit bonus *)
|
||||||
|
|
||||||
|
(* On considère les listes et on définit une relation binaire inductive sur les listes. On note
|
||||||
|
"perm l1 l2" cette relation, avec l'idée que "perm l1 l2" représente le fait que l2 est une
|
||||||
|
permutation de l1.
|
||||||
|
Cette définition inductive est donnée par les quatres règles d'inférence suivantes :
|
||||||
|
|
||||||
|
perm l₁ l₂ perm l₂ l₃
|
||||||
|
───────────── (refl) ──────────────────────────── (trans)
|
||||||
|
perm l l perm l₁ l₃
|
||||||
|
|
||||||
|
|
||||||
|
perm l₁ l₂
|
||||||
|
────────────────────── (tail) ────────────────────────── (head)
|
||||||
|
perm (x::l₁) (x::l₂) perm (x::y::l) (y::x::l)
|
||||||
|
|
||||||
|
|
||||||
|
*)
|
||||||
|
|
||||||
|
Inductive perm : [...]:=
|
||||||
|
[...].
|
||||||
|
|
||||||
|
(* Petit bonus *)
|
||||||
|
(* Vous vous êtes peut être demandé pourquoi est-ce que l'on a pris cette règle-là pour head et pas une autre ?
|
||||||
|
Notamment, on aurait pu penser à prendre cette règle-ci :
|
||||||
|
|
||||||
|
perm l₁ l₂
|
||||||
|
─────────────────────────────(head')
|
||||||
|
perm (x::y::l₁) (y::x::l₂)
|
||||||
|
|
||||||
|
On peut cependant prouver que l'on a pas besoin de cette règle.
|
||||||
|
Pour vous aider à comprendre pourquoi, montrez d'abord l'exemple suivant. *)
|
||||||
|
|
||||||
|
Lemma perm_example : perm (1::2::4::5::3::nil) (2::1::4::3::5::nil).
|
||||||
|
[...]
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(* Prouvez maintenant le lemme suivant, montrant que la règle donnée
|
||||||
|
précédemment est vraie dans notre définition. *)
|
||||||
|
|
||||||
|
Lemma perm_head_alt : forall x y l1 l2, perm l1 l2 -> perm (x::y::l1) (y::x::l2).
|
||||||
|
[...]
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
(* Fin du petit bonus *)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Parameter X : Set.
|
||||||
|
Definition relation:= X -> X -> Prop.
|
||||||
|
|
||||||
|
(* Définir le prédicat inductif union R1 R2 qui est l'union de deux relations *)
|
||||||
|
Inductive union : relation -> relation -> X -> X -> Prop :=
|
||||||
|
[...]
|
||||||
|
|
||||||
|
(* De même pour l'intersection *)
|
||||||
|
Inductive inter : relation -> relation -> relation :=
|
||||||
|
[...]
|
||||||
|
|
||||||
|
(* Pour comparer des relations entre elles, il faut définir la notion d'égalité, '=' est trop fort ici.*)
|
||||||
|
Definition equal : relation -> relation -> Prop := [...]
|
||||||
|
|
||||||
|
(* On peut maintenant prouver la distributivité entre les deux par exemple *)
|
||||||
|
Lemma distr : forall R1 R2 R3, equal (inter (union R1 R2) R3) (union (inter R1 R3) (inter R2 R3)).
|
||||||
|
[...]
|
||||||
|
Qed.
|
||||||
Loading…
x
Reference in New Issue
Block a user