Zulip Chat Archive
Stream: mathlib4
Topic: synthesis failure on non-preferred parent
Matthew Ballard (Mar 24 2024 at 19:59):
import Mathlib.RingTheory.Congruence
abbrev AddCon.Quotient''' {R : Type*} [Add R] (c : AddCon R) := Quotient c.toSetoid
instance {R : Type*} [Add R] (c : AddCon R) : Add (c.Quotient''') := sorry
abbrev Con.Quotient''' {R: Type*} [Mul R] (c : Con R) := Quotient c.toSetoid
instance {R : Type*} [Mul R] (c : Con R) : Mul (c.Quotient''') := sorry
abbrev RingCon.Quotient'' {R : Type*} [Ring R] (c : RingCon R) := Quotient c.toSetoid
variable {R : Type*} [Ring R] (c : RingCon R)
#synth Mul (c.Quotient'') -- ok, finds the above
#synth Add (c.Quotient'') -- failed
Should I already know the answer as to why this fails?
Matthew Ballard (Mar 24 2024 at 20:20):
Even more troubling
#synth Add (c.toAddCon.Quotient’’’) — fails
Hopefully this is user error :)
Matthew Ballard (Mar 24 2024 at 20:31):
Mathlib free is easy
structure Con (R : Type _) [Mul R] extends Setoid R
structure AddCon (R : Type _) [Add R] extends Setoid R
structure RingCon (R : Type _) [Add R] [Mul R] extends Con R, AddCon R
abbrev AddCon.Quotient''' {R : Type _} [Add R] (c : AddCon R) := Quotient c.toSetoid
instance {R : Type _} [Add R] (c : AddCon R) : Add (c.Quotient''') := sorry
abbrev Con.Quotient''' {R: Type _} [Mul R] (c : Con R) := Quotient c.toSetoid
instance {R : Type _} [Mul R] (c : Con R) : Mul (c.Quotient''') := sorry
abbrev RingCon.Quotient'' {R : Type _} [Mul R] [Add R] (c : RingCon R) := Quotient c.toSetoid
variable {R : Type _} [Mul R] [Add R] (c : RingCon R)
#synth Mul (c.Quotient'') — ok
#synth Add (c.Quotient'') — fails
#synth Add (c.toAddCon.Quotient''') — fails
Matthew Ballard (Mar 24 2024 at 20:38):
I think it is reasonable to expect this to succeed right?
Matthew Ballard (Mar 24 2024 at 21:06):
Well this works…
def RingCon.toAddCon’ {R : Type _} [Mul R] [Add R] (c : RingCon R) : AddCon R := { toSetoid := c.toSetoid}
#synth Add (c.toAddCon’.Quotient’’’)
Matthew Ballard (Mar 24 2024 at 21:06):
If I mark it reducible it fails again
Eric Wieser (Mar 24 2024 at 21:20):
Further minimized:
structure Con (R : Type _) [Mul R] extends Setoid R
structure AddCon (R : Type _) [Add R] extends Setoid R
structure RingCon (R : Type _) [Add R] [Mul R] extends Con R, AddCon R
variable {R : Type _}
instance [Add R] (c : AddCon R) : Add (Quotient c.toSetoid) := sorry
instance [Mul R] (c : Con R) : Mul (Quotient c.toSetoid) := sorry
variable [Mul R] [Add R] (c : RingCon R)
#synth Mul (Quotient c.toSetoid) -- ok
#synth Add (Quotient c.toSetoid) -- fails
#synth Add (Quotient c.toAddCon.toSetoid) -- fails
Eric Wieser (Mar 24 2024 at 21:21):
The problem with the second one is that the expression is c.toMulCon.toSetoid
which doesn't match the pattern AddCon.toSetoid ?_
that the first instance expects.
Matthew Ballard (Mar 24 2024 at 21:21):
You can even remove Setoid
structure Setoid' (R : Type _) where
instance : CoeSort (Setoid' R) (Type _) := sorry
def Setoid'.Quotient {R : Type _} (c : Setoid' R) : Type _ := c
structure Con (R : Type _) [Mul R] extends Setoid' R
structure AddCon (R : Type _) [Add R] extends Setoid' R
structure RingCon (R : Type _) [Add R] [Mul R] extends Con R, AddCon R
@[reducible]
def RingCon.toAddCon' {R : Type _} [Add R] [Mul R] (c : RingCon R) : AddCon R :=
{toSetoid' := c.toSetoid'}
abbrev AddCon.Quotient''' {R : Type _} [Add R] (c : AddCon R) := c.toSetoid'.Quotient
instance AddCon.instAdd {R : Type _} [Add R] (c : AddCon R) : Add (c.Quotient''') := sorry
abbrev Con.Quotient''' {R: Type _} [Mul R] (c : Con R) := c.toSetoid'.Quotient
instance Con.instMul {R : Type _} [Mul R] (c : Con R) : Mul (c.Quotient''') := sorry
abbrev RingCon.Quotient'' {R : Type _} [Mul R] [Add R] (c : RingCon R) := c.toSetoid'.Quotient
variable {R : Type _} [Mul R] [Add R] (c : RingCon R) (c' : AddCon R)
#synth Mul (c.Quotient'')
#synth Add (c.Quotient'')
#synth Add (c'.Quotient''')
#synth Add (c.toAddCon'.Quotient''')
#synth Add (AddCon.Quotient''' c.toAddCon)
Eric Wieser (Mar 24 2024 at 21:24):
Eric Wieser said:
The problem with the second one is that the expression is
c.toMulCon.toSetoid
which doesn't match the patternAddCon.toSetoid ?_
that the first instance expects.
The third one in this example is fixed by making src#Quotient reducible
Matthew Ballard (Mar 24 2024 at 21:25):
Eric Wieser said:
The problem with the second one is that the expression is
c.toMulCon.toSetoid
which doesn't match the patternAddCon.toSetoid ?_
that the first instance expects.
Thanks! It only fails to match with reducible transparency
Eric Wieser (Mar 24 2024 at 21:25):
Well it doesn't match syntactically either, which I think is the problem
Matthew Ballard (Mar 24 2024 at 21:27):
Eric Wieser said:
Eric Wieser said:
The problem with the second one is that the expression is
c.toMulCon.toSetoid
which doesn't match the patternAddCon.toSetoid ?_
that the first instance expects.The third one in this example is fixed by making src#Quotient reducible
Third? I get that working always. The fourth you can toggle on/off by toggling reduciblity of RingCon.toAddCon’
Eric Wieser (Mar 24 2024 at 21:28):
I'm counting in my code sample not yours
Eric Wieser (Mar 24 2024 at 21:28):
Making the three structures classes in my example, along with reducible Quotient, fixes everything
Eric Wieser (Mar 24 2024 at 21:29):
Not that it make any sense for them to be classes...
Matthew Ballard (Mar 24 2024 at 21:33):
Eric Wieser said:
Making the three structures classes in my example, along with reducible Quotient, fixes everything
Do you understand the underlying reason? I haven’t opened the source yet
Matthew Ballard (Mar 24 2024 at 22:00):
In the last code block I shared, you only need to make AddCon
a class
Matthew Ballard (Mar 24 2024 at 22:04):
For all but the 2nd.
Matthew Ballard (Mar 24 2024 at 22:06):
And of course if you switch the order of the parents the failures flip
Eric Wieser (Mar 24 2024 at 22:09):
Can you think of any reason that Quotient
shouldn't be reducible?
Matthew Ballard (Mar 24 2024 at 22:10):
No (edit: assuming benchmarking doesn’t complain)
Matthew Ballard (Mar 24 2024 at 22:10):
But I think the issue is broader than that
Matthew Ballard (Mar 24 2024 at 22:38):
Ah ok, there is a discrimination tree involved
Matthew Ballard (Mar 24 2024 at 22:52):
We don’t match on
[Add, Quotient, *, AddCon.0, *]
but
[Mul, Quotient, *, Con.0, *]
is ok
Matthew Ballard (Mar 24 2024 at 22:53):
With docs#Lean.Meta.DiscTree.getUnify
Matthew Ballard (Mar 24 2024 at 23:06):
And trace.Meta.Disctree
is not turned on…
Matthew Ballard (Mar 25 2024 at 00:29):
It looks like that since the custom projection RingCon.toAddCon’
is reducible we end up at c.toSetoid’
which takes (c : Con R)
as an argument and goes into the keys for the discrimination tree search. But this doesn’t match the AddCon
in the entry from the Add
instance so it just gets tossed.
If you don’t make the custom projection RingCon.toAddCon’
reducible, then you get AddCon
as the key to match on.
Matthew Ballard (Mar 25 2024 at 00:33):
Since projections from classes are not reducible, this is another way to block the unfolding and make it work.
Matthew Ballard (Mar 25 2024 at 12:13):
Should Lean be able to synthesis these instances (really only needs to not cut them here)?
My answer is “obviously, yes” but what do I know. I feel like this might be a contributing factor to other failures coming from passing to non-preferred parents.
Eric Wieser (Mar 25 2024 at 13:43):
Matthew Ballard said:
It looks like that since the custom projection
RingCon.toAddCon’
is reducible we end up atc.toSetoid’
which takes(c : Con R)
as an argument and goes into the keys for the discrimination tree search. But this doesn’t match theAddCon
in the entry from theAdd
instance so it just gets tossed.If you don’t make the custom projection
RingCon.toAddCon’
reducible, then you getAddCon
as the key to match on.
Sorry, this is what I was trying to say above.
Eric Wieser (Mar 25 2024 at 13:44):
Matthew Ballard said:
Since projections from classes are not reducible, this is another way to block the unfolding and make it work.
Are they reducible on structures?
Last updated: May 02 2025 at 03:31 UTC