Zulip Chat Archive
Stream: new members
Topic: Any advice for advoiding type class ambiguities?
Robert Culling (Jan 29 2024 at 03:16):
Kia ora :)
I am trying to recreate some of the algebra hierarchy. I have the following code leading up to the definition of an elementary theorem in Group theory.
-- Magma are types with a single binary operation.
class Magma (α : Type) where
bop : α → α → α
infixl: 70 " * " => Magma.bop
open Magma
-- Semirgroups are a Magma whose binary operation is associative.
class Semigroup (G : Type) extends Magma G where
bop_assoc : ∀ x y z : G, (x * y) * z = x * (y * z)
open Semigroup
-- Monoids are Semigroups with an identity.
class Monoid (G : Type) extends Semigroup G where
id : G
id_bop : ∀ x : G, id * x = x
open Monoid
-- Groups are Monoids with inverses.
class Group (G : Type) extends Monoid G where
inv : G → G
inv_bop : ∀ x : G, (inv x) * x = id
postfix: 100 " ⁻¹ " => Group.inv
open Group
theorem bop_cancel_left (G : Type) (t : Group G) :
∀ a x y : G, a * x = a * y → x = y :=
by
intro a x y
intro h
calc x
_ = id * x := by rw [←id_bop]
_ = (a⁻¹ * a) * x := by rw [←inv_bop]
_ = a⁻¹ * (a * x) := by rw [bop_assoc]
_ = a⁻¹ * (a * y) := by rw [h]
_ = (a⁻¹ * a) * y := by rw [←bop_assoc]
_ = id * y := by rw [inv_bop]
_ = y := by rw [id_bop]
Lean is unhappy with the first line in the calculation. There is a red line underneath id * x
and it explains that it doesn't know how to make sense of id
. I changed the name of the identity, and I introduced parentheses. But the ambiguity remains.
Does any one have any advice on how to set up the hierarchy in such a way as to avoid the ambiguities? Thank you!
Kyle Miller (Jan 29 2024 at 04:44):
The other ambiguity is that there's already a *
. It'd be best if you didn't override the notation and instead made an HMul instance, but if you set a high priority you can override *
completely.
I'm not sure if there's anything you can do for id
but rename it, so it doesn't conflict with the identity function. I suppose you could do notation "id" => Monoid.id
to make it be syntax.
-- Magma are types with a single binary operation.
class Magma (α : Type) where
bop : α → α → α
infixl:70 (priority := high)" * " => Magma.bop
open Magma
-- Semirgroups are a Magma whose binary operation is associative.
class Semigroup (G : Type) extends Magma G where
bop_assoc : ∀ x y z : G, (x * y) * z = x * (y * z)
open Semigroup
-- Monoids are Semigroups with an identity.
class Monoid (G : Type) extends Semigroup G where
id' : G
id_bop : ∀ x : G, id' * x = x
open Monoid
-- Groups are Monoids with inverses.
class Group (G : Type) extends Monoid G where
inv : G → G
inv_bop : ∀ x : G, (inv x) * x = id'
postfix:100 (priority := high) " ⁻¹ " => Group.inv
open Group
theorem bop_cancel_left (G : Type) (t : Group G) :
∀ a x y : G, a * x = a * y → x = y :=
by
intro a x y
intro h
calc x
_ = id' * x := by rw [id_bop]
_ = (a⁻¹ * a) * x := by rw [←inv_bop]
_ = a⁻¹ * (a * x) := by rw [bop_assoc]
_ = a⁻¹ * (a * y) := by rw [h]
_ = (a⁻¹ * a) * y := by rw [←bop_assoc]
_ = id' * y := by rw [inv_bop]
_ = y := by rw [id_bop]
Robert Culling (Jan 29 2024 at 06:20):
@Kyle Miller thank you :) Renaming id and renaming the multiplication symbol fixed the errors!
Is it possible to make Magma.bop an instance of HMul?
N Gelwan (Jan 29 2024 at 16:51):
Given an instance of Magma α
you can obtain an instance of HMul α α α
:
instance [Magma α] : HMul α α α where
hMul := Magma.bop
Last updated: May 02 2025 at 03:31 UTC