Zulip Chat Archive
Stream: new members
Topic: Basics of class and instance
Luiz Kazuo Takei (Oct 12 2025 at 16:11):
I am trying to understand class and instance and have the following code:
import Mathlib.Data.Real.Basic
import Mathlib.Tactic.Ring
namespace TestClass
class AddComm (α : Type) extends Add α where
add_comm : ∀ (x y : α), x + y = y + x
def Wn (n : ℕ) : Type := Fin n → ℝ
Now I want to show that (Wn n) with the obvious addition is an instance of AddComm and tried this:
instance (n : ℕ) : AddComm (Wn n) where
add u v := fun i ↦ u i + v i
add_comm := by
intro x y
funext i
ring
Lean tells me that the ring tactic failed to close the goal. Could someone tell me why?
Also, and probably related to the question above, when I check the Lean InfoView, I see that it does not convert (x + y) i into x i + y i. Why is that?
Aaron Liu (Oct 12 2025 at 16:12):
typeclass can't see through the definition of Wn
Aaron Liu (Oct 12 2025 at 16:12):
btw this is docs#AddCommMagma
Riccardo Brasca (Oct 12 2025 at 16:13):
Are you importing the fact that the reals are a ring?
Aaron Liu (Oct 12 2025 at 16:14):
yes
Aaron Liu (Oct 12 2025 at 16:14):
Aaron Liu (Oct 12 2025 at 16:15):
well ring needs docs#Real.instCommSemiring
Kenny Lau (Oct 12 2025 at 16:15):
Luiz Kazuo Takei said:
I see that it does not convert
(x + y) iintox i + y i. Why is that?
every time you make a new definition (which includes Wn), you need to include all of the simp lemmas you need to interact with said new object
Riccardo Brasca (Oct 12 2025 at 16:18):
Ah yes, it's difficult to guess the error with a phone and no infowiew :sweat_smile:. The error is that ring cannot see that (x + y) i = x i + y i automatically
Riccardo Brasca (Oct 12 2025 at 16:19):
Those are equal by definition, but still two different objects as far as Lean is concerned
Luiz Kazuo Takei (Oct 13 2025 at 11:19):
Correct me if I am wrong but I think the fact that reals are ring are imported when I say
import Mathlib.Data.Real.Basic
Also, it seems like Lean is having difficulties interpreting (x + y) i. In fact, when I tried this:
instance (n : ℕ) : AddComm (Wn n) where
add u v := fun i ↦ u i + v i
add_comm := by
intro x y
funext i
calc
(x + y) i = x i + y i := by rfl
_ = y i + x i := by apply add_comm
_ = (y + x) i := by rfl
I got an error message in the first line of calc. More specifically, it underlines the (x + y) and says that
failed to synthesize
HAdd (Wn n) (Wn n) ?m.48
Luiz Kazuo Takei (Oct 13 2025 at 11:26):
Ok. I tried the code below and it worked. It seems like if I first declare an instance of Add (only defining addition) and then declare an instance of AddComm (proving it is commutative), then it works.
Why can't I just declare an instance of AddComm (defining addition and proving it is commutative) in one step?
instance (n : ℕ) : Add (Wn n) where
add u v := fun i ↦ u i + v i
instance (n : ℕ) : AddComm (Wn n) where
add_comm := by
intro x y
funext i
calc
(x + y) i = x i + y i := by rfl
_ = y i + x i := by apply add_comm
_ = (y + x) i := by rfl
Riccardo Brasca (Oct 13 2025 at 11:28):
The problem here is that you should define the Add instance before, and then prove that addition is commutative.
import Mathlib.Data.Real.Basic
namespace TestClass
class AddComm (α : Type) extends Add α where
add_comm : ∀ (x y : α), x + y = y + x
def Wn (n : ℕ) : Type := Fin n → ℝ
instance (n : ℕ) : Add (Wn n) where
add u v := fun i ↦ u i + v i
instance (n : ℕ) : AddComm (Wn n) where
add_comm := by
intro x y
funext i
calc
(x + y) i = x i + y i := by rfl
_ = y i + x i := by apply add_comm
_ = (y + x) i := by rfl
end TestClass
Riccardo Brasca (Oct 13 2025 at 11:29):
This is probably an issue with calc, but I am not 100% sure.
Riccardo Brasca (Oct 13 2025 at 11:29):
import Mathlib.Data.Real.Basic
namespace TestClass
class AddComm (α : Type) extends Add α where
add_comm : ∀ (x y : α), x + y = y + x
def Wn (n : ℕ) : Type := Fin n → ℝ
instance (n : ℕ) : AddComm (Wn n) where
add u v := fun i ↦ u i + v i
add_comm := by
intro x y
funext i
show x i + y i = y i + x i
rw [add_comm]
end TestClass
also works.
Riccardo Brasca (Oct 13 2025 at 11:31):
(The issue with calc is, I think, that it cannot use the expected type to find the HAdd instance. We cannot make it smarter for technical reasons)
Luiz Kazuo Takei (Oct 13 2025 at 11:34):
Thanks a lot!
Aaron Liu (Oct 13 2025 at 12:10):
Riccardo Brasca said:
(The issue with
calcis, I think, that it cannot use the expected type to find theHAddinstance. We cannot make it smarter for technical reasons)
No this is actually not it
Aaron Liu (Oct 13 2025 at 12:10):
The issue is not with calc
Aaron Liu (Oct 13 2025 at 12:11):
if you define the addition and commutativity in one go then the addition hadn't finished being defined at the time you're proving commutativity
Aaron Liu (Oct 13 2025 at 12:11):
so it's not available to typeclass
Riccardo Brasca (Oct 13 2025 at 12:42):
Ah OK, I thought it somehow did it, since in the infoview (x + y) i is shown, so something related to Add is found.
Luiz Kazuo Takei (Oct 14 2025 at 10:04):
Thanks for the input @Aaron Liu but I have a question.
I tried this
class MyAdd (α : Type) where
add : α → α → α
infixl:70 " ⋄ " => MyAdd.add
class AddComm (α : Type) extends MyAdd α where
add_comm : ∀ (x y : α), x ⋄ y = y ⋄ x
def Wn (n : ℕ) : Type := Fin n → ℝ
instance (n : ℕ) : AddComm (Wn n) where
add u v := fun i ↦ u i + v i
add_comm := by
intro x y
funext i
ring
And now it works. In the Lean InfoView, it doesn't even show (u + v) i when I try to show add_comm. In fact, it already applies the definition and it shows the goal as
∀ (x y : Wn n), (fun i ↦ x i + y i) = fun i ↦ y i + x i
So, if I use Lean's built-in class Add, it doesn't understand the definition. On the other hand, if I use a custom-made MyAdd class, it does. Why?
Aaron Liu (Oct 14 2025 at 10:05):
That's because when you use Add it goes through HAdd.hAdd
Last updated: Dec 20 2025 at 21:32 UTC