Zulip Chat Archive
Stream: lean4
Topic: typeclass inference failure
Kevin Buzzard (Feb 01 2024 at 23:13):
import Mathlib.LinearAlgebra.TensorProduct
import Mathlib.LinearAlgebra.Finsupp
import Mathlib.LinearAlgebra.Quotient
open TensorProduct
variable (k α A : Type*) [CommRing k] [AddCommGroup A]
[Module k A] (S : Submodule k (A ⊗[k] (α →₀ k)))
set_option trace.Meta.synthInstance true in
#check (A ⊗[k] (α →₀ k)) ⧸ S -- fails to synthesise HasQuotient instance
noncomputable instance : AddCommGroup (A ⊗[k] (α →₀ k)) := inferInstance -- shortcut
#check (A ⊗[k] (α →₀ k)) ⧸ S -- now works fine
The relevant instance trace is
[Meta.synthInstance] ❌ HasQuotient (A ⊗[k] (α →₀ k)) (Submodule k (A ⊗[k] (α →₀ k))) ▼
[] new goal HasQuotient _tc.0 (Submodule k (A ⊗[k] (α →₀ k))) ▶
[] ❌ apply @Submodule.hasQuotient to HasQuotient ?m.2747 (Submodule k (A ⊗[k] (α →₀ k))) ▼
[tryResolve] ❌ HasQuotient ?m.2747 (Submodule k (A ⊗[k] (α →₀ k))) ≟ HasQuotient ?m.2752 (Submodule ?m.2751 ?m.2752) ▼
[] ✅ Ring k ▶
[] ❌ AddCommGroup (A ⊗[k] (α →₀ k)) ▼
[] new goal AddCommGroup (A ⊗[k] (α →₀ k)) ▶
[] ❌ apply inst✝¹ to AddCommGroup (A ⊗[k] (α →₀ k)) ▶
[] ❌ apply @TensorProduct.addCommGroup to AddCommGroup (A ⊗[k] (α →₀ k)) ▼
[tryResolve] ❌ AddCommGroup (A ⊗[k] (α →₀ k)) ≟ AddCommGroup (?m.2830 ⊗[?m.2828] ?m.2831) ▼
[] ❌ AddCommGroup (α →₀ k) ▼
[] new goal AddCommGroup (α →₀ k) ▶
[] ❌ apply inst✝¹ to AddCommGroup (α →₀ k) ▶
[] ❌ apply @Finsupp.addCommGroup to AddCommGroup (α →₀ k) ▼
[tryResolve] ❌ AddCommGroup (α →₀ k) ≟ AddCommGroup (?m.2851 →₀ ?m.2852)
and the last line is the inexplicable failure. Is it something to do with computability?
Matthew Ballard (Feb 02 2024 at 00:19):
It isn’t computability because the #check
still works if you remove the noncomputable
attribute. You only get an error about not generating IR
Matthew Ballard (Feb 02 2024 at 00:20):
Something isn’t being unfolded
Matthew Ballard (Feb 04 2024 at 14:15):
At some point it reaches
AddMonoid.toAddSemigroup =?= TensorProduct.addSemigroup A (α →₀ k)
What is supposed to happen:
[Meta.isDefEq] ✅ AddMonoid.toAddSemigroup =?= TensorProduct.addSemigroup A (α →₀ k) ▼
[] ✅ TensorProduct.addSemigroup A (α →₀ k) =?= TensorProduct.addSemigroup A (α →₀ k) ▼
[] ✅ A =?= A
[] ✅ α →₀ k =?= α →₀ k
[] ✅ k =?= k
[] ✅ CommRing.toCommSemiring =?= CommRing.toCommSemiring
[] ✅ AddCommGroup.toAddCommMonoid =?= AddCommGroup.toAddCommMonoid
[] ✅ AddCommGroup.toAddCommMonlean=?= Finsupp.addCommMonoid ▶
[] ✅ inst✝ =?= inst✝
[] ✅ Finsupp.module α k =?= Finsupp.module α k
What actually does
[] ❌ AddMonoid.toAddSemigroup =?= TensorProduct.addSemigroup A (α →₀ k) ▼
[] ❌ AddMonoid.toAddSemigroup =?= let src := AddCon.addMonoid (addConGen (TensorProduct.Eqv k A (α →₀ k)));
AddSemigroup.mk
(_ :
∀ (a b c : AddCon.Quotient (addConGen (TensorProduct.Eqv k A (α →₀ k)))),
a + b + c = a + (b + c)) ▶
It looks like it’s having trouble filling a metavariable for R
in the tensor product with k
Matthew Ballard (Feb 04 2024 at 14:21):
A trace class for the branching logic of unification would be nice
Kevin Buzzard (Feb 10 2024 at 18:44):
I came back to this today. I've stripped the example down to importing Algebra.Ring.Basic
. It's a delicate minimisation problem -- you make one false move and suddenly it all magically works again. An empirical observation is that when it works, the trace looks like this:
[Meta.synthInstance] ✅ HasQuotient (TensorProduct k A (Finsupp α k)) (Submodule k (TensorProduct k A (Finsupp α k))) ▼
[] new goal HasQuotient _tc.0 (Submodule k (TensorProduct k A (Finsupp α k))) ▶
[] ✅ apply @Submodule.hasQuotient to HasQuotient (TensorProduct k A (Finsupp α k))
(Submodule k (TensorProduct k A (Finsupp α k))) ▼
[tryResolve] ✅ HasQuotient (TensorProduct k A (Finsupp α k))
(Submodule k
(TensorProduct k A
(Finsupp α
k))) ≟ HasQuotient (TensorProduct k A (Finsupp α k)) (Submodule k (TensorProduct k A (Finsupp α k)))
and the [tryResolve]
for HasQuotient
has no metavariables in. But when it's failing (like the example I post below), the trace looks like this:
[Meta.synthInstance] ❌ HasQuotient (TensorProduct k A (Finsupp α k)) (Submodule k (TensorProduct k A (Finsupp α k))) ▼
[] new goal HasQuotient _tc.0 (Submodule k (TensorProduct k A (Finsupp α k))) ▶
[] ❌ apply @Submodule.hasQuotient to HasQuotient ?m.6925 (Submodule k (TensorProduct k A (Finsupp α k))) ▼
[tryResolve] ❌ HasQuotient ?m.6925 (Submodule k (TensorProduct k A (Finsupp α k))) ≟ HasQuotient ?m.6928 (Submodule ?m.6927 ?m.6928) ▶
i.e. there's a bunch of metavariables in [tryResolve]
.
I have no understanding of what encourages the metavariables to appear/disappear; I just try simplifying the problem a bit and sometimes it's metavariables, sometimes it isn't.
Kevin Buzzard (Feb 10 2024 at 21:11):
Mathlib-free! It's totally weird: one way to fix it is to change the definition of Ring
so it extends the two things in the other order.
class Zero (α : Type) where
zero : α
class AddCommGroup (α : Type) extends Zero α where
-- Note: no need to extend Zero mathematically, as it's in `AddCommGroup`, but if we
-- don't extend `Zero` then the problem goes away, and if we
-- extend `AddCommGroup` first and then `Zero` the problem also goes waway.
-- note: in mathlib this is what is happening (we extend two things both of which have a zero
-- in the definition of `Ring`)
class Ring (α : Type) extends Zero α, AddCommGroup α
class Module (R : Type) (M : Type) [Zero R] [Zero M] where
instance (R : Type) [Zero R] : Module R R := ⟨⟩
structure Submodule (R : Type) (M : Type) [Zero R] [Zero M] [Module R M] : Type where
class HasQuotient (A : outParam <| Type) (B : Type) where
quotient' : B → Type
instance Submodule.hasQuotient {R : Type} {M : Type} [Ring R] [AddCommGroup M]
[Module R M]: HasQuotient M (Submodule R M) := ⟨fun _ => M⟩
def TensorProduct (R : Type) [Zero R] (M : Type) (N : Type)
[Zero M] [Zero N] [Module R M] [Module R N] : Type := Unit
instance TensorProduct.zero {R : Type} [Zero R] {M : Type}
{N : Type} [Zero M] [Zero N] [Module R M]
[Module R N] : Zero (TensorProduct R M N) :=
({ zero := .unit } : Zero Unit) -- or `sorry`
instance TensorProduct.addCommGroup {R : Type} [Zero R]
{M : Type} {N : Type} [AddCommGroup M] [AddCommGroup N] [Module R M]
[Module R N] : AddCommGroup (TensorProduct R M N) :=
{ TensorProduct.zero with }
instance TensorProduct.module {R : Type} [Zero R] {M : Type}
{N : Type} [Zero M] [Zero N] [Module R M]
[Module R N] : Module R (TensorProduct R M N) :=
{ }
-- if you remove `[Zero M]` then the problem goes away
def Finsupp (M : Type) [Zero M] := Unit
instance Finsupp.zero {G : Type} [Zero G] : Zero (Finsupp G) :=
sorry -- replacing with `{ zero := sorry}` makes the problem go away?!
-- in the original example from mathlib there is no sorry at all
instance Finsupp.addCommGroup {G : Type} [AddCommGroup G] : AddCommGroup (Finsupp G) :=
{ Finsupp.zero with }
instance Finsupp.module (M : Type) {R : Type} [Zero R] [Zero M] [Module R M] :
Module R (Finsupp M) := { }
variable (k A : Type) [Ring k] [AddCommGroup A] [Module k A]
-- set_option trace.Meta.synthInstance true in
#synth HasQuotient (TensorProduct k A (Finsupp k)) (Submodule k (TensorProduct k A (Finsupp k))) -- fails
-- the trace indicates that this is the instance which typeclass inference gives up on,
-- but it's easily found
noncomputable instance : AddCommGroup (Finsupp k) := inferInstance
-- and now the original `#synth` works fine
#synth HasQuotient (TensorProduct k A (Finsupp k)) (Submodule k (TensorProduct k A (Finsupp k)))
The trace looks like this:
[Meta.synthInstance] ❌ HasQuotient (TensorProduct k A (Finsupp k)) (Submodule k (TensorProduct k A (Finsupp k))) ▼
[] new goal HasQuotient _tc.0 (Submodule k (TensorProduct k A (Finsupp k))) ▶
[] ✅ apply @Submodule.hasQuotient to HasQuotient (TensorProduct k A (Finsupp k))
(Submodule k (TensorProduct k A (Finsupp k))) ▶
[] ❌ apply inst✝¹ to AddCommGroup (TensorProduct k A (Finsupp k)) ▶
[] ❌ apply @TensorProduct.addCommGroup to AddCommGroup (TensorProduct k A (Finsupp k)) ▼
[tryResolve] ❌ AddCommGroup (TensorProduct k A (Finsupp k)) ≟ AddCommGroup (TensorProduct ?m.1245 ?m.1247 ?m.1248) ▼
[] ✅ AddCommGroup A ▶
[] ❌ AddCommGroup (Finsupp k) ▼
[] result <not-available> (cached)
With pp.all
both the <not-available>
instance and the instance found by typeclass inference in the shortcut are AddCommGroup (@Finsupp k (@Ring.toZero k inst✝²))
(so syntactically equal).
Vague conjecture: changing the definition of Ring
in mathlib from
class Ring (R : Type u) extends Semiring R, AddCommGroup R, AddGroupWithOne R
to
class Ring (R : Type u) extends AddCommGroup R, AddGroupWithOne R, Semiring R,
might fix this. But I have no idea what's going on. Hopefully the minimisation can make it easier for others to find out. The wall I hit is that I cannot see any more details about what tryResolve
is doing and in particular why it's failing.
Kevin Buzzard (Feb 10 2024 at 21:21):
Indeed I have just confirmed that changing the definition of Ring
in mathlib from
class Ring (R : Type u) extends Semiring R, AddCommGroup R, AddGroupWithOne R
to
class Ring (R : Type u) extends AddCommGroup R, AddGroupWithOne R, Semiring R
makes the original error at the top of this thread disappear.
This is ridiculously brittle. What are we supposed to be doing here? Are there guidelines for how we are supposed to build the algebra heirarchy? And are we not following them? @Sébastien Gouëzel you understood this at some point. Does my suggestion fit into your understanding of things or is this a new phenomenon?
Kevin Buzzard (Feb 12 2024 at 08:33):
Amelia (who found the original issue) points out that I can remove the tensor product from the mix:
class Zero (α : Type) where
zero : α
class AddCommGroup (α : Type) extends Zero α where
-- switching the order makes the issue go away
class Ring (α : Type) extends Zero α, AddCommGroup α
class Module (R : Type) (M : Type) [Zero R] [Zero M] where
instance (R : Type) [Zero R] : Module R R := ⟨⟩
structure Submodule (R : Type) (M : Type) [Zero R] [Zero M] [Module R M] : Type where
class HasQuotient (A : outParam <| Type) (B : Type) where
quotient' : B → Type
instance Submodule.hasQuotient {R : Type} {M : Type} [Ring R] [AddCommGroup M]
[Module R M]: HasQuotient M (Submodule R M) := ⟨fun _ => M⟩
def Finsupp (M : Type) [Zero M] := Unit
instance Finsupp.zero {G : Type} [Zero G] : Zero (Finsupp G) :=
sorry -- replacing with `{ zero := sorry}` makes the problem go away?!
-- in the original example from mathlib there is no sorry at all
instance Finsupp.addCommGroup {G : Type} [AddCommGroup G] : AddCommGroup (Finsupp G) :=
{ Finsupp.zero with }
instance Finsupp.module (M : Type) {R : Type} [Zero R] [Zero M] [Module R M] :
Module R (Finsupp M) := { }
variable (k : Type) [Ring k]
-- set_option trace.Meta.synthInstance true in
#synth HasQuotient (Finsupp (Finsupp k)) (Submodule k (Finsupp (Finsupp k))) -- fails
-- the trace indicates that this is the instance which typeclass inference gives up on,
-- but it's easily found
noncomputable instance : AddCommGroup (Finsupp k) := inferInstance
-- and now the original `#synth` works fine
#synth HasQuotient (Finsupp (Finsupp k)) (Submodule k (Finsupp (Finsupp k))) -- works
/-
Failing trace:
[Meta.synthInstance] ❌ HasQuotient (Finsupp (Finsupp k)) (Submodule k (Finsupp (Finsupp k))) ▼
[] new goal HasQuotient _tc.0 (Submodule k (Finsupp (Finsupp k))) ▶
[] ❌ apply @Submodule.hasQuotient to HasQuotient ?m.639 (Submodule k (Finsupp (Finsupp k))) ▼
[tryResolve] ❌ HasQuotient ?m.639 (Submodule k (Finsupp (Finsupp k))) ≟ HasQuotient ?m.642 (Submodule ?m.641 ?m.642) ▼
[] ✅ Ring k ▶
[] ❌ AddCommGroup (Finsupp (Finsupp k)) ▼
[] new goal AddCommGroup (Finsupp (Finsupp k)) ▶
[] ❌ apply @Finsupp.addCommGroup to AddCommGroup (Finsupp (Finsupp k)) ▼
[tryResolve] ❌ AddCommGroup (Finsupp (Finsupp k)) ≟ AddCommGroup (Finsupp ?m.655) ▼
[] ❌ AddCommGroup (Finsupp k) ▼
[] new goal AddCommGroup (Finsupp k) ▶
[] ❌ apply @Finsupp.addCommGroup to AddCommGroup (Finsupp k) ▼
[tryResolve] ❌ AddCommGroup (Finsupp k) ≟ AddCommGroup (Finsupp ?m.659)
-/
Shall I open an issue?
Matthew Ballard (Feb 12 2024 at 19:43):
[stuckMVar] found stuck MVar ?m.644 : AddCommGroup (Finsupp (Finsupp k))
Kevin Buzzard (Feb 12 2024 at 19:59):
I don't know how you're doing that but I now have a sorry-free example -- is the error still the same?
class Zero (α : Type) where
zero : α
class AddCommGroup (α : Type) extends Zero α where
class Ring (α : Type) extends Zero α, AddCommGroup α
class Module (R : Type) (M : Type) [Zero R] [Zero M] where
instance (R : Type) [Zero R] : Module R R := ⟨⟩
structure Submodule (R : Type) (M : Type) [Zero R] [Zero M] [Module R M] : Type where
class HasQuotient (A : outParam <| Type) (B : Type) where
quotient' : B → Type
instance Submodule.hasQuotient {R : Type} {M : Type} [Ring R] [AddCommGroup M]
[Module R M]: HasQuotient M (Submodule R M) := ⟨fun _ => M⟩
def Synonym (M : Type) [Zero M] := M
instance Synonym.zero {G : Type} [Zero G] : Zero (Synonym G) := ⟨(Zero.zero : G)⟩
instance Synonym.addCommGroup {G : Type} [AddCommGroup G] : AddCommGroup (Synonym G) :=
{ Synonym.zero with }
instance Synonym.module (M : Type) {R : Type} [Zero R] [Zero M] [Module R M] :
Module R (Synonym M) := { }
variable (R : Type) [Ring R]
set_option trace.Meta.synthInstance true in
#synth HasQuotient (Synonym (Synonym R)) (Submodule R (Synonym (Synonym R))) -- fails
-- the trace indicates that this is the instance which typeclass inference gives up on,
-- but it's easily found
noncomputable instance : AddCommGroup (Synonym R) := inferInstance
-- and now the original `#synth` works fine
#synth HasQuotient (Synonym (Synonym R)) (Submodule R (Synonym (Synonym R))) -- works
Kevin Buzzard (Feb 12 2024 at 20:07):
I opened lean4#3313 now I got rid of the sorry. I changed Finsupp
to Synonym
and made it a type synonym.
Kevin Buzzard (Feb 12 2024 at 20:10):
With set_option trace.Meta.isDefEq.stuckMVar true
I also see some stuck metavariables, the one nearest to the problem being
...
[tryResolve] ❌ AddCommGroup (Synonym R) ≟ AddCommGroup (Synonym ?m.667) ▼
[isDefEq.stuckMVar] found stuck MVar ?m.668 : AddCommGroup R
Here we have [Ring R]
and class Ring (α : Type) extends Zero α, AddCommGroup α
Matthew Ballard (Feb 12 2024 at 20:35):
I am confused as to how we reach a branch of code. (Be warned: off the top of my head)
We have the following ToMessageData
instance
instance : ToMessageData (Option Expr) := ⟨fun | none => "<not-available>" | some e => toMessageData e⟩
Now in docs#Lean.Meta.synthInstance? there is the following branch of code
match s.cache.synthInstance.find? (localInsts, type) with
| some result =>
trace[Meta.synthInstance] "result {result} (cached)"
Here (result: Option Expr)
so how do I reach the message?
[] result <not-available> (cached)
What dumb thing am I doing here?
As far as I can tell, this is the only place (cached)
occurs in a message and above is the only place that not-available
occurs.
Matthew Ballard (Feb 12 2024 at 20:38):
Nevermind - the answer is in front of my face. The result
is still an Option
Matthew Ballard (Feb 12 2024 at 20:46):
You can also "fix" this by making Synonym
reducible
. At some point, Lean wants to unify
[] ✅ Synonym (Synonym R) =?= Synonym R ▶
Matthew Ballard (Feb 12 2024 at 20:56):
Aha you have abused defeq
instance Synonym.zero {G : Type} [Zero G] : Zero (Synonym G) := ⟨(Zero.zero : G)⟩
forces Lean to unwrap Synonym
to unify
Matthew Ballard (Feb 12 2024 at 21:00):
If you place AddCommGroup
first then Lean doesn't have to take the path through Zero
Kevin Buzzard (Feb 12 2024 at 21:22):
Yeah I can fix this by making Synonym
reducible, but I can't make Finsupp
reducible (which is the application -- I was just minimising here), and yeah I can fix this by reordering the definition of Ring
, but I am not sure I'm allowed to reorder the definition of Ring
in mathlib either, because my impression was that we already thought hard about the definition of Ring
(again this is an artifact of minimising) :-( .
How do I make that instance without abusing defeq? And does the failure still occur? It wouldn't surprise me if it did.
Eric Wieser (Feb 12 2024 at 21:30):
def Synonym.mk {M : Type} [Zero M] (m : M) : Synonym M := m
is the fragile way to avoid the abuse
Eric Wieser (Feb 12 2024 at 21:30):
But it doesn't help here
Eric Wieser (Feb 12 2024 at 21:31):
Here's the repro with no defeq abuse at all (no def
)
class Zero (α : Type) where
zero : α
class AddCommGroup (α : Type) extends Zero α where
class Ring (α : Type) extends Zero α, AddCommGroup α
class Module (R : Type) (M : Type) [Zero R] [Zero M] where
instance (R : Type) [Zero R] : Module R R := ⟨⟩
structure Submodule (R : Type) (M : Type) [Zero R] [Zero M] [Module R M] : Type where
class HasQuotient (A : outParam <| Type) (B : Type)
instance Submodule.hasQuotient {R : Type} {M : Type} [Ring R] [AddCommGroup M]
[Module R M]: HasQuotient M (Submodule R M) := {}
structure Synonym (M : Type) [Zero M] where m : M
instance Synonym.zero {G : Type} [Zero G] : Zero (Synonym G) := ⟨.mk (Zero.zero : G)⟩
instance Synonym.addCommGroup {G : Type} [AddCommGroup G] : AddCommGroup (Synonym G) :=
{ Synonym.zero with }
instance Synonym.module (M : Type) {R : Type} [Zero R] [Zero M] [Module R M] :
Module R (Synonym M) := { }
variable (R : Type) [Ring R]
set_option trace.Meta.synthInstance true in
#synth HasQuotient (Synonym (Synonym R)) (Submodule R (Synonym (Synonym R))) -- fails
-- the trace indicates that this is the instance which typeclass inference gives up on,
-- but it's easily found
noncomputable instance : AddCommGroup (Synonym R) := inferInstance
-- and now the original `#synth` works fine
#synth HasQuotient (Synonym (Synonym R)) (Submodule R (Synonym (Synonym R))) -- works
Kevin Buzzard (Feb 12 2024 at 21:33):
Thanks!
Eric Wieser (Feb 12 2024 at 21:38):
Edited to simplify further
Eric Wieser (Feb 12 2024 at 21:40):
Even removing the outParam
makes no difference
Eric Wieser (Feb 12 2024 at 21:57):
In fact, the first argument of HasQuotient
is a distraction here
Eric Wieser (Feb 12 2024 at 22:02):
Here's a slightly simpler example:
set_option autoImplicit false
class Zero (α : Type) where
zero : α
class AddCommGroup (α : Type) extends Zero α where
class Ring (α : Type) extends Zero α, AddCommGroup α
class Module (R : Type) (M : Type) [Zero R] [Zero M] where
instance (R : Type) [Zero R] : Module R R := ⟨⟩
structure Submodule (R : Type) (M : Type) [Zero R] [Zero M] [Module R M] : Type where
class HasQuotient (A : outParam <| Type) (B : Type)
instance Submodule.hasQuotient {R : Type} {M : Type} [Ring R] [AddCommGroup M]
[Module R M]: HasQuotient M (Submodule R M) := {}
structure Synonym (M : Type) [Zero M] where m : M
instance Synonym.zero {G : Type} [Zero G] : Zero (Synonym G) := ⟨.mk (Zero.zero : G)⟩
instance Synonym.addCommGroup {G : Type} [AddCommGroup G] : AddCommGroup (Synonym G) :=
{ Synonym.zero with }
instance Synonym.module (M : Type) {R : Type} [Zero R] [Zero M] [Module R M] :
Module R (Synonym M) := { }
variable (R : Type) [Ring R]
class OhNo (B : Type)
instance ohno {R : Type} {M : Type} [Ring R] [AddCommGroup M] [Module R M] : OhNo (Submodule R M) := {}
-- `abbrev` makes no difference, but makes the trace shorter
abbrev S2 := Synonym (Synonym R)
def oh1 : OhNo (Submodule R (S2 R)) := @ohno _ _ _ _ _ -- fails
def oh2 : OhNo (Submodule R (S2 R)) := @ohno _ (S2 R) _ _ _ -- ok
-- the trace indicates that this is the instance which typeclass inference gives up on,
-- but it's easily found
noncomputable instance : AddCommGroup (Synonym R) := inferInstance
def oh3 : type_of% (oh2 R) := ohno -- ok
Now it's a unification problem rather than a TC problem
Eric Wieser (Feb 12 2024 at 22:05):
My hunch is that this is a caching bug with the DiscrTree, and that somehow@Synonym R Ring.toZero
and @Synonym R AddCommGroup.toZero
end up at the same key despite being different types
Matthew Ballard (Feb 12 2024 at 22:57):
This seems like a strange decision
[] ❌ fun [Zero G] => { zero := { m := Zero.zero } } =?= fun [AddCommGroup G] => AddCommGroup.toZero ▼
[] ❌ Zero G =?= AddCommGroup G ▼
[] ❌ Zero =?= AddCommGroup
Eric Wieser (Feb 12 2024 at 23:07):
Which message is that trace from?
Matthew Ballard (Feb 12 2024 at 23:07):
oh1
with isDefEq
trace.
Eric Wieser (Feb 12 2024 at 23:09):
What's the full path?
Eric Wieser (Feb 12 2024 at 23:10):
(There are 7 traces in the sidebar for me, and I don't know which one to expand, or how to fully expand them)
Matthew Ballard (Feb 12 2024 at 23:10):
The cache in docs#Lean.Meta.synthInstance? seems to have a none
for AddCommGroup (S2 R)
before the inferInstance
and then addCommGroup
after
Matthew Ballard (Feb 12 2024 at 23:15):
Here is another (full) trace
[Meta.isDefEq] ❌ Submodule ?m.1034 ?m.1035 =?= Submodule R (S2 R) ▼
[] ✅ ?m.1034 =?= R ▶
[] ✅ ?m.1035 =?= S2 R ▶
[] ❌ ?m.1038 =?= Synonym.module (Synonym R) ▼
[] ?m.1038 [assignable] =?= Synonym.module (Synonym R) [nonassignable]
[] ❌ Module R (S2 R) =?= Module R (Synonym (Synonym R)) ▼
[] ✅ R =?= R
[] ✅ S2 R =?= Synonym (Synonym R) ▶
[] ✅ Ring R =?= Ring R
[] ✅ Ring.toZero =?= Ring.toZero ▶
[] ❌ AddCommGroup.toZero =?= Synonym.zero ▼
[] ❌ AddCommGroup.toZero =?= { zero := { m := Zero.zero } } ▼
[] ❌ ?m.1037.1 =?= { zero := { m := Zero.zero } } ▼
[] ✅ Zero (S2 R) =?= Zero (Synonym (Synonym R)) ▶
[] ❌ Zero.zero =?= { m := Zero.zero } ▼
[] ❌ ?m.1037.1.1 =?= { m := Zero.zero } ▼
[] ✅ S2 R =?= Synonym (Synonym R) ▶
[] ❌ ?m.1037.1.1.m =?= Zero.zero ▼
[] ❌ ?m.1037.1.1.1 =?= Zero.zero ▼
[] ❌ ?m.1037.1.1.1 =?= Synonym.zero.1 ▼
[] ❌ ?m.1037.1.1.1 =?= { m := Zero.zero } ▼
[] ✅ Synonym R =?= Synonym R
[] ❌ ?m.1037.1.1.1.m =?= Zero.zero ▼
[] ❌ ?m.1037.1.1.1.1 =?= Zero.zero ▼
[] ❌ ?m.1037.1.1.1.1 =?= Ring.toZero.1 ▼
[onFailure] ❌ ?m.1037.1.1.1.1 =?= Ring.toZero.1 ▼
[stuckMVar] found stuck MVar ?m.1037 : AddCommGroup (S2 R)
Matthew Ballard (Feb 12 2024 at 23:15):
And
[Meta.isDefEq] ❌ @AddCommGroup.toZero =?= @Synonym.zero ▼
[] ❌ @AddCommGroup.toZero =?= fun {G} [Zero G] => { zero := { m := Zero.zero } } ▼
[] ❌ fun {G} [Zero G] => { zero := { m := Zero.zero } } =?= fun {α} => @AddCommGroup.toZero α ▼
[] ✅ Type =?= Type
[] ❌ fun [Zero G] => { zero := { m := Zero.zero } } =?= @AddCommGroup.toZero G ▼
[] ❌ fun [Zero G] => { zero := { m := Zero.zero } } =?= fun [AddCommGroup G] => AddCommGroup.toZero ▼
[] ❌ Zero G =?= AddCommGroup G ▼
[] ❌ Zero =?= AddCommGroup
[onFailure] ❌ Zero G =?= AddCommGroup G
[onFailure] ❌ Zero G =?= AddCommGroup G
Matthew Ballard (Feb 12 2024 at 23:23):
Note that the instance added for AddCommGroup (Synonym R)
is not Synonym.addCommGroup
which is now found in oh3
but is instAddCommGroupSynonymToZero
Matthew Ballard (Feb 12 2024 at 23:24):
Why did we go from none
to Synonym.addCommGroup
in the cache?
Last updated: May 02 2025 at 03:31 UTC