lean4-htt/tests/lean/run/sym_pattern.lean
Leonardo de Moura 2bca310bea
feat: efficient pattern matching and unification for the symbolic simulation framework (#11825)
This PR completes the new pattern matching and unification procedures
for the symbolic simulation framework using a two-phase approach.

**Phase 1 (Syntactic Matching):**
- Patterns use de Bruijn indices for expression variables and renamed
level params for universe variables
- Purely structural matching after reducible definitions are unfolded
- Universe levels treat `max`/`imax` as uninterpreted functions
- Proof arguments skipped via proof irrelevance
- Instance and binder constraints deferred to Phase 2

**Phase 2 (Pending Constraints):**
- Level constraints: structural equality with mvar assignment
- Instance constraints: `isDefEqI` (full `isDefEq` for TC synthesis)
- Expression constraints: `isDefEqS` with Miller pattern support
- Unassigned instance pattern variables synthesized via
`trySynthInstance`

**`isDefEqS` (Structural DefEq):**
- Miller pattern detection and assignment (`?m x y z := rhs` → `?m :=
fun x y z => rhs`)
- Scope checking via `maxFVar` to prevent out-of-scope assignments
- Optional zeta-delta reduction for let-declarations
- Proof irrelevance and instance delegation to `isDefEqI`

**Key optimizations:**
- `abstractFVars` skips metavariables and uses `maxFVar` for early
cutoff
- Per-pattern `ProofInstInfo` cache for fast argument classification
- Maximal sharing.
2025-12-29 05:18:16 +00:00

30 lines
1 KiB
Text

import Lean.Meta.Sym
open Lean Meta Sym Grind
set_option grind.debug true
opaque p : Nat → Prop
opaque q : Nat → Nat → Prop
def ex := ∃ x : Nat, p x ∧ x = .zero
def test : SymM Unit := do
let pEx ← mkPatternFromTheorem ``Exists.intro
let pAnd ← mkPatternFromTheorem ``And.intro
let pEq ← mkPatternFromTheorem ``Eq.refl
let e ← shareCommon (← getConstInfo ``ex).value!
let some r₁ ← pEx.match? e | throwError "failed"
logInfo <| mkAppN (mkConst ``Exists.intro r₁.us) r₁.args
let some r₂ ← pAnd.match? (← inferType r₁.args[3]!) | throwError "failed"
logInfo <| mkAppN (mkConst ``And.intro r₂.us) r₂.args
let some r₃ ← pEq.unify? (← inferType r₂.args[3]!) | throwError "failed"
logInfo <| mkAppN (mkConst ``Eq.refl r₃.us) r₃.args
/--
info: @Exists.intro Nat (fun x => And (p x) (@Eq Nat x Nat.zero)) ?m.1 ?m.2
---
info: @And.intro (p ?m.1) (@Eq Nat ?m.1 Nat.zero) ?m.3 ?m.4
---
info: @Eq.refl Nat Nat.zero
-/
#guard_msgs in
set_option pp.explicit true in
#eval SymM.run' test