Zulip Chat Archive
Stream: lean4
Topic: Traversing the goal and local context
Jason Rute (Nov 25 2023 at 14:08):
I'm interested in traversing the goal (for the purpose of machine learning), including all the goal expressions and their local context expressions (at the level of Expr
). I am very familiar with how to do this in Lean 3, but I'd like to know how to get started in Lean 4. Is there a good resource or example? Maybe the metaprogramming book? Or is the interface very similar to Lean 3, in which case I just need to map from my old code to the new API. Also, ideally, I'd like to take advantage of pointer-based optimizations, which I think Lean 4 has, to avoid traversing the same subexpression (if it uses the same pointer).
Jason Rute (Nov 25 2023 at 14:12):
To be more clear, I want to work in MetaM
and write code to extract information from the current goal.
Jason Rute (Nov 25 2023 at 14:32):
Here is some old code I once used to gather this sort of data in Lean 3 (and serialize it to JSON).
Jason Rute (Nov 25 2023 at 14:32):
Maybe to make it more concrete:
- How do I use
MetaM
to access the list of current goals (wastactic.get_goals
in Lean 3)? - For each goal, how do I access their expressions and their local contexts?
- Are there any data structures I should be aware of to accurately capture the goal state?
- How do I traverse these structures with pointer optimization?
Shreyas Srinivas (Nov 25 2023 at 14:36):
see the examples in hitchhikers guide 2023 version
Jason Rute (Nov 25 2023 at 14:36):
Oh, actually the Tactics FAQ in the metaprogramming book seems to have exactly the answers to at least questions (1) and (2). Nice!
Jason Rute (Nov 25 2023 at 14:48):
Ok, those two books seem like a good start! I can't find stuff about pointer-based optimization in either, but that is probably premature optimization anyway.
Kyle Miller (Nov 25 2023 at 17:33):
Something you might be interested in is being able to completely extract the main goal's state as a single expression (including eliminating metavariables as additional function arguments).
import Lean
open Lean Meta
def captureGoal (g : MVarId) : MetaM Expr := g.withContext do
let fvars ← (← g.getDecl).lctx.getFVars.filterM fun fvar => do
return !(← fvar.fvarId!.getDecl).isImplementationDetail
let ty ← mkForallFVars fvars (← g.getType)
let res ← abstractMVars ty
let ty := res.expr
if true then
logInfo m!"Universe level metavariables: {res.paramNames}\n{
""}Number of abstracted metavariables: {res.numMVars}\n{
""}Captured goal:{indentD ty}"
return ty
elab "goal" : tactic => do
let g ← Elab.Tactic.getMainGoal
discard <| captureGoal g
example {α : Type _} (x y : Nat) (h : x = y) : let z := x + y; z = y + x := by
intro z
/-
α : Type ?u.4868
x y : Nat
h : x = y
z : Nat := x + y
⊢ z = y + x
-/
goal
/-
Universe level metavariables: [_abstMVar.0]
Number of abstracted metavariables: 0
Captured goal:
∀ {α : Type _abstMVar.0} (x y : Nat),
x = y →
let z := x + y;
z = y + x
-/
Kyle Miller (Nov 25 2023 at 17:37):
Here's an example of a complicated metavariable situation that it can handle, so you don't have to wade through all the MetaM state yourself.
example {α : Type _} : True := by
have : (x : α) → ?_ := ?_
/-
α : Type ?u.4954
this : (x : α) → ?m.4966 x
⊢ True
-/
set_option pp.funBinderTypes true in goal
/-
Universe level metavariables: [_abstMVar.0, _abstMVar.1]
Number of abstracted metavariables: 1
Captured goal:
fun (x_0 : {α : Type _abstMVar.0} → α → Sort _abstMVar.1) ↦
∀ {α : Type _abstMVar.0}, ((x : α) → x_0 x) → True
-/
Kyle Miller (Nov 25 2023 at 17:46):
Re traversing with optimizations, many core operations use a cache, and the Expr equality operation tries pointer equality first I believe (equality checking even uses a cache).
Last updated: Dec 20 2023 at 11:08 UTC