Zulip Chat Archive
Stream: new members
Topic: Why doesn't defining this instance work?
Dan Abramov (Jul 25 2025 at 20:54):
Consider this setup (extracted from Tao's book):
import Mathlib.Tactic
class SetTheory where
Set : Type u -- Axiom 3.1
Object : Type v -- Axiom 3.1
set_to_object : Set ↪ Object -- Axiom 3.1
singleton : Object → Set -- Axiom 3.4
export SetTheory (Set Object)
variable [SetTheory]
instance sets_are_objects : Coe Set Object where
coe X := SetTheory.set_to_object X
theorem SetTheory.Set.coe_eq {X Y:Set} (h: (X: Object) = (Y: Object)) : X = Y :=
SetTheory.set_to_object.inj' h
instance : Singleton Object Set where
singleton := SetTheory.singleton
example (x: Object) : Set := {x}
My question is about how instances work in Lean.
Suppose I also want to support declaring nested Sets.
I can do it like this:
example (x: Object) : Set := {(({x}: Set): Object)}
But the two levels of conversion are annoying to write.
I was hoping adding a separate Singleton Set Set instance would help.
So I tried adding this to the end of the file:
instance : Singleton Set Set where
singleton x := {(x: Object)}
example (s: Set) : Set := {s} -- works
example (x: Object) : Set := {({x}: Set)} -- doesn't
but as you can see, I still won't let me do {({x}: Set)}. Why?
overloaded, errors
failed to synthesize
Singleton Object SetTheory.Set
Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.
invalid {...} notation, expected type is not of the form (C ...)
Dan Abramov (Jul 25 2025 at 20:54):
Full code:
import Mathlib.Tactic
class SetTheory where
Set : Type u -- Axiom 3.1
Object : Type v -- Axiom 3.1
set_to_object : Set ↪ Object -- Axiom 3.1
singleton : Object → Set -- Axiom 3.4
export SetTheory (Set Object)
variable [SetTheory]
instance sets_are_objects : Coe Set Object where
coe X := SetTheory.set_to_object X
theorem SetTheory.Set.coe_eq {X Y:Set} (h: (X: Object) = (Y: Object)) : X = Y :=
SetTheory.set_to_object.inj' h
instance : Singleton Object Set where
singleton := SetTheory.singleton
example (x: Object) : Set := {x}
example (x: Object) : Set := {(({x}: Set): Object)}
instance : Singleton Set Set where
singleton x := {(x: Object)}
example (s: Set) : Set := {s} -- works
example (x: Object) : Set := {({x}: Set)} -- doesn't
Dan Abramov (Jul 25 2025 at 21:09):
For a concrete use case, I was hoping I could make something like this read shorter.
lemma aux2 : ({(({x}: Set): Object)}: Set) = {(({y}: Set): Object), (({y, z}: Set): Object)} ↔ x = y ∧ x = z := by
sorry
Eric Wieser (Jul 25 2025 at 22:11):
Lean is getting confused about your universes; [SetTheory.{u,v}] works
Kenny Lau (Jul 25 2025 at 22:12):
SetTheory is tricky to work with because it takes no arguments but contains universe parameters
Kenny Lau (Jul 25 2025 at 22:13):
I don't think we have any similar things in mathlib (but I can be wrong)
Eric Wieser (Jul 25 2025 at 22:13):
#eval Lean.toLevel.toNat
is the canonical example of "typeclass search is bad at universes"
Eric Wieser (Jul 25 2025 at 22:13):
It should be complaining that it couldn't work out the universe, rather than picking randomly
Dan Abramov (Jul 26 2025 at 02:32):
Oh wow. That's unexpected! I'm so glad I asked here.
Would it be correct for me to PR the change to the repo I took the code from? I.e. is it the author's fault that Lean wouldn't infer the universe correctly in this case? Or is it a bug that needs to be filed in Lean? Or is this undefined behavior?
Dan Abramov (Jul 26 2025 at 03:01):
I guess maybe the approach isn't very fruitful anyway because I'd have to declare each instance twice. So it's not just singleton but also membership, "insert", and so on.
Last updated: Dec 20 2025 at 21:32 UTC