lean4-htt/tests/lean/run/sym_pattern.lean
Leonardo de Moura 4eaaadf1c1
feat: add pattern matching/unification for symbolic simulation (#11813)
This PR introduces a fast pattern matching and unification module for
the symbolic simulation framework (`Sym`). The design prioritizes
performance by using a two-phase approach:

**Phase 1 (Syntactic Matching)**
- Patterns use de Bruijn indices for expression variables and renamed
level params (`_uvar.0`, `_uvar.1`, ...) for universe variables
- Matching is purely structural after reducible definitions are unfolded
during preprocessing
- Universe levels treat `max` and `imax` as uninterpreted functions (no
AC reasoning)
- Binders and term metavariables are deferred to Phase 2

**Phase 2 (Pending Constraints)** [WIP]
- Handles binders (Miller patterns) and metavariable unification
- Converts remaining de Bruijn variables to metavariables
- Falls back to `isDefEq` when necessary

**Key design decisions:**
- Preprocessing unfolds reducible definitions and performs beta/zeta
reduction
- Kernel projections are expected to be folded as projection
applications before matching
- Assignment conflicts are deferred to pending rather than invoking
`isDefEq` inline
- `instantiateRevS` ensures maximal sharing of result expressions

**TODO:**
- Skip instance arguments during matching, synthesize later
- Skip proof arguments (proof irrelevance)
- Implement `processPending` for Phase 2 constraints
2025-12-28 01:44:36 +00:00

29 lines
706 B
Text

import Lean.Meta.Sym
open Lean Meta Sym
opaque p : Nat → Prop
opaque q : Nat → Nat → Prop
def ex := ∃ x : Nat, p x ∧ q x .zero
def test : SymM Unit := do
let p ← mkPatternFromTheorem ``Exists.intro
let e := (← getConstInfo ``ex).value!
let some r ← p.match? e | throwError "failed"
let app := mkAppN (mkConst ``Exists.intro r.us) r.args
logInfo app
for arg in r.args do
if arg.isMVar then
logInfo m!"{arg} : {← inferType arg}"
return ()
/--
info: @Exists.intro Nat (fun x => And (p x) (q x Nat.zero)) ?m.1 ?m.2
---
info: ?m.1 : Nat
---
info: ?m.2 : (fun x => And (p x) (q x Nat.zero)) ?m.1
-/
#guard_msgs in
set_option pp.explicit true in
#eval SymM.run' test