Zulip Chat Archive

Stream: mathlib4

Topic: How to get simp to fire?


Michael Stoll (Jun 12 2024 at 20:18):

Can someone explain this?

import Mathlib

lemma foo {n m : } [m.AtLeastTwo] : (OfNat.ofNat (α := ZMod n) m).val = m % n :=
  ZMod.val_natCast m

lemma foo' (n : ) {m : } [m.AtLeastTwo] : (OfNat.ofNat (α := ZMod n) m).val = m % n :=
  ZMod.val_natCast m

lemma foo'' {n : } (m : ) [m.AtLeastTwo] : (OfNat.ofNat (α := ZMod n) m).val = m % n :=
  ZMod.val_natCast m

example {F} [Field F] (x : F) : x ^ ((3 : ZMod 8).val) = x := by
  -- rw [foo] -- OK
  -- rw [foo'] -- OK
  -- rw [foo''] -- OK
  -- simp only [foo] -- no progress
  -- simp only [@foo] -- no progress
  -- simp only [@foo _] -- OK
  -- simp only [(foo)] -- OK
  -- simp only [@foo (m := 3)] -- OK
  -- simp only [foo'] -- no progress
  -- simp only [foo' _] -- OK
  -- simp only [(foo')] -- no progress
  -- simp only [foo''] -- no progress
  -- simp only [foo'' _] -- OK
  -- simp only [(foo'')] -- OK
  sorry

attribute [simp] foo foo' foo''

example {F} [Field F] (x : F) : x ^ ((3 : ZMod 8).val) = x := by
  -- simp -- no progress
  sorry

lemma bar {n : } [NeZero n] {m : } : (OfNat.ofNat (α := Fin n) m).val = m % n := rfl

lemma bar' (n : ) [NeZero n] {m : } : (OfNat.ofNat (α := Fin n) m).val = m % n := rfl

lemma bar'' {n : } [NeZero n] (m : ) : (OfNat.ofNat (α := Fin n) m).val = m % n := rfl

example {F} [Field F] (x : F) : x ^ ((3 : Fin 8).val) = x := by
  -- rw [bar] -- OK
  -- rw [bar'] -- OK
  -- rw [bar''] -- OK
  -- simp only [bar] -- no progress
  -- simp only [@bar] -- no progress
  -- simp only [(bar)] -- no progress
  -- simp only [@bar _] -- no progress
  -- simp only [@bar 8] -- no progress
  -- simp only [@bar _ _ 3] -- OK
  -- simp only [bar'] -- no progress
  -- simp only [(bar')] -- no progress
  -- simp only [bar' _] -- no progress
  -- simp only [bar' 8] -- no progress
  -- simp only [bar''] -- no progress
  -- simp only [bar'' _] -- no progress
  -- simp only [bar'' 3] -- OK
  -- simp only [(bar'')] -- no progress
  sorry

I'd like simp to use a variant of foo (and bar) by itself, i.e., by tagging foo with @[simp] and then just using simp without specifying foo explicitly. This seems to be related to whether simp only [foo] works or not, so the secondary question is how to write foo so that this works.

llllvvuu (Jun 12 2024 at 21:28):

Mathlib-free minimization:

@[simp] theorem bar {n : Nat} (m : Nat) : (OfNat.ofNat (α := Fin n.succ) m).val = m % n.succ := rfl

set_option trace.Meta.Tactic.simp true in
example : ((3 : Fin 8).val) = 3 := by
  -- simp only [bar 3] -- OK
  -- simp only [bar] -- no progress
  sorry

Very interesting. It looks like the lemma is not tried at all

Alex J. Best (Jun 12 2024 at 23:20):

You need no_index for such ofnat lemmas

@[simp] theorem bar {n : Nat} (m : Nat) : (no_index (OfNat.ofNat (α := Fin n.succ) (no_index m))).val = m % n.succ := rfl

llllvvuu (Jun 12 2024 at 23:27):

huh, that's interesting (lean4#2867). Looks like only the first no_index is required

Alex J. Best (Jun 12 2024 at 23:31):

oh yes the second is a typo, i forgot where its meant to go

Michael Stoll (Jun 13 2024 at 15:54):

I think I tried no_index, but I must have put it in the wrong place.


Last updated: May 02 2025 at 03:31 UTC