Zulip Chat Archive
Stream: new members
Topic: def nat greater than 0
Henrik Böving (Apr 18 2021 at 13:51):
Hey, so I'm currently learning lean and I'm trying to formalize a bit of abstract algebra for self learning purposes so i got this class representing a semigroup:
class semigroup (H: Type) extends has_mul H :=
(mul_assoc: ∀ (a b c: H), (a * b) * c = a * (b * c))
and now I'd basically like to define exponentiation for this class. So I went ahead and wrote
def pow {SG: Type*} [semigroup SG] : SG -> nat -> SG
| a (nat.succ 0) := a
| a (nat.succ n) := a * (pow a n)
and rightfully so lean does now complain about the fact that I didnt define my pattern for the natural number 0, however this is only possible inside a monoid as far as I'm concerned since a^0 = 1 which is not something I can express inside a semigroup i believe. So my question would be whether there is some way to still formalize what i want by basically saying that this function only works for "any nat greater than 0"? Or do i have to give up defining this function for a semigroup and instead use a monoid?
Eric Wieser (Apr 18 2021 at 13:58):
You could use docs#pnat (ℕ+
) instead of nat
Henrik Böving (Apr 18 2021 at 13:59):
Looks just like what I needed, thank you!
Henrik Böving (Apr 18 2021 at 14:13):
So I now ended up with
def pow {SG: Type*} [half_group SG] : SG -> pnat -> SG
| a one := a
| a (pnat.succ n) := a * (pow a n)
but pnat.succ isn't actually defined...and I can't use nat.succ anymore either. Any idea on what the correct notation for this would be?
Eric Wieser (Apr 18 2021 at 14:54):
This works:
import data.pnat.basic
namespace henrik
class semigroup (H: Type) extends has_mul H :=
(mul_assoc: ∀ (a b c: H), (a * b) * c = a * (b * c))
def pow {SG: Type*} [semigroup SG] : SG -> pnat -> SG
| a ⟨0, h⟩ := false.elim (nat.lt_asymm h h)
| a ⟨1, h⟩ := a
| a ⟨n + 2, h⟩ :=
have n.succ < n + 2 := nat.succ_le_succ rfl.le,
a * (pow a ⟨n.succ, n.zero_lt_succ⟩)
end henrik
Last updated: Dec 20 2023 at 11:08 UTC