Rewrite hypothesis in Coq, keeping implication - coq

I'm doing a Coq proof. I have P -> Q as a hypothesis, and (P -> Q) -> (~Q -> ~P) as a lemma. How can I transform the hypothesis into ~Q -> ~P?
When I try to apply it, I just spawn new subgoals, which isn't helpful.
Put another way, I wish to start with:
P : Prop
Q : Prop
H : P -> Q
and end up with
P : Prop
Q : Prop
H : ~Q -> ~P
given the lemma above - i.e. (P -> Q) -> (~Q -> ~P).

This is not as elegant as just an apply, but you can use pose proof (lemma _ _ H) as H0, where lemma is the name of your lemma. This will add another hypothesis with the correct type to the context, with the name H0.

This is one case where ssreflect views do help:
From Coq Require Import ssreflect.
Variable (P Q : Prop).
Axiom u : (P -> Q) -> (~Q -> ~P).
Lemma test (H : P -> Q) : False.
Proof. move/u in H. Abort.
apply u in H does also work, however it is too smart for its own good and does too much.

If I wanted to transform H in place I would go with #ejgallego's answer, since SSReflect is now (starting from Coq 8.7.0) a part of standard Coq, but here is another option:
Ltac dumb_apply_in f H := generalize (f H); clear H; intros H.
Tactic Notation "dumb" "apply" constr(f) "in" hyp(H) := dumb_apply_in f H.
A simple test:
Variable (P Q : Prop).
Axiom u : (P -> Q) -> (~Q -> ~P).
Lemma test (H : P -> Q) : False.
Proof. dumb apply u in H. Abort.

Related

The missing De Morgan's law

Coq uses constructive logic, which means that if you try to fill out
De Morgan's laws, you'll end up missing 2.
Namely, you can't prove:
Theorem deMorgan_nand P Q (andPQ : ~(P /\ Q)) : P \/ Q.
Abort.
Theorem deMorgan_nall {A} (P : A -> Prop) (allPa : ~forall a, P a) : exists a, ~P a.
Abort.
This makes sense, because you've have to compute whether it was
the left or right item of the or, which you can't do in general.
Looking at
"Classical Mathematics for a Constructive World"
(https://arxiv.org/pdf/1008.1213.pdf)
has the definitions
Definition orW P Q := ~(~P /\ ~Q).
Definition exW {A} (P : A -> Prop) := ~forall a, ~P a.
similar to De Morgan's law. This suggests an alternative formulation.
Theorem deMorgan_nand P Q (andPQ : ~(P /\ Q)) : orW (~P) (~Q).
hnf; intros nnPQ; destruct nnPQ as [ nnP nnQ ].
apply nnP; clear nnP; hnf; intros p.
apply nnQ; clear nnQ; hnf; intros q.
apply (andPQ (conj p q)).
Qed.
Theorem deMorgan_nall {A} (P : A -> Prop) (allPa : ~forall a, P a) : exW (fun a => ~P a).
Abort.
But, it doesn't work with negating forall. In particular, it gets stuck on
trying to convert ~~P a into P a. So, despite in the nand case
converting ~~P into P, it doesn't seem to work with forall.
You can also show that there is some element of a that has
P a.
Similarly, you could try to show
Theorem deMorgan_nexn {A} (P : A -> Prop) (exPa : ~exists a, ~P a) : ~~forall a, P a.
Abort.
but that gets stuck in that once you have the argument a,
the conclusion is no longer False, so you can't use ~~P -> P.
So, if you can't prove deMorgan_nall, is there any theorem like it?
Or is ~forall a, P a already as simplified as it can get?
More generally, when the conclusion is False, that allows for using
the law of excluded middle (P \/ ~P). Is there any counterpart
to that that works when the proposition takes an argument, that is
P : A -> Prop instead of P : Prop ?
The principle you are looking for is known as double negation shift. It is not valid in intuitionistic logic in general. Despite looking fairly innocuous at first, as its conclusion is a doubly-negated formula, it is actually quite potent. Indeed, DNS is essentially what is needed in order to interpret the axiom of choice through the double-negation translation.
Edit by scubed:
So, that means I have to add an axiom to handle this case. Using the axiom,
Axiom deMorgan_allnn : forall {A} (P : A -> Prop) (allPa : forall a, ~~P a), ~~forall a, P a.
Theorem deMorgan_nall {A} (P : A -> Prop) (allPa : ~forall a, P a) : exW (fun a => ~P a).
hnf; intros ex1; apply deMorgan_allnn in ex1.
apply ex1; clear ex1; hnf; intros all2.
apply (allPa all2).
Qed.

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.

Is there any thing like apply lem in *?

Is there any way to call apply lem in H for every possible H in premises, like rewrite lem in *?
Axiom P Q : nat -> Prop.
Axiom lem : forall (n : nat), P n -> Q n.
Goal P O -> P (S O) -> True.
intros. apply lem in H. apply lem in H0.
I couldn't find anything built in, but it's possible to write such a tactic with Ltac.
First, the special case.
Axiom P Q : nat -> Prop.
Axiom lem : forall (n : nat), P n -> Q n.
Goal P O -> P (S O) -> True.
intros.
repeat match goal with
x : _ |- _ => apply lem in x
end.
Abort.
Now we can generalize this
Ltac apply_in_premises t :=
repeat match goal with
x : _ |- _ => apply t in x
end.
and use it like this:
Goal P O -> P (S O) -> True.
intros.
apply_in_premises lem.
Abort.
Unfortunately, this way of doing it can cause an infinite loop if applying lem produces something else that lem can be applied to.
Axiom P : nat -> Prop.
Axiom lem : forall (n : nat), P n -> P (S n).
Ltac apply_in_premises t :=
repeat match goal with
x : _ |- _ => apply t in x
end.
Goal P O -> P (S O) -> nat -> True.
intros.
apply_in_premises lem. (* infinite loop *)
Abort.
If this is a concern for you, you can use a variant suggested by Yves in the comments. Simply changing apply t in x to apply t in x; revert x will ensure that that hypothesis won't be matched again. However, the end result will have all the hypotheses in the goal, like P -> G, instead of p: P as a premise and G as the goal.
To automatically reintroduce these hypotheses, we can keep track of how many times a hypothesis was reverted, then introduce them again.
Ltac intro_n n :=
match n with
| 0 => idtac
| S ?n' => intro; intro_n n'
end.
Ltac apply_in_premises_n t n :=
match goal with
| x : _ |- _ => apply t in x; revert x;
apply_in_premises_n t (S n)
| _ => intro_n n (* now intro all the premises that were reverted *)
end.
Tactic Notation "apply_in_premises" uconstr(t) := apply_in_premises_n t 0.
Axiom P : nat -> Prop.
Axiom lem : forall (n : nat), P n -> P (S n).
Goal P O -> P (S O) -> nat -> True.
intros.
apply_in_premises lem. (* only applies `lem` once in each of the premises *)
Abort.
Here, the tactic intro_n n applies intro n times.
I haven't tested this in general, but it works well in the case above. It might fail if a hypothesis can't be reverted (for example, if some other hypothesis depends on it). It also may reorder the hypotheses, since when a reverted hypothesis is reintroduced, it's put on the end of the hypothesis list.

Subtyping in Coq

I defined Subtype as follows
Record Subtype {T:Type}(P : T -> Prop) := {
subtype :> Type;
subtype_inj :> subtype -> T;
subtype_isinj : forall (s t:subtype), (subtype_inj s = subtype_inj t) -> s = t;
subtype_h : forall (x : T), P x -> (exists s:subtype,x = subtype_inj s);
subtype_h0 : forall (s : subtype), P (subtype_inj s)}.
Can the following theorem be proven?
Theorem Subtypes_Exist : forall {T}(P : T -> Prop), Subtype P.
If not, is it provable from any well-known compatible axiom? Or Can I add this as an axiom? Would it conflict with any usual axiom?(like extensionality, functional choice, etc.)
Your definition is practically identical to the one of MathComp; indeed, what you are missing mainly is injectivity due to proof relevance.
For that, I am afraid you will need to assume propositional irrelevance:
Require Import ProofIrrelevance.
Theorem Subtypes_Exist : forall {T}(P : T -> Prop), Subtype P.
Proof.
intros T P; set (subtype_inj := #proj1_sig T P).
apply (#Build_Subtype _ _ { x | P x} subtype_inj).
+ intros [s Ps] [t Pt]; simpl; intros ->.
now rewrite (proof_irrelevance _ Ps Pt).
+ now intros x Px; exists (exist _ x Px).
+ now destruct 0.
Qed.
You can always restrict you predicate P to a type which is effectively proof-irrelevant, of course.