lean4-htt/tests/lean/run/sym_intro.lean
Leonardo de Moura 175661b6c3
refactor: reorganize SymM and GrindM monad hierarchy (#11909)
This PR reorganizes the monad hierarchy for symbolic computation in
Lean.

## Motivation

We want a clean layering where:
1. A foundational monad (`SymM`) provides maximally shared terms and
structural/syntactic `isDefEq`
2. `GrindM` builds on this foundation, adding E-graphs, congruence
closure, and decision procedures
3. Symbolic execution / VCGen uses `GrindM` directly without introducing
a third monad

## Changes

The core symbolic computation layer still lives in `Lean.Meta.Sym`. This
monad (`SymM`) provides:
- Maximally shared terms with pointer-based equality
- Structural/syntactic `isDefEq` and matching (no reduction, predictable
cost)
- Monotonic local contexts (no `revert` or `clear`), enabling O(1)
metavariable validation
- Efficient `intro`, `apply`, and `simp` implementations

The name "Sym" reflects that this is infrastructure for symbolic
computation: symbolic simulation, verification condition generation, and
decision procedures.

### Updated hierarchy

```
Lean.Meta.Sym   -- SymM: shared terms, syntactic isDefEq, intro, apply, simp
Lean.Meta.Grind -- GrindM: E-graphs, congruence closure (extends SymM)
```

Symbolic execution is a usage pattern of `GrindM` operating on
`Grind.Goal`, not a separate monad. This keeps the API surface minimal:
users learn two monads, and VCGen is "how you use `GrindM`" (for users
that want to use `grind`) rather than a third abstraction to understand.
2026-01-06 01:12:07 +00:00

37 lines
928 B
Text

import Lean
macro "gen_term" n:num : term => do
let mut stx ← `(True)
for _ in 0...n.getNat do
stx := ← `(let z : Nat := x + y; let y := y + 1; have : y >= 0 := Nat.zero_le y; forall x : Nat, $stx)
`(let z : Nat := 0 ; forall x : Nat, forall y : Nat, $stx)
open Lean Meta Sym Elab Tactic
def test (mvarId : MVarId) : MetaM MVarId := do
SymM.run do
let (_, mvarId) ← intros mvarId
return mvarId
/--
trace: z✝² : Nat := 0
x✝² y✝² : Nat
z✝¹ : Nat := x✝² + y✝²
y✝¹ : Nat := y✝² + 1
this✝¹ : y✝¹ ≥ 0 := Nat.zero_le y✝¹
x✝¹ : Nat
z✝ : Nat := x✝¹ + y✝¹
y✝ : Nat := y✝¹ + 1
this✝ : y✝ ≥ 0 := Nat.zero_le y✝
x✝ : Nat
⊢ True
-/
#guard_msgs in
example : gen_term 2 := by
run_tac liftMetaTactic1 fun mvarId => test mvarId
trace_state
constructor
example : gen_term 70 := by
run_tac liftMetaTactic1 fun mvarId => test mvarId
constructor