feat: checkMaxShared (#12083)

This PR adds the debugging helper functions `Expr.checkMaxShared` and
`MVarId.checkMaxShared` to `Sym`, and fixes a bug when visiting
telescopes in `Sym.simp`.
This commit is contained in:
Leonardo de Moura 2026-01-21 06:55:46 -08:00 committed by GitHub
parent b09e33f76b
commit b8f8dde0b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 22 additions and 4 deletions

View file

@ -81,7 +81,7 @@ public def simpForall (e : Expr) : SimpM Result := do
else if (← isProp e) then
let n := getForallTelescopeSize e.bindingBody! 1
forallBoundedTelescope e n fun xs b => withoutModifyingCacheIfNotWellBehaved do
main xs b
main xs (← share b)
else
return .rfl
where
@ -90,7 +90,7 @@ where
| .rfl _ => return .rfl
| .step b' h _ =>
let h ← mkLambdaFVars xs h
let e' ← shareCommonInc (← mkForallFVars xs b')
let e' ← share (← mkForallFVars xs b')
-- **Note**: consider caching the forall-congr theorems
let hcongr ← mkForallCongrFor xs
return .step e' (mkApp3 hcongr (← mkLambdaFVars xs b) (← mkLambdaFVars xs b') h)

View file

@ -48,14 +48,14 @@ def mkFunextFor (xs : Array Expr) (β : Expr) : MetaM Expr := do
public def simpLambda (e : Expr) : SimpM Result := do
lambdaTelescope e fun xs b => withoutModifyingCacheIfNotWellBehaved do
main xs b
main xs (← share b)
where
main (xs : Array Expr) (b : Expr) : SimpM Result := do
match (← simp b) with
| .rfl _ => return .rfl
| .step b' h _ =>
let h ← mkLambdaFVars xs h
let e' ← shareCommonInc (← mkLambdaFVars xs b')
let e' ← share (← mkLambdaFVars xs b')
let funext ← getFunext xs b
return .step e' (mkApp3 funext e e' h)

View file

@ -9,6 +9,7 @@ public import Lean.Meta.Sym.SymM
public import Lean.Meta.Transform
import Init.Grind.Util
import Lean.Meta.WHNF
import Lean.Util.ForEachExpr
namespace Lean.Meta.Sym
/--
@ -91,4 +92,21 @@ public def preprocessMVar (mvarId : MVarId) : SymM MVarId := do
mvarId.assign mvarNew
return mvarNew.mvarId!
/-- Debug helper: throws if any subexpression of `e` is not in the table of maximally shared terms. -/
public def _root_.Lean.Expr.checkMaxShared (e : Expr) (msg := "") : SymM Unit := do
e.forEach fun e => do
if let some prev := (← get).share.set.find? { expr := e } then
unless isSameExpr prev.expr e do
throwNotMaxShared e
else
throwNotMaxShared e
where
throwNotMaxShared (e : Expr) : SymM Unit := do
let msg := if msg == "" then msg else s!"[{msg}] "
throwError "{msg}term is not in the maximally shared table{indentExpr e}"
/-- Debug helper: throws if any subexpression of the goal's target type is not in the table of maximally shared. -/
public def _root_.Lean.MVarId.checkMaxShared (mvarId : MVarId) (msg := "") : SymM Unit := do
(← mvarId.getDecl).type.checkMaxShared msg
end Lean.Meta.Sym