How do I change a concrete variable to an existentially quantified var in a hypothesis? - coq

Say I have a hypothesis like this:
FooProp a b
I want to change the hypothesis to this form:
exists a, FooProp a b
How can I do this?
I know I can do assert (exists a, FooProp a b) by eauto but I'm trying to find a solution that doesn't require me to explicitly write down the entire hypothesis; this is bad for automation and is just generally a headache when the hypothesis are nontrivial. Ideally I'd like to specify intro_exists a in H1 or something; it really should be that simple.
EDIT: Why? Because I have a lemma like this:
Lemma find_instr_in:
forall c i,
In i c <-> (exists z : Z, find_instr z c = Some i).
And a hypothesis like this:
H1: find_instr z c = Some i
And I'm trying to rewrite like this:
rewrite <- find_instr_in in H1
Which fails with the error Found no subterm matching "exists z, ..." .... But if I assert (exists z, find_instr z c = Some i) by eauto. first the rewrite works.

How about something like this:
Ltac intro_exists' a H :=
pattern a in H; apply ex_intro in H.
Tactic Notation "intro_exists" ident(a) "in" ident(H) := intro_exists' a H.
Section daryl.
Variable A B : Type.
Variable FooProp : A -> B -> Prop.
Goal forall a b, FooProp a b -> False.
intros.
intro_exists a in H.
Admitted.
End daryl.
The key to this is the pattern tactic, which finds occurrences of a term and abstracts them into a function applied to an argument. So pattern a converts the type of H from FooProp a b to (fun x => FooProp x b) a. After that, Coq can figure out what you mean when you apply ex_intro.
Edit:
All that being said, in your concrete case I would actually recommend a different approach, which is to not state your lemma like that. Instead it is convenient to split it into two lemmas, one for each direction. The forwards direction is just the same, but the backwards direction should be restated as follows
forall c i z,
find_instr z c = Some i -> In i c.
If you do this, then the rewrite will succeed without needing to introduce the existential.

Related

Proving equality between instances of dependent types

When attempting to formalize the class which corresponds to an algebraic structure (for example the class of all monoids), a natural design is to create a type monoid (a:Type) as a product type which models all the required fields (an element e:a, an operator app : a -> a -> a, proofs that the monoid laws are satisfied etc.). In doing so, we are creating a map monoid: Type -> Type. A possible drawback of this approach is that given a monoid m:monoid a (a monoid with support type a) and m':monoid b (a monoid wih support type b), we cannot even write the equality m = m' (let alone prove it) because it is ill-typed. An alternative design would be to create a type monoid where the support type is just another field a:Type, so that given m m':monoid, it is always meaningful to ask whether m = m'. Somehow, one would like to argue that if m and m' have the same supports (a m = a m) and the operators are equals (app m = app m', which may be achieved thanks to some extensional equality axiom), and that the proof fields do not matter (because we have some proof irrelevance axiom) etc. , then m = m'. Unfortunately, we can't event express the equality app m = app m' because it is ill-typed...
To simplify the problem, suppose we have:
Inductive myType : Type :=
| make : forall (a:Type), a -> myType.
.
I would like to have results of the form:
forall (a b:Type) (x:a) (y:b), a = b -> x = y -> make a x = make b y.
This statement is ill-typed so we can't have it.
I may have axioms allowing me to prove that two types a and b are same, and I may be able to show that x and y are indeed the same too, but I want to have a tool allowing me to conclude that make a x = make b y. Any suggestion is welcome.
A low-tech way to prove this is to insert a manual type-cast, using the provided equality. That is, instead of having an assumption x = y, you have an assumption (CAST q x) = y. Below I explicitly write the cast as a match, but you could also make it look nicer by defining a function to do it.
Inductive myType : Type :=
| make : forall (a:Type), a -> myType.
Lemma ex : forall (a b:Type) (x:a) (y:b) (q: a = b), (match q in _ = T return T with eq_refl => x end) = y -> make a x = make b y.
Proof.
destruct q.
intros q.
congruence.
Qed.
There is a nicer way to hide most of this machinery by using "heterogenous equality", also known as JMeq. I recommend the Equality chapter of CPDT for a detailed introduction. Your example becomes
Require Import Coq.Logic.JMeq.
Infix "==" := JMeq (at level 70, no associativity).
Inductive myType : Type :=
| make : forall (a:Type), a -> myType.
Lemma ex : forall (a b:Type) (x:a) (y:b), a = b -> x == y -> make a x = make b y.
Proof.
intros.
rewrite H0.
reflexivity.
Qed.
In general, although this particular theorem can be proved without axioms, if you do the formalization in this style you are likely to encounter goals that can not be proven in Coq without axioms about equality. In particular, injectivity for this kind of dependent records is not provable. The JMEq library will automatically use an axiom JMeq_eq about heterogeneous equality, which makes it quite convenient.

Instantiating an existential with a specific proof

I'm currently trying to write a tactic that instantiates an existential quantifier using a term that can be generated easily (in this specific example, from tauto). My first attempt:
Ltac mytac :=
match goal with
| |- (exists (_ : ?X), _) => cut X;
[ let t := fresh "t" in intro t ; exists t; firstorder
| tauto ]
end.
This tactic will work on a simple problem like
Lemma obv1(X : Set) : exists f : X -> X, f = f.
mytac.
Qed.
However it won't work on a goal like
Lemma obv2(X : Set) : exists f : X -> X, forall x, f x = x.
mytac. (* goal becomes t x = x for arbitrary t,x *)
Here I would like to use this tactic, trusting that the f which tauto finds will be just fun x => x, thus subbing in the specific proof (which should be the identity function) and not just the generic t from my current script. How might I go about writing such a tactic?
It's much more common to create an existential variable and let some tactic (eauto or tauto for example) instantiate the variable by unification.
On the other hand, you can also literally use a tactic to provide the witness using tactics in terms:
Ltac mytac :=
match goal with
| [ |- exists (_:?T), _ ] =>
exists (ltac:(tauto) : T)
end.
Lemma obv1(X : Set) : exists f : X -> X, f = f.
Proof.
mytac.
auto.
Qed.
You need the type ascription : T so that the tactic-in-term ltac:(tauto) has the right goal (the type the exists expects).
I'm not sure this is all that useful (usually the type of the witness isn't very informative and you want to use the rest of the goal to choose it), but it's cool that you can do this nonetheless.
You can use eexists to introduce an existential variable, and let tauto instantiates it.
This give the following simple code.
Lemma obv2(X : Set) : exists f : X -> X, forall x, f x = x.
eexists; tauto.
Qed.

Strong Induction on Lists

I'm trying to prove that a proposition P holds for every element of a type A. Unfortunately, I only know how to prove P for a given a:A if I have access to proofs of P for all a' less than a.
This should be provable by induction on a list containing all elements of A, starting with the smallest element in A and then incrementally proving that P holds for all other elements, but I just can't get it to work.
Formally, the problem is the following:
Parameter A : Type.
Parameter lt : A -> A -> Prop.
Notation "a < b" := (lt a b).
Parameter P : A -> Prop.
Parameter lma : forall a, (forall a', a' < a -> P a') -> P a.
Goal forall a, P a.
I may have made a mistake formalizing this problem. Feel free to assume reasonable constraints on the inputs, e.g. A can be assumed to be enumerable, lt can be transitive, decidable ...
This looks at lot like well founded induction. If you can prove that your lt function is well-founded, then your goal becomes trivial. You can find example of such proofs on naturals here
You also have to prove that the relation is well-founded. There's a relevant standard library module. From there, you should prove well_founded A for your A type, and then you can use well_founded_ind to prove P for all values.

Using `apply with` without giving names of parameters in Coq?

In using the Coq apply ... with tactic, the examples I have seen all involve explicitly giving the names of variables to instantiate. For example, given a theorem about the transitivity of equality.
Theorem trans_eq : forall (X:Type) (n m o : X),
n = m -> m = o -> n = o.
To apply it:
Example test: forall n m: nat,
n = 1 -> 1 = m -> n = m.
Proof.
intros n m.
apply trans_eq with (m := 1). Qed.
Note that in the last line apply trans_eq with (m := 1)., I have to remember that the name of the variable to instantiate is m, rather than o or n or some other names y.
To me, whether m n o or x y z are used in the original statement of the theorem shouldn't matter, because they are like dummy variables or formal parameters of a function. And sometimes I can't remember the specific names I used or somebody else put down in a different file when defining the theorem.
Is there a way by which I can refer to the variables e.g. by their position and use something like:
apply trans_eq with (#1 := 1)
in the above example?
By the way, I tried: apply trans_eq with (1 := 1). and got Error: No such binder.
Thanks.
You can specialize the lemma with the right arguments. The _ is used for all arguments that we don't want to specialize (because they can be inferred). The # is required to specialize implicit arguments.
Example test: forall n m: nat,
n = 1 -> 1 = m -> n = m.
Proof.
intros n m.
apply (#trans_eq _ _ 1).
Qed.
You can omit the binder names after with, so in your case do apply trans_eq with 1.
Example test: forall n m: nat,
n = 1 -> 1 = m -> n = m.
Proof.
intros n m.
apply trans_eq with 1; auto.
Qed.
I've changed your original example a little to conclude the proof.
Why this works
To understand why this works, check the manual under Bindings:
Tactics that take a term as an argument may also accept bindings to
instantiate some parameters of the term by name or position. The
general form of a term with bindings is termtac with bindings where
bindings can take two different forms:
bindings::= (ident | ​natural := term)+
| one_term+
What is shown in this example is the form one_term, which is described as follows:
in the case of apply, or of constructor and its variants, only instances for the dependent products that are not bound in the conclusion of termtac are required.
Which is why only one term needs to be supplied.

coq change premise 'negation of not equal' to 'equal'

Suppose I have a premise like this:
H2: ~ a b c <> a b c
And I wish to change it to:
a b c = a b c
Where
a is Term -> Term -> Term
b and c are both Term
How can I do it? Thanks!
If you unfold the definitions of ~ and <>, you hypothesis has the following type:
H2: (a b c = a b c -> False) -> False
Therefore, what you wish to achieve is what logicians usually call "double negation elimination". It is not an intuitionistically-provable theorem, and is therefore defined in the Classical module of Coq (see http://coq.inria.fr/distrib/V8.4/stdlib/Coq.Logic.Classical_Prop.html for details):
Classical.NNPP : forall (p : Prop), ~ ~ p -> p
I assume your actual problem is more involved than a b c = a b c, but for the sake of mentioning it, if you really care about obtaining that particular hypothesis, you can safely prove it without even looking at H2:
assert (abc_refl : a b c = a b c) by reflexivity.
If your actual example is not immediately reflexive and the equality is actually false, maybe you want to turn your goal into showing that H2 is absurd. You can do so by eliminating H2 (elim H2., which is basically doing a cut on the False type), and you will end up in the context:
H2 : ~ a b c <> a b c
EQ : a b c = a b c
=====================
False
I'm not sure whether all of this helps, but you might have oversimplified your problem so that I cannot provide more insight on what your real problem is.
Just a little thought to add to Ptival's answer - if your desired goal was not trivially solved by reflexivity, you could still make progress provided you had decidable equality on your Term, for example by applying this little lemma:
Section S.
Parameter T : Type.
Parameter T_eq_dec : forall (x y : T), {x = y} + {x <> y}.
Lemma not_ne : forall (x y : T), ~ (x <> y) -> x = y.
Proof.
intros.
destruct (T_eq_dec x y); auto.
unfold not in *.
assert False.
apply (H n).
contradiction.
Qed.
End S.