Zulip Chat Archive
Stream: mathlib4
Topic: to_additive issues
Jireh Loreaux (Nov 23 2022 at 09:16):
to_additive
has been through the ringer recently. Let me throw another punch or two.
In Algebra.Group.Defs
the to_additive
attributes for HPow
are wrong which leads to errors when converting from pow
to smul
where it complains about HMul.hMul
. The first issue is to recognize that the argument reordering is wrong for HPow.hPow
(it should be 1 5
). However, that doesn't lead to a complete fix because Pow
is really the heterogeneous HPow
under the hood.
I came up with a fix: Define a heterogeneous scalar multiplication class HSmul
with field hSmul
, then make •
notation for HSmul.hSmul
and provide an instance instHSmul
to mirror things like instHPow
. Of course, we could do the same thing for Vadd
if we wanted / needed, but I feel this is less pressing. Then all the translation seems to work.
This allows the successful(∗) fix of the note lower in this file:
-- FIXME The lemmas in this section should be done by `to_additive` below, but it fails.
What do we think of this? Should I implement it?
Jireh Loreaux (Nov 23 2022 at 09:25):
Regarding the (∗): it actually doesn't work for succ_nsmul
, but for a different reason. With the above fix implemented, to_additive
fails when trying to additivize pow_succ
into succ_nsmul
because it sees the 1
and incorrectly changes it into 0
(here it is incorrect because it occurs as n + 1
, so it really represents n.succ
). Note that to_additive
in Lean 3 correctly additivizes this declaration.
This happens despite the fact that there is a note in the file about add_monoid
s that:
/- In the definition, we use `n.succ` instead of `n + 1` in the `nsmul_succ'` and `npow_succ'` fields
to make sure that `to_additive` is not confused (otherwise, it would try to convert `1 : ℕ`
to `0 : ℕ`). -/
Moreover, even though in Lean 4 we still use n.succ
in the definition of AddMonoid
I think to_additive
still manages to see a 1
somehow and converts it into a 0
(this is based on trying to port Algebra.Group.InjSurj
and noting that with the fix in the previous post, to_additive
fails to additivize in certain situations for what I believe to be this reason).
Yaël Dillies (Nov 23 2022 at 09:37):
What is HPow
used for?
Jireh Loreaux (Nov 23 2022 at 09:38):
Lean 4 core has all kinds of heterogeneous operations HMul
, HAdd
, HPow
and the notations are actually defined on these type classes, not on Mul
, Add
, and Pow
, but the latter have instances of the former, so they inherit the notation.
Jireh Loreaux (Nov 23 2022 at 09:40):
If you wanted, you could use it get it a pow functions ℕ → ℚ → ℝ
(with junk values for negative powers). I'm not saying we should do this, only that it's possible.
Yaël Dillies (Nov 23 2022 at 09:41):
so HSMul
is HMul
, right?
Jireh Loreaux (Nov 23 2022 at 09:44):
Well, yes and no? They are essentially the same (i.e., structures with a single function α → β → γ
), but their respective functions get different notation •
vs. *
.
Jireh Loreaux (Nov 23 2022 at 09:46):
So they are the same and / or different in precisely the same ways as HMul
, HAdd
and HPow
.
Jireh Loreaux (Nov 23 2022 at 09:47):
Anyway, I need to go to bed. Hopefully while I sleep a few hours people can discuss this a bit.
Jireh Loreaux (Nov 23 2022 at 09:50):
Just to emphasize one point about why I think we need this type class HSmul
: if we don't have it, what is the additivization of instHPow
(which is necessary to have)?
Floris van Doorn (Nov 23 2022 at 10:33):
I'll take a look today. 1 : ℕ
should not be transformed to 0
by to_additive
for a long time already.
Yaël Dillies (Nov 23 2022 at 10:50):
I don't think instHPow
makes sense in this generality
Floris van Doorn (Nov 23 2022 at 13:44):
Did we discuss that we don't want to use HMul
for scalar multiplication? If we do, HMul
could be the additive analogue of HPow
.
Floris van Doorn (Nov 23 2022 at 13:52):
There are currently multiple issues with not translating multiplicative things on ℕ
with additive things (both in the code and in the attributes that are set).
Since numerals are encoded differently in Lean 4, we need some logic around those.
@Mario Carneiro: if I look through a fully elaborated expression, will all natural number literals (Expr.lit
) be inside an application of OfNat.ofNat
?
Jireh Loreaux (Nov 23 2022 at 15:16):
Floris, I saw the branch to_additive_fixes
. FYI: it still is translating 1 : ℕ
to 0
. See the offshoot branch j-loreaux/HSmul
and look at the first error in Algebra.Group.Defs
where it tries to additivize pow_succ
.
Jireh Loreaux (Nov 23 2022 at 15:19):
Shouldn't we just create a new type class HSmul
for the new notation? It seems better to keep things separate instead of merging them under the hood (i.e., I think it's a bad idea to implement both Smul
and Mul
in terms of HMul
, especially because at some point in time we might want an actual heterogenous multiplication; that is, a heterogenous operation which gets the *
notation).
Jireh Loreaux (Nov 23 2022 at 15:20):
Yaël, can you explain why you don't think instHPow
makes sense? I don't see any issue with it yet.
Floris van Doorn (Nov 23 2022 at 15:20):
Still todo:
- deal with literals in Nat (see my question here)
Jireh Loreaux (Nov 23 2022 at 15:21):
Oh sorry, I misread.
Floris van Doorn (Nov 23 2022 at 15:23):
I'm fine with keeping mul
and smul
separate. And if we do, I agree we need an HSmul
.
Yaël Dillies (Nov 23 2022 at 15:46):
I thought the entire point of HMul
was to unify mul
and smul
?
Yaël Dillies (Nov 23 2022 at 15:47):
Do we have any use for HMul
?
Jireh Loreaux (Nov 23 2022 at 16:04):
Why would we want to unify them? Unless we're trying to unify notation? Types are cheap.
Kyle Miller (Nov 23 2022 at 16:08):
There are two potential reasons to want to unify them. (1) Then we have a reasonable way to write left actions and right actions (I'd like to see bimodules properly handled notationally), (2) there is special elaborator support for HMul, though I don't really know the details (maybe we can use the binop%
elaboration helper for an HSmul
too? then this wouldn't be an advantage)
Jireh Loreaux (Nov 23 2022 at 16:15):
I don't see why this requires unification. We could accomplish this with an HSmul
and it has the added benefit that we keep things separate. We can add the elaboration support if we want of course.
Yaël Dillies (Nov 23 2022 at 16:17):
But why would we want HSmul
? This doesn't represent anything that HMul
doesn't represent already.
Jireh Loreaux (Nov 23 2022 at 16:18):
I'm pushing this for two reasons: (1) I think it will be easier to plug in to to_additive
, but perhaps more importantly (2) it safeguards against what I think could be very painful refactors down the road.
Yaël Dillies (Nov 23 2022 at 16:18):
HMul
is to Mul
what HMul
is to SMul
.
Jireh Loreaux (Nov 23 2022 at 16:18):
Disagree.
Yaël Dillies (Nov 23 2022 at 16:19):
So I don't think we want HPow
at all.
Jireh Loreaux (Nov 23 2022 at 16:19):
Hmul is still for *
, but heterogeneous.
Kyle Miller (Nov 23 2022 at 16:23):
So long as HSMul
is fully generic in the two inputs and the output like HMul
, I think I'm on board with it. It's a good way to indicate "this is an action of some sort", and I think it should work for both left and right actions.
(We might still have some HMul
instances for certain kinds of actions, like for scalar multiplication on pi types, since that's more of a lift of the scalar using const
. Is it a scalar action, or is it a coercion to the pi structure?)
Kevin Buzzard (Nov 23 2022 at 16:25):
Yaël Dillies said:
But why would we want
HSmul
? This doesn't represent anything thatHMul
doesn't represent already.
has_one
doesn't represent anything that has_zero
doesn't represent already but that's not an argument for removing has_one
. We're talking about a notational typeclass here, right?
Jireh Loreaux (Nov 23 2022 at 16:25):
Yes
Kyle Miller (Nov 23 2022 at 16:26):
Another thing about mul
and smul
is that mul
is generally associative but smul
isn't (usually because of type reasons; but a group acting on itself by conjugation is a nonassociative action, for example).
Sebastien Gouezel (Nov 23 2022 at 16:27):
Any idea why the heterogeneous multiplication HMul
was introduced in Lean 4?
Kevin Buzzard (Nov 23 2022 at 16:28):
I think Leo saw we were using smul
and decided to see if it was worth generalising to mul
?
Kyle Miller (Nov 23 2022 at 16:29):
The examples I've seen are generally scalar multiplication of vectors. When writing programs, it seems like it's also useful for multiplications where you could insert a coercion, but it might be more efficient to use the uncoerced type directly.
Johan Commelin (Nov 23 2022 at 16:47):
I think it's fair to say that Hmul (m : Nat) (n : Int) : Int
is a very specific kind of smul
. And also that there might be some sense in supporting it.
Johan Commelin (Nov 23 2022 at 16:47):
So I can imagine using Hmul
for algebras.
Johan Commelin (Nov 23 2022 at 16:47):
But still keeping smul around for general actions.
Scott Morrison (Nov 23 2022 at 17:41):
Floris van Doorn said:
If I look through a fully elaborated expression, will all natural number literals (
Expr.lit
) be inside an application ofOfNat.ofNat
?
Yes.
Frédéric Dupuis (Nov 23 2022 at 18:18):
Sebastien Gouezel said:
Any idea why the heterogeneous multiplication
HMul
was introduced in Lean 4?
Matrix multiplication is one obvious place where it would be nice (and the one Leo gave when talking about this new feature).
Jireh Loreaux (Nov 23 2022 at 20:19):
Just for reference, I can even think now of a situation where I might want HAdd
: in operator algebraic K-theory one constructs K_0 (almost) as the Grothendieck group of a semigroup of projections which lie in matrix algebras (of varying sizes) over the algebra in question. So one might want to add something in M_n(A) to something in M_k(A) and get something in M_{n+k}(A).
Jireh Loreaux (Nov 23 2022 at 20:20):
Point being, let's have the heterogeneous versions in general; there's little harm if they never get used.
Yaël Dillies (Nov 23 2022 at 22:00):
No but you corroborate my point here: We might want HMul
and HAdd
, but
- they appear in situations similar to
smul
, so we might as well get rid ofsmul
- Nobody can come up with an actual use case for
HPow
Jireh Loreaux (Nov 23 2022 at 22:20):
No, I still disagree with this. My point about HAdd
was this: in case you didn't know about operator algebraic K-theory, you might think that HAdd
is not necessary (of course, you may have your own examples), but then I gave a counterexample. Look, mathlib has a rule about not overgeneralizing when there is some cost; however, when it's essentially free, and it's conceivable that it has a use, there's no reason not to generalize.
I believe HPow
and HSmul
fall into this category. In fact, I already gave a potential use for HPow
, you've just ignored it: ℕ → ℚ → ℝ
. Again, I'm not arguing that we want that particular HPow
instance, only that we might.
Moreover, I think we should not make things overlap just because it's convenient. So smul
should not use HMul
under the hood, because the latter is the typeclass for *
, not •
.
Scott Morrison (Nov 23 2022 at 22:21):
The *
vs \bu
difference seems quite important. :-)
Yaël Dillies (Nov 23 2022 at 23:13):
I wouldn't call your example of possible use of HPow
"actual" :big_smile:
Yaël Dillies (Nov 23 2022 at 23:14):
My point is not that we shouldn't generalise. My point is that generalising doesn't mean what you claim it does.
Jireh Loreaux (Nov 24 2022 at 01:49):
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. Can I have thumbs up or thumbs down from people on this?
Jireh Loreaux (Nov 24 2022 at 04:46):
Jireh Loreaux (Nov 24 2022 at 04:53):
Sorry, I thought it built properly on my machine, but apparently not. I'll fix it shortly.
Jireh Loreaux (Nov 24 2022 at 06:15):
I have no idea why the abel
test is failing on this PR. Help appreciated @Mario Carneiro (of course you're welcome to ignore this ping; it is Thanksgiving after all)
Jireh Loreaux (Nov 24 2022 at 06:50):
Okay, I think I have some idea. I think the issue is that the case matching on abel
only handles SMul
but now it needs to handle HSMul
(in Mathlib.Tactic.Abel.eval
). If someone wants to have a go at fixing it, be my guest, but it's bedtime for me.
Jireh Loreaux (Nov 24 2022 at 08:06):
This now has a :check:
Last updated: Dec 20 2023 at 11:08 UTC