Research-Stack/2-Search-Space/PIST/Trace.lean
Brandon Schneider 5290413080 fix(avm-isa): stabilize AVMIsa + PIST.Trace build; canary #eval fires clean
AVMIsa fixes (all pre-existing errors from the upstream merge):
- Types.lean: add Repr to AvmTy
- Value.lean: replace `deriving Inhabited` with explicit instance (AnyVal
  is a dependent structure; auto-derive can't pick a default ty+val pair);
  add Repr instance that delegates to AvmVal.repr
- Instr.lean: add Repr to Prim and Instr
- State.lean: fix `List.set ⟨i, h⟩` → `List.set i` (List.set takes Nat,
  not Fin); drop now-dead `h` binding; add Repr to State
- Step.lean: rewrite evalPrim branches to pattern-match directly on AnyVal
  `⟨ty, val⟩` pairs instead of `if v.ty = T` + separate val match (Lean
  can't unify `AvmVal v.ty` with `AvmVal T` from a propositional if-guard);
  replace `List.get? pc` (removed in Lean 4.30) with `list[pc]?` subscript;
  rename Q0_16.addSat/subSat → Q0_16.add/sub (no sat variants exist);
  add Repr to StepError and Outcome

PIST.Trace fixes:
- Drop invalid `set_option pp.pretty true`
- MVarId.toNat → MVarId.name.toString
- List.size → List.length (then .toArray for Json.arr)
- Json.num takes JsonNumber {mantissa : Int, exponent : Int}; cast Nat → Int
- goals.mapM goalToJson: lift MetaM → TacticM via liftMetaM

Canary result: `#eval run 8 canaryNot canaryState` →
  Outcome.ok { pc := 2, stack := [AvmVal.b true], halted := true }

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-26 21:39:46 -05:00

68 lines
1.9 KiB
Text

import Lean
open Lean Elab Tactic Meta
/-!
# PIST Trace — goal-state snapshotter for Tier 2 flexure recording.
Provides a tactic `trace_state_json "tag"` that emits structured goal-state
snapshots to `logInfo` with a `@@PIST_TRACE_JSON@@` sentinel that the Python
trace bridge can parse from stdout.
Usage:
```lean
import PIST.Trace
theorem t (n : Nat) : n + 0 = n := by
trace_state_json "step_0_before"
simp
trace_state_json "step_0_after"
```
-/
namespace PIST.Trace
private def natToJson (n : Nat) : Json :=
Json.num { mantissa := (n : Int), exponent := 0 }
private def goalToJson (g : MVarId) : MetaM Json := do
let decl ← g.getDecl
let target ← instantiateMVars decl.type
let targetFmt ← ppExpr target
let mut hyps : Array Json := #[]
for localDecl in decl.lctx do
if !localDecl.isImplementationDetail then
let ty ← instantiateMVars localDecl.type
let tyFmt ← ppExpr ty
hyps := hyps.push <| Json.mkObj [
("name", Json.str localDecl.userName.toString),
("type", Json.str tyFmt.pretty)
]
return Json.mkObj [
("target", Json.str targetFmt.pretty),
("goal_id", Json.str g.name.toString),
("hypotheses", Json.arr hyps),
("hypothesis_count", natToJson hyps.size)
]
/-- Emit a structured goal-state snapshot tagged with `tag`.
The output is prefixed with `@@PIST_TRACE_JSON@@` so the Python bridge
can scrape it from Lean's stdout.
-/
elab "trace_state_json" tag:str : tactic => do
let goals ← getGoals
let goalJsons ← goals.mapM (fun g => liftMetaM (goalToJson g))
let payload : Json := Json.mkObj [
("event", Json.str "pist_trace_state"),
("tag", Json.str tag.getString),
("goal_count", natToJson goals.length),
("goals", Json.arr goalJsons.toArray)
]
logInfo m!"@@PIST_TRACE_JSON@@{payload.compress}"
end PIST.Trace