Zulip Chat Archive

Stream: mathlib4

Topic: Algebra.cast


Artie Khovanov (Dec 16 2025 at 02:07):

The (scoped) coercion from a commutative semiring to an algebra over this semiring is registered as Algebra.cast, which is reducibly defeq to algebraMap, but not syntactically or simp-equal. In fact, absolutely nothing is proved about Algebra.cast except that it commutes with ring operations.

This makes it annoying to state lemmas about algebras because you have to either write algebraMap _ everywhere or rewrite away the casts. I therefore propose to either

  1. add a simp lemma Algebra.cast_eq_algebraMap, or
  2. remove Algebra.cast and change the scoped coercion to be algebraMap.

What are people's thoughts?

Aaron Liu (Dec 16 2025 at 02:15):

I prefer #2

Aaron Liu (Dec 16 2025 at 02:16):

we don't need more nothing-definitions

Riccardo Brasca (Dec 16 2025 at 09:16):

I also prefer the second option. Note that this should stay scoped, as in the very common case R is there is already a coercion ℤ → A.

Artie Khovanov (Dec 17 2025 at 05:07):

#32991

Artie Khovanov (Dec 17 2025 at 15:46):

Here is a problem with option 2: @[coe] can only be applied to function type declarations. Therefore it doesn't work for algebraMap, which is bundled. This breaks the delaborator, which is fine - but it also breaks norm_cast, which is an issue. I want to register coe for the expression @DFunLike.coe (R →+* A) R (fun x ↦ A) RingHom.instFunLike (algebraMap R A). Working up to reducible defeq by defining Algebra.cast is not good enough because Mathlib tactics care about syntactic equality (ie, status quo / option 1 is bad).

Riccardo Brasca (Dec 17 2025 at 15:58):

In my opinion we should live with the fact that algebraMap is not a coercion. We already do so in most of the library, and even if it is not the perfect solution it works in practice.

Artie Khovanov (Dec 17 2025 at 16:00):

In that case we should add a simp lemma to convert between Algebra.cast and algebraMap. The current situation is very bad: we have a nothing-definition with no API!

Johan Commelin (Dec 18 2025 at 08:18):

Maybe Riccardo is suggesting:

  1. remove Algebra.cast

Riccardo Brasca (Dec 18 2025 at 08:25):

Yes, honestly I don't see why it's there. The idea is nice, but in practice it doesn't work. Is it used a lot?

Eric Wieser (Dec 18 2025 at 08:32):

It's there because it was part of a larger development that got reverted by the port

Eric Wieser (Dec 18 2025 at 08:32):

I believe the plan was to make it the simp-normal form instead of algebraMap (which has the benefit of making it work for towers of monoids and groups, like the units of the rings)

Eric Wieser (Dec 18 2025 at 08:33):

The plan was a little more compelling in Lean 3 where it could replace Nat.cast, Int.cast, and Rat.cast at the same time

Artie Khovanov (Dec 18 2025 at 12:37):

Oh OK
Yeah let's remove Algebra.cast

Artie Khovanov (Dec 18 2025 at 16:10):

#32991 - remove Algebra.cast

Artie Khovanov (Dec 18 2025 at 17:17):

Riccardo Brasca said:

Yes, honestly I don't see why it's there. The idea is nice, but in practice it doesn't work. Is it used a lot?

Places where the cast is actually used as a cast (as opposed to notation):
Algebra.adjoin_insert_natCast
div_eq_quo_add_rem_div_add_rem_div
(WIP)

Eric Wieser (Dec 19 2025 at 00:43):

See also #mathlib4 > Algebra.cast and algebraMap @ 💬

Artie Khovanov (Dec 19 2025 at 00:44):

ah, an old question
I would really suggest having a simp lemma for now and then we can decide whether to go ahead with ripping out the coercion in future

Artie Khovanov (Dec 19 2025 at 00:46):

@Eric Wieser what do you mean when you say the following:
image.png
If there is some way to make algebraMap work with norm_cast, then we should just do that.

Eric Wieser (Dec 19 2025 at 00:56):

(note you can quote messages from other threads rather than screenshotting)

Artie Khovanov (Dec 19 2025 at 22:09):

So.. what does that message mean? Is there some way to make algebraMap work with norm_cast?

Aaron Liu (Dec 19 2025 at 22:10):

I thought @[coe] was just a pretty printer thing

Aaron Liu (Dec 19 2025 at 22:10):

why is it messing up norm_cast

Artie Khovanov (Dec 19 2025 at 22:12):

norm_cast looks for coercion instances. It is not possible to register a bundled function as a coercion.

Jireh Loreaux (Dec 19 2025 at 22:26):

No, norm_cast looks for @[coe] attributes, not coercion instances, those attributes don't just affect pretty-printing.

Jireh Loreaux (Dec 19 2025 at 22:27):

In particular, since Lean inserts the function underlying a coercion (via coercion instances) during elaboration, the fact that they were / are a coercion would be lost in the resulting Expr, so we need the attribute to tell Lean "hey, when you see Subtype.val, that's a coercion."

Artie Khovanov (Dec 19 2025 at 22:54):

Ah, thanks for the correction! The situation is the same though right? It sounds like there's no way to make this work, then?

Eric Wieser (Dec 19 2025 at 22:56):

I think there's a request here for a version norm_cast that accepts an explicit list of names rather than just everything tagged with coe

Eric Wieser (Dec 19 2025 at 22:57):

norm_cast could be a shorthand for norm_fun [Coe.coe] or similar

Artie Khovanov (Dec 19 2025 at 22:57):

Or alternatively a request to allow coercion functions to be bundled, via a CoeFun instance.

Artie Khovanov (Dec 19 2025 at 22:58):

Or both tbh :joy:

Eric Wieser (Dec 19 2025 at 22:58):

I think we have exactly one function we want to do that with (algebraMap), but if we decided to

Eric Wieser said:

make [Algebra.cast] the simp-normal form instead of algebraMap (which has the benefit of making it work for towers of monoids and groups, like the units of the rings)

then we would have zero of them

Artie Khovanov (Dec 19 2025 at 22:59):

The issue with making it the SNF is we lose all the bundled function API
I'd rather have a bare coercion that simps to algebraMap

Artie Khovanov (Dec 19 2025 at 23:00):

Also we could make the Nat.toInt etc coercions bundled!

Eric Wieser (Dec 19 2025 at 23:01):

docs#Nat.toInt isn't a thing

Artie Khovanov (Dec 19 2025 at 23:04):

Sorry I mean Nat.cast

Aaron Liu (Dec 19 2025 at 23:05):

Artie Khovanov said:

Sorry I mean Nat.cast

There are times when it makes sense to not bundle those, and there are times it makes sense to use docs#Nat.castRingHom etc.

Aaron Liu (Dec 19 2025 at 23:05):

Artie Khovanov said:

It is not possible to register a bundled function as a coercion.

Why do you say this? I think it's definitely possible

Aaron Liu (Dec 19 2025 at 23:06):

you just write a CoeFun instance and you make the coercion part the bundled function

Artie Khovanov (Dec 19 2025 at 23:09):

Aaron Liu said:

Artie Khovanov said:

Sorry I mean Nat.cast

There are times when it makes sense to not bundle those, and there are times it makes sense to use docs#Nat.castRingHom etc.

Well in that case we should add API to Algebra.cast to relate it to algebraMap!

Artie Khovanov (Dec 19 2025 at 23:09):

Like we should do something

Aaron Liu (Dec 19 2025 at 23:09):

well the difference is that I don't think it makes sense to not bundle algebraMap

Artie Khovanov (Dec 19 2025 at 23:09):

right

Aaron Liu (Dec 19 2025 at 23:09):

like with the absolutely minimal assumptions you put that makes the definition work is still gives you enough to make it bundled

Aaron Liu (Dec 19 2025 at 23:10):

whereas there's times that Nat.cast is useful but the target isn't a ring

Eric Wieser (Dec 19 2025 at 23:27):

Aaron Liu said:

like with the absolutely minimal assumptions you put that makes the definition work is still gives you enough to make it bundled

Only because the current generality is wrong; consider non-associative rings or non-commutative base rings or monoids.

Eric Wieser (Dec 19 2025 at 23:27):

e.g.

class AlgebraCast (R A) where
  algebraCast : R  A

-- imagine that `Algebra` extended `AlgebraCast`
instance [Algebra R A] : AlgebraCast R A where algebraCast := algebraMap R A

-- This can't be bundled as a ringhom
instance [Algebra R A] : AlgebraCast Rˣ Aˣ where
  algebraCast r := algebraCast r, algebraCast r⁻¹, sorry, sorry

Last updated: Dec 20 2025 at 21:32 UTC