how do I prove forall P Q : Prop, ((((P -> Q) -> P) -> P) -> Q) ->Q. in coq? - coq

I am very new to coq so if you only say intros. I don't know what to introduce. So being specific like (Ex. intros p q.) would be very helpful.

Fortunately, your goal can be automatically solved by the auto tactic.
If you use its variant info_auto, Coq tells you which steps lead to the solution .
Goal forall P Q : Prop, ((((P -> Q) -> P) -> P) -> Q) -> Q.
info_auto.
Then, you may replay the proof by yourself, and add comments and explicit variables names to the introstactics, and you will understand the
strategy used by auto (what to do when the conclusion is a forall or an implication, or an atomic proposition).
Restart.
intros P Q H.
apply H (* no-choice ! *).
intro H0.
apply H0. (* no other possibility ! *)
intro p.
apply H. (* no alternative ! *)
intros _.
assumption.
Qed.

Related

How to prove forall (p q:Prop), ~p->~((p ->q) ->p). using coq

I am completely new to coq programming and unable to prove below theorem. I need help on steps how to solve below construct?
Theorem PeirceContra: forall (p q:Prop), ~p->~((p ->q) ->p).
I tried the proof below way.
Given axiom as Axiom classic : forall P:Prop, P \/ ~ P.
Theorem PeirceContra: forall (p q:Prop), ~ p -> ~((p -> q) -> p).
Proof.
unfold not.
intros.
apply H.
destruct (classic p) as [ p_true | p_not_true].
- apply p_true.
- elimtype False. apply H.
Qed.
Getting subgoal after using elimtype and apply H as
1 subgoal
p, q : Prop
H : p -> False
H0 : (p -> q) -> p
p_not_true : ~ p
______________________________________(1/1)
p
But now I am stuck here because I am unable to prove P using p_not_true construct of given axiom......Please suggest some help......
I am not clear how to use the given axiom to prove logic................
This lemma can be proved constructively. If you think about what can be done at each step to make progress the lemma proves itself:
Lemma PeirceContra :
forall P Q, ~P -> ~((P -> Q) -> P).
Proof.
intros P Q np.
unfold "~".
intros pq_p.
apply np. (* this is pretty much the only thing we can do at this point *)
apply pq_p. (* this is almost inevitable too *)
(* the rest should be easy *)
(* Qed. *)

Proving (~A -> ~B)-> (~A -> B) -> A in Coq

I have been trying to prove the following tautology in Coq.
Theorem Axiom3: forall A B: Prop, (~A -> ~B)-> ((~A -> B) -> A).
My plan was the to do following
Theorem Axiom3: forall A B: Prop, (~A -> ~B)-> ((~A -> B) -> A).
Proof.
intros A B.
unfold not.
intros nA_implies_nB.
intros nA_implies_B.
pose (proof_of_False := nA_implies_nB nA_implies_B).
case proof_of_False.
Qed.
However, the following is where my issues lies.
pose (proof_of_False := nA_implies_nB nA_implies_B).
I cannot simply compose together the following to get a proof for false.
nA_implies_nB : (A -> False) -> B -> False
nA_implies_B : (A -> False) -> B
Can my proof be adapted to make or correct or is there an easy way to prove this theorem?
This statement is equivalent to the principle of the excluded middle, which says that A \/ ~A holds for any proposition A. The excluded middle is notorious for its absence in Coq and other systems based on constructive mathematics. To prove the statement in Coq, you must explicitly declare that you want to assume non-constructive reasoning.
Require Import Coq.Logic.Classical.
Theorem Axiom3: forall A B: Prop, (~A -> ~B)-> ((~A -> B) -> A).
Proof. intros A B. tauto. Qed.
If you comment out the first line, you will see that the proof fails, because Coq will not attempt to use the excluded middle in the proof.
In case you are curious, here is a more explicit proof of how Axiom3 implies the excluded middle:
Axiom Axiom3: forall A B: Prop, (~A -> ~B)-> ((~A -> B) -> A).
Lemma classical : forall A : Prop, A \/ ~ A.
Proof.
intros A.
apply (Axiom3 (A \/ ~A) (A \/ ~A)).
- trivial.
- intros H. exfalso.
assert (H' : ~ ~ A).
{ intros HA. apply H. right. trivial. }
apply H'. intros HA. apply H. left. trivial.
Qed.

How does `auto` interract with biconditional (iff)

I noticed, that auto is ignoring biconditionals. Here is a simplified example:
Parameter A B : Prop.
Parameter A_iff_B : A <-> B.
Theorem foo1: A -> B.
Proof.
intros H. apply A_iff_B. assumption.
Qed.
Theorem bar1: B -> A.
Proof.
intros H. apply A_iff_B. assumption.
Qed.
Theorem foo2_failing: A -> B.
Proof.
intros H. auto using A_iff_B.
Abort.
Theorem bar2_failing: B -> A.
Proof.
intros H. auto using A_iff_B.
Abort.
Now, I know that A <-> B is a syntactic sugar for A -> B /\ B -> A so I wrote two theorems to extract one or the other:
Theorem iff_forward : forall {P Q : Prop},
(P <-> Q) -> P -> Q.
Proof.
intros P Q H. apply H.
Qed.
Theorem iff_backward : forall {P Q : Prop},
(P <-> Q) -> Q -> P.
Proof.
intros P Q H. apply H.
Qed.
Theorem foo3: A -> B.
Proof.
intros H.
auto using (iff_forward A_iff_B).
Qed.
Theorem bar3: B -> A.
Proof.
intros H.
auto using (iff_backward A_iff_B).
Qed.
How come apply A_iff_B works and auto using A_iff_B does not? I
thought that auto n is performing an exhaustive search of all
possible sequences of apply of length <= n using the hypotheses
and all theorems in a given database.
Is there a standard trick for working with biconditionals or are
those two projection functions the usual solution?
Are such projection functions somewhere in the standard library? I
could not found them.
How come apply A_iff_B works and auto using A_iff_B does not?
auto generally uses simple apply instead of apply and this restricted version of apply does not handle biconditionals.
Is there a standard trick for working with biconditionals or are those two projection functions the usual solution?
You can use Hint Resolve -> (<-) feature for that:
Hint Resolve -> A_iff_B.
Hint Resolve <- A_iff_B. (* if you remove this one, then `auto` won't be able to prove the `bar3` theorem *)
Theorem foo3: A -> B.
Proof. info_auto. Qed. (* look at the output *)
Are such projection functions somewhere in the standard library?
Yes, they are called: proj1 and proj2. Here is how you can find them:
Search (?A /\ ?B -> ?A).
Or a bit easier to type, but finds a tad more stuff than we need:
Search (_ /\ _ -> _).

Why can't inversion be used on a universally qualified hypothesis in Coq?

I've been going through the Software Foundations course and found the following proof (source link).
Theorem not_exists_dist :
excluded_middle ->
forall (X:Type) (P : X -> Prop),
~ (exists x, ~ P x) -> (forall x, P x).
Proof.
unfold not. intros.
unfold excluded_middle in H.
assert ((P x) \/ ((P x) -> False)) as HP.
apply H with (P:=(P x)).
inversion HP.
apply H1.
apply ex_falso_quodlibet. apply H0. exists x. apply H1.
Qed.
I'm curious, why is there an assertion saying (P x) \/ ((P x) -> False), when if I unfold excluded_middle in H and unfold not in H, I'll get the exact same H : forall P : Prop, P \/ (P -> False) as the assertion, only that there's a universal quantifier.
This is even more obvious as the assertion can be proved just by doing apply H, and the whole reason for this step is to do inversion HP on the newly asserted hypothsesis.
The question is, why isn't it possible to do inversion H at the beginning directly, and spare the extra step of defining an assertion, which just copies one of the assumptions? Is there a better way to do this?
inversion only works on things of inductive type, such as or. forall is not an inductive type constructor, hence one cannot perform inversion on it. One could maybe extend inversion to behave like (e)destruct: if you give it something that is universally quantified, it'll generate additional existentials and proof obligations that you need to fulfill to fill in the missing spots, as well as destructing the conclusion. However, this is not how it works right now...
One could do a more direct proof by just applying H and destructing it directly:
Theorem not_exists_dist :
excluded_middle ->
forall (X:Type) (P : X -> Prop),
~ (exists x, ~ P x) -> (forall x, P x).
Proof.
intros.
destruct (H (P x)).
apply H1.
exfalso. apply H0. exists x. apply H1.
Qed.

induction hypothesis for even numbers

I am trying to write an induction hypothesis specifically for proving properties of even numbers. I formulated and proved the following:
Theorem ind_hyp_on_evens:
forall (p : nat -> Prop),
(p 0 -> (forall n, p n -> p (S (S n))) ->
forall n, p (n + n)).
Proof.
intros p P0 P1.
intro n.
assert(p (n + n) /\ p (S (S (n + n)))).
induction n as [| n'].
split. unfold plus. assumption.
unfold plus.
apply (P1 0).
assumption.
destruct IHn' as [A B].
split.
rewrite <- plus_Snm_nSm.
rewrite -> ? plus_Sn_m.
assumption.
rewrite <- plus_Snm_nSm.
rewrite -> ? plus_Sn_m.
apply (P1 (S (S (n' + n')))).
assumption.
destruct H as [H1 H2].
assumption. Qed.
Despite the fact that it's proved, any attempt to use it results in the error message: "Error: Not the right number of induction arguments."
Can someone please tell me what is the problem with the induction hypothesis, or otherwise, how to apply it??
Thanks,
Mayer
I believe induction assumes that any induction principle that will be used has the
fixed form
forall ... (P : SomeType -> Type) ..., (* or ->Set or ->Prop *)
... ->
forall (v : SomeType), P v
Your ind_hyp_on_evens matches only P (plus n n) which seems to confuse induction.
If you have a suitable goal, say forall n, is_even (n+n), you can manually do the
steps that induction normally does and extend that to handle the special form.
intro n0; (* temp. var *)
pattern (n0 + n0); (* restructure as (fun x => (is_even x)) (n0+n0) *)
refine (ind_hyp_on_evens _ _ _ n0); (* apply ind. scheme *)
clear n0; [| intros n IHn ]. (* clear temp., do one 'intros' per branch *)
I don't know if it's possible to pack that up as a general helper tactic for any induction scheme, packing these steps up as a per-scheme Ltac tactic should work however.
You could consider writing an inductive predicate that describes even numbers (code not tested):
Inductive even : nat -> Prop :=
| evenO : even O
| evenSSn : forall n, even n -> even (S (S n))
.
Coq will generate the induction principle automatically.
You would have to prove that even n holds before being able to perform induction on the "evenness" of n.