I have a base of rewrite lemmas. Some of them are parameterized by typeclasses. When applying a lemma, it is important that the rewrite fails when the typeclass cannot be automatically resolved by Coq. The only way I have found to get this behaviour is to declare most of the parameters implicit.
Class T (t:Type) : Type.
Instance T1 : T nat.
Instance T2 : forall {A1 A2:Type} {t1:T A1} {t2:T A2}, T (A1*A2).
Definition f {A:Type} (x:A) := x.
Lemma f_eq : forall {A:Type} (t:T A) (x:A), f x = x.
Proof.
reflexivity.
Qed.
Lemma test1 : f (0,1) = (0,1).
Proof.
rewrite f_eq.
(* a subgoal T (nat * nat) is generated,
which should have been resolved directly *)
Abort.
Lemma test2 : f (0,true) = (0,true).
Proof.
rewrite f_eq.
(* a subgoal T (nat * bool) is generated,
while it should have failed *)
Abort.
Arguments f_eq {_ _} _.
Lemma test1 : f (0,1) = (0,1).
Proof.
rewrite f_eq.
reflexivity. (* OK *)
Qed.
Lemma test2 : f (0,true) = (0,true).
Proof.
Fail rewrite f_eq. (* fails as expected *)
Abort.
Then I want to add my lemmas to a rewrite database, but the lemma added to the database is already specialized.
Hint Rewrite f_eq : my_db. Print Rewrite HintDb my_db. (* Database my_db rewrite -> f_eq of type forall x : nat, f x = x *)
How can I add my lemmas to a rewrite database and get the proper behaviour in terms of typeclass resolution of their arguments ?
EDIT: there is an option Set Typeclass Resolution After Apply.
that seems to enable the behaviour that I expect, but only for apply
, not rewrite
.
The corresponding commit gives the following description:
Add an option to solve typeclass goals generated by apply which can't be catched otherwise due to the discrepancy between evars and metas.
Definition f {A:Type} {t : T A} (x:A) := x.
, you'd be able to use rewrite hints and you wouldn't be abled to even stateLemma test2 : f (0,true) = (0,true).
– Anton Trunov