Zulip Chat Archive

Stream: mathlib4

Topic: Heterogeneous scalar multiplication


Heather Macbeth (Dec 23 2022 at 00:15):

In mathlib4#1169, having made the notation heterogeneous seems to have broken some simps. Here's an import-free example: a simp that doesn't work, but if in the middle section you change

class HSMul (M α : Type) (β : outParam (Type)) where
  hSMul : M  α  β

infixr:73 " • " => HSMul.hSMul

instance instHSMul [SMul M α] : HSMul M α α where
  hSMul := SMul.smul

to

infixr:73 " • " => SMul.smul

then it does work.

Heather Macbeth (Dec 23 2022 at 00:16):

Is this a familiar problem? What's the fix? (And can someone remind me why we made heterogeneous, anyway?)

Gabriel Ebner (Dec 23 2022 at 02:41):

This is the same issue as https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/unfolding.20earlier.20fields

Gabriel Ebner (Dec 23 2022 at 02:48):

One potential workaround is to define the smul instance separately, and add an explicit simp-lemma to unfold it.

Heather Macbeth (Dec 23 2022 at 02:48):

Thanks Gabriel! I don't understand your comment at that link, though -- could you explain more about the fix? snap :racecar:

Gabriel Ebner (Dec 23 2022 at 02:48):

Heather Macbeth (Dec 23 2022 at 03:00):

Interesting! Yes, that works in the file, thanks.

Heather Macbeth (Jan 11 2023 at 06:51):

I just made an import-free example of a typeclass inference problem which came up in the port earlier today, where the problem is seemingly not a Lean 3/Lean 4 change, but a Mathlib 3/Mathlib 4 change: our choice to wrap scalar multiplication in an extra layer of heterogeneous scalar multiplication. Compare

variable {α β γ : Type}

class Singleton (α : outParam Type) (β : Type) where
  singleton : α  β

def Set (α : Type) := α  Prop

instance : Singleton α (Set α) := sorry

class HSMul (α : Type) (β : Type) (γ : outParam Type) where
 hSMul : α  β  γ

class SMul (α : Type) (β : Type) where
  smul : α  β  β

instance instHSMul [SMul α β] : HSMul α β β := SMul.smul

variable [SMul α β] {s : Set α} {b : β}

instance Set.hasSmul : SMul (Set α) (Set β) := sorry

example : Set β := HSMul.hSMul s (Singleton.singleton b) -- fails

example : Set β := SMul.smul s (Singleton.singleton b) -- works

with the mathlib3 version.

Heather Macbeth (Jan 11 2023 at 06:51):

As far as I can tell these two are exact translations and fail in the same ways. So the culprit should be the HSMul layer.

Heather Macbeth (Jan 11 2023 at 06:52):

Did we previously discuss the choice to invent HSMul? Could someone link to that discussion? What is the expected benefit?

Heather Macbeth (Jan 11 2023 at 06:53):

While writing this message I discovered that I had previously started another thread with the same title, with something else that was broken by adding an HSMul layer. Scroll up to see it.

Ruben Van de Velde (Jan 11 2023 at 06:59):

I think we introduced hsmul to match the built-in operator type classes like hmul

Heather Macbeth (Jan 11 2023 at 07:00):

Right, it in fact has the same signature as HMul. But did we have some intended use case?

James Gallicchio (Jan 11 2023 at 07:02):

I vaguely remember it was about separating the notation (cdot) from the mathlib meaning (multiplication by scalar) because somebody wanted to use the notation for something that was not scalar multiplication?

Mario Carneiro (Jan 11 2023 at 07:42):

As far as I know there wasn't any particular motivation to add HSMul other than consistency with core. We certainly don't have any current things that need it.

Yaël Dillies (Jan 11 2023 at 07:43):

Yes, I would be happy to ditch it.

Mario Carneiro (Jan 11 2023 at 07:43):

I think this issue is caused by not marking the SMul -> HSMul instance as a default instance though

Mario Carneiro (Jan 11 2023 at 07:43):

unlike the Add -> HAdd instances

Yaël Dillies (Jan 11 2023 at 07:43):

@Jireh Loreaux introduced it because of to_additive troubles. But I think those could have been solved another way.

Mario Carneiro (Jan 11 2023 at 07:44):

I would be surprised if HSMul has any issues above and beyond what we already have to deal with for HAdd and HPow

Heather Macbeth (Jan 11 2023 at 08:07):

OK, I found Jireh's post in favour of HSMul using the pointers Yaël gave about the history with to_additive.

Jireh Loreaux said:

Look, I propose creating the HSMul class for now so that I can fix to_additive translating pow to smul without potentially clobbering HMul. If later we wish to change Lean 4 core to remove HPow and we can convince the devs, fine, we can do that when the time comes.

Heather Macbeth (Jan 11 2023 at 08:08):

Mario, does this clarify anything for you? Do you still think we need a SMul -> HSMul default instance to fix this?

Jireh Loreaux (Jan 11 2023 at 15:05):

@Yaël Dillies what other way?

Yes, the introduction of HSMul was primarily to fix to_additive, but I think the other benefit was keeping the smul and mul notations completely separate. Eric also mentioned a use case in that thread IIRC (can't link right now, on mobile, Heather, can you do it?).

Eric Wieser (Jan 11 2023 at 15:21):

Do you still think we need a SMul -> HSMul default instance to fix this?

I think we should certainly have this, and can revisit whether the H version is needed at all later

Eric Wieser (Jan 11 2023 at 15:23):

To be clear, docs4#instHSMul aleady exists, it's just missing the @[defaultInstance] attribute that docs4#instHMul has

Floris van Doorn (Jan 12 2023 at 11:29):

Added in mathlib4#1501


Last updated: Dec 20 2023 at 11:08 UTC