Zulip Chat Archive
Stream: lean4
Topic: Typeclass propagation loop?
Anne Baanen (Jan 29 2025 at 11:18):
Here's a fascinating failure I came across while implementing the concrete category refactor for MonCat
:
class Bottom (X : Type)
class Left (X : Type) extends Bottom X
class Right (X : Type) extends Bottom X
class Middle₁ (X : Type) extends Left X, Right X
class Middle₂ (X : Type) extends Middle₁ X
class Top (X : Type) extends Middle₂ X
structure Bundled where
(X : Type)
[inst : Left X]
instance loopy [i : Middle₂ X] : Middle₂ (Bundled.mk X).X := i
set_option trace.Meta.synthInstance true in
example (X : Type) [Top X] : Right X := inferInstance
-- Fails after 256 lines of "[resume] propagating Middle₂ (Bundled.mk X).X to subgoal Middle₂ X of Middle₂ X"
I think this is because in the loopy
instance, (Bundled.mk X).X
can be reduced to X
so somehow this gets Lean confused and makes it think has solved the wrong subgoal?
Anne Baanen (Jan 29 2025 at 11:19):
If we collapse Middle₁
and Middle₂
into one Middle
class, we only get 128 passes through the [resume] propagating
loop before we exit, which makes Lean happy to apply the instance.
Yaël Dillies (Jan 29 2025 at 11:37):
Yes, fascinating! Maybe that should be in #lean4 ?
Notification Bot (Jan 29 2025 at 12:15):
This topic was moved here from #mathlib4 > Typeclass propagation loop? by Anne Baanen.
Jovan Gerbscheid (Feb 01 2025 at 06:41):
using set_option pp.explicit true
, we can see that each next type (of the 256) contains an extra application of loopy
. The part of the code that checks whether a new instance is different from the previous ones uses ==
, and it has a comment:
Remark: isDefEq here is too expensive. TODO: if ==
is too imprecise, add some light normalization to resultType
at addAnswer
Last updated: May 02 2025 at 03:31 UTC