Rewrite with variable from inner scope? - coq

Is it possible to rewrite something that uses variables from another scope,
such as a function call that uses a variable from a match, fun, or fix ?
For example,
Theorem foo (f : nat -> nat) (rw : forall x, f x = 5) x : match x with
| 0 => 5
| S a => f a
end = 5.
rewrite rw.
(* Error: Found no subterm matching "f ?M160" in the current goal. *)
destruct x; try rewrite rw; apply eq_refl.
Qed.
So, the theorem is provable, but trying to rewrite rw initially fails,
seemingly because a is in another scope. But, the rewrite applies
unconditionally, so it seems like it should apply there too.
Of course, this is a toy example. Assume that, in a real-world scenario,
getting into the scope is a bit more complicated than just a destruct.
From Rewrite tactic fails to find term occurrence within pattern matching it looks like this isn't possible in Coq. So, is it just that it isn't implemented, or does it cause contradictions or allow for bad behavior like smuggling variables out of their scope?
What about harder cases like fix ?

You have likely heard that the Logic of Coq is not powerful enough to derive functional exensionality.
Now what you prove above is a point wise equality, that is you prove that an applied function has a certain value.
A rewrite in the match would correspond to a proof that two unapplied functions are equal: The original match statement (which is a function of x) and the rewritten match statement (also a function of x). This means you would prove a more general result as intermediate step - and Coq's logic is not able to prove this more general result.
Functional extensionality is compatible with Coq's logic, though. So one can add it as axiom and then one can add some setoid instances which allow to setoid_rewrite under binders. But afaik this does not work for rewrites under matches either.
It would also be possible to detect that in the end you prove a point wise equality, do the destruct behind the scenes, do the point wise rewrite and put things together again, but this would work only in rather trivial cases, which I guess are not sufficiently interesting to implement this.
To close here is an example of proving functional extensionality (suggested by the edit by #scubed) with a rewrite under binders - which is enabled by a global type class instance which is itself based on the functional extensionality axiom. So this proves an axiom with itself and it doesn't help for your match case, but it shows that rewriting under binders is equivalent to functional extensionality.
Require Import PeanoNat.
Require Import Setoid.
Require Import Morphisms.
Definition fun1 (x : nat) := x + 1.
Definition fun2 (x : nat) := 1 + x.
Example Fun1EqFun2: fun1 = fun2.
Proof.
unfold fun1, fun2.
Fail setoid_rewrite Nat.add_comm.
Abort.
Require Import FunctionalExtensionality.
(* This is derived from the error message of setoid_rewrite above *)
Global Instance:
forall (A B : Type),
Proper
(#pointwise_relation A B eq ==>
#pointwise_relation A B eq ==> Basics.flip Basics.impl) eq.
Proof.
(* See what all this Setoid stuff actually means ... *)
unfold Proper, pointwise_relation, respectful, Basics.flip, Basics.impl.
intros A B f g fgeq f' g' fg'eq gg'eq.
apply functional_extensionality.
intros x.
rewrite fgeq, fg'eq, gg'eq.
reflexivity.
Qed.
Theorem eq_arg (A B : Type) (f : A -> B) : f = (fun x => f x). reflexivity. Qed.
Lemma functional_extensionality' :
forall (A B : Type), forall (f g : A -> B),
(forall a : A, (f a) = (g a)) -> f = g.
Proof.
intros.
setoid_rewrite eq_arg at 2.
setoid_rewrite H.
reflexivity.
Qed.

Related

Axiom reuse with Typeclasses in Coq

I am trying to use typeclasses for code reuse, but I am getting setoid errors applying parent typeclass axioms in child typeclass theorems. I made a MRE with the following Equality and Addition operations:
Require Import Setoid.
(* Equality *)
Parameter CEq : forall A, A->A->Prop.
Arguments CEq [A] _ _.
Notation "x ¦ y" := (CEq x y) (at level 70, no associativity).
Axiom ceq_reflexivity: forall A, forall a:A, a¦a.
Axiom ceq_symmetry: forall A, forall a b:A, a¦b->b¦a.
Axiom ceq_transitivity: forall A, forall a b c:A, a¦b->b¦c->a¦c.
Add Parametric Relation A : (A) (#CEq A)
reflexivity proved by (#ceq_reflexivity A)
symmetry proved by (#ceq_symmetry A)
transitivity proved by (#ceq_transitivity A)
as ceq_rel.
(* Addition *)
Parameter CAdd: forall A, A->A->A.
Arguments CAdd [A] _ _.
Infix "±" := CAdd (at level 50, left associativity).
The following are the parent and child classes:
(* Parent Typeclass *)
Class CDiscT (CDisc: Set) := {
O: forall CDisc, CDisc;
cdisc_add_neutral:forall CDisc, forall x:CDisc, x±(O CDisc)¦x;
}.
(* Natural Set & Child Typeclass *)
Parameter CNat: Set.
Class CNatT `{CDiscT CNat} := {}.
And here is the failing theorem:
(* Axiom inheritance test *)
Example test `{CNatT}: (O CNat)¦(O CNat)±(O CNat).
Proof.
rewrite <- cdisc_add_neutral. (* Error *)
reflexivity.
Qed.
Here is the error:
Error:
Tactic failure: setoid rewrite failed: Unable to satisfy the following constraints:
In environment:
H : CDiscT CNat
H0 : CNatT
?s : "subrelation (CEq (A:=Prop)) (Basics.flip Basics.impl)"
What is missing here to be able to use CDiscT axioms inside CNatT theorems? Is there a better way to do this?
This may be in part because your example is too simplified, but rewriting right-to-left with cdisc_add_neutral is problematic because the right-hand side x matches anything and can have any type.
The error you get is that Coq is trying to rewrite the whole goal with it, but that would use logical implication impl, which in turn requires that your relation CEq is a subrelation of impl.
You can avoid this by specializing the lemma a bit:
rewrite <- (cdisc_add_neutral CNat) at 1.
You need the at 1 because now the subterm that matches is O CNat, but it occurs three times in your goal. rewrite tries to rewrite all of them by default, which requires Proper instances that are missing here. (You can get those via the Parametric Morphism mechanism described in the manual).
Also, you can rewrite left-to-right:
rewrite cdisc_add_neutral

What is a good example of a simple proof in Coq where the conclusion has a existential quantifier?

I wanted to see a few hands on examples of Coq proofs of the form:
\exists A(x1,...,xn)
essentially where the Goal had an existential quantifier. I was having issues manipulating the goal in meaningful ways to make progress in my proof and wanted to see a few examples of common tactics to manipulate.
What are some good existential quantifiers examples in Coq to prove?
My specific example I had:
Theorem Big_Small_ForwardImpl :
forall (P : Program) (S' : State),
(BigStepR (B_PgmConf P) (B_StateConf S')) -> (ConfigEquivR (S_PgmConf P) (S_BlkConf EmptyBlk S')).
Proof.
intros.
induction P.
unfold ConfigEquivR.
refine (ex_intro _ _ _) .
my context and goals was:
1 subgoal
l : list string
s : Statement
S' : State
H : BigStepR (B_PgmConf (Pgm l s)) (B_StateConf S')
______________________________________(1/1)
exists N : nat, NSmallSteps N (S_PgmConf (Pgm l s)) (S_BlkConf EmptyBlk S')
but then changed to:
1 subgoal
l : list string
s : Statement
S' : State
H : BigStepR (B_PgmConf (Pgm l s)) (B_StateConf S')
______________________________________(1/1)
NSmallSteps ?Goal (S_PgmConf (Pgm l s)) (S_BlkConf EmptyBlk S')
after using the refine (ex_intro _ _ _) tactic. Since I am not sure what is going on I was hoping some simpler examples could show me how to manipulate existential quantifiers in my Coq goal.
helpful comment:
The ?Goal was introduced by Coq as a placeholder for some N that will have to be deduced later in the proof.
The following example is based on the code provided in this answer.
Suppose we have a type T and a binary relation R on elements of type T. For the purpose of this example, we can define those as follows.
Variable T : Type.
Variable R : T -> T -> Prop.
Let us prove the following simple theorem.
Theorem test : forall x y, R x y -> exists t, R x t.
Here is a possible solution.
Proof.
intros. exists y. apply H.
Qed.
Instead of explicitly specifying that y is the element we are looking for, we can rely on Coq's powerful automatic proof mechanisms in order to automatically deduce which variable satisfies R x t:
Proof.
intros.
eexists. (* Introduce a temporary placeholder of the form ?t *)
apply H. (* Coq can deduce from the hypothesis H that ?t must be y *)
Qed.
There exist numerous tactics that make ise of the same automated deduction mechanisms, such as eexists, eapply, eauto, etc.
Note that their names often correspond to usual tactics prefixed with an e.

How to turn an single unification variable into a goal, during proof

I want to construct an existential variable interactively. I can't use Grab Existential Variables because I need to fill the existential before I complete the goal.
Minimal exmaple
Here is a minimal example (since it's simple, it has other solutions, but it illustrates my question)
Context (A:Type).
Parameter P Q: A -> Prop.
Definition filter: forall {a}, P a -> A:= fun a Pa=> a.
Lemma my_lemma:
forall a b, Q b -> (Q b -> P a) ->
exists a (H: P a), P (filter H).
Proof.
intros ?? H H0.
do 2 eexists.
At this point, there are two solutions that don't answer my questions: (1) I could run (eauto) and then do Grab Existential Variables, but suppose that eauto doesn't succeed until I instantiate the unification variable; (2) I could just pass the proof term explicitly with instantiate(1:= H0 H) (or even instantiate(1:= ltac:(eauto))), but assume that the proof of the xistential was tedious and we wished to do it interactively.
What else can we do? We can try to use cut or assert, like so:
match goal with
|[|- P (filter ?x)] =>
match type of x with
| ?T => assert (HH:T) by eauto
end
end.
But HH is not in the context of the unification variable, so it can't be instantiated.
instantiate(1:=HH). (* Instance is not well-typed in the environment of ?H. *)
As far as I can tell, the only way to solve this is to use Show Existentials, see the type of the variable copy it by hand, roll back the proof to before the unification was introduced and construct the variable there. In the example it looks like this:
Lemma my_lemma:
forall a b, Q b -> (Q b -> P a) ->
exists a (H: P a), P (filter H).
Proof.
intros ?? H H0.
do 2 eexists.
Show Existentials.
Restart. (* This command restores the proof editing process to the original goal. *)
intros ?? H H0.
assert (HH:P a) by eauto.
eexists; exists HH.
auto.
Qed.
Obviously, I would like to avoid this workflow. So, anyway to turn the existential variables into subgoals?
Your best bet is probably to avoid creating the existential variable as an evar in the first place. You don't have to construct the variable by hand to do this; if you can identify where it's created, you can wrap the offending tactic with unshelve t, which turns all evars created by t into goals. Where this might be difficult is if the relevant tactic is deep inside some automation and difficult to identify or change.

Proof irrelevance in COQ

I am thinking about proof irrelevance in COQ.
One provable statement says:
If equality of a type is decidable then there can be only one proof for the equality statement, namely reflexivity.
I wonder if its possible to construct types with more than one equality proof in COQ. Therefore I ask if the following construct is consistent?
(*it is known that f=g is undecidable in COQ *)
Definition f(n:nat) := n.
Definition g(n:nat) := n+0.
Axiom p1: f=g.
Axiom p2: f=g.
Axiom nonirrelevance:p1<>p2.
What me puzzles here is the fact that by introducing p1 I made the equality f=g decidable and therefore it should only have one proof! What is my error in reasoning here?
Is that all a pure COQ behaviour or is it similar in HOTT?
I think you're confusing several things.
The provable statement you are speaking of can be found in https://coq.inria.fr/library/Coq.Logic.Eqdep_dec.html and is
Theorem eq_proofs_unicity A (eq_dec : forall x y : A, x = y \/ x <> y) (x : A) :
forall (y:A) (p1 p2:x = y), p1 = p2.
Now what is quite interesting is the type of eq_dec. First of all, it doesn't even really ask for equality to be decidable, it just asks for it to be true or false which is way less stronger than {x = y} + {x <> y}
Then notice that it doesn't ask this just for the x and y to prove the equality irrevelance of, it ask this property for all functions.
So you would need to prove your contradiction that forall (f g : nat -> nat), f = g \/ f <> g which you cannot. p1 is just a proof that f = g \/ f <> g for your specific f and g.
Notice though that if you could, it would just mean that there is no way to build a system in which you can compare functions and yet have multiple ways which are provably different to check them.
Finally, for P to be undecidable only means that there is no constructible functions over {P} + {~P} yet, it doesn't mean that adding one as an axiom leads to a contradiction. Just adding that in case it wasn't clear.

Is one being penalized by using 'same_relation' (and possibly other library definitions)?

Given any programming language, whenever a standard library function exists, we should most likely use it rather than write our own code. One would think that this advice applies equally to Coq. However, I recently forced myself to use the same_relation predicate of the Relation module, and I am left with the feeling of being worse off. So I must be missing something, hence my question. To illustrate what I mean let us consider to possible relations:
Require Import Relations. (* same_relation *)
Require Import Setoids.Setoid. (* seems to be needed for rewrite *)
Inductive rel1 {A:Type} : A -> A -> Prop :=
| rel1_refl : forall x:A, rel1 x x. (* for example *)
Inductive rel2 {A:Type} : A -> A -> Prop :=
| rel2_refl : forall x:A, rel2 x x. (* for example *)
The specific details of these relations do not matter here, as long as rel1 and rel2 are equivalent. Now, if I want to ignore the Coq library, I could simply state:
Lemma L1: forall (A:Type)(x y:A), rel1 x y <-> rel2 x y.
Proof.
(* some proof *)
Qed.
and if I want to follow my instinct and use the Coq library:
Lemma L2: forall (A:Type), same_relation A rel1 rel2.
Proof.
(* some proof *)
Qed.
In the simplest of cases, it seems that having proven lemma L1 or Lemma L2 is equally beneficial:
Lemma application1: forall (A:Type) (x y:A),
rel1 x y -> rel2 x y (* for example *)
Proof.
intros A x y H. apply L1 (* or L2 *) . exact H.
Qed.
Whether I decide to use apply L1 or apply L2 makes no difference...
However in practice, we are likely to be faced with a more complicated goal:
Lemma application2: forall (A:Type) (x y:A) (p:Prop),
p /\ rel1 x y -> p /\ rel2 x y.
Proof.
intros A x y p H. rewrite <- L1. exact H.
Qed.
My point here is that replacing rewrite <- L1 by rewrite <- L2 will fail. This is also true of the previous example, but at least I was able to use apply rather than rewrite. I cannot use apply in this case (unless I go through the trouble of splitting my goal). So it seems that I have lost the convenience of using rewrite, if I only have Lemma L2.
Using rewrite on results which are an equivalence (not just an equality) is very convenient. It seems that wrapping an equivalence into the predicate same_relation takes away this convenience. Was I right to follow my instinct and force myself to use same_relation? More generally, is it so true that if a construct is defined in the standard Coq library, I should use it, rather than define my own version of it?
You pose two questions, I try to answer separately:
Regarding your rewrite problem, this problem is natural as the definition of same_relation goes as double inclusion. I agree that maybe a definition using iff would be more convenient. It would really depend on the kind of goals you have. A possible solution for your problem is to define a view:
Lemma L1 {A:Type} {x y:A} : rel1 x y <-> rel2 x y.
Proof.
Admitted.
Lemma L2 {A:Type} : same_relation A rel1 rel2.
Proof.
Admitted.
Lemma U {T} {R1 R2 : relation T} :
same_relation _ R1 R2 -> forall x y, R1 x y <-> R2 x y.
Proof. now destruct 1; intros x y; split; auto. Qed.
Lemma application2 {A:Type} {x y:A} {p:Prop} :
p /\ rel1 x y -> p /\ rel2 x y.
Proof. now rewrite (U L2). Qed.
Note also that rewriting with a <-> relation is not really based on equality, but on "setoid rewriting". In fact, the following doesn't hold in Coq A <-> B -> A = B.
Regarding your second question, whether to use the Coq standard library is a highly subjective topic. I personally rarely use it, I prefer a different library called math-comp, but YMMV. Regarding relations, mathcomp is mostly specialized into boolean relations rel x y = x -> y -> bool, thus, equivalence is simply defined as equality, typically, given r1 r2 you'd write r1 =2 r2.
IMHO in the end, such choices are highly dependent on your application domain.
[edit]: Note that the Relation library is dated:
Naive set theory in Coq. Coq V6.1. This work was started in July 1993 by F. Prost.
So indeed, it may not be the best modern base to build Coq developments on.