This PR adds the function `Sym.replaceS`, which is similar to `replace_fn` available in the kernel but assumes the input is maximally shared and ensures the output is also maximally shared. The PR also generalizes the `AlphaShareBuilder` API.
34 lines
1,002 B
Text
34 lines
1,002 B
Text
import Lean.Meta.Sym
|
|
import Lean.Meta.Tactic.Grind.AlphaShareBuilder
|
|
open Lean Meta Grind Sym
|
|
|
|
def checkMaxFVar (e : Expr) (x : Expr) : SymM Unit := do
|
|
let some fvarId ← getMaxFVar? e | unreachable!
|
|
assert! x.fvarId! == fvarId
|
|
|
|
def test1 : MetaM Unit := do
|
|
let nat := mkConst ``Nat
|
|
withLocalDeclD `x nat fun x => do
|
|
let m₁ ← mkFreshExprMVar nat
|
|
withLocalDeclD `y nat fun y => do
|
|
let m₂ ← mkFreshExprMVar nat
|
|
withLocalDeclD `z nat fun z => do
|
|
SymM.run' do
|
|
let x ← shareCommon x
|
|
let y ← shareCommon y
|
|
let z ← shareCommon z
|
|
let m₁ ← shareCommon m₁
|
|
let m₂ ← shareCommon m₂
|
|
let f ← mkConstS `f
|
|
let e₁ ← mkAppS f x
|
|
checkMaxFVar e₁ x
|
|
let e₂ ← mkAppS e₁ m₁
|
|
checkMaxFVar e₂ x
|
|
let e₂ ← mkAppS e₁ m₂
|
|
checkMaxFVar e₂ y
|
|
let e₃ ← mkAppS e₂ (← mkProjS ``Prod 0 (← mkAppS f z))
|
|
checkMaxFVar e₃ z
|
|
let e₄ ← mkAppS f (← shareCommon (mkNatLit 3))
|
|
assert! (← getMaxFVar? e₄).isNone
|
|
|
|
#eval test1
|