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