Prove that one hypothesis is negation of another in Coq - coq

For example I have these two hypotheses (one is negation of other)
H : forall e : R, e > 0 -> exists p : X, B e x p -> ~ F p
H0 : exists e : R, e > 0 -> forall p : X, B e x p -> F p
And goal
False
How to prove it?

You can't, because H0 is not the negation of H. The correct statement would be
Definition R := nat.
Parameter X: Type.
Parameter T: Type.
Parameter x: T.
Parameter B : R -> T -> X -> Prop.
Parameter F : X -> Prop.
Lemma foobar: forall (H: forall e : R, e > 0 -> exists p : X, B e x p -> ~ F p)
(H0: exists e: R, e > 0 /\ forall p: X, B e x p /\ F p), False.
Proof.
intros H H0.
destruct H0 as [e [he hforall]].
destruct (H e he) as [p hp].
destruct (hforall p) as [hB hF].
exact (hp hB hF).
Qed.

Related

Cannot apply one hypothesis to another

I am very new to Coq and I'm trying to prove that if two functions are injectives, the composition of theses two functions is also injective.
Here is my code:
Definition compose {A B C} (g: B -> C) (f: A -> B) :=
fun x : A => g (f x).
Definition injective {A B} (f: A -> B) :=
forall x1 x2, f x1 = f x2 -> x1 = x2.
(*
Definition surjective {A B} (f: A -> B) :=
forall y: B, exists x: A, f x = y.
*)
Theorem example {A B C} (g: B -> C) (f: A -> B) :
injective f /\ injective g -> injective (compose g f).
Proof.
intros.
destruct H as (H1,H2).
cut (forall x1 x2: A, (compose g f) x1 = (compose g f) x2).
intros.
unfold compose in H.
unfold injective in H2.
The result is:
2 goals
A : Type
B : Type
C : Type
g : B -> C
f : A -> B
H1 : injective f
H2 : forall x1 x2 : B, g x1 = g x2 -> x1 = x2
H : forall x1 x2 : A, g (f x1) = g (f x2)
______________________________________(1/2)
injective (compose g f)
______________________________________(2/2)
forall x1 x2 : A, compose g f x1 = compose g f x2
From this state, I am trying to apply H2 in H in order to prove that f(x1)=f(x2). I have tried the apply tactic as well as the specialized tactic but none of them worked.
Here is the actual proof I am following :
EDIT:
Thank you very much for you help! This code works now :
Theorem compose_injective {A B C} (g: B -> C) (f: A -> B) :
injective f /\ injective g -> injective (compose g f).
Proof.
intros.
destruct H as (H1,H2).
unfold injective.
intros.
unfold injective in H2.
apply H2 in H.
unfold injective in H1.
apply H1 in H.
exact H.
Instead of cut, use unfold injective. to reveal the hypothesis compose g f x = compose g f x'.
apply H2 in H says you're missing an x1 and x2. First get yourself an x1 and x2 by unfolding injective in your goal and using intros. Then you can apply H2 (with appropriate parameters) in H1.

Don't understand `destruct` tactic on hypothesis `~ (exists x : X, ~ P x)` in Coq

I'm new to Coq and try to learn it through Software foundations. In the chapter "Logic in Coq", there is an exercise not_exists_dist which I completed (by guessing) but not understand:
Theorem not_exists_dist :
excluded_middle →
∀ (X:Type) (P : X → Prop),
¬ (∃ x, ¬ P x) → (∀ x, P x).
Proof.
intros em X P H x.
destruct (em (P x)) as [T | F].
- apply T.
- destruct H. (* <-- This step *)
exists x.
apply F.
Qed.
Before the destruct, the context and goal looks like:
em: excluded_middle
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
F: ~ P x
--------------------------------------
(1/1)
P x
And after it
em: excluded_middle
X: Type
P: X -> Prop
x: X
F: ~ P x
--------------------------------------
(1/1)
exists x0 : X, ~ P x0
While I understand destruct on P /\ Q and P \/ Q in hypothesis, I don't understand how it works on P -> False like here.
Let me try to give some intuition behind this by doing another proof first.
Consider:
Goal forall A B C : Prop, A -> C -> (A \/ B -> B \/ C -> A /\ B) -> A /\ B.
Proof.
intros. (*eval up to here*)
Admitted.
What you will see in *goals* is:
1 subgoal (ID 77)
A, B, C : Prop
H : A
H0 : C
H1 : A ∨ B → B ∨ C → A ∧ B
============================
A ∧ B
Ok, so we need to show A /\ B. We can use split to break the and apart, thus we need to show A and B. A follows easily by assumption, B is something we do not have. So, our proof script now might look like:
Goal forall A B C : Prop, A -> C -> (A \/ B -> B \/ C -> A /\ B) -> A /\ B.
Proof.
intros. split; try assumption. (*eval up to here*)
Admitted.
With goals:
1 subgoal (ID 80)
A, B, C : Prop
H : A
H0 : C
H1 : A ∨ B → B ∨ C → A ∧ B
============================
B
The only way we can get to the B is by somehow using H1. Let's see what destruct H1 does to our goals:
3 subgoals (ID 86)
A, B, C : Prop
H : A
H0 : C
============================
A ∨ B
subgoal 2 (ID 87) is:
B ∨ C
subgoal 3 (ID 93) is:
B
We get additional subgoals! In order to destruct H1 we need to provide it proofs for A \/ B and B \/ C, we cannot destruct A /\ B otherwise!
For the sake of completeness: (without the split;try assumption shorthand)
Goal forall A B C : Prop, A -> C -> (A \/ B -> B \/ C -> A /\ B) -> A /\ B.
Proof.
intros. split.
- assumption.
- destruct H1.
+ left. assumption.
+ right. assumption.
+ assumption.
Qed.
Another way to view it is this: H1 is a function that takes A \/ B and B \/ C as input. destruct works on its output. In order to destruct the result of such a function, you need to give it an appropriate input.
Then, destruct performs a case analysis without introducing additional goals.
We can do that in the proof script as well before destructing:
Goal forall A B C : Prop, A -> C -> (A \/ B -> B \/ C -> A /\ B) -> A /\ B.
Proof.
intros. split.
- assumption.
- specialize (H1 (or_introl H) (or_intror H0)).
destruct H1.
assumption.
Qed.
From a proof term perspective, destruct of A /\ B is the same as match A /\ B with conj H1 H2 => (*construct a term that has your goal as its type*) end.
We can replace the destruct in our proof script with a corresponding refine that does exactly that:
Goal forall A B C : Prop, A -> C -> (A \/ B -> B \/ C -> A /\ B) -> A /\ B.
Proof.
intros. unfold not in H0. split.
- assumption.
- specialize (H1 (or_introl H) (or_intror H0)).
refine (match H1 with conj Ha Hb => _ end).
exact Hb.
Qed.
Back to your proof. Your goals before destruct
em: excluded_middle
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
F: ~ P x
--------------------------------------
(1/1)
P x
After applying the unfold not in H tactic you see:
em: excluded_middle
X: Type
P: X -> Prop
H: (exists x : X, P x -> ⊥) -> ⊥
x: X
F: ~ P x
--------------------------------------
(1/1)
P x
Now recall the definition of ⊥: It's a proposition that cannot be constructed, i.e. it has no constructors.
If you somehow have ⊥ as an assumption and you destruct, you essentially look at the type of match ⊥ with end, which can be anything.
In fact, we can prove any goal with it:
Goal (forall (A : Prop), A) <-> False. (* <- note that this is different from *)
Proof. (* forall (A : Prop), A <-> False *)
split; intros.
- specialize (H False). assumption.
- refine (match H with end).
Qed.
Its proofterm is:
(λ (A B C : Prop) (H : A) (H0 : C) (H1 : A ∨ B → B ∨ C → A ∧ B),
conj H (let H2 : A ∧ B := H1 (or_introl H) (or_intror H0) in match H2 with
| conj _ Hb => Hb
end))
Anyhow, destruct on your assumption H will give you a proof for your goal if you are able to show exists x : X, ~ P x -> ⊥.
Instead of destruct, you could also do exfalso. apply H. to achieve the same thing.
Normally, destruct t applies when t is an inhabitant of an inductive type I, giving you one goal for each possible constructor for I that could have been used to produce t. Here as you remarked H has type P -> False, which is not an inductive type, but False is. So what happens is this: destruct gives you a first goal corresponding to the P hypothesis of H. Applying H to that goal leads to a term of type False, which is an inductive type, on which destruct works as it should, giving you zero goals since False has no constructors. Many tactics for inductive types work like this on hypothesis of the form P1 -> … -> Pn -> I where I is an inductive type: they give you side-goals for P1 … Pn, and then work on I.

Show that a monic (injective) and epic (surjective) function has an inverse in Coq

A monic and epic function is an isomorphism, hence it has an inverse. I'd like a proof of that in Coq.
Axiom functional_extensionality: forall A B (f g : A->B), (forall a, f a = g a) -> f = g.
Definition compose {A B C} (f : B->C) (g: A->B) a := f (g a).
Notation "f ∘ g" := (compose f g) (at level 40).
Definition id {A} (a:A) := a.
Definition monic {A B} (f:A->B) := forall C {h k:C->A}, f ∘ h = f ∘ k -> h = k.
Definition epic {A B} (f:A->B) := forall C {h k:B->C}, h ∘ f = k ∘ f -> h = k.
Definition iso {A B} (f:A->B) := monic f /\ epic f.
Goal forall {A B} (f:A->B), iso f -> exists f', f∘f' = id /\ f'∘f = id.
The proofs I have found online (1, 2) do not give a construction of f' (the inverse). Is it possible to show this in Coq? (It is not obvious to me that the inverse is computable...)
First, a question of terminology. In category theory, an isomorphism is a morphism that has a left and a right inverse, so I am changing slightly your definitions:
Definition compose {A B C} (f : B->C) (g: A->B) a := f (g a).
Notation "f ∘ g" := (compose f g) (at level 40).
Definition id {A} (a:A) := a.
Definition monic {A B} (f:A->B) := forall C {h k:C->A}, f ∘ h = f ∘ k -> h = k.
Definition epic {A B} (f:A->B) := forall C {h k:B->C}, h ∘ f = k ∘ f -> h = k.
Definition iso {A B} (f:A->B) :=
exists g : B -> A, f ∘ g = id /\ g ∘ f = id.
It is possible to prove this result by assuming a few standard axioms, namely propositional extensionality and constructive definite description (a.k.a. the axiom of unique choice):
Require Import Coq.Logic.FunctionalExtensionality.
Require Import Coq.Logic.PropExtensionality.
Require Import Coq.Logic.Description.
Section MonoEpiIso.
Context (A B : Type).
Implicit Types (f : A -> B) (x : A) (y : B).
Definition surjective f := forall y, exists x, f x = y.
Lemma epic_surjective f : epic f -> surjective f.
Proof.
intros epic_f y.
assert (H : (fun y => exists x, f x = y) = (fun y => True)).
{ apply epic_f.
apply functional_extensionality.
intros x; apply propositional_extensionality; split.
- intros _; exact I.
- now intros _; exists x. }
now pattern y; rewrite H.
Qed.
Definition injective f := forall x1 x2, f x1 = f x2 -> x1 = x2.
Lemma monic_injective f : monic f -> injective f.
Proof.
intros monic_f x1 x2 e.
assert (H : f ∘ (fun a : unit => x1) = f ∘ (fun a : unit => x2)).
{ now unfold compose; simpl; rewrite e. }
assert (e' := monic_f _ _ _ H).
exact (f_equal (fun g => g tt) e').
Qed.
Lemma monic_epic_iso f : monic f /\ epic f -> iso f.
Proof.
intros [monic_f epic_f].
assert (Hf : forall y, exists! x, f x = y).
{ intros y.
assert (sur_f := epic_surjective _ epic_f).
destruct (sur_f y) as [x xP].
exists x; split; trivial.
intros x' x'P.
now apply (monic_injective _ monic_f); rewrite xP, x'P. }
exists (fun a => proj1_sig (constructive_definite_description _ (Hf a))).
split; apply functional_extensionality; unfold compose, id.
- intros y.
now destruct (constructive_definite_description _ (Hf y)).
- intros x.
destruct (constructive_definite_description _ (Hf (f x))); simpl.
now apply (monic_injective _ monic_f).
Qed.
End MonoEpiIso.
I believe it is not possible to prove this result without at least some form of unique choice. Assume propositional and functional extensionality. Note that, if exists! x : A, P x holds, then the unique function
{x | P x} -> unit
is both injective and surjective. (Injectivity follows from the uniqueness part, and surjectivity follows from the existence part.) If this function had an inverse for every P : A -> Type, then we could use this inverse to implement the axiom of unique choice. Since this axiom does not hold in Coq, it shouldn't be possible to build this inverse in the basic theory.

Logic: All_In can't expand nested forall

I am facing a pretty strange problem: coq doesn't want to move forall variable into the context.
In the old times it did:
Example and_exercise :
forall n m : nat, n + m = 0 -> n = 0 /\ m = 0.
Proof.
intros n m.
It generates:
n, m : nat
============================
n + m = 0 -> n = 0 /\ m = 0
But when we have forall inside forall, it doesn't work:
(* Auxilliary definition *)
Fixpoint All {T : Type} (P : T -> Prop) (l : list T) : Prop :=
(* ... *)
Lemma All_In :
forall T (P : T -> Prop) (l : list T),
(forall x, In x l -> P x) <->
All P l.
Proof.
intros T P l. split.
- intros H.
After this we get:
T : Type
P : T -> Prop
l : list T
H : forall x : T, In x l -> P x
============================
All P l
But how to move x outside of H and destruct it into smaller pieces? I tried:
destruct H as [x H1].
But it gives an error:
Error: Unable to find an instance for the variable x.
What is it? How to fix?
The problem is that forall is nested to the left of an implication rather than the right. It does not make sense to introduce x from a hypothesis of the form forall x, P x, just like it wouldn't make sense to introduce the n in plus_comm : forall n m, n + m = m + n into the context of another proof. Instead, you need to use the H hypothesis by applying it at the right place. I can't give you the answer to this question, but you might want to refer to the dist_not_exists exercise in the same chapter.

Moving from computable functions to inductive relations

I am trying to understand how to move from theorems that operate on computable functions to theorems that use inductively defined relations to represent computations. Consider this simple development below. Let's start with a standard definition of relations and their properties:
Definition relation (X : Type) := X -> X -> Prop.
Definition reflexive {X : Type} (R : relation X) :=
forall a, R a a.
Definition transitive {X : Type} (R : relation X) :=
forall a b c : X, (R a b) -> (R b c) -> (R a c).
Now I define three properties defined for a relation R and two functions F and G:
Definition propA {X : Type} (R : relation X) (F G : X -> X) :=
forall p q, R (F p) q <-> R p (G q).
Definition propB {X : Type} (R : relation X) (F G : X -> X) :=
forall x, R x (G (F x)).
Definition propC {X : Type} (R : relation X) (F : X -> X) :=
forall a b : X, R a b -> R (F a) (F b).
I state a theorem that if R is reflexive and property A holds for R, F and G, then property B also holds R, F and G.
Lemma aPropB {X : Type} {R : relation X} {F G : X -> X} (Rrefl : reflexive R)
(H : propA R F G) :
propB R F G.
Proof.
unfold propB in *.
intros.
apply H. apply Rrefl.
Qed.
Finally I state a theorem that if R is reflexive and transitive, and property A holds for R, F and G, then property C holds for R and F.
Lemma aPropC {X : Type} {R : relation X} {F G : X -> X}
(Rrefl : reflexive R) (Rtrans : transitive R) (H : propA R F G) :
propC R F.
Proof.
unfold propC in *.
intros.
apply H.
eapply Rtrans. eassumption.
apply aPropB; assumption.
Qed.
Now I would like to move from representing F and G as computations to representing them as relations. So instead of saying F : X -> X I will now just say F : relation X and insist that F is deterministic:
Definition deterministic {X : Type} (F : relation X) :=
forall x y1 y2, F x y1 -> F x y2 -> y1 = y2.
I restate all three properties:
Definition propA' {X : Type} (R : relation X) (F G : relation X)
(Fdet : deterministic F) (Gdet : deterministic G) :=
forall p q x y, F p x -> G q y -> R x q <-> R p y.
Definition propB' {X : Type} (R : relation X) (F G : relation X)
(Fdet : deterministic F) (Gdet : deterministic G) :=
forall x y z, F x y -> G y z -> R x z.
Definition propC' {X : Type} (R : relation X) (F : relation X)
(Fdet : deterministic F) :=
forall a b x y : X, F a x -> F b y -> R a b -> R x y.
Transformation pattern that I have followed is that expression R a (F b) is turned into F b x -> R a x, meaning "F b evaluates to some x and a is in relation R with that x". Now for the theorems. First one follows quite easily:
Lemma aPropB' {X : Type} {R : relation X} {Rrefl : reflexive R}
{F G : relation X} {Fdet : deterministic F} {Gdet : deterministic G}
(H : propA' R F G Fdet Gdet) :
propB' R F G Fdet Gdet.
Proof.
unfold propA', propB' in *.
intros.
specialize (H x y y z).
apply H; auto.
Qed.
But I am stuck with the second one. I start the proof like this:
Lemma aPropC' {X : Type} {R : relation X} {F G : relation X}
{Fdet : deterministic F} {Gdet : deterministic G}
(Rrefl : reflexive R) (Rtrans : transitive R)
(H : propA' R F G Fdet Gdet) :
propC' R F Fdet.
Proof.
unfold propC' in *.
intros.
eapply H; try eassumption.
and end with a following goal to prove (some irrelevant hypotheses omitted):
H : propA' R F G Fdet Gdet
H0 : F a x
H1 : F b y
H2 : R a b
─────────────────────────────────────────────────────
G y b
The problem is that G is now an explicit premise of propA' and I have to prove it if I want to rely on propA'. But I have no assumptions about G in my current proof context and I don't see a way to finish the proof. Previously in aPropC, that used functions, G would only appear in conclusions of aPropA and aPropB. So the shape of the goal matched the shape of my hypotheses and known lemmas, allowing me to use them easily.
Where am I going wrong here? Is my transition from functions to relations incorrect? Is there any technique that I could use here?
Functions in Coq are not just deterministic relations but also total ones. So you may want to throw in:
Definition total {X : Type} (R : relation X) : Prop :=
forall x, exists y, R x y.
And then the notion of being functional is the conjunction of deterministic and total:
Definition functional {X : Type} (R : relation X) : Prop :=
deterministic R /\ total R.
Alternatively, you can add assumptions to your lemmas relating the domains of the partial functions your relations represent.