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

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.

Related

Rewriting with John Major's equality

John Major's equality comes with the following lemma for rewriting:
Check JMeq_ind_r.
(*
JMeq_ind_r
: forall (A : Type) (x : A) (P : A -> Prop),
P x -> forall y : A, JMeq y x -> P y
*)
It is easy to generalize it like that:
Lemma JMeq_ind2_r
: forall (A:Type)(x:A)(P:forall C,C->Prop),
P A x -> forall (B:Type)(y:B), #JMeq B y A x -> P B y.
Proof.
intros.
destruct H0.
assumption.
Qed.
However I need something a bit different:
Lemma JMeq_ind3_r
: forall (A:Type)(x:A*A) (P:forall C,C*C->Prop),
P A x -> forall (B:Type)(y:B*B), #JMeq (B*B) y (A*A) x -> P B y.
Proof.
intros.
Fail destruct H0.
Abort.
Is JMeq_ind3_r provable?
If not:
Is it safe to assume it as an axiom?
Is it reducible to a simpler and safe axiom?
It's not provable. JMeq is essentially two equality proofs bundled together, one for the types and one for the values. In this case, we get from the hypothesis that A * A = B * B. From this, it is not provable that A = B, so we cannot convert a P A x into P B y.
If A * A = B * B implies A = B, that means that the pair type constructor is injective. Type constructor injectivity in general (i.e. for all types) is inconsistent with classical logic and also with univalence. For some type constructors, injectivity is provable, but not for pairs.
Is it safe to assume it as an axiom?
If you use classical logic or univalence then it isn't. Otherwise, it probably is, but I would instead try to rephrase the problem so that type constructor injectivity does not come up.

Proof leaking in Coq extraction?

In order to understand how general recursive Function definitions works, and how they comply with Coq's structural recursion constraint, I tried to reimplement it on the Peano natural numbers. I want to define recursive nat -> nat functions that can use any previous values, not just the predecessor. Here is what I did :
Definition nat_strong_induction_set
(* erased at extraction, type specification *)
(P : nat -> Set)
(* The strong induction step. To build the P n it can, but does not have to,
recursively query the construction of any previous P k's. *)
(ind_step : forall n : nat, (forall k : nat, (lt k n -> P k)) -> P n)
(n : nat)
: P n.
Proof.
(* Force the hypothesis of ind_step as a standard induction hypothesis *)
assert (forall m k : nat, lt k m -> P k) as partial_build.
{ induction m.
- intros k H0. destruct k; inversion H0.
- intros k H0. apply ind_step. intros k0 H1. apply IHm. apply (lt_transitive k0 k).
assumption. apply le_lt_equiv. assumption. }
apply (partial_build (S n) n). apply succ_lt.
Defined.
I used some custom lemmas on nats that I didn't paste here. It works, I managed to define the euclidean division div a b with it, which recursively uses div (a-b) b. The extraction is almost what I expected :
let nat_strong_induction_set ind_step n =
let m = S n in
let rec f n0 k =
match n0 with
| O -> assert false (* absurd case *)
| S n1 -> ind_step k (fun k0 _ -> f n1 k0)
in f m n
Except for the n0 parameter. We see that the only effect of this parameter is to stop the recursion at the S n-nth step. The extraction also mentions that this assert false should not happen. So why is it extracted ? This seems better
let nat_strong_induction_set ind_step n =
let rec f k = ind_step k (fun k0 _ -> f k0)
in f n
It looks like a glitch of Coq's structural recursion constraint, to ensure the termination of all recursions. The Coq definition of nat_strong_induction_set writes lt k n, so Coq knows only previous P k's will be queried. This makes a decreasing chain in the nats, which is forced to terminate in less than S n steps. This allows a structural recursive definition on an additional fuel parameter n0 starting at S n, it won't affect the result. So if it is only a part of the termination proof, why is it not erased by the extraction ?
Your match is not erased because your definition mixes two things: the termination argument, where the match is needed, and the computationally relevant recursive call, where it isn't.
To force erasure, you need to convince Coq that the match is computationally irrelevant. You can do so by making the termination argument -- that is, the induction on m -- produce the proof of a proposition instead of a function of type forall m k, lt k m -> P k. Luckily, the standard library provides an easy way of doing so, with the Fix combinator:
Require Import Coq.Arith.Wf_nat.
Definition nat_strong_induction_set
(P : nat -> Set)
(ind_step : forall n : nat, (forall k : nat, (lt k n -> P k)) -> P n)
(n : nat)
: P n :=
Fix lt_wf P ind_step n.
Here, lt_wf is a proof that lt is well-founded. When you extract this function, you get
let rec nat_strong_induction_set ind_step n =
ind_step n (fun y _ -> nat_strong_induction_set ind_step y)
which is exactly what you wanted.
(As an aside, note that you don't need well-founded recursion to define division -- check for instance how it is defined in the Mathematical Components library.)

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.

Attempting to use proof irrelevance without creating ill-typed terms

To illustrate the issue I am facing let us assume we have a predicate on nat:
Parameter pred : nat -> Prop
Let us assume further that we have a type which encapsulates data, as well as a proof that the encapsulated data satisfies a certain property. For example:
Inductive obj : Type :=
| c : forall (n:nat), pred n -> obj
.
Now we would like to regard two objects c n p and c m q to be the same objects as long as n = m, regardless of the proofs involved to build them. So let us introduce a proof irrelevance axiom:
Axiom irrel : forall (P:Prop) (p q:P), p = q.
Now given this axiom, it is expected that the equality c n p = c m q be provable for n = m :
Theorem obvious : forall (n m:nat) (p: pred n) (q:pred m),
n = m -> c n p = c m q.
Now I have been playing around with this for a while, and none of the typical 'rewrite' tactics can work as they create ill-typed terms. I am guessing the theorem should be true within Coq's type theory (given the proof irrelevance axiom) but probably involves some trick unknown to a beginner. Any suggestion is greatly appreciated.
TL;DR
Theorem obvious n m (p: pred n) (q: pred m) :
n = m -> c n p = c m q.
Proof.
intros ->.
rewrite (irrel _ p q).
reflexivity.
Qed.
Explanation
Let me show how one can use information containing in error messages to come up with a solution:
Theorem obvious n m (p: pred n) (q: pred m) :
n = m -> c n p = c m q.
Proof.
intros E.
Fail rewrite E.
At this point we get the following error message:
The command has indeed failed with message:
Abstracting over the term "n" leads to a term fun n0 : nat => c n0 p = c m q
which is ill-typed.
Reason is: Illegal application:
The term "c" of type "forall n : nat, pred n -> obj"
cannot be applied to the terms
"n0" : "nat"
"p" : "pred n"
The 2nd term has type "pred n" which should be coercible to "pred n0".
The rewrite tactic tried to build the proof term using eq_ind_r lemma. Let us look at its type:
eq_ind_r
: forall (A : Type) (x : A) (P : A -> Prop),
P x -> forall y : A, y = x -> P y
rewrite tries to build the following term:
#eq_ind_r _ m (fun x => c x p = c m q) (subgoal : c m p = c m q) n E.
which is ill-typed:
Fail Check #eq_ind_r _ m (fun x => c x p = c m q).
The term "p" has type "pred n" while it is expected to have type "pred x".
This means that the link between n and pred n has been lost at this point and we can restore it by saying explicitly that x and p must comply with each other by generalizing over p:
Check #eq_ind_r _ m (fun x => forall (p : pred x), c x p = c m q).
The above means we can proceed to finish the proof in the following manner:
revert p.
rewrite H; intros p.
rewrite (irrel _ p q).
reflexivity.
Qed.
The original version of the code uses intro-pattern intros -> to achieve the effect of the longer intros E; revert p; rewrite E; intros p. for this particular case.

How to formalize the termination of a term reduction relation in Coq?

I have a term rewriting system (A, →) where A is a set and → a infix binary relation on A. Given x and y of A, x → y means that x reduces to y.
To implement some properties I simply use the definitions from Coq.Relations.Relation_Definitions and Coq.Relations.Relation_Operators.
Now I want to formalize the following property :
→ is terminating, that is : there is no infinite descending chain a0 → a1 → ...
How can I achieve that in Coq ?
Showing that a rewriting relation terminates is the same thing as showing that it is well-founded. This can be encoded with an inductive predicate in Coq:
Inductive Acc {A} (R : A -> A -> Prop) (x: A) : Prop :=
Acc_intro : (forall y:A, R x y -> Acc R y) -> Acc R x.
Definition well_founded {A} (R : A -> A -> Prop) :=
forall a:A, Acc R a.
(This definition is essentially the same one of the Acc and well_founded predicates in the standard library, but I've changed the order of the relation to match the conventions used in rewriting systems.)
Given a type A and a relation R on A, Acc R x means that every sequence of R reductions starting from x : A is terminating; thus, well_founded R means that every sequence starting at any point is terminating. (Acc stands for "accessible".)
It might not be very clear why this definition works; first, how can we even show that Acc R x holds for any x at all? Notice that if x is an element does not reduce (that is, such that R x y never holds for any y), then the premise of Acc_intro trivially holds, and we are able to conclude Acc R x. For instance, this would allow us to show Acc gt 0. If R is indeed well-founded, then we can work backwards from such base cases and conclude that other elements of A are accessible. A formal proof of well-foundedness is more complicated than that, because it has to work generically for every x, but this at least shows how we could show that each element is accessible separately.
OK, so maybe we can show that Acc R x holds. How do we use it, then?
With the induction and recursion principles that Coq generates for Acc; for instance:
Acc_ind : forall A (R : A -> A -> Prop) (P : A -> Prop),
(forall x : A, (forall y : A, R x y -> P y) -> P x) ->
forall x : A, Acc R x -> P x
When R is well-founded, this is simply the principle of well-founded induction. We can paraphrase it as follows. Suppose that we can show that P x holds for any x : A while making use of an induction hypothesis that says that P y holds whenever R x y. (Depending on the meaning of R, this could mean that x steps to y, or that y is strictly smaller than x, etc.) Then, P x holds for any x such that Acc R x. Well-founded recursion works similarly, and intuitively expresses that a recursive definition is valid if every recursive call is performed on "smaller" elements.
Adam Chlipala's CPDT has a chapter on general recursion that has a more comprehensive coverage of this material.