Zulip Chat Archive
Stream: lean4
Topic: synth bug, not inferring instance defined just above
RustyYato (Mar 25 2025 at 03:03):
For context, I'm working on a clone of mathlib with some of my own changes for my own learning purposes.
I ran into a bug where Lean is unable to synthesize an instance that was declared just above it. Due to how deep this is in my project, and my unfamiliarity with #synth, I'm not able to create a nice MVE. But I have saved this bug into a branch linked below.
The relevant portion looks like this, with the following error showing up in VSCode
instance : IsMetricSpace (α × β) := Prod.metricSpaceSup
#synth IsMetricSpace (α × β)
failed to synthesize
IsMetricSpace (α × β)
Additional diagnostic information may be available using the `set_option diagnostics true` command.
My lean version
Lean (version 4.19.0-nightly-2025-03-24, x86_64-unknown-linux-gnu, commit 635af865bf52, Release)
I wanted to check to see if this was something I was doing before filing a bug report. Does anyone know what might be going on?
Kyle Miller (Mar 25 2025 at 03:15):
Does this work?
example : IsMetricSpace (α × β) := inferInstance
Also, if you hover over the keyword instance
in instance : IsMetricSpace (α × β) := Prod.metricSpaceSup
, what type do you see?
RustyYato (Mar 25 2025 at 03:59):
no, inferInstance is in the same boat (and that's actually how I found this, since I wasn't able to synthesize this instance for some reason, and while trying to reduce that bug I ran into this more weird bug).
Also, if you hover over the keyword
instance
ininstance : IsMetricSpace (α × β) := Prod.metricSpaceSup
, what type do you see?
This type, which is correct as far as I can tell.
instIsMetricSpaceProd.{u_1, u_2, u_3} {α : Type u_2} {γ : Type u_3} {β : Type u_1} [Dist α γ] [Dist β γ] [LE γ] [LT γ]
[AddMonoidOps γ] [IsOrderedAddCommMonoid γ] [Sup γ] [IsSemiLatticeSup γ] [IsAddCancel γ] [IsMetricSpace α]
[IsMetricSpace β] : IsMetricSpace (α × β)
I forgot to put this in my example above, but I also have these variables in scope
variable
[Dist α γ] [Dist β γ]
[LE γ] [LT γ] [AddMonoidOps γ]
[IsOrderedAddCommMonoid γ]
[Sup γ] [IsSemiLatticeSup γ]
[IsAddCancel γ]
[IsMetricSpace α] [IsMetricSpace β]
Aaron Liu (Mar 25 2025 at 05:18):
RustyYato said:
I forgot to put this in my example above, but I also have these variables in scope
variable [Dist α γ] [Dist β γ] [LE γ] [LT γ] [AddMonoidOps γ] [IsOrderedAddCommMonoid γ] [Sup γ] [IsSemiLatticeSup γ] [IsAddCancel γ] [IsMetricSpace α] [IsMetricSpace β]
If I put that at the top of my scope, I get an error, because docs#Dist only takes one type argument.
Kevin Buzzard (Mar 25 2025 at 05:35):
Maybe lean is failing to synthesise gamma? Is it an outparam?
RustyYato (Mar 25 2025 at 05:40):
If I put that at the top of my scope, I get an error, because docs#Dist only takes one type argument.
Yes, that's because this isn't Mathlib :), this is from my own project which is quite similar to mathlib (since I'm using it as a reference for my own learning,).
Maybe lean is failing to synthesise gamma? Is it an outparam?
yes it's in outparam in Dist
, IsPseudoMetricSpace
and IsMetricSpace
.
And now that I think of it, why is it an outparam in IsPseudoMetricSpace
and IsMetricSpace
? That seems suspect.
RustyYato (Mar 25 2025 at 05:42):
Wow, removing outparam on the Is*MetricSpace
type-classes fixed the issue. I still don't understand why that is. Is there a special interaction that I'm not aware of?
the relevant snippet is this one
class Dist (α: Type*) (β: outParam Type*) where
dist: α -> α -> β
class IsPseudoMetricSpace (α: Type*) {β: Type*} -- before β was also marked as an outParam, and that seemed to cause the issue
[LT β] [LE β] [AddMonoidOps β] [IsOrderedAddCommMonoid β]
[Dist α β] : Prop extends IsLinearOrder β where
Aaron Liu (Mar 25 2025 at 05:46):
Meybe set_option trace.Meta.synthInstance true
will be able to help you
RustyYato (Mar 25 2025 at 05:50):
Thanks for all the help! Looks like I'll need to figure out how to properly use outParam :smiley:. I thought I had understood it, but it looks like there are some subtleties I need to figure out.
Kyle Miller (Mar 25 2025 at 15:19):
I think you're running into a (known) bug where it's failing to report that IsPseudoMetricSpace
has a questionable parent projection instance.
The parent projection to IsLinearOrder β
needs to somehow figure out what α
is to apply. How can it do this? (Take a look at IsPseudoMetricSpace.toIsLinearOrder
to see the instance.) Could you try set_option trace.Meta.synthOrder true
and report back on the synth order for the arguments to this instance?
I believe what you need to do instead is not extend IsLinearOrder β
, and instead add it as an [IsLinearOrder β]
argument.
RustyYato (Mar 25 2025 at 17:41):
Could you try
set_option trace.Meta.synthOrder true
and report back on the synth order for the arguments to this instance?
[Meta.synthOrder] synthesizing the arguments of @instIsMetricSpaceProd in the order [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:
Dist α γ
Dist β γ
LE γ
LT γ
AddMonoidOps γ
IsOrderedAddCommMonoid γ
Sup γ
IsSemiLatticeSup γ
IsAddCancel γ
IsMetricSpace α
IsMetricSpace β
I think you're running into a (known) bug where it's failing to report that
IsPseudoMetricSpace
has a questionable parent projection instance.
I see, is this because there's no reliable way to work backwards from IsLinearOrder Y
to IsMetricSpace A
(with Dist A Y
)?
Kyle Miller (Mar 25 2025 at 18:27):
Yeah, there's no way to infer A
.
I think the only reason it's looking like it works at the moment is that instances that come from the local context (e.g. ones from variables
or binders) use slightly different rules, and the consequence is that it's solving for A
by unification. I didn't do an experiment to validate this in your case.
Kyle Miller (Mar 25 2025 at 18:28):
(The bug is that the synthOrder checker ignores issues with parent projection type parameters. It assumes they're all solvable by unification, which is not true in general.)
RustyYato (Mar 25 2025 at 18:28):
Ok that makes sense, I'll probably switch over to [IsLinearOrder] soon then. Thanks for the heads up!
RustyYato (Mar 30 2025 at 19:04):
I think you're running into a (known) bug where it's failing to report that
IsPseudoMetricSpace
has a questionable parent projection instance.
Oh wow, I ran into this exact issue somewhere else in my project, it would have taken forever to debug without your heads up! Thanks again @Kyle Miller
Last updated: May 02 2025 at 03:31 UTC