lean4-htt/tests/elab/sym_simp_perm1.lean
Leonardo de Moura 9f4db470c4
feat: add permutation theorem support to Sym.simp (#13046)
This PR prevents `Sym.simp` from looping on permutation theorems like
`∀ x y, x + y = y + x`.

- Add `perm : Bool` field to `Theorem`
- Add `isPerm` that checks if LHS and RHS have the same structure with
  pattern variables (de Bruijn indices) rearranged via a consistent
  bijection. Uses `ReaderT` (offset for binder entry), `StateT`
  (forward/backward maps), `ExceptT` (failure).
- Compute `perm` in `mkTheoremFromDecl` / `mkTheoremFromExpr`
- In `Theorem.rewrite`, when `perm` is true, only apply the rewrite if
  the result is strictly less than the input (using `acLt`)
- Tests include the classic AC normalization stress test with
  `add_comm`, `add_assoc`, `add_left_comm`

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 00:22:36 +00:00

37 lines
1 KiB
Text

import Lean
/-! Tests for permutation theorem support in `Sym.simp` -/
-- Nat.add_comm is a permutation theorem: x + y = y + x
-- Without perm support, `simp` with this theorem would loop.
register_sym_simp commSimp where
post := ground >> rewrite [Nat.add_comm]
-- This should terminate: Nat.add_comm is detected as perm,
-- and only applied when result < input.
example (x y : Nat) : x + y = y + x := by
sym =>
simp commSimp
-- Combining perm with non-perm theorems
register_sym_simp commZeroSimp where
post := ground >> rewrite [Nat.add_comm, Nat.zero_add, Nat.add_zero]
example (x y : Nat) : 0 + (x + y) = y + x := by
sym =>
simp commZeroSimp
-- Verify perm doesn't interfere with non-perm theorems
register_sym_simp nonPermSimp where
post := ground >> rewrite [Nat.zero_add]
example (x : Nat) : 0 + x = x := by
sym =>
simp nonPermSimp
register_sym_simp simple where
post := ground
example (x y z w : Nat) : x + y + z + w = w + (z + y) + x := by
sym => simp simple [Nat.add_comm, Nat.add_assoc, Nat.add_left_comm]