Zulip Chat Archive
Stream: mathlib4
Topic: Semiring definition
Martin Dvořák (Dec 21 2025 at 09:17):
In the definition of a semiring
class Semiring (α : Type u) extends NonUnitalSemiring α, NonAssocSemiring α, MonoidWithZero α
is the MonoidWithZero α requirement redundant?
Robin Arnez (Dec 21 2025 at 10:39):
Well, it's redundant in the sense that all the properties about + and * that constitute a Semiring are already in NonUnitalSemiring + NonAssocSemiring. However, for type-class resolution MonoidWithZero is used here to infer Monoid and MonoidWithZero from Semiring and Monoid and thus MonoidWithZero introduces a new operation: a ^ n for n : ℕ.
Martin Dvořák (Dec 21 2025 at 11:10):
Monoid could be an instance, couldn't it?
Why is it better to have it in the Semiring definition?
Aaron Liu (Dec 21 2025 at 13:42):
So that semiring inherits an npow field
Martin Dvořák (Dec 21 2025 at 14:29):
Why not to do something like
import Mathlib
class Semiring' (α : Type) extends NonUnitalSemiring α, NonAssocSemiring α
def myPow {α : Type} [Semigroup α] (_1 : α) (a : α) : ℕ → α
| 0 => _1
| n+1 => myPow _1 a n * a
instance (α : Type) [Semiring' α] : Monoid α where
npow n a := myPow (1 : α) a n
example {T : Type} [Semiring' T] (x : T) : x ^ 3 * x ^ 2 = x ^ 5 := by
noncomm_ring
but cleaner?
Aaron Liu (Dec 21 2025 at 15:12):
because it breaks the whole point of the npow field
Aaron Liu (Dec 21 2025 at 15:13):
the point is that you should be able to set it to what you want
Adam Topaz (Dec 21 2025 at 15:46):
Yeah, to expand a bit, we have such an npow field (and analogously zpow for groups) to be able to have these pow operations with good definitional properties. We then also include proofs saying that the pow operations agree (propositionally!) with the recursive definition. In practice these have default values so that you can choose whether or not to define an npow or just use the recursive version
Aaron Liu (Dec 21 2025 at 15:49):
for example if I have this better definition I want to use
def Int.betterPow (a : Int) (b : Nat) : Int :=
if b % 2 = 0 ∨ 0 ≤ a then (a.natAbs ^ b : Nat)
else -(a.natAbs ^ b : Nat)
Aaron Liu (Dec 21 2025 at 15:49):
I should be able to override the default implementation
Martin Dvořák (Dec 21 2025 at 16:29):
Thanks for explanation!
Last updated: Feb 28 2026 at 14:05 UTC