Coq use refine with bi-implication - coq

I'm not sure how to word my question, because I'm new to coq. I want to use refine with a theorem that includes bi-implication. Example code:
Parameters A B C : Prop.
Theorem t1:
A -> B -> C.
Admitted.
Theorem t2:
A -> B <-> C.
Admitted.
Theorem test1:
A -> B -> C.
Proof.
intros.
refine (t1 _ _).
assumption.
assumption.
Qed.
Theorem test2:
A -> B -> C.
Proof.
intros A B.
refine (t2 _ _).
t1 and t2 are theorems I want to use in refine. t1 works how i expect (shown in test1). But i have a problem with t2. The error I get is:
Ltac call to "refine (uconstr)" failed.
Error: Illegal application (Non-functional construction):
The expression "t2 ?a" of type "Top.B <-> C"
cannot be applied to the term
"?y" : "?T"
Not in proof mode.
What I have tried is something like this:
Theorem test3:
A -> B -> C.
Proof.
intros.
cut (B <-> C).
firstorder.
refine (t2 _).
assumption.
Qed.
But with longer props and proofs, it becomes a bit messy. (Also I have to prove the bi-implication myself). Can I use t2 and get its subgoals in a simpler way?
Thanks

A <-> B is defined as (A -> B) /\ (B -> A) so you can project with proj1, proj2:
Theorem test2:
A -> B -> C.
Proof.
intros A B.
refine (proj1 (t2 _) _).

Related

Using or_comm in Coq

I want to prove the following theorem:
Theorem T14 : forall s t u,
S u s t <-> S u t s.
Where S is defined like this:
Definition S u s t := forall v,
((ObS u v) <-> (ObS v s \/ ObS v t)).
The first tactics I used are:
Proof.
intros s t u.
unfold S.
And my goal is now:
1 subgoal
s, t, u : Entity
______________________________________(1/1)
(forall v : Entity, ObS u v <-> ObS v s \/ ObS v t) <->
(forall v : Entity, ObS u v <-> ObS v t \/ ObS v s)
It feels like the proof can be finished if I use the commutativity of the OR operator, and then apply the tauto tactic. However, I don't know how to rewrite the inner bit of only the right part of the equivalence. Is it possible?
This can be done using generalized rewriting.
Require Setoid.
Use setoid_rewrite because you are rewriting under a binder (forall v). (Without binders, rewrite would be sufficient).
It works out-of-the-box in this case, but when your project gets more sophisticated, with your own combinators/logical connectives, some work will be necessary to ensure that "rewriting" is sound. The reference manual describes the set up required by generalized rewriting.
(* 1 *)
Require Import Setoid.
Parameter T : Type.
Parameter ObS : T -> T -> Prop.
Definition S u s t := forall v,
((ObS u v) <-> (ObS v s \/ ObS v t)).
Theorem T14 : forall s t u,
S u s t <-> S u t s.
Proof.
intros s t u.
unfold S.
(* 2 *)
setoid_rewrite (or_comm (ObS _ s)).
reflexivity.
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.

How to project (with `proj1` or `proj2`) a universally quantified biconditional (iff)?

How to project (with proj1 or proj2) a universally quantified biconditional (iff) such as in the following example?
Parameter T : Set.
Parameter P Q R: T -> Prop.
Parameter H : forall (t : T), P t <-> Q t.
When I try to use proj1 H, it fails with the following error:
Error: The term "H" has type "forall t : T, P t <-> Q t" while it is
expected to have type "?A /\ ?B".
While I would like to get forall (t : T), P t -> Q t.
Edit
Using the suggested solution, I have now two ways to project the biconditional:
Theorem proj1' : (forall t, P t <-> Q t) -> forall t, P t -> Q t.
Proof.
intros H t.
exact (proj1 (H t)).
Qed.
Theorem foo : forall (t1 t2 : T),
(R t1 -> P t1) ->
(R t2 -> P t2) ->
R t1 /\ R t2 -> Q t1 /\ Q t2.
Proof.
intros t1 t2 H1 H2 [H3 H4].
(* Does not solve the goal, as expected. *)
auto using H.
(* Solves the goal, but is unnecessary explicit. *)
(* auto using (proj1 (H t1)), (proj1 (H t2)). *)
(* Solves the goal and instanciations are infered. *)
auto using (proj1' H).
Qed.
Now, a function such as proj1' seems to be quite useful. If it is not offered in the standard library, is it because such situations are actually not happening often enough to justify it, or is it simply an historical accident?
I do realize that a distinct function would be require for two, three, etc. universal quantification (e.g. proj1'' : (forall t u, P t u <-> Q t u) -> forall t u, P t u -> Q t u). But wouldn't functions for up to three or four arguments be enough for most cases?
Related
How does `auto` interract with biconditional (iff)
Since a term of type forall (t : T), P t <-> Q t is a function, you need to apply it to a t of type T to get access to the body, which is a pair of proofs:
Goal (forall t, P t <-> Q t) -> forall t, P t -> Q t.
Proof.
intros H t.
exact (proj1 (H t)).
Qed.
The above is like the following (modulo transparency):
Definition proj1' : (forall t, P t <-> Q t) -> forall t, P t -> Q t :=
fun H t => proj1 (H t).
Respond to Edit
One can suggest many proofs of the foo theorem. I wouldn't use proj1' in any of them:
Theorem foo t1 t2 : (R t1 -> P t1) -> (R t2 -> P t2) ->
P t1 /\ P t2 -> Q t1 /\ Q t2.
Solution 1
apply is one smart tactic, it can handle biconditionals:
Proof. now split; apply H. Qed.
Solution 2
intros can apply lemmas when moving stuff to the context:
Proof. now intros _ _ [H3%H H4%H]. Qed.
It's like SSReflects's by move=> _ _ [/H H3 /H H4].
Solution 3
Coq can use biconditionals to do rewrites if you Require Import Setoid. first:
Proof. now rewrite !H. Qed.
! in front of a term means "rewrite as many times as you can, but at least once".

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 (_ /\ _ -> _).