Zulip Chat Archive
Stream: lean4
Topic: simp with custom rule set succeeds unexpectedly
Raghuram (Jun 28 2025 at 12:55):
Is it expected behaviour for the following simp to succeed?
-- File1
import Lean.Meta.Tactic.Simp.Attr
initialize do pure () <*
Lean.Meta.registerSimpAttr `myrule "rule for my purpose"
import File1
-- File 2
def foo : Nat := 1
class CustomClass (α : Type _) where
data : α
theorem foo_def [CustomClass Nat] : foo = 1 := rfl
attribute [myrule 1] foo_def
-- local instance instClassNat : CustomClass Nat where
-- data := 1
-- Succeeds, even without an instance of `CustomClass Nat`
#check_tactic foo ~> 1 by
simp only [myrule]
If I replace the definition of foo with axiom foo : Nat and add axiom bar : foo = 1 and replace the proof of foo_def with bar, then the simp succeeds iff the instance is defined, as I expected.
Robin Arnez (Jun 28 2025 at 18:46):
You don't need a custom ruleset for this:
def foo : Nat := 1
class CustomClass (α : Type _) where
data : α
theorem foo_def [CustomClass Nat] : foo = 1 := rfl
theorem th : foo = 1 := by
simp only [foo_def]
Why is this? simp tracks proofs by rfl separately, so it applies it as an rfl lemma instead of actually using it as a proof term. Because it holds by defeq (as simp knows) it only needs to match the left-hand side and doesn't need to synthesize anything. It still tries to though because you might have something like
def bar : Unit := ()
theorem bar_eq_data [CustomClass Unit] : bar = CustomClass.data := rfl
instance : CustomClass Unit := ⟨()⟩
theorem th2 : bar = () := by
conv => lhs; simp only [bar_eq_data]
Last updated: Dec 20 2025 at 21:32 UTC