Zulip Chat Archive
Stream: mathlib4
Topic: How is `IsCancelAdd (Fin n)` implemented?
Hanting Zhang (Dec 09 2024 at 02:00):
The core theorem seems to be defined here:
/-- Note this is more general than `Fin.addCommGroup` as it applies (vacuously) to `Fin 0` too. -/
instance instIsCancelAdd (n : ℕ) : IsCancelAdd (Fin n) where
add_left_cancel := Nat.casesOn n finZeroElim fun _i _ _ _ ↦ add_left_cancel
add_right_cancel := Nat.casesOn n finZeroElim fun _i _ _ _ ↦ add_right_cancel
But I'm failing to understand how the proof is even correct. How does the final add_{left|right}_cancel
at the end complete the proof?
I tried my own implementation of MyFin
to try and step through each part, like this:
structure MyFin (n : Nat) where
mk ::
val : Nat
isLt : LT.lt val n
theorem myMlt {n b : Nat} : {a : Nat} → a < n → b % n < n
| 0, h => Nat.mod_lt _ h
| _+1, h =>
have : n > 0 := Nat.lt_trans (Nat.zero_lt_succ _) h;
Nat.mod_lt _ this
def elim0.{v} {α : Sort v} : MyFin 0 → α
| ⟨_, h⟩ => absurd h (Nat.not_lt_zero _)
/-- Addition modulo `n` -/
def myFinAdd {n : Nat} : MyFin n → MyFin n → MyFin n
| ⟨a, h⟩, ⟨b, _⟩ => ⟨(a + b) % n, myMlt h⟩
instance {n : Nat} : Add (MyFin n) where
add := myFinAdd
/-- Elimination principle for the empty set `Fin 0`, dependent version. -/
def myFinZeroElim {α : MyFin 0 → Sort*} (x : MyFin 0) : α x :=
elim0 x
-- set_option diagnostics true
/-- Note this is more general than `Fin.addCommGroup` as it applies (vacuously) to `Fin 0` too. -/
instance instIsCancelAdd (n : Nat) : IsCancelAdd (MyFin n) where
add_left_cancel := Nat.casesOn n finZeroElim fun _i _ _ _ ↦ add_left_cancel
add_right_cancel := Nat.casesOn n finZeroElim fun _i _ _ _ ↦ add_right_cancel
but then I get:
failed to synthesize
IsLeftCancelAdd (MyFin _i.succ)
Additional diagnostic information may be available using the `set_option diagnostics true` command.Lean 4
So clearly there's something happening in the native Fin
implementation that I'm missing and/or don't understand.
I have two main questions:
- What is missing from my dummy example that would make it work?
- How does the native implementation work? (Possibly very related to (1).)
Thank you!
Eric Wieser (Dec 09 2024 at 02:11):
- You implement
AddCommGroup (Fin n.succ)
first - It implements
AddCommGroup (Fin n.succ)
first
Last updated: May 02 2025 at 03:31 UTC