-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
coqc infinite loop in type class resolution #17
Comments
Maybe useful to know: collacoq gets "Stack overflow." https://x80.org/collacoq/apakagupok.coq Also noteworhty: It doesn't happen if Setoid is not imported. Could it be a kind of "loop" in the instance definitions in RelationClasses.v? |
Here is how to debug: Require Import Setoid.
Require Import Morphisms. (* for Equivalence *)
Definition equ {T} {e} `(Equivalence T e) := e.
Notation "f == g" := (equ _ f g) (at level 80).
Class Op (A:Type) := op : A -> A -> A.
Set Typeclasses Debug.
Set Typeclasses Depth 2.
Class C F `(Op F) (* `(Equivalence F) *) :=
{
foo : forall a b , op a b == op a b;
}. We see that
We restricted the depth to 2, so we look for instances that keep repeating. It looks like Another way to check this theory is to use breadth first search typeclass search: Require Import Setoid.
Require Import Morphisms. (* for Equivalence *)
Definition equ {T} {e} `(Equivalence T e) := e.
Notation "f == g" := (equ _ f g) (at level 80).
Class Op (A:Type) := op : A -> A -> A.
Set Typeclasses Iterative Deepening.
Class C F `(Op F) (* `(Equivalence F) *) :=
{
foo : forall a b , op a b == op a b;
}.
This finishes, so it probably is the instance outlined above repeating over and over again. The fix would be to not make this an instance or somehow cut it from being repeated. |
@coq/typeclasses-maintainers What is the correct way to restrict this instance short of removing it? |
That makes no sense, relation_equivalence_equivalence has no typeclass argument so it can't recurse. You can Putting Hint Mode on Equivalence may or may not break setoid rewriting or other stuff. |
Also note that the notation |
Here is another small test case that goes into an infinite loop, for what I think is the same reason.
|
It seems indeed a duplicate of #38; this is one reason why hint modes are important. |
I want to endorse this report as a serious problem. I too made a small error so that an intended Equivalence instance could not be found, sending the typeclass inference engine into an infinite regress with no clue where I had gone wrong. I recognize that I can err in writing instances that recurse infinitely and get what I deserve when I do. I found my mistake but then went searching for where I could have introduced the looping behavior. I traced the problem to Equivalence.pointwise_equivalence. This comes in indirectly through Setoids.Setoid from all over the standard library. I can't give up setoid rewriting so there is no avoiding this. I note in other places in the Classes libraries where there are comments about Hint Extern ... : typeclass_instances needed to drive typeclass inference avoiding looping from full resolution. I can only hope there can be some analogous fix here. Typeclass inference for setoid rewriting is magical and I can't begin to suggest how to repair this. But having typeclass inference looping when it can't find a needed instance isn't acceptable when it is due to something embedded so deeply in the standard library. |
Description of the problem
Compiling this program makes
coqc
go into an infinite loop.Note that there is a "bug" in the program because I commented out `(Equivalence F).
This will make coqc search forever for which Equivalence instance it should
use in
foo
.Coq Version
I installed v8.15.1 with
nix
.[nix-shell]$ coqc --version
The Coq Proof Assistant, version 8.15.1
compiled with OCaml 4.12.1
I also tried 8.14.1 and 8.13.1 with the same result.
And I just (July 16, 2022) tried it with master, i.e. 8.17+alpha 672b144 , and it still has the same problem.
The text was updated successfully, but these errors were encountered: