Unprovable theorem forall A : Prop, ~~A -> A - logic

I am stuck with a theorem and I think that it's unprovable.
Theorem double_negation : forall A : Prop, ~~A -> A.
Can you prove it or explain why it is unprovable?
Is it due to Gödel's incompleteness theorems?

Double negation elimination is not provable in constructive logic which underpins Coq. Attempting to prove it we quickly get stuck:
Theorem double_negation_elim : forall A : Prop, ~~A -> A.
Proof.
unfold not.
intros A H.
(* stuck because no way to reach A with H : (A -> False) -> False *)
Abort.
We can show that if double negation elimination was provable then Law of Excluded Middle would hold, that is, (forall (A : Prop) , (~~A -> A)) -> forall A : Prop, A \/ ~A.
First we prove intermediate result ∼∼(A ∨ ∼A):
Lemma not_not_lem: forall A: Prop, ~ ~(A \/ ~A).
Proof.
intros A H.
unfold not in H.
apply H.
right.
intro a.
destruct H.
left.
apply a.
Qed.
Therefore
Theorem not_not_lem_implies_lem:
(forall (A : Prop) , (~~A -> A)) -> forall A : Prop, A \/ ~A.
Proof.
intros H A.
apply H.
apply not_not_lem.
Qed.
But this is a contradiction as LEM does not hold in constructive logic.

Related

Understanding and working with nested inductive definitons in coq

I'm trying to prove insert_SearchTree, a theorem about the preservation of a binary search tree after an insertion relation, below. I'm not sure how to use the induction hypothesis which relies on the nested Inductive definitions, namely SearchTree's single constructor calls on SearchTree'. Once I instantiate and invert the IH, though, we are given an arguement hi0 which is incomparable to k?
....
H1 : SearchTree' 0 (insert k0 v0 l) hi0
H2 : k0 < k
============================
SearchTree' 0 (insert k0 v0 l) k
Is my approach to this proof flawed, or is there a trick to make them comparable? I had thought to try to prove something like
Theorem insert_SearchTree'':
forall k v t hi,
SearchTree' 0 t hi -> SearchTree' 0 (insert k v t) hi .
Proof.
but after attempting I realized this is not equivalent (and I think unproveable, although I'm not sure)... Any advice is welcome. Most of the code is auxiliary, and I included it based on the advice that questions be stand-alone.
Require Export Coq.Arith.Arith.
Require Export Coq.Arith.EqNat.
Require Export Coq.omega.Omega.
Notation "a >=? b" := (Nat.leb b a)
(at level 70, only parsing) : nat_scope.
Notation "a >? b" := (Nat.ltb b a)
(at level 70, only parsing) : nat_scope.
Notation " a =? b" := (beq_nat a b)
(at level 70) : nat_scope.
Print reflect.
Lemma beq_reflect : forall x y, reflect (x = y) (x =? y).
Proof.
intros x y.
apply iff_reflect. symmetry. apply beq_nat_true_iff.
Qed.
Lemma blt_reflect : forall x y, reflect (x < y) (x <? y).
Proof.
intros x y.
apply iff_reflect. symmetry. apply Nat.ltb_lt.
Qed.
Lemma ble_reflect : forall x y, reflect (x <= y) (x <=? y).
Proof.
intros x y.
apply iff_reflect. symmetry. apply Nat.leb_le.
Qed.
Hint Resolve blt_reflect ble_reflect beq_reflect : bdestruct.
Ltac bdestruct X :=
let H := fresh in let e := fresh "e" in
evar (e: Prop);
assert (H: reflect e X); subst e;
[eauto with bdestruct
| destruct H as [H|H];
[ | try first [apply not_lt in H | apply not_le in H]]].
Section TREES.
Variable V : Type.
Variable default: V.
Definition key := nat.
Inductive tree : Type :=
| E : tree
| T: tree -> key -> V -> tree -> tree.
Inductive SearchTree' : key -> tree -> key -> Prop :=
| ST_E : forall lo hi, lo <= hi -> SearchTree' lo E hi
| ST_T: forall lo l k v r hi,
SearchTree' lo l k ->
SearchTree' (S k) r hi ->
SearchTree' lo (T l k v r) hi.
Inductive SearchTree: tree -> Prop :=
| ST_intro: forall t hi, SearchTree' 0 t hi -> SearchTree t.
Fixpoint insert (x: key) (v: V) (s: tree) : tree :=
match s with
| E => T E x v E
| T a y v' b => if x <? y then T (insert x v a) y v' b
else if y <? x then T a y v' (insert x v b)
else T a x v b
end.
Theorem insert_SearchTree:
forall k v t,
SearchTree t -> SearchTree (insert k v t).
Proof.
clear default.
intros.
generalize dependent v.
generalize dependent k.
induction H.
induction H.
- admit.
- intros.
specialize (IHSearchTree'1 k0 v0).
inversion IHSearchTree'1.
subst.
simpl.
bdestruct (k0 <? k).
apply (ST_intro _ hi0 ).
constructor.
admit.
End TREES.
The goal is currently too weak when you start induction. At the beginning of the second case, the goal looks like this:
H : SearchTree' lo l k
H0 : SearchTree' (S k) r hi
IHSearchTree'1 : forall (k : key) (v : V), SearchTree (insert k v l)
IHSearchTree'2 : forall (k : key) (v : V), SearchTree (insert k v r)
============================
forall (k0 : key) (v0 : V), SearchTree (insert k0 v0 (T l k v r))
and the high-level idea to go on is to combine H and IHSearchTree'2, or H0 and IHSearchTree'1, depending on which side the insertion goes. But this is impossible because the SearchTree predicate in the two IH assumptions is not compositional: knowing only that insert k0 v0 l is a search tree does not help to know whether a tree containing it, T (insert k0 v0 l) k v r, is also a search tree. So the proof doesn't go through.
When putting search trees together, we don't just want to know that something is a search tree. We also want to know some bounds on the keys (here in particular, they must be bounded by k). This is what the auxiliary predicate SearchTree' provides. This matter of compositionality is precisely why SearchTree is defined using an auxiliary inductive predicate SearchTree', which is compositional (it can be, and is, defined in terms of itself).
Properties about recursive functions on trees mentioning SearchTree should first be generalized as more informative properties using SearchTree' so induction can go through. It will look like this:
Lemma insert_SearchTree' :
forall t k0 v0 ??? ,
SearchTree' ??? t ??? -> SearchTree' ??? (insert k0 v0 t) ???.
There are multiple valid ways of filling these "???" blanks. Coming up with new ones is a good exercise for the reader. One way that should work well here and many other situations is to put variables for all the missing arguments of predicates, and then figure out some suitable relation between them:
Lemma insert_SearchTree' :
forall t k0 v0 lo hi lo' hi',
??? (* find a suitable assumption *) ->
SearchTree' lo t hi -> SearchTree' lo' (insert k0 v0 t) hi'.
The relation should reflect the behavior of insert. What insert does, as far as those bounds are concerned, is to add the key k0 to the tree, so the bounds must bound that, in addition to the rest of the tree:
Lemma insert_SearchTree' :
forall t k0 v0 lo hi lo' hi',
lo' <= lo -> hi <= hi' ->
lo' <= k0 -> k0 < hi' ->
SearchTree' lo t hi -> SearchTree' lo' (insert k0 v0 t) hi'.
Finally, since we're going to use induction on the SearchTree' lo t hi assumption, it's desirable to move most variables and hypotheses that it does not mention to the right, to strengthen the induction hypothesis further (as far as I can tell, this is always safe to do):
Lemma insert_SearchTree' :
forall t k0 v0 lo hi, (* k0 and v0 remain constant throughout the recursive applications of (insert k0 v0), so they can stay here (it would still be fine if they are moved with the rest). *)
SearchTree' lo t hi ->
forall lo' hi', (* The bounds are going to change at every step, so they move to the right of the inductive predicate. *)
lo' <= lo -> hi <= hi' ->
lo' <= k0 -> k0 < hi' ->
SearchTree' lo' (insert k0 v0 t) hi'.
Proving this lemma and using it to prove insert_SearchTree is left as an exercise for the reader.

Coq proof that complement is involutive

How can I prove that the complement of a set is involutive?
Require Import Ensembles. Arguments In {_}. Arguments Complement {_}.
Variables (T:Type) (A:Ensemble T).
Axiom set_eq: forall (E1 E2:Ensemble T), (forall x, E1 x <-> E2 x) -> E1 = E2.
Lemma complement_involutive:
forall x, In (Complement (Complement A)) x -> In A x.
EDIT: Assuming decidable (In A x) enables firstorder to prove the lemma completely.
complement_involutive is exactly ~ ~ A x -> A x which is well-known to be equivalent to excluded middle, in this case in Type, thus not provable in Coq without assuming it as an axiom. See this answer https://math.stackexchange.com/questions/1370805/why-cant-you-prove-the-law-of-the-excluded-middle-in-intuitionistic-logic-for

How to prove excluded middle is irrefutable in Coq?

I was trying to prove the following simple theorem from an online course that excluded middle is irrefutable, but got stuck pretty much at step 1:
Theorem excluded_middle_irrefutable: forall (P:Prop), ~~(P \/ ~ P).
Proof.
intros P. unfold not. intros H.
Now I get:
1 subgoals
P : Prop
H : P \/ (P -> False) -> False
______________________________________(1/1)
False
If I apply H, then the goal would be P \/ ~P, which is excluded middle and can't be proven constructively. But other than apply, I don't know what can be done about the hypothesis P \/ (P -> False) -> False: implication -> is primitive, and I don't know how to destruct or decompose it. And this is the only hypothesis.
My question is, how can this be proven using only primitive tactics (as characterized here, i.e. no mysterious autos)?
Thanks.
I'm not an expert on this subject, but it was recently discussed on the Coq mailing-list. I'll summarize the conclusion from this thread. If you want to understand these kinds of problems more thoroughly, you should look at double-negation translation.
The problem falls within intuitionistic propositional calculus and can thus be decided by tauto.
Theorem excluded_middle_irrefutable: forall (P:Prop), ~~(P \/ ~ P).
tauto.
Qed.
The thread also provides a more elaborate proof. I'll attempt to explain how I would have come up with this proof. Note that it's usually easier for me to deal with the programming language interpretation of lemmas, so that's what I'll do:
Theorem excluded_middle_irrefutable: forall (P:Prop), ~~(P \/ ~ P).
unfold not.
intros P f.
We are asked to write a function that takes the function f and produces a value of type False. The only way to get to False at this point is to invoke the function f.
apply f.
Consequently, we are asked to provide the arguments to the function f. We have two choices, either pass P or P -> False. I don't see a way to construct a P so I'm choosing the second option.
right.
intro p.
We are back at square one, except that we now have a p to work with!
So we apply f because that's the only thing we can do.
apply f.
And again, we are asked to provide the argument to f. This is easy now though, because we have a p to work with.
left.
apply p.
Qed.
The thread also mentions a proof that is based on some easier lemmas. The first lemma is ~(P /\ ~P).
Lemma lma (P:Prop) : ~(P /\ ~P).
unfold not.
intros H.
destruct H as [p].
apply H.
apply p.
Qed.
The second lemma is ~(P \/ Q) -> ~P /\ ~Q:
Lemma lma' (P Q:Prop) : ~(P \/ Q) -> ~P /\ ~Q.
unfold not.
intros H.
constructor.
- intro p.
apply H.
left.
apply p.
- intro q.
apply H.
right.
apply q.
Qed.
These lemmas suffice to the show:
Theorem excluded_middle_irrefutable: forall (P:Prop), ~~(P \/ ~ P).
intros P H.
apply lma' in H.
apply lma in H.
apply H.
Qed.

How to prove (R -> P) [in the Coq proof assistant]?

How does one prove (R->P) in Coq. I'm a beginner at this and don't know much of this tool. This is what I wrote:
Require Import Classical.
Theorem intro_neg : forall P Q : Prop,(P -> Q /\ ~Q) -> ~P.
Proof.
intros P Q H.
intro HP.
apply H in HP.
inversion HP.
apply H1.
assumption.
Qed.
Section Question1.
Variables P Q R: Prop.
Hypotheses H1 : R -> P \/ Q.
Hypotheses H2 : R -> ~Q.
Theorem trans : R -> P.
Proof.
intro HR.
apply NNPP.
apply intro_neg with (Q := Q).
intro HNP.
I can only get to this point.
The subgoals at this point are:
1 subgoals
P : Prop
Q : Prop
R : Prop
H1 : R -> P \/ Q
H2 : R -> ~ Q
HR : R
HNP : ~ P
______________________________________(1/1)
Q /\ ~ Q
You can use tauto to prove it automatically:
Section Question1.
Variables P Q R: Prop.
Hypotheses H1 : R -> P \/ Q.
Hypotheses H2 : R -> ~Q.
Theorem trans : R -> P.
Proof.
intro HR.
tauto.
Qed.
If you want to prove it manually, H1 says that given R, either P or Q is true. So if you destruct H1, you get 3 goals. One to prove the premise (R), one to prove the goal (P) using the left conclusion (P) of the or, and one to prove the goal (P) using the right conclusion (Q).
Theorem trans' : R -> P.
Proof.
intro HR.
destruct H1.
- (* Prove the premise, R *)
assumption.
- (* Prove that P is true given that P is true *)
assumption.
- (* Prove that P is true given that Q is false *)
contradiction H2.
Qed.
End Question1.

Proving (p->q)->(~q->~p) using Coq Proof Assistant

I am fairly new to Coq and am trying out sample lemmas from Ruth and Ryan. The proof using natural deduction is pretty trivial, and this is what I want to prove using Coq.
assume p -> q.
assume ~q.
assume p.
q.
False.
therefore ~p.
therefore ~q -> ~p.
therefore (p -> q) => ~q => ~p.
I am stuck at the line 3 assume p.
Can someone please tell me if there is an one-to-one mapping from natural deduction to Coq keywords?
NNPP is useless !
Theorem easy : forall p q:Prop, (p->q)->(~q->~p).
Proof. intros. intro. apply H0. apply H. exact H1. Qed.
You can start your proof like this:
Section CONTRA.
Variables P Q : Prop.
Hypothesis PimpQ : P -> Q.
Hypothesis notQ : ~Q.
Hypothesis Ptrue : P.
Theorem contra : False.
Proof.
Here is the environment at that point:
1 subgoal
P : Prop
Q : Prop
PimpQ : P -> Q
notQ : ~ Q
Ptrue : P
============================
False
You should be able to continue the proof. It will be a bit more verbose than your proof (on line 4 you just wrote q, here you will have to prove it by combining PimpQ and Ptrue. It should be fairly trivial though... :)
Not that difficult, actually.
Just played around, introduced a double negation, and things fell flat automatically. This is how the proof looks like.
Theorem T1 : (~q->~p)->(p->q).
Proof.
intros.
apply NNPP.
intro.
apply H in H1.
contradiction.
Qed.
Ta daaaa!

Resources