On the relative strength of some extensional equality axioms - coq

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.

Related

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.

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.

Path induction using eq_rect

According to Homotopy Type Theory (page 49), this is the full induction principle for equality :
Definition path_induction (A : Type) (C : forall x y : A, (x = y) -> Type)
(c : forall x : A, C x x eq_refl) (x y : A) (prEq : x = y)
: C x y prEq :=
match prEq with
| eq_refl => c x
end.
I don't understand much about HoTT, but I do see path induction is stronger than eq_rect :
Lemma path_ind_stronger : forall (A : Type) (x y : A) (P : A -> Type)
(prX : P x) (prEq : x = y),
eq_rect x P prX y prEq =
path_induction A (fun x y pr => P x -> P y) (fun x pr => pr) x y prEq prX.
Proof.
intros. destruct prEq. reflexivity.
Qed.
Conversely, I failed to construct path_induction from eq_rect. Is it possible ? If not, what is the correct induction principle for equality ? I thought those principles were mechanically derived from the Inductive type definitions.
EDIT
Thanks to the answer below, the full induction principle on equality can be generated by
Scheme eq_rect_full := Induction for eq Sort Prop.
Then we get the converse,
Lemma eq_rect_full_works : forall (A : Type) (C : forall x y : A, (x = y) -> Prop)
(c : forall x : A, C x x eq_refl) (x y : A)
(prEq : x = y),
path_induction A C c x y prEq
= eq_rect_full A x (fun y => C x y) (c x) y prEq.
Proof.
intros. destruct prEq. reflexivity.
Qed.
I think you are referring to the fact that the result type of path_induction mentions the path that is being destructed, whereas the one of eq_rect does not. This omission is the default for inductive propositions (as opposed to what happens with Type), because the extra argument is not usually used in proof-irrelevant developments. Nevertheless, you can instruct Coq to generate more complete induction principles with the Scheme command: https://coq.inria.fr/distrib/current/refman/user-extensions/proof-schemes.html?highlight=minimality. (The Minimality variant is the one used for propositions by default.)

Decomposing equality of constructors coq

Often in Coq I find myself doing the following: I have the proof goal, for example:
some_constructor a c d = some_constructor b c d
And I really only need to prove a = b because everything else is identical anyway, so I do:
assert (a = b).
Then prove that subgoal, then
rewrite H.
reflexivity.
finishes the proof.
But it seems to just be unnecessary clutter to have those hanging around at the bottom of my proof.
Is there a general strategy in Coq for taking an equality of constructors and splitting it up into an equality of constructor parameters, kinda like a split but for equalities rather than conjunctions.
You can use Coq's searching capabilities:
Search (?X _ = ?X _).
Search (_ _ = _ _).
Among some noise it reveals a lemma
f_equal: forall (A B : Type) (f : A -> B) (x y : A), x = y -> f x = f y
And its siblings for multi-argument equalities: f_equal2 ... f_equal5 (as of Coq version 8.4).
Here is an example:
Inductive silly : Set :=
| some_constructor : nat -> nat -> nat -> silly
| another_constructor : nat -> nat -> silly.
Goal forall x y,
x = 42 ->
y = 6 * 7 ->
some_constructor x 0 1 = some_constructor y 0 1.
intros x y Hx Hy.
apply f_equal3; try reflexivity.
At this point all you need to prove is x = y.
In particular, standard Coq provides the f_equal tactic.
Inductive u : Type := U : nat -> nat -> nat -> u.
Lemma U1 x y z1 z2 : U x y z1 = U x y z2.
f_equal
Also, ssreflect provides a general-purpose congruence tactic congr.

How does 'elim' in Coq work on existential quantifier?

I'm confused by Coq on its way dealing with existential quantification.
I have a predicate P and an assumption H
P : nat -> Prop
H : exists n, P n
while the current goal is (whatever)
(Some goal)
If I want to instantiate n in H, I will do
elim H.
However after the elimination, the current goal becomes
forall n, P n -> (Some goal)
It looks like Coq converts an existential quantifier into a universal one. I know that (forall a, P a -> Q a) -> ((exists a, P a) -> Q a) out of my limited knowledge on first-order logic. But the reverse proposition seems to be incorrect. If the 'forall' one and 'exists' one are not equivalent, why Coq would do such conversion?
Does 'elim' in Coq replace the goal with a harder to prove one? Or could anyone please show why ((exists a, P a) -> Q a) -> (forall a, P a -> Q a) holds in first-order logic?
Maybe the missing key is that the goal:
forall n, P n -> (Some goal)
is to be read as:
forall n, (P n -> (Some goal))
and not as:
(forall n, P n) -> (Some goal)
That is, the goal you are given just gives you an arbitrary n and a proof P n, which is indeed the proper way to eliminate an existential (you don't get to know the value of the witness since it could be any value that makes P true, you just get to know that there is a n and that P n holds).
On the contrary, the latter would provide you with a function that can build P n for any n you pass it, which is indeed a stronger statement than the one you have.
I realize this question is old but I would like to add the following important clarification:
In Coq, (and more generally, in intuitionistic logic) the existential quantifier is defined (see here) as follows
(exists x, (P x)) := forall (P0 : Prop), ((forall x, (P x -> P0)) -> P0)
Intuitively this can be read as
(exists x, P x) is the smallest proposition which holds whenever P x0 holds for some x0
In fact one can easily prove the following two theorems in Coq:
forall x0, (P x0 -> (exists x, P x)) (* the introduction rule -- proved from ex_intro *)
and (provided A : Prop)
(exists x : A, P x) -> {x : A | P x} (* the elimination rule -- proved from ex_ind *)
So a Coq goal of the form
H1...Hn, w : (exists x, P x) |- G
is transformed (using elim) to a Coq goal of the form
H1...Hn, w : (exists x, P x) |- forall x0, (P x0 -> G)
because whenever h : forall x0, (P x0 -> G), then G is precisely justified by the proof term
(ex_ind A P G h w) : G
which works whenever G : Prop.
Note: the elimination rule above is only valid whenever A : Prop, and cannot be proved whenever A : Type. In Coq, this mean that we do not have the ex_rect eliminator.
From my understanding (see here for more details), this is a design choice to preserve good program extraction properties.