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