Pose proof in Coq - coq

I’m trying to prove a theorem in Coq. My current context is:
1 subgoal
s, x : Entity
Pssx : Ps s x
Fxs : F x s
IPssx : F x s /\ Ps s x
t : Entity
Ctss : C t s s
Pstx : Ps t x
Fxt : F x t
______________________________________(1/1)
C s s s
F, Ps and C are relations of the theory. I’ve also Axiom 4:
Axiom A4 : forall x s t,
Ps s x /\ F x s /\ Ps t x /\ F x t -> s = t.
What I want to do, is to use A4 in the proof, as it will help me to say that s and t are equals. So I’ve tested: pose proof (A4 x s t). A new hypothesis is added : H : Ps s x /\ F x s /\ Ps t x /\ F x t -> s = t. I know I can destruct the hypothesis H, prove the premisses and use the conclusion. But I also know that I can give the premisses directly in the pose proof command. I want to do something like pose proof (A4 x s t Premisses). But I don’t know what to put instead of Premisses.
I tried several solutions:
composing the hypothesis with /, such as pose proof (A4 x s t (Pssx /\ Fxs /\ Pstx /\ Fxt)). but I got the error The term "Pssx" has type "Ps s x" while it is expected to have type "Ps s x /\ F x s /\ Ps t x /\ F x t".
using the assert command and pose proof (A4 x s t H1).:
assert (H1 := (Ps s x) /\ (F x s) /\ (Ps t x) /\ (F x t)). but I got The term "H1" has type "Prop" while it is expected to have type "Ps s x /\ F x s /\ Ps t x /\ F x t".
assert (H1 := (Pssx) /\ (Fxs) /\ (Pstx) /\ (Fxt)). but I got The term "Pssx" has type "Ps s x" while it is expected to have type "Prop".
So my question is the following: what should I put instead of Premisses for my code to work? Is there a command to create new hypothesis based on other ones? I know how to destruct an hypothesis into two smaller hypothesis, but I don't know how to compose hypothesis to create bigger ones.

The standard in Coq would be to curry your A4 so that instead of receiving one large conjunction as a premise, it receives several different premises:
Axiom A4' : forall x s t,
Ps s x -> F x s -> Ps t x -> F x t -> s = t.
Then you can do:
pose proof (A4' x s t Pssx Fxs Pstx Fxt).
If you absolutely need A4 with the conjunctions, you can use conj (which you can find with Print "_ /\ _"):
pose proof (A4 x s t (conj Pssx (conj Fxs (conj Pstx Fxt)))).

Related

Is there a shorter proof to this Coq theorem?

I'm learning to use Coq and I try to prove the theorems of a paper I'm reading. The paper is Having a Part Twice Over of Karen Bennett, published in 2013. The paper propopes a mereological theory composed of two primitives F and Ps and defines the parthood relation P using the two primitives.
I coded it as follows:
Class Entity: Type.
(* Slot Mereology defines the parthood relation
* with the two primitives F and Ps.
* The idea is that wholes have slots
* filled by their parts.
* F x s means that x fills slot s.
* Ps s y means that s is a parthood slot of y.
* P is the parthood relation.
*)
Parameter F : Entity -> Entity -> Prop.
Parameter Ps : Entity -> Entity -> Prop.
Definition P (x y : Entity) :=
exists s, F x s /\ Ps s y.
(* Slot Inheritance *)
Axiom A5 : forall x y z1 z2 : Entity,
(Ps z1 y /\ F x z1) /\ Ps z2 x -> Ps z2 y.
(* Parthood Transitivity *)
Theorem T7 : forall x y z : Entity,
(P x y /\ P y z) -> P x z.
Proof.
intros x y z.
unfold P.
intro h.
destruct h as (EsPxy, EsPyz).
destruct EsPxy as (s1, Pxy).
destruct Pxy as (Fxs1, Pss1y).
destruct EsPyz as (s2, Pyz).
destruct Pyz as (Fys2, Pss2z).
exists s1.
split.
apply Fxs1.
apply A5 with (z1 := s2) (x := y).
split.
split.
assumption.
assumption.
assumption.
Qed.
I succeeded to prove theorem T7. I have two questions:
is my Coq code ok? (I'm not sure If the way I declared the type, the primitives and the predicate is the right way to do it.)
is there a shorter proof? (About the length of the proof, I only want to know about the number of tactics.)
Another approach, using ssreflect and its neat notation for destructuring, one can rephrase your explicit proof in a more compact way (I'm using Arthur's version).
From mathcomp Require Import all_ssreflect.
Parameter Entity: Type.
Parameter F : Entity -> Entity -> Prop.
Parameter Ps : Entity -> Entity -> Prop.
Definition P (x y : Entity) :=
exists s, F x s /\ Ps s y.
Axiom A5 : forall x y z1 z2 : Entity,
(Ps z1 y /\ F x z1) /\ Ps z2 x -> Ps z2 y.
Theorem T7 : forall x y z : Entity,
(P x y /\ P y z) -> P x z.
Proof.
move=> x y z [[s1 [Fxs1 Ps1y]] [s2 [Fys2 Ps2z]]].
by exists s1; split; [|exact: (A5 y z s2 s1)].
Qed.
Yes, your Coq code is OK. But there are shorter proofs. This theorem is simple enough that it can be solved with Coq's automation tactics. E.g.,
Parameter Entity: Type.
(* Slot Mereology defines the parthood relation
* with the two primitives F and Ps.
* The idea is that wholes have slots
* filled by their parts.
* F x s means that x fills slot s.
* Ps s y means that s is a parthood slot of y.
* P is the parthood relation.
*)
Parameter F : Entity -> Entity -> Prop.
Parameter Ps : Entity -> Entity -> Prop.
Definition P (x y : Entity) :=
exists s, F x s /\ Ps s y.
(* Slot Inheritance *)
Axiom A5 : forall x y z1 z2 : Entity,
(Ps z1 y /\ F x z1) /\ Ps z2 x -> Ps z2 y.
(* Parthood Transitivity *)
Theorem T7 : forall x y z : Entity,
(P x y /\ P y z) -> P x z.
Proof.
unfold P; firstorder; eauto 10 using A5.
Qed.
(Notice that I replaced "Class Entity" with "Parameter Entity": The first form is actually just defining a type whose elements are records with no fields, whereas the second one is postulating that the type Entity exists without placing any further constraints on it.)

Implementing/specifying permutation groups in coq

I am trying to implement/specify the permutation groups (symmetric groups) in coq. This went well for a bit, until I tried to prove that the identity is actually the identity. My proof gets stuck on proving that the proposition "x is invertible" is exactly the same as the proposition "id * x is invertible".
Are these two propositions actually the same? Am I trying to prove something that is not true? Is there a better way of specifying the permutation group (as a type)?
(* The permutation group on X contains all functions between X and X that are bijective/invertible *)
Inductive G {X : Type} : Type :=
| function (f: X -> X) (H: exists g: X -> X, forall x : X, f (g x) = x /\ g (f x) = x).
(* Composing two functions preserves invertibility *)
Lemma invertible_composition {X : Type} (f g: X -> X) :
(exists f' : X -> X, forall x : X, f (f' x) = x /\ f' (f x) = x) ->
(exists g' : X -> X, forall x : X, g (g' x) = x /\ g' (g x) = x) ->
exists h : X -> X, forall x : X, (fun x => f (g x)) (h x) = x /\ h ((fun x => f (g x)) x) = x.
Admitted.
(* The group operation is composition *)
Definition op {X : Type} (a b : G) : G :=
match a, b with
| function f H, function g H' => function (fun x => f (g x)) (#invertible_composition X f g H H')
end.
Definition id' {X : Type} (x : X) : X := x.
(* The identity function is invertible *)
Lemma id_invertible {X : Type} : exists g : X -> X, forall x : X, id' (g x) = x /\ g (id' x) = x.
Admitted.
Definition id {X : Type} : (#G X) := function id' id_invertible.
(* The part on which I get stuck: proving that composition with the identity does not change elements. *)
Lemma identity {X: Type} : forall x : G, op id x = x /\ #op X x id = x.
Proof.
intros.
split.
- destruct x.
simpl.
apply f_equal.
Abort.
I believe that your statement cannot be proved without assuming extra axioms:
proof_irrelevance:
forall (P : Prop) (p q : P), p = q.
You need this axiom to show that two elements of G are equal when the underlying functions are:
Require Import Coq.Logic.ProofIrrelevance.
Inductive G X : Type :=
| function (f: X -> X) (H: exists g: X -> X, forall x : X, f (g x) = x /\ g (f x) = x).
Arguments function {X} _ _.
Definition fun_of_G {X} (f : G X) : X -> X :=
match f with function f _ => f end.
Lemma fun_of_G_inj {X} (f g : G X) : fun_of_G f = fun_of_G g -> f = g.
Proof.
destruct f as [f fP], g as [g gP].
simpl.
intros e.
destruct e.
f_equal.
apply proof_irrelevance.
Qed.
(As a side note, it is usually better to declare the X parameter of G explicitly, rather than implicitly. It is rarely the case that Coq can figure out what X should be on its own.)
With fun_of_G_inj, it should be possible to show identity simply by applying it to each equality, because fun a => (fun x => x) (g a) is equal to g for any g.
If you want to use this representation for groups, you'll probably also need the axiom of functional extensionality eventually:
functional_extensionality:
forall X Y (f g : X -> Y), (forall x, f x = g x) -> f = g.
This axiom is available in the Coq.Logic.FunctionalExtensionality module.
If you want to define the inverse element as a function, you probably also need some form of the axiom of choice: it is necessary for extracting the inverse element g from the existence proof.
If you don't want to assume extra axioms, you have to place restrictions on your permutation group. For instance, you can restrict your attention to elements with finite support -- that is, permutation that fix all elements of X, except for a finite set. There are multiple libraries that allow you to work with permutations this way, including my own extensional structures.

How to eliminate a disjunction inside of an expression?

Lemma In_map_iff :
forall (A B : Type) (f : A -> B) (l : list A) (y : B),
In y (map f l) <->
exists x, f x = y /\ In x l.
Proof.
split.
- generalize dependent y.
generalize dependent f.
induction l.
+ intros. inversion H.
+ intros.
simpl.
simpl in H.
destruct H.
* exists x.
split.
apply H.
left. reflexivity.
*
1 subgoal
A : Type
B : Type
x : A
l : list A
IHl : forall (f : A -> B) (y : B),
In y (map f l) -> exists x : A, f x = y /\ In x l
f : A -> B
y : B
H : In y (map f l)
______________________________________(1/1)
exists x0 : A, f x0 = y /\ (x = x0 \/ In x0 l)
Since proving exists x0 : A, f x0 = y /\ (x = x0 \/ In x0 l) is the same as proving exists x0 : A, f x0 = y /\ In x0 l, I want to eliminate x = x0 inside the goal here so I can apply the inductive hypothesis, but I am not sure how to do this. I've tried left in (x = x0 \/ In x0 l) and various other things, but I haven't been successful in making it happen. As it turns out, defining a helper function of type forall a b c, (a /\ c) -> a /\ (b \/ c) to do the rewriting does not work for terms under an existential either.
How could this be done?
Note that the above is one of the SF book exercises.
You can get access to the components of your inductive hypothesis with any of the following:
specialize (IHl f y h); destruct IHl
destruct (IHl f y H)
edestruct IHl
You can then use exists and split to manipulate the goal into a form that is easier to work with.
As it turns out, it is necessary to define a helper.
Lemma In_map_iff_helper : forall (X : Type) (a b c : X -> Prop),
(exists q, (a q /\ c q)) -> (exists q, a q /\ (b q \/ c q)).
Proof.
intros.
destruct H.
exists x.
destruct H.
split.
apply H.
right.
apply H0.
Qed.
This does the rewriting that is needed right off the bat. I made a really dumb error thinking that I needed a tactic rather than an auxiliary lemma. I should have studied the preceding examples more closely - if I did, I'd have realized that existentials need to be accounted for.

On the relative strength of some extensional equality axioms

Given the following axioms:
Definition Axiom1 : Prop := forall (a b:Type) (f g: a -> b),
(forall x, f x = g x) -> f = g.
Definition Axiom2 : Prop := forall (a:Type) (B:a -> Type) (f g: forall x, B x),
(forall x, f x = g x) -> f = g.
One can easily show that Axiom2 is a stronger axiom than Axiom1:
Theorem Axiom2ImpAxiom1 : Axiom2 -> Axiom1.
Proof.
intros H a b f g H'. apply H. exact H'.
Qed.
Does anyone know if (within the type theory of Coq), these two axioms are in fact equivalent or whether they are known not to be. If equivalent, is there a simple Coq proof of the fact?
Yes, the two axioms are equivalent; the key is to go through fun x => existT B x (f x) and fun x => existT B x (g x), though there's some tricky equality reasoning that has to be done. There's a nearly complete proof at https://github.com/HoTT/HoTT/blob/c54a967526bb6293a0802cb2bed32e0b4dbe5cdc/contrib/old/Funext.v#L113-L358 which uses slightly different terminology.

How to give a counterxample in Coq?

Is it possible to give a counterexample for a statement which doesn't hold in general? Like, for example that the all quantor does not distribute over the connective "or". How would you state that to begin with?
Parameter X : Set.
Parameter P : X -> Prop.
Parameter Q : X -> Prop.
(* This holds in general *)
Theorem forall_distributes_over_and
: (forall x:X, P x /\ Q x) -> ((forall x:X, P x) /\ (forall x:X, Q x)).
Proof.
intro H. split. apply H. apply H.
Qed.
(* This doesn't hold in general *)
Theorem forall_doesnt_distributes_over_or
: (forall x:X, P x \/ Q x) -> ((forall x:X, P x) \/ (forall x:X, Q x)).
Abort.
Here is a quick and dirty way to prove something similar to what you want:
Theorem forall_doesnt_distributes_over_or:
~ (forall X P Q, (forall x:X, P x \/ Q x) -> ((forall x:X, P x) \/ (forall x:X, Q x))).
Proof.
intros H.
assert (X : forall x : bool, x = true \/ x = false).
destruct x; intuition.
specialize (H _ (fun b => b = true) (fun b => b = false) X).
destruct H as [H|H].
now specialize (H false).
now specialize (H true).
Qed.
I have to quantify X P and Q inside the negation in order to be able to provide the one I want. You couldn't quite do that with your Parameters as they somehow fixed an abstract X, P and Q, thus making your theorem potentially true.
In general, if you want to produce a counterexample, you can state the negation of the formula and then prove that this negation is satisfied.