Hello everyone
In the abstract, my question(s) is the following.
- Is there a way to require import a file without putting in scope the global instances that it declares?
- Alternatively, what is the status of #7342, for having a command to remove an Instance from the Visible scope?
- Even better, are there any plans to associate sets of instances to namespaces in the style of hint databases?
- And finally, in the temporary absence of these, does any one have a good hack to achieve the initial goal?
For more of a specific, concrete context for the curious, I got bitten hard by the following issue. In the Interaction Trees library, we heavily rely on type classes to work with rewriting for non-trivial relations. Overall, it’s fairly stable, we’re quite happy with it.
However I have been working on using this library to prove a pass of compilation from a language developed independently, and things there got slow and unpredictable. I eventually fired up some debugging: turns out that while trying to justify rewrites, the inference mechanism is now exploring branches relying on checking whether my structure wouldn’t happen to be a lattice, semi-group, and so on…
And indeed, even if I don’t import it locally, the language depends on MathClasses! So that a myriads of instances sneaked in behind my back, and happily try to contribute where I don’t need them.
The smallest example for reference that I have at hand would be to consider the rewrite H
happening here. If I trace it, I get a reasonable resolution in 9 steps, with the deepest branch being of depth 3.
Now if I first do Require Import MathClasses.interfaces.abstract_algebra.
, and perform the same rewrite, it still works, but now after more than 200 steps, exploring dead branches of roughly depth 15.
Once in my actual context where the rewrites happen in non-trivial terms, it gets unreasonable, and the import is imposed on me.
I would love to hear of any potentially hacky way to get around this problem immediately, but would also be happy to discuss long term solutions to tackle this issue in general.
Best,
Yannick
EDIT: Here is a self contained example avoiding any dependency on itrees:
From Coq Require Import
Setoid
Morphisms
RelationClasses.
Section Foo.
Variable op: nat -> nat.
Variable rel: nat -> nat -> Prop.
Context {rel_op_Proper: (Proper (rel ==> rel) op)}.
Context {rel_refl: Transitive rel}.
Goal forall (a b: nat) (REL: rel a b),
rel (op a) (op b).
Proof.
intros.
Typeclasses eauto := debug.
rewrite REL.
(* Resolution in 6 steps *)
Undo.
Require Import MathClasses.interfaces.abstract_algebra.
rewrite REL.
(* Resolution in over 100 steps *)
Abort.
End Foo.
In my use case:
- I cannot avoid this
Require Import
because I inherit it transitively from a file that I have toRequire Import
- I do not use on my side any reasoning inherited from MathClasses, I therefore do not need any Hint/Instances they export
- I cannot afford this blowup in TC resolution.
Is there a way for the second rewrite in this example to still lead to the same resolution as the first one?