Dans ce TP nous allons manipuler Coq. C'est un outil permettant de faire des preuves et des programmes. Ce TP est inspiré du
Partie 1
Démontrez les lemmes suivants :
Lemma hilbertS (A B C : Prop) : (A -> B -> C) -> (A -> B) -> A -> C.
Lemma q2 (A B : Prop) : A -> (B -> A).
Lemma q3 (A B : Prop) : A -> (~A -> B).
Lemma q4 (A B C : Prop) : (A -> B) -> ((B -> C) -> (A -> C)).
Lemma q5 (A B : Prop) : (A -> B) -> (~B -> ~A).
Nous vons besoin de la logique classique pour certaines des preuves suivantes. Pour cela nous avons besoin d'une des règles telles que le tiers exclus (A \/ ~A
), la double négation (A -> ~~A
) ou le raisonnement par l'absurde ((~A -> False) -> A
). Pour cela nous allons charger la librairie Classical
:
Require Import Classical.
Vous pourrez ainsi utiliser la nouble négation avec la commande apply NNPP.
.
Lemma tiersexclus (A : Prop) : A \/ ~A.
Lemma bottom_c (A : Prop) : (~A -> False) -> A.
Lemma q8 (A B : Prop) : (~B -> ~A) -> (A -> B).
Utilisez des puces pour marquer les différentes branches de vos preuves : +
, *
, -
.
Lemma q9 (A : Prop) : ~~A <-> A.
Lemma q10 (A : Prop) : (A /\ ~A) <-> False.
Lemma q11 (A B : Prop) : (A \/ B) <-> ~(~A /\ ~B).
Lemma q12 (A : Prop) : ~A <-> (A -> False).
Lemma q13 (A B : Prop) : (A <-> B) <-> (A -> B) /\ (B -> A).
Lemma q14 (A B C : Prop) : (A /\ B -> C) <-> (A -> B -> C).
Lemma q15 (A B C : Prop) : (C -> A)\/ (C -> B) <-> (C -> A \/ B).
Lemma q16 (X : Type) (A B : X -> Prop) :
((forall x, A x) \/ (forall x, B x)) -> forall x, A x \/ B x.
Lemma q17 (X : Type) (A B : X -> Prop) :
(exists x, A x /\ B x) -> ((exists x, A x) /\ (exists x, B x)).
Lemma q18 (A B : Prop) : ~ (A /\ B) -> (~ A \/ ~ B).
Lemma q19 (X : Type) : forall (x1 x2 : X), x1 = x2 -> x2 = x1.
Lemma q20 (X : Type) : forall (x1 x2 x3 : X), x1 = x2 /\ x2 = x3 -> x1 = x3.
Partie 2
Nous avons utilisé jusque là les connecteurs de Coq, qui sont basés sur les types inductifs. Nous allons maintenant définir les connecteurs avec le quantificateur universel (pour tout) et l'implication et prouver les règles de déduction.
Definition faux := forall (P : Prop), P.
Definition non (A : Prop) :=
forall (P : Prop), ((A -> faux) -> P) -> P.
Definition et (A B : Prop) :=
forall (P : Prop), (A -> B -> P) -> P.
Definition ou (A B : Prop) :=
forall (P : Prop), ((A -> P) -> (B -> P) -> P).
Definition existe (A : Type) (P : A -> Prop) :=
forall (Q : Prop), (forall a, P a -> Q) -> Q.
Definition egal (A : Type) (a a' : A) :=
forall (P : A -> Prop), P a -> P a'.
Montrez la règle bottom e:
Lemma bottom_e (A : Prop) : faux -> A.
Montrez les règles de l'opérateur non :
Lemma non_intro (A : Prop) : (A -> faux) -> non A.
Lemma non_elim (A : Prop) : A -> non A -> faux.
Montrez les règles de l'opérateur et :
Lemma et_intro (A B : Prop) : A -> B -> et A B.
Lemma et_elim_g (A B : Prop) : et A B -> A.
Lemma et_elim_d (A B : Prop) : et A B -> B.
Montrez les règles de l'opérateur ou :
Lemma ou_intro_g (A B : Prop) : A -> ou A B.
Lemma ou_intro_d (A B : Prop) : B -> ou A B.
Lemma ou_elim (A B C : Prop) : ou A B -> (A -> C) -> (B -> C) -> C.
Montrez les règles de l'opérateur existentiel :
Lemma existe_intro (A : Type) (P : A -> Prop) : forall x : A, P x -> existe A P.
Lemma existe_elim (A : Type) (P : A -> Prop) (Q : Prop) :
existe A P -> (forall x : A, P x -> Q) -> Q.
Nous pouvons aussi vérifier que les connecteurs que nous avons définis sont équivalents à ceux de Coq :
Lemma faux_false : faux <-> False.
Lemma non_not (A : Prop) : non A <-> ~A.
Lemma et_and (A B : Prop) : et A B <-> A /\ B.
Lemma ou_or (A B : Prop) : ou A B <-> A \/ B.
Lemma existe_exists (A : Type) (P : A -> Prop) : existe A P <-> exists a, P a.
Lemma egal_eq (A : Type) (a a' : A) : egal _ a a' <-> a = a'.