Zulip Chat Archive
Stream: mathlib4
Topic: FunLike issues
Frédéric Dupuis (Dec 10 2022 at 03:39):
I've just hit what looks like a very scary issue when trying to port Algebra.Order.Hom.Monoid
in mathlib4#944. If you look at the instance [OrderMonoidWithZeroHomClass F α β] : CoeTC F (α →*₀o β)
in that PR, you'll see that when proving map_one
, (1) the type class system is struggling to get the OneHomClass
instance it needs, and (2) when it is supplied manually, we run into the issue that @FunLike.coe F α (fun a ↦ β) MulHomClass.toFunLike f 1
is apparently not defeq with @FunLike.coe F α (fun a ↦ β) OneHomClass.toFunLike f 1
. This looks eerily reminiscent of issues that we had in mathlib3 when not using old_structure_cmd
to define these objects. Does anyone have any insights about how to fix this?
Jireh Loreaux (Dec 10 2022 at 06:29):
I think we don't want CoeTC here, but I'm not sure if changing it will fix the problem.
Eric Wieser (Dec 10 2022 at 09:25):
I find it very hard to believe those are not defeq. Is this just another synthesized/unified clash again? How did you test if they were defeq?
Kevin Buzzard (Dec 10 2022 at 12:27):
map_one' := by
letI : MonoidHomClass F α β := MonoidWithZeroHomClass.toMonoidHomClass
exact map_one f
You had haveI
instead of letI
, so the data was being forgotten.
Kevin Buzzard (Dec 10 2022 at 12:37):
That resolves the second issue, but the first one is still confusing to me:
attribute [instance] MonoidWithZeroHomClass.toMonoidHomClass -- presumably it's an instance,
-- even though this is not possible to easily check in Lean 4
instance [OrderMonoidWithZeroHomClass F α β] : CoeTC F (α →*₀o β) :=
⟨fun f =>
-- comment out the next line and the proof breaks
-- `:= inferInstance` also fails here (deterministic timeout)
letI : MonoidHomClass F α β := MonoidWithZeroHomClass.toMonoidHomClass;
{ toFun := f,
map_one' := map_one f
map_zero' := map_zero f,
map_mul' := map_mul f
monotone' := OrderMonoidWithZeroHomClass.Monotone f }⟩
Kevin Buzzard (Dec 10 2022 at 12:40):
The fact that it's a deterministic timeout rather than just an "i give up" makes me wonder if typeclass inference is getting into some kind of loop. Can someone remind me how to look at instance traces in Lean 4? I don't think I've done this before. I tried set_option trace.Meta.synthInstance true
but all I got was
[Meta.synthInstance] 💥 MonoidHomClass F α β ▶
which is certainly funny, but also not helpful enough
Kevin Buzzard (Dec 10 2022 at 12:47):
trace.png
The various options I've found all have defeq docstrings :-(
Kevin Buzzard (Dec 10 2022 at 12:52):
set_option trace.Meta.synthInstance.tryResolve true
generates so much output that it crashes VS Code :-(
Kevin Buzzard (Dec 10 2022 at 12:58):
(in the same file in the same PR):
-- this is in the file already
-- See note [lower instance priority]
instance (priority := 100) OrderMonoidWithZeroHomClass.toOrderMonoidHomClass
[OrderMonoidWithZeroHomClass F α β] : OrderMonoidHomClass F α β :=
{ ‹OrderMonoidWithZeroHomClass F α β› with }
-- this is where the experiment starts
variable [OrderMonoidWithZeroHomClass F α β] in
#synth OrderMonoidHomClass F α β -- fails
Am I doing something wrong? It doesn't work if you change the priority to 100000000000000 either.
Kevin Buzzard (Dec 10 2022 at 13:14):
OK so here is a not particularly MWE of the borkage:
import Mathlib.Algebra.Hom.Group
variable [MulZeroOneClass α] [MulZeroOneClass β] [MonoidWithZeroHomClass F α β] in
#synth MonoidHomClass F α β -- works
This file works as it stands on master. On branch dupuisf/algebra/order/hom/monoid
(which has a half-finished Algebra.Order.Hom.Monoid
) if you replace lines 177ff of Algebra.Order.Hom.Monoid
with
-- See note [lower instance priority]
instance (priority := 100) OrderMonoidWithZeroHomClass.toOrderMonoidHomClass
[OrderMonoidWithZeroHomClass F α β] : OrderMonoidHomClass F α β :=
{ ‹OrderMonoidWithZeroHomClass F α β› with }
#align
order_monoid_with_zero_hom_class.to_order_monoid_hom_class OrderMonoidWithZeroHomClass.toOrderMonoidHomClass
end MonoidWithZero
variable [MulZeroOneClass α] [MulZeroOneClass β] [MonoidWithZeroHomClass F α β] in
#synth MonoidHomClass F α β -- now fails
#exit
then it doesn't work any more. Instead, the #synth
fails with a timeout. So this instance OrderMonoidWithZeroHomClass.toOrderMonoidHomClass
seems to me to be introducing a loop. I am eager to learn how to diagnose this further, but cannot figure out how to look at the traces myself. This failure is very strange to me because the failing #synth
has nothing to do with the Order
heirarchy.
Kevin Buzzard (Dec 10 2022 at 14:05):
Here's a version which demonstrates the issue on mathlib4 master:
import Mathlib.Algebra.Hom.Group
import Mathlib.Order.Hom.Basic
variable {F α β : Type _}
class OrderMonoidHomClass (F : Type _) (α β : outParam <| Type _) [Preorder α] [Preorder β]
[MulOneClass α] [MulOneClass β] extends MonoidHomClass F α β where
Monotone (f : F) : Monotone f
class OrderMonoidWithZeroHomClass (F : Type _) (α β : outParam <| Type _) [Preorder α] [Preorder β]
[MulZeroOneClass α] [MulZeroOneClass β] extends MonoidWithZeroHomClass F α β where
Monotone (f : F) : Monotone f
-- deleting this instance makes the below #synth work
instance (priority := 100) OrderMonoidWithZeroHomClass.toOrderMonoidHomClass
[Preorder α] [Preorder β] [MulZeroOneClass α] [MulZeroOneClass β]
[OrderMonoidWithZeroHomClass F α β] : OrderMonoidHomClass F α β :=
{ ‹OrderMonoidWithZeroHomClass F α β› with }
variable [MulZeroOneClass α] [MulZeroOneClass β] [MonoidWithZeroHomClass F α β] in
#synth MonoidHomClass F α β -- fails
Removing mathlib is harder: I tried here but couldn't reproduce as yet, #synth
succeeds. If I could figure out how to see the traces I'd know which instances are missing in my mathlib-free failed MWE attempt. I think I'm going to have to leave this now; any help with figuring out how to see which instances Lean is getting confused by is welcome! Let me stress again that something very weird is going on here -- this MWE adds two new order-releated classes and an instance relating them; this then makes a type class inference search whch has nothing to do with orders fail.
Mario Carneiro (Dec 10 2022 at 14:48):
Kevin Buzzard said:
The fact that it's a deterministic timeout rather than just an "i give up" makes me wonder if typeclass inference is getting into some kind of loop. Can someone remind me how to look at instance traces in Lean 4? I don't think I've done this before. I tried
set_option trace.Meta.synthInstance true
but all I got was[Meta.synthInstance] 💥 MonoidHomClass F α β ▶
which is certainly funny, but also not helpful enough
That line is a link
Kevin Buzzard (Dec 10 2022 at 14:52):
oh cool! Indeed, it's a link which crashes VS Code. Edit: set_option synthInstance.maxHeartbeats 400
saves me. Thanks a lot!
Kevin Buzzard (Dec 10 2022 at 14:55):
[] ✅ apply OrderDual.instPreorderOrderDual to (i : ?m.954) →
(i_1 : ?m.1026 i) →
(i_2 : ?m.1134 i i_1) →
(i_3 : ?m.1278 i i_1 i_2) →
(i_4 : ?m.1458 i i_1 i_2 i_3) →
(i_5 : ?m.1674 i i_1 i_2 i_3 i_4) →
(i_6 : ?m.1926 i i_1 i_2 i_3 i_4 i_5) →
(i_7 : ?m.2214 i i_1 i_2 i_3 i_4 i_5 i_6) →
(i_8 : ?m.2538 i i_1 i_2 i_3 i_4 i_5 i_6 i_7) →
Preorder (?m.2753 i i_1 i_2 i_3 i_4 i_5 i_6 i_7 i_8)ᵒᵈ
Is this bad?
Yaël Dillies (Dec 10 2022 at 14:56):
An auto-implicit issue?
Kevin Buzzard (Dec 10 2022 at 14:56):
definitely not.
Mario Carneiro (Dec 10 2022 at 14:57):
searching for a preorder on a metavar means we applied a dangerous instance. Goals should not be metavars or it will enumerate all preorders
Mario Carneiro (Dec 10 2022 at 14:58):
you should look for who introduced that
Kevin Buzzard (Dec 10 2022 at 15:00):
[Meta.synthInstance] 💥 MonoidHomClass F α β ▼
[] new goal MonoidHomClass F _tc.0 _tc.1 ▶
[] ✅ apply @OrderMonoidHomClass.toMonoidHomClass to MonoidHomClass F ?m.848 ?m.849 ▶
[] ✅ apply @OrderMonoidWithZeroHomClass.toOrderMonoidHomClass to OrderMonoidHomClass F ?m.869 ?m.870 ▶
[] ✅ apply @WithTop.preorder to Preorder (WithTop ?m.911) ▶
[] ✅ apply @OrderHom.instPreorderOrderHom to Preorder (?m.914 →o ?m.915) ▶
[] ✅ apply @WithTop.preorder to Preorder (WithTop ?m.930) ▶
[] ✅ apply @OrderHom.instPreorderOrderHom to Preorder (?m.934 →o ?m.935) ▶
[] ✅ apply Prod.instPreorderProd to Preorder (?m.939 × ?m.940) ▶
[] ✅ apply OrderDual.instPreorderOrderDual to Preorder ?m.944ᵒᵈ ▶
[] ✅ apply @Subtype.instPreorderSubtype to Preorder (Subtype ?m.949) ▶
[] ✅ apply @WithBot.preorder to Preorder (WithBot ?m.951) ▶
[] ✅ apply @instPreorderForAll to Preorder ((i : ?m.954) → ?m.955 i) ▶
[] ✅ apply @WithTop.preorder to (i : ?m.954) → Preorder (WithTop (?m.972 i)) ▶
[] ✅ apply @OrderHom.instPreorderOrderHom to (i : ?m.954) → Preorder (?m.981 i →o ?m.982 i) ▶
[] ✅ apply Prod.instPreorderProd to (i : ?m.954) → Preorder (?m.991 i × ?m.992 i) ▶
[] ✅ apply OrderDual.instPreorderOrderDual to (i : ?m.954) → Preorder (?m.1001 i)ᵒᵈ ▶
[] ✅ apply @Subtype.instPreorderSubtype to (i : ?m.954) → Preorder (Subtype (?m.1011 i)) ▶
[] ✅ apply @WithBot.preorder to (i : ?m.954) → Preorder (WithBot (?m.1018 i)) ▶
[] ✅ apply @instPreorderForAll to (i : ?m.954) → Preorder ((i_1 : ?m.1026 i) → ?m.1027 i i_1) ▶
[] ✅ apply @WithTop.preorder to (i : ?m.954) → (i_1 : ?m.1026 i) → Preorder (WithTop (?m.1050 i i_1)) ▶
[] ✅ apply @OrderHom.instPreorderOrderHom to (i : ?m.954) → (i_1 : ?m.1026 i) → Preorder (?m.1064 i i_1 →o ?m.1065 i i_1) ▶
[] ✅ apply Prod.instPreorderProd to (i : ?m.954) → (i_1 : ?m.1026 i) → Preorder (?m.1079 i i_1 × ?m.1080 i i_1) ▶
[] ✅ apply OrderDual.instPreorderOrderDual to (i : ?m.954) → (i_1 : ?m.1026 i) → Preorder (?m.1094 i i_1)ᵒᵈ ▶
[] ✅ apply @Subtype.instPreorderSubtype to (i : ?m.954) → (i_1 : ?m.1026 i) → Preorder (Subtype (?m.1109 i i_1)) ▶
[] ✅ apply @WithBot.preorder to (i : ?m.954) → (i_1 : ?m.1026 i) → Preorder (WithBot (?m.1121 i i_1)) ▶
[] ✅ apply @instPreorderForAll to (i : ?m.954) → (i_1 : ?m.1026 i) → Preorder ((i_2 : ?m.1134 i i_1) → ?m.1135 i i_1 i_2) ▶
[] ✅ apply @WithTop.preorder to (i : ?m.954) →
(i_1 : ?m.1026 i) → (i_2 : ?m.1134 i i_1) → Preorder (WithTop (?m.1164 i i_1 i_2)) ▶
[] ✅ apply @OrderHom.instPreorderOrderHom to (i : ?m.954) →
(i_1 : ?m.1026 i) → (i_2 : ?m.1134 i i_1) → Preorder (?m.1183 i i_1 i_2 →o ?m.1184 i i_1 i_2) ▶
[] ✅ apply Prod.instPreorderProd to (i : ?m.954) →
(i_1 : ?m.1026 i) → (i_2 : ?m.1134 i i_1) → Preorder (?m.1203 i i_1 i_2 × ?m.1204 i i_1 i_2) ▶
[] ✅ apply OrderDual.instPreorderOrderDual to (i : ?m.954) →
(i_1 : ?m.1026 i) → (i_2 : ?m.1134 i i_1) → Preorder (?m.1223 i i_1 i_2)ᵒᵈ ▶
[] ✅ apply @Subtype.instPreorderSubtype to (i : ?m.954) →
(i_1 : ?m.1026 i) → (i_2 : ?m.1134 i i_1) → Preorder (Subtype (?m.1243 i i_1 i_2)) ▶
[] ✅ apply @WithBot.preorder to (i : ?m.954) →
(i_1 : ?m.1026 i) → (i_2 : ?m.1134 i i_1) → Preorder (WithBot (?m.1260 i i_1 i_2)) ▶
[] ✅ apply @instPreorderForAll to (i : ?m.954) →
(i_1 : ?m.1026 i) → (i_2 : ?m.1134 i i_1) → Preorder ((i_3 : ?m.1278 i i_1 i_2) → ?m.1279 i i_1 i_2 i_3) ▶
[] ✅ apply @WithTop.preorder to (i : ?m.954) →
(i_1 : ?m.1026 i) →
(i_2 : ?m.1134 i i_1) → (i_3 : ?m.1278 i i_1 i_2) → Preorder (WithTop (?m.1314 i i_1 i_2 i_3)) ▶
[] ✅ apply @OrderHom.instPreorderOrderHom to (i : ?m.954) →
(i_1 : ?m.1026 i) →
(i_2 : ?m.1134 i i_1) → (i_3 : ?m.1278 i i_1 i_2) → Preorder (?m.1338 i i_1 i_2 i_3 →o ?m.1339 i i_1 i_2 i_3) ▶
[] ✅ apply Prod.instPreorderProd to (i : ?m.954) →
(i_1 : ?m.1026 i) →
(i_2 : ?m.1134 i i_1) → (i_3 : ?m.1278 i i_1 i_2) → Preorder (?m.1363 i i_1 i_2 i_3 × ?m.1364 i i_1 i_2 i_3) ▶
[] ✅ apply OrderDual.instPreorderOrderDual to (i : ?m.954) →
(i_1 : ?m.1026 i) → (i_2 : ?m.1134 i i_1) → (i_3 : ?m.1278 i i_1 i_2) → Preorder (?m.1388 i i_1 i_2 i_3)ᵒᵈ ▶
[] ✅ apply @Subtype.instPreorderSubtype to (i : ?m.954) →
(i_1 : ?m.1026 i) →
(i_2 : ?m.1134 i i_1) → (i_3 : ?m.1278 i i_1 i_2) → Preorder (Subtype (?m.1413 i i_1 i_2 i_3)) ▶
[] ✅ apply @WithBot.preorder to (i : ?m.954) →
(i_1 : ?m.1026 i) →
(i_2 : ?m.1134 i i_1) → (i_3 : ?m.1278 i i_1 i_2) → Preorder (WithBot (?m.1435 i i_1 i_2 i_3)) ▶
[] ✅ apply @instPreorderForAll to (i : ?m.954) →
(i_1 : ?m.1026 i) →
(i_2 : ?m.1134 i i_1) →
(i_3 : ?m.1278 i i_1 i_2) → Preorder ((i_4 : ?m.1458 i i_1 i_2 i_3) → ?m.1459 i i_1 i_2 i_3 i_4) ▶
[] ✅ apply @WithTop.preorder to (i : ?m.954) →
(i_1 : ?m.1026 i) →
(i_2 : ?m.1134 i i_1) →
(i_3 : ?m.1278 i i_1 i_2) → (i_4 : ?m.1458 i i_1 i_2 i_3) → Preorder (WithTop (?m.1500 i i_1 i_2 i_3 i_4)) ▶
[] ✅ apply @OrderHom.instPreorderOrderHom to (i : ?m.954) →
(i_1 : ?m.1026 i) →
(i_2 : ?m.1134 i i_1) →
(i_3 : ?m.1278 i i_1 i_2) →
(i_4 : ?m.1458 i i_1 i_2 i_3) → Preorder (?m.1529 i i_1 i_2 i_3 i_4 →o ?m.1530 i i_1 i_2 i_3 i_4) ▶
At what point did it go wrong? I've never seen one of these outputs before.
Mario Carneiro (Dec 10 2022 at 15:01):
[] ✅ apply @OrderMonoidWithZeroHomClass.toOrderMonoidHomClass to OrderMonoidHomClass F ?m.869 ?m.870 ▶
[] ✅ apply @WithTop.preorder to Preorder (WithTop ?m.911) ▶
Mario Carneiro (Dec 10 2022 at 15:01):
second line is definitely bad, first line is ok iff the two metavariables are out params
Mario Carneiro (Dec 10 2022 at 15:02):
so OrderMonoidWithZeroHomClass.toOrderMonoidHomClass
looks like the suspect
Kevin Buzzard (Dec 10 2022 at 15:02):
And what's wrong with this instance, which has lived in mathlib3 for a while now?
Mario Carneiro (Dec 10 2022 at 15:03):
what's the signature?
Kevin Buzzard (Dec 10 2022 at 15:03):
See the MWE above.
Ruben Van de Velde (Dec 10 2022 at 15:04):
(docs#order_monoid_with_zero_hom_class.to_order_monoid_hom_class)
Mario Carneiro (Dec 10 2022 at 15:04):
is it true that the last two params in MonoidHomClass
are outparams?
Mario Carneiro (Dec 10 2022 at 15:07):
You may need to mark [Preorder α] [Preorder β] [MulZeroOneClass α] [MulZeroOneClass β]
as outparams. I thought this was fixed so that they were automatically marked as outparams? cc: @Gabriel Ebner
Kevin Buzzard (Dec 10 2022 at 15:09):
/-- `MonoidHomClass F M N` states that `F` is a type of `Monoid`-preserving homomorphisms.
You should also extend this typeclass when you extend `MonoidHom`. -/
@[to_additive]
class MonoidHomClass (F : Type _) (M N : outParam (Type _)) [MulOneClass M] [MulOneClass N]
extends MulHomClass F M N, OneHomClass F M N
#align monoid_hom_class MonoidHomClass
Mario Carneiro (Dec 10 2022 at 15:10):
That seems like it might be worth posting as an issue
Mario Carneiro (Dec 10 2022 at 15:11):
that is, it is surprising to me that OrderMonoidWithZeroHomClass.toOrderMonoidHomClass
is being applied in this situation
Mario Carneiro (Dec 10 2022 at 15:12):
what happens if you mark alpha and beta as outparams in the instance?
Kevin Buzzard (Dec 10 2022 at 15:14):
these links are super-cool BTW
Kevin Buzzard (Dec 10 2022 at 15:15):
Mario Carneiro said:
what happens if you mark alpha and beta as outparams in the instance?
Doesn't fix it :-(
Mario Carneiro (Dec 10 2022 at 15:19):
Can you make an MWE just for this instance to be applied in a TC search? It shouldn't depend on anything other than the types of the classes and instances used
Kevin Buzzard (Dec 10 2022 at 15:27):
It's this instance which causes the chaos:
instance {ι : Type u} {α : ι → Type v} [∀ i, Preorder (α i)] : Preorder (∀ i, α i) where
__ := inferInstanceAs (LE (∀ i, α i))
le_refl := fun a i ↦ le_refl (a i)
le_trans := fun a b c h₁ h₂ i ↦ le_trans (h₁ i) (h₂ i)
Kevin Buzzard (Dec 10 2022 at 15:27):
Mathlib-free MWE on the way
Kevin Buzzard (Dec 10 2022 at 15:28):
(unless someone tells me that something should be an outparam in the above instance)
Kevin Buzzard (Dec 10 2022 at 15:59):
@Mario Carneiro is this OK as a MWE?
class Preorder (α : Type _) where
class Zero.{u} (α : Type u) where
class One (α : Type _) where
-- this instance (in mathlib) is just here in this example to ensure that
-- typeclass search for `Preorder ?m_1` causes chaos;
instance {ι : Type _} {α : ι → Type _} [∀ i, Preorder (α i)] : Preorder (∀ i, α i) where
class MulZeroClass (M₀ : Type _) extends Mul M₀, Zero M₀ where
class MulOneClass (M : Type _) extends One M, Mul M where
class MulZeroOneClass (M₀ : Type _) extends MulOneClass M₀, MulZeroClass M₀
class FunLike (F : Sort _) (α : outParam (Sort _)) (β : outParam <| α → Sort _) where
coe : F → ∀ a : α, β a
instance (priority := 100) {F α β} [FunLike F α β] : CoeFun F fun _ => ∀ a : α, β a where
coe := FunLike.coe
class MulHomClass (F : Type _) (M N : outParam (Type _)) [Mul M] [Mul N]
extends FunLike F M fun _ => N where
class OneHomClass (F : Type _) (M N : outParam (Type _)) [One M] [One N]
extends FunLike F M fun _ => N where
class ZeroHomClass (F : Type _) (M N : outParam (Type _)) [Zero M] [Zero N]
extends FunLike F M fun _ => N where
class MonoidHomClass (F : Type _) (M N : outParam (Type _)) [MulOneClass M] [MulOneClass N]
extends MulHomClass F M N, OneHomClass F M N
class MonoidWithZeroHomClass (F : Type _) (M N : outParam (Type _)) [MulZeroOneClass M]
[MulZeroOneClass N] extends MonoidHomClass F M N, ZeroHomClass F M N
class OrderMonoidHomClass (F : Type _) (α β : outParam <| Type _) [Preorder α] [Preorder β]
[MulOneClass α] [MulOneClass β] extends MonoidHomClass F α β where
class OrderMonoidWithZeroHomClass (F : Type _) (α β : outParam <| Type _) [Preorder α] [Preorder β]
[MulZeroOneClass α] [MulZeroOneClass β] extends MonoidWithZeroHomClass F α β where
-- removing this instance makes the #synth below succeed
instance (priority := 1000) OrderMonoidWithZeroHomClass.toOrderMonoidHomClass
{α β F : Type _} [Preorder α] [Preorder β] [MulZeroOneClass α] [MulZeroOneClass β]
[OrderMonoidWithZeroHomClass F α β] : OrderMonoidHomClass F α β :=
{ ‹OrderMonoidWithZeroHomClass F α β› with }
set_option synthInstance.maxHeartbeats 400 -- make trace manageable
set_option trace.Meta.synthInstance true
variable {α β F : Type _} [MulZeroOneClass α] [MulZeroOneClass β] [MonoidWithZeroHomClass F α β] in
#synth MonoidHomClass F α β -- fails
Kevin Buzzard (Dec 10 2022 at 16:18):
https://github.com/leanprover/lean4/issues/1940
Frédéric Dupuis (Dec 10 2022 at 16:21):
@Kevin Buzzard Thanks a lot for distilling this down to an MWE!
Kevin Buzzard (Dec 10 2022 at 16:22):
I quite like this kind of detective work. It teaches me more about the system. I've learnt several new things just from this conversation.
Gabriel Ebner (Dec 10 2022 at 20:13):
You may need to mark [Preorder α] [Preorder β] [MulZeroOneClass α] [MulZeroOneClass β] as outparams. I thought this was fixed so that they were automatically marked as outparams?
You're mixing things up, this has only incidentally to do with outparams. The issue is that TC search shouldn't create a subgoal for the [Preorder α]
argument (because that will almost certainly be the very very bad subgoal Preorder ?m
).
For automatically created instances, like the parent projection, we now mark these arguments as implicit instead of instance-implicit. (This was the quick fix to lean4#1901) We might need to do (something like) this also for manually declared instances if writing {_ : Preorder α}
proves too cumbersome.
Kevin Buzzard (Dec 10 2022 at 21:15):
Thanks a lot Gabriel! I've learnt a ton today.
Kevin Buzzard (Dec 10 2022 at 21:25):
@Frédéric Dupuis I've pushed Gabriel's fix to your branch.
Mario Carneiro (Dec 10 2022 at 21:28):
@Gabriel Ebner I was thinking about that, but it seemed not to be the right solution in a lot of instances like this because we do want to use instance search once we know what alpha and beta are, because we won't be able to find those arguments by unification esp. if it's a stronger class than is expected by whatever is producing the outparam values (e.g if the instance only applies when the preorder on alpha is actually a linear order)
Gabriel Ebner (Dec 10 2022 at 22:49):
That is wishful thinking and not at all what the square brackets mean today.
Gabriel Ebner (Dec 10 2022 at 22:50):
Marking those arguments as instance implicit right now won't magically make TC search do the right thing. It will just time out.
Gabriel Ebner (Dec 10 2022 at 22:52):
If you mark then as implicit it should work with the current set up. The LinearOrder instance should be synthesized during unification as a nested TC problem.
Kevin Buzzard (Dec 10 2022 at 22:57):
Well, it works for now and I know what to look for later; we'll see if any problems show up later and if so we can revisit.
Gabriel Ebner (Dec 10 2022 at 22:57):
I kind of agree that this is an inadequate solution. We shouldn't need to tweak the braces everywhere (because it's awkward and inconsistent with other definitions). TC search should probably also fill in the LinearOrder as a separate subgoal, but that's a much larger refactoring.
Mario Carneiro (Dec 10 2022 at 23:03):
Gabriel Ebner said:
That is wishful thinking and not at all what the square brackets mean today.
I understand that, but {} brackets are also not the right solution, which is why I recommended to make an issue for it. It's possible that we can delay fixing the problem by using {} brackets instead, but this will fail if you actually need to use instance search on these arguments, which seems like a fairly common situation for typeclass instances.
Mario Carneiro (Dec 10 2022 at 23:04):
Gabriel Ebner said:
If you mark then as implicit it should work with the current set up. The LinearOrder instance should be synthesized during unification as a nested TC problem.
If you use implicits, why would it be solved as a nested TC problem at all? It would just be an implicit arg that can't be inferred.
Gabriel Ebner (Dec 10 2022 at 23:40):
"Nested" TC problem means a TC problem that is created during unification. E.g. you unify inferInstanceAs (Add Nat) =?= @AddMonoid.toAdd Nat ?m
, then Lean will try to synthesize an AddMonoid Nat
(the type of ?m
) instance to unstuck the unification.
Gabriel Ebner (Dec 10 2022 at 23:43):
(This solves the same issue as the unification hints in canonical structures, btw.)
Winston Yin (Dec 11 2022 at 01:43):
Is this failure to synthesise a Preorder
instance an example of the issue in this thread?
Winston Yin (Dec 11 2022 at 02:04):
mathlib4#927 also has problems synthesising LE
instance, preventing any progress on the file. Happy to start a new thread if this isn't the same problem
Kevin Buzzard (Dec 11 2022 at 11:16):
Winston Yin said:
Is this failure to synthesise a
Preorder
instance an example of the issue in this thread?
I don't think it is. Hovering over the ↑
in failed to synthesize instance Preorder ↑s
indicates that it's type_of_Set
, so it seems to me that the issue is that the instance Subtype.instPreorderSubtype
isn't firing because it's looking for Preorder (Subtype p)
. If you add the missing instance, e.g.
instance [Preorder α] (s : Set α) : Preorder (↑s) := Subtype.instPreorderSubtype s
(although probably the construction should be filled in properly rather than relying on defeq abuse) then
theorem monotoneOn_iff_monotone : MonotoneOn f s ↔
(Monotone fun a : s => f a) := by
...
works (the proof breaks, but that's another issue)
Kevin Buzzard (Dec 11 2022 at 11:20):
Winston Yin said:
mathlib4#927 also has problems synthesising
LE
instance, preventing any progress on the file. Happy to start a new thread if this isn't the same problem
Can you show me where the error is? I'm not even sure which file you're talking about in that PR. The first error in Data.Nat.Order.Lemmas
is not related to LE.
Scott Morrison (Dec 12 2022 at 08:00):
Coming late to this thread, but just in case not everyone has seen this: Gabriel recently gave #lint a power-up for detecting instances which will create bad typeclass searches (e.g. Preorder ?α
). Your first step upon encountering a typeclass search blow-up should always be a #lint immediately before it, and then go solve any problems it finds before even beginning to think about the blow-up.
Gabriel Ebner (Mar 31 2023 at 01:00):
The lean4#2174 PR addresses the issue and after that instance [Preorder α] [Preorder β] [MulZeroOneClass α] [MulZeroOneClass β] [OrderMonoidWithZeroHomClass F α β] : OrderMonoidHomClass F α β
will work out of the box. When adding the instance, the new code figures out the order the arguments should be synthesized in (here, we'd start with the OrderMonoidWithZeroHomClass and then do the rest from left-to-right).
Gabriel Ebner (Mar 31 2023 at 01:02):
To figure out the order, it adds a new semiOutParam
tag to some classes like Coe
because otherwise we can't figure out the order for those classes. (For those who know the dangerous instances linter in std4, it's got a hardcoded list to encode that information.)
Gabriel Ebner (Mar 31 2023 at 01:05):
outParam
means two things: 1) instances should provide a value for that parameter (e.g. an instance : FunLike Nat Nat fun _ => β := ...
is not kosher because it doesn't determine the β
), and 2) this value must be unique (you shouldn't have both FunLike Nat Nat fun _ => Nat
and FunLike Nat Nat fun _ => Int
)
Gabriel Ebner (Mar 31 2023 at 01:05):
semiOutParam
is just like outParam
except that it only means (1) and not (2).
Gabriel Ebner (Mar 31 2023 at 01:05):
Does that make any sense to you?
Gabriel Ebner (Mar 31 2023 at 01:06):
Here's how mathlib would look like after the change: https://github.com/leanprover-community/mathlib4/pull/3139/files
Gabriel Ebner (Apr 11 2023 at 00:03):
I have prepared a bump PR for tomorrow, only the lean-toolchain
file needs to be updated: !4#3139
Matthew Ballard (Apr 11 2023 at 00:40):
(Sadly no squee emoji)
Nikolas Kuhn (Jun 11 2023 at 09:41):
There's different naming conventions for FunLike instances: I've found both funLike
and FunLike_instance
. Do we have a preferred one, or is there some principle distinguishing their usage?
Edit: As Moritz Doll points out, there is also instFunLike
.
Moritz Doll (Jun 11 2023 at 09:46):
shouldn't it be instFunLike
?
Nikolas Kuhn (Jun 11 2023 at 10:10):
Following a suggestion of @Scott Morrison in https://github.com/leanprover-community/mathlib4/pull/4047, I tried to add a FunLike
instance to the homomorphism type of SemiNormedGroupCat
. Previously, I had added a CoeFun
instance.
Now, this seems to break some proof step where I need to show ↑f 0 = 0
further down in the file. Trying to rw [map_zero]
gives a complaint that there is no instance of ZeroHomClass
is missing. Is the solution here to add that instance ?
Nikolas Kuhn (Jun 11 2023 at 10:13):
Concretely, I've been replacing
instance {X Y : SemiNormedGroupCat} : CoeFun (X ⟶ Y) fun _ => X → Y where
coe (f : X ⟶ Y) := NormedAddGroupHom.toFun f
by
instance FunLike_instance (X Y : SemiNormedGroupCat) : FunLike (X ⟶ Y) X (fun _ => Y) :=
show FunLike (NormedAddGroupHom X Y) X (fun _ => Y) from inferInstance
in the current version of the PR.
Yury G. Kudryashov (Jun 11 2023 at 15:10):
(deleted)
Nikolas Kuhn (Jun 11 2023 at 15:45):
I added a ZeroHomClass
, and everything seems to work.
Last updated: Dec 20 2023 at 11:08 UTC