@@ -21,25 +21,44 @@ This file defines the tactics that use the backend defined in `Mathlib.Tactic.GR
2121
2222 -/
2323
24- public meta section
24+ meta section
2525
2626namespace Mathlib.Tactic
2727
2828open Lean Meta Elab Parser Tactic
2929
30+ /-- Analogous to `elabRewrite`. -/
31+ def elabGRewrite (mvarId : MVarId) (e : Expr) (stx : Syntax) (forwardImp symm : Bool)
32+ (config : GRewrite.Config) : TacticM GRewriteResult := do
33+ let mvarCounterSaved := (← getMCtx).mvarCounter
34+ let thm ← elabTerm stx none true
35+ if thm.hasSyntheticSorry then
36+ throwAbortTactic
37+ unless ← occursCheck mvarId thm do
38+ throwErrorAt stx
39+ "Occurs check failed: Expression{indentExpr thm}\n contains the goal {Expr.mvar mvarId}"
40+ let r ← mvarId.grewrite e thm (forwardImp := forwardImp) (symm := symm) (config := config)
41+ let mctx ← getMCtx
42+ let mvarIds := r.mvarIds.filter fun mvarId => mvarCounterSaved ≤ (mctx.getDecl mvarId).index
43+ return { r with mvarIds }
44+
45+ /-- Analogous to `finishElabRewrite`. -/
46+ def finishElabGRewrite (r : GRewriteResult) : MetaM GRewriteResult := do
47+ let mvarIds ← r.mvarIds.filterM (not <$> ·.isAssigned)
48+ mvarIds.forM fun newMVarId => newMVarId.withContext do
49+ if ← Meta.isProp (← newMVarId.getType) then
50+ newMVarId.setKind .syntheticOpaque
51+ return { r with mvarIds }
52+
3053/-- Apply the `grewrite` tactic to the current goal. -/
3154def grewriteTarget (stx : Syntax) (symm : Bool) (config : GRewrite.Config) : TacticM Unit := do
3255 let goal ← getMainGoal
33- Term.withSynthesize <| goal.withContext do
34- let e ← elabTerm stx none true
35- if e.hasSyntheticSorry then
36- throwAbortTactic
37- let goal ← getMainGoal
38- let target ← goal.getType
39- let r ← goal.grewrite target e (forwardImp := false ) (symm := symm) (config := config)
40- let mvarNew ← mkFreshExprSyntheticOpaqueMVar r.eNew (← goal.getTag)
41- goal.assign (mkApp r.impProof mvarNew)
42- replaceMainGoal (mvarNew.mvarId! :: r.mvarIds)
56+ let r ← Term.withSynthesize <| goal.withContext do
57+ elabGRewrite goal (← goal.getType) stx (forwardImp := false ) (symm := symm) (config := config)
58+ let r ← finishElabGRewrite r
59+ let mvarNew ← mkFreshExprSyntheticOpaqueMVar r.eNew (← goal.getTag)
60+ goal.assign (r.impProof.app mvarNew)
61+ replaceMainGoal (mvarNew.mvarId! :: r.mvarIds)
4362
4463/-- Apply the `grewrite` tactic to a local hypothesis. -/
4564def grewriteLocalDecl (stx : Syntax) (symm : Bool) (fvarId : FVarId) (config : GRewrite.Config) :
@@ -48,12 +67,9 @@ def grewriteLocalDecl (stx : Syntax) (symm : Bool) (fvarId : FVarId) (config : G
4867 -- See issues https://github.com/leanprover-community/mathlib4/issues/2711 and https://github.com/leanprover-community/mathlib4/issues/2727.
4968 let goal ← getMainGoal
5069 let r ← Term.withSynthesize <| withMainContext do
51- let e ← elabTerm stx none true
52- if e.hasSyntheticSorry then
53- throwAbortTactic
54- let localDecl ← fvarId.getDecl
55- goal.grewrite localDecl.type e (forwardImp := true ) (symm := symm) (config := config)
56- let proof := .app (r.impProof) (.fvar fvarId)
70+ elabGRewrite (← getMainGoal) (← fvarId.getType) stx symm (forwardImp := true ) (config := config)
71+ let r ← finishElabGRewrite r
72+ let proof := r.impProof.app (.fvar fvarId)
5773 let { mvarId, .. } ← goal.replace fvarId proof r.eNew
5874 replaceMainGoal (mvarId :: r.mvarIds)
5975
@@ -95,7 +111,8 @@ interprets `· → ·` as a relation instead of adding the hypothesis as a side
95111 -/
96112syntax (name := grewriteSeq) "grewrite" optConfig rwRuleSeq (location)? : tactic
97113
98- @ [tactic grewriteSeq, inherit_doc grewriteSeq] def evalGRewriteSeq : Tactic := fun stx => do
114+ @ [tactic grewriteSeq, inherit_doc grewriteSeq]
115+ public def evalGRewriteSeq : Tactic := fun stx => do
99116 let cfg ← elabGRewriteConfig stx[1 ]
100117 let loc := expandOptLocation stx[3 ]
101118 withRWRulesSeq stx[0 ] stx[2 ] fun symm term => do
0 commit comments