Zulip Chat Archive
Stream: general
Topic: How to do TacticM's options in MetaM?
Zihao Zhang (Apr 13 2025 at 03:38):
import Mathlib
open Lean Meta Elab Tactic Term
def fun1 (i : TacticInfo) : MetaM Unit:= do
let goalsBefore:=i.goalsBefore
let goalsAfter:=i.goalsAfter
for goal1 in goalsBefore do
for goal2 in goalsAfter do
let goal2_type ← goal2.getType
let p ← mkFreshExprMVar goal2_type MetavarKind.syntheticOpaque `h_100
goal1.withContext do
let (_, goal1New) ← MVarId.intro1P $ ← goal1.assert `h_100 goal2_type p
replaceMainGoal [goal1New]
Like this, the replaceMainGoal [goal1New]
reported an error. It is just an example, so don't just change TacticM into MetaM.
Kyle Miller (Apr 13 2025 at 03:41):
replaceMainGoal
doesn't make sense from within MetaM
. The TacticM
monad contains a list of current goals, and it has all of the TermElabM
state too. The MetaM
monad has neither of these things.
What are you trying to do with fun1
? Likely you don't need replaceMainGoal
.
Zihao Zhang (Apr 13 2025 at 03:42):
So it is impossible?
Zihao Zhang (Apr 13 2025 at 03:53):
@Kyle Miller
import TrainingData.Frontend
import TrainingData.InfoTree.ToJson
import Mathlib.Data.String.Defs
import Mathlib.Lean.CoreM
import Batteries.Data.String.Basic
import Cli
open Lean Elab IO Meta Tactic Term
open Cli System
#check Format
namespace Lean.Elab.TacticInfo
def foo (m : MetaM α) : IO α := CoreM.withImportModules #[`Mathlib] <| m.run'
def verboseTrainingData_1 (module : Name) (i : TacticInfo) (ctx : ContextInfo) : MetaM String := do
let mut result := "===\n"
let sourceUpToTactic := Substring.mk (← moduleSource module) 0 (i.stx.getPos?.getD 0)
let chunks := sourceUpToTactic.splitOn "\n\n"
let goalstate_before:=← i.goalState ctx
--for x in goalstate_before do
-- IO.println ("x:",x)
let goalsBefore:=i.goalsBefore
let goalsAfter:=i.goalsAfter
for goal1 in goalsBefore do
for goal2 in goalsAfter do
let goal2_type ← goal2.getType
let p ← mkFreshExprMVar goal2_type MetavarKind.syntheticOpaque `h_100
goal1.withContext do
let (_, goal1New) ← MVarId.intro1P $ ← goal1.assert `h_100 goal2_type p
replaceMainGoal [goal1New]
--let goalFmt ← Meta.ppGoal goal
--IO.println s!"Goal ID: {goal.name}\nType: {goalType}\nContext:\n{goalFmt}\n"
result := result ++ (Format.joinSep (← i.goalState ctx) "\n").pretty ++ "\n---\n"
result := result ++ (← i.pp ctx).pretty ++ "\n---\n"
result := result ++ (Format.joinSep (← i.goalStateAfter ctx) "\n").pretty ++ "\n"
return result
def verboseTrainingData (module : Name) (i : TacticInfo) (ctx : ContextInfo) : IO String := do
let s ← foo (verboseTrainingData_1 module i ctx)
return s
This is my original code, I just want to do some options of TacticM and MetaM, and return a string to verboseTrainingData
.
Zihao Zhang (Apr 13 2025 at 03:55):
More concisely, I want to make goal2 a hyp of goal1.
Kyle Miller (Apr 13 2025 at 03:57):
Zihao Zhang said:
So it is impossible?
It's not strictly impossible (one can run TacticM from within MetaM and collect a resulting goal list), but it doesn't make sense to use replaceMainGoal
in MetaM
. There's no goal list in MetaM
, and the purpose of replaceMainGoal
is to manipulate the goal list.
I don't see in the code any motivation to manipulate a goal list.
Just to check: are you expecting that the for
loops are manipulating a global state, and that somehow the i.goalsAfter
will be changed? Lean is a functional language, and that's not possible. Instead, you can keep track of the new data you produce yourself.
Zihao Zhang (Apr 13 2025 at 04:00):
So, I can only manipulate the strings to ugly achieve my goal--making the goal2 a hyp of goal1 and print goal1's tactic state?
Kyle Miller (Apr 13 2025 at 04:01):
No, I didn't say that at all. I'm just saying that replaceMainGoal
is likely not part of your solution.
Zihao Zhang (Apr 13 2025 at 04:06):
Without replaceMainGoal
, I think the goal of goal1 with be No goals
,it's not what I want. Like this:
import Mathlib
open Lean Meta Elab Tactic Term
elab "add_goal_to_hyps " : tactic => do
let mvarId ← getMainGoal
let t ← mvarId.getType
let p ← mkFreshExprMVar t MetavarKind.syntheticOpaque `h_1
mvarId.withContext do
let (_, mvarIdNew) ← MVarId.intro1P $ ← mvarId.assert `h_1 t p
--replaceMainGoal [mvarIdNew]
example : 0 + a = a := by
add_goal_to_hyps
Kyle Miller (Apr 13 2025 at 17:40):
Are you looking for something like this?
def fun1 (i : TacticInfo) : MetaM Unit:= do
let goalsBefore:=i.goalsBefore
let goalsAfter:=i.goalsAfter
let mut newGoals := #[]
for goal1 in goalsBefore do
for goal2 in goalsAfter do
let goal2_type ← goal2.getType
let p ← mkFreshExprMVar goal2_type MetavarKind.syntheticOpaque `h_100
let goal1New ← goal1.withContext do
let (_, goal1New) ← MVarId.intro1P $ ← goal1.assert `h_100 goal2_type p
pure goal1New
newGoals := newGoals.push goal1New
-- do something with `newGoals` here
Last updated: May 02 2025 at 03:31 UTC