Zulip Chat Archive
Stream: lean4
Topic: simplifying typeclass definitions
Chris B (Nov 07 2021 at 18:57):
What is the right way to simplify/rewrite using typeclass definitions? In Fin.val_zero
, I want to simplify (@OfNat.ofNat (Fin (Nat.succ n)) 0 (@Fin.instOfNatFinHAdd n 0))
to the definition of Fin.instOfNatFinHAdd.ofNat
, which is Fin.ofNat 0
. If I go directly with simp only [OfNat.ofNat]
, I get a maximum recursion error.
The intermediate thing h0
is a workaround that makes the simplifier happy; the trace output is h0:1000, @OfNat.ofNat (Fin (Nat.succ n)) 0 (@Fin.instOfNatFinHAdd n 0) ==> @Fin.ofNat n 0
.
import Mathlib.Data.Nat.Basic
import Mathlib.Algebra.Group.Defs
section Fin
variable {n : Nat}
instance : Zero (Fin n.succ) where
zero := Fin.ofNat 0
lemma Fin.val_zero : (0 : Fin n.succ).val = (0 : Nat) := by
have h0 : ∀ x, (OfNat.ofNat x : Fin n.succ) = Fin.ofNat x := by simp [OfNat.ofNat]
simp only [h0, Fin.ofNat, Nat.zero_mod]
Gabriel Ebner (Nov 08 2021 at 09:57):
What is the right way to simplify/rewrite using typeclass definitions?
The usual way is to just state the desired rewrite as a lemma:
lemma ofNat_eq : (OfNat.ofNat x : Fin (n+1)) = Fin.ofNat x := rfl
In a similar vein, you can restate lemmas in terms of the canonical representation (i.e., OfNat.ofNat instead of Fin.ofNat):
lemma ofNat_val : (OfNat.ofNat x : Fin (n+1)).val = x % (n+1) := rfl
Chris B (Nov 08 2021 at 21:16):
@Gabriel Ebner Thanks, that makes sense. I got used to the convenience of being able to write simp [<def>]
for definitions and thought classes might have similar behavior without writing explicit lemmas.
Chris B (Nov 12 2021 at 21:57):
In working with USize more today, the solution of extracting things into lemmas does not work well in some cases. For this: lemma val_zero : (0 : USize).val = (0 : Fin size)
, where the instance of Zero is defined as instance : Zero (Fin size) := (Nat.succ_pred_eq_of_pos size_positive) ▸ inferInstance
, things are really obscured by the fact that size
isn't reducible and isn't defined in terms of succ
.
Without being able to just reduce what's already in the context of the theorem, it seems like I have set pp.all to true, then extract something about Zero (Fin size)
, which actually requires Zero (Fin size.pred.succ)
, and now I need another lemma to relate the two.
Chris B (Nov 12 2021 at 21:58):
Also where does the recursion depth error for simp only [OfNat.ofNat]
come from?
Last updated: Dec 20 2023 at 11:08 UTC