Just out of curiosity, I was wondering where in the source code I could find the implementation of typeclass resolution. I was reading through "First-class Typeclasses" https://sozeau.gitlabpages.inria.fr/www/research/publications/First-Class_Type_Classes.pdf and couldn't really get a full picture of how the unification algorithm works. Does anyone know where in the source I can crawl through to take a look? (If there are other sources of documentation that I could try reading, I would also appreciate that a lot. Thanks)
Hi Irene, I'm afraid the source is the only reliable source if you're looking at the details of the unification. But the reference manual chapter should also give you some information.
Hi Matthieu, I see, where in the source can I find it, if you don't mind? I'm having a hard time paging through all the various directories in the repo
If you're looking for unification as used in TC search, a reasonable entry point is class_apply... with the caveat that TC search doesn't loop over hints using class_apply, but first filters hints using dnets accounting for hint opacity
I see, as found here? https://github.com/coq/coq/blob/611468b3bb25e8c2ee18bc7e03e3a5b1726df9c0/theories/Classes/Init.v#L26 Thanks as always Paulo, I'll take a look and see what I can make out of it.
The search algorithm proper is in class_tactics.ml
Thanks Matthieu!
Ah, more curious poking here, is the UniCoq project (https://people.mpi-sws.org/~beta/papers/unicoq.pdf) upstreamed to the main dev branch for coq? Or is it only be available as a plugin for now? (Is there a good reason that it's not upstreamed if it's more powerful?)
I'm trying to clean up some resolution issues for higher-order objects so I'm trying to see what the best solution is
I believe it is differently powerful, not more
The usual summary is that UniCoq is the third unification algorithm for Coq after tactic unification (used by tactics) and evarconv (used by ssreflect tactics), and the first with a documented semantics. The "unifall" branch planned to replace tactic unification by evarconv, at least in typeclass search, but it breaks too much...
When an instance/hint resolve doesn't apply because of tactic unification (say because of canonical structures like in Iris), the usual workaround is to write Hint Externs that use ssreflect's apply:.
And I'm remembering that you do use Iris, @Irene Yoon , so maybe this is the problem you run into? My summary is biased to Iris users anyway...
FTR evarconv is also used by the pretyper, which means it is used when typing Definition ...
and Lemma ...
.
"tactic unification" is used only by a few tactics, like apply. As you mention, changing the behavior of a very common tactic like apply is not easy
Among other reasons, ltac practice ensures that even "make tactics strictly more powerful" is a breaking change, and in combination with backtracking it becomes a fun one. And I guess evarconv might be slower sometimes?
OK. I've been running into issues for a project that does not use Iris, canonical structures, or ssreflect.
I must say I do not understand the expected behavior of tactic unification, but indeed the main issue was apply
or rewrite
failing, where I had to write some custom tactics for inferring the evars in the context instead of directly using apply
or rewrite
.
I was wondering if there was an easy way to extend the evar resolution/unification, maybe I should instead look into extending the unification using canonical structures? Does extending unification using canonical structures work nicely with setoid_rewrite
?
evarconv is slower, yes. Although it is typical of software which aims at being sound and complete to be slower than software which shortcuts in random ways :-)
refine
can serve as a (non-ssreflect) alternative to apply
if you know the number of arguments to your lemma in advance. It uses evarconv and might help with the problem of inferring evars.
Does extending unification using canonical structures work nicely with setoid_rewrite?
don't have a lot of first-hand experience with the interaction of TC search and CS resolution but I hear it doesn't work all that well. That might be outdated, though. Still, this could mean that setoid_rewrite
with CS won't solve your problem.
Isn't the problem precisely that TC search uses tactic unification which does not handle CSes well?
Yes but I never really understood what that means exactly
Clearly tactic unification does CS resolution otherwise a lot of things would just not work at all. I remember a few MRs in the past few years that were related to this problem but I don't know if any of them went in. Maybe they were all part of unifall?
Paolo Giarrusso said:
Isn't the problem precisely that TC search uses tactic unification which does not handle CSes well?
what problem?
Since we're discussing using CS to tweak tactic unification, this seems potentially relevant, as long as both unification strategies are treated as almost-black-boxes:
https://gitlab.mpi-sws.org/iris/iris/-/wikis/coq-bugs
[HIGH] #6294: apply (including TC search) and canonical structures don't mix very well, so we randomly use apply: and cannot grow our algebraic hierarchy any further.
And to be sure, I'd prefer discussing the unification algorithms by their specifications, rather than "by superstition" as I'm doing, but I understand their behaviors are unspecified for good reason since they're too complex and quirky, which unicoq fixes...
(and I'm sad I've never read the unicoq paper)
Oh, thanks for the pointer on the Iris side.
[HIGH] #7916: Cannot set mode for Reflexive because setoid_rewrite makes some strange queries, so we suffer from backtracking and slow rewriting whenever Reflexive ? comes up.
This (now closed) issue also sounds close to the problem I'm coming across. I should also try out my development against 8.16 and see if that helps as well
It's especially good to know that there are potential issues with apply
+CS as Robbert pointed out in issue #6294. Well, I guess I will go carve out some smaller examples where resolution goes awry in my development, and experiment to see what 8.16 fixes / unicoq can do in my situation. I might come back for more questions, but I think I have enough pointers for now. Thanks for the help everyone!
A small thing to be aware of regarding unicoq and CS: unicoq has not been patched to implement the recent improvements to CS (see https://coq.inria.fr/refman/changes.html#id383). I don't think many people use these new features yet but I thought I'd mention it just in case you do.
The UniCoq paper says that it purposely lacks a technique known as constraint postponement. At some point, I observed some cases that evarconv works but UniCoq fails, in MathComp.
@Irene Yoon if you have Reflexive trouble, remember that 8.16 does not set the mode, it just has code that doesn't break if you do...
A message was moved from this topic to #Coq devs & plugin devs > Typeclass resolution algorithm? by Karl Palmskog.
Last updated: Oct 01 2023 at 17:01 UTC