Zulip Chat Archive
Stream: new members
Topic: Refine HMul to specific instance
Edmund Lam (Mar 14 2025 at 14:09):
Hi, I am unsure of how to refine a general HMul.hMul
to a specific defined instance when proving properties about an instance. I wrote a simple group class as follows:
class Group (G: Type u) where
identity: G
mul: G -> G -> G
mul_assoc: ∀ a b c: G, mul a (mul b c) = mul (mul a b) c
mul_identity: ∀ a: G, mul identity a = a ∧ mul a identity = a
mul_inv: ∀ a: G, ∃ a₁: G, mul a a₁ = identity ∧ mul a₁ a = identity
instance : Group Int where
identity := 0
mul := Int.add
mul_assoc := by
intros a b c
simp_arith[]
rw [Int.add_assoc]
mul_identity := by
simp_arith[]
mul_inv := by
intros a
exists -a
simp_arith[]
rw [Int.add_right_neg, Int.add_left_neg]
trivial
Everything compiles as expected but I wanted to make Group G
extend Mul G
so that I can use nice notation
class Group (G: Type u) extends Mul G where
identity: G
mul_assoc: ∀ a b c: G, a * (b * c) = (a * b) * c
mul_identity: ∀ a: G, identity * a = a ∧ a * identity = a
mul_inv: ∀ a: G, ∃ a₁: G, a * a₁ = identity ∧ a₁ * a = identity
But simp_arith
is no longer able to make progress as it is not sure what to do with the multiplies which have now become @HMul.hMul Int Int Int instHMul b c : Int
with@instHMul Int { mul := Int.add } : HMul Int Int Int
. How can I tell the solver that HMul
is actually Int.add
for an integer group on addition?
Yaël Dillies (Mar 14 2025 at 14:11):
You could do
instance : Mul Int where
mul := Int.add
@[simp] lemma mul_eq_add (m n : Int) : m * n = Int.add m n := rfl
instance : Group Int where
identity := 0
mul_assoc := by
intros a b c
simp_arith[]
rw [Int.add_assoc]
mul_identity := by
simp_arith[]
mul_inv := by
intros a
exists -a
simp_arith[]
rw [Int.add_right_neg, Int.add_left_neg]
trivial
Yaël Dillies (Mar 14 2025 at 14:12):
Though you might want to do your experiments on a type other than Int
, which already comes with a (different) Mul
instance
Edmund Lam (Mar 14 2025 at 14:16):
I see, is the specific issue I am having occurring because I am using a type that already has conflicting mul
or would I have to generally do this for any group I define?
Yaël Dillies (Mar 14 2025 at 14:27):
This is something you should be able to figure out for yourself :wink:
Kyle Miller (Mar 14 2025 at 14:30):
Here's a hint for handling the conflict: instead of making a Group Int
instance, make a Group AddInt
instance with
def AddInt := Int
def AddInt.mk (n : Int) : AddInt := n
Edmund Lam (Mar 14 2025 at 14:43):
Even with a new type defined it seems like I still need the lemma, am I totally on the wrong track? I now have
def GInt := Int
def GInt.mk (n: Int) : GInt := n
instance : Mul GInt where
mul := Int.add
@[simp] theorem mul_add (m n: GInt) : m * n = Int.add m n := rfl
instance : Group GInt where
identity := GInt.mk 0
mul_assoc := by
intros a b c
repeat rw [mul_add]
simp[]
rw [Int.add_assoc]
Kevin Buzzard (Mar 14 2025 at 14:46):
For some reason you have to fill in the mul
field still (I am surprised) (but at least you can now fill it in with what you want it to look like...)
def GInt := Int
def GInt.mk (n: Int) : GInt := n
instance : Mul GInt where
mul := Int.add
@[simp] theorem mul_add (m n: GInt) : m * n = Int.add m n := rfl
universe u
class Group (G: Type u) where
identity: G
mul: G -> G -> G
mul_assoc: ∀ a b c: G, mul a (mul b c) = mul (mul a b) c
mul_identity: ∀ a: G, mul identity a = a ∧ mul a identity = a
mul_inv: ∀ a: G, ∃ a₁: G, mul a a₁ = identity ∧ mul a₁ a = identity
instance : Group GInt where
mul := (· * ·)
identity := GInt.mk 0
mul_assoc := by
intros a b c
repeat rw [mul_add]
simp[]
rw [Int.add_assoc]
mul_identity := sorry
mul_inv := sorry
Edmund Lam (Mar 14 2025 at 14:49):
I don't have to anymore because I have Group extends Mul
with
class Group (G: Type u) extends Mul G where
identity: G
mul_assoc: ∀ a b c: G, a * (b * c) = (a * b) * c
mul_identity: ∀ a: G, identity * a = a ∧ a * identity = a
mul_inv: ∀ a: G, ∃ a₁: G, a * a₁ = identity ∧ a₁ * a = identity
which is where all the issues came from regarding needing mul_add
. Still not sure whether that can be gotten rid of...
Edmund Lam (Mar 14 2025 at 14:49):
As an aside, I don't have the lemma
keyword, is this a mathlib specific keyword or something? I can only use theorem
.
Kevin Buzzard (Mar 14 2025 at 14:51):
Lemma: yes this is mathlib-specific because core doesn't like two words for exactly the same thing but mathematicians find it extremely hard to call the thousands of trivialities in mathlib "theorems", so it's cultural more than anything else.
Aaron Liu (Mar 14 2025 at 15:20):
Edmund Lam said:
As an aside, I don't have the
lemma
keyword, is this a mathlib specific keyword or something? I can only usetheorem
.
Yes, it's in file#Tactic/Lemma.
Kevin Buzzard (Mar 14 2025 at 15:29):
Fortunately the principle that the proofs all the lemmas in mathlib should be strictly shorter than the proofs of all the theorems does not seem to be enforced in that file.
Edmund Lam (Mar 14 2025 at 15:32):
Cool, thanks!
Last updated: May 02 2025 at 03:31 UTC