@@ -5,7 +5,10 @@ Authors: Leonardo de Moura
55-/
66module
77prelude
8+ public import Lean.Elab.Tactic.Grind.Basic
89public import Lean.Meta.Tactic.Grind.Main
10+ import Lean.Meta.Tactic.Grind.Internalize
11+ import Lean.Meta.Tactic.Grind.ForallProp
912import Lean.Elab.Tactic.Grind.Basic
1013import Lean.Elab.Tactic.Grind.Anchor
1114namespace Lean.Elab.Tactic
@@ -81,6 +84,7 @@ def processParam (params : Grind.Params)
8184 (id : TSyntax `ident)
8285 (minIndexable : Bool)
8386 (only : Bool)
87+ (incremental : Bool)
8488 : MetaM Grind.Params := do
8589 let mut params := params
8690 let declName ← try
@@ -106,11 +110,13 @@ def processParam (params : Grind.Params)
106110 | .ematch kind =>
107111 params ← withRef p <| addEMatchTheorem params id declName kind minIndexable
108112 | .cases eager =>
113+ if incremental then throwError "`cases` parameter are not supported here"
109114 ensureNoMinIndexable minIndexable
110115 withRef p <| Grind.validateCasesAttr declName eager
111116 params := { params with casesTypes := params.casesTypes.insert declName eager }
112117 | .intro =>
113118 if let some info ← Grind.isCasesAttrPredicateCandidate? declName false then
119+ if incremental then throwError "`cases` parameter are not supported here"
114120 for ctor in info.ctors do
115121 params ← withRef p <| addEMatchTheorem params id ctor (.default false ) minIndexable
116122 else
@@ -143,14 +149,18 @@ def processAnchor (params : Grind.Params) (val : TSyntax `hexnum) : CoreM Grind.
143149
144150/--
145151Elaborates `grind` parameters.
152+ `incremental = true` for tactics such as `finish`, in this case, we disable some kinds of parameters
153+ such as `- ident`.
146154-/
147155public def elabGrindParams (params : Grind.Params) (ps : TSyntaxArray ``Parser.Tactic.grindParam)
148- (only : Bool) (lax : Bool := false ) : MetaM Grind.Params := do
156+ (only : Bool) (lax : Bool := false ) (incremental := false ) : MetaM Grind.Params := do
149157 let mut params := params
150158 for p in ps do
151159 try
152160 match p with
153161 | `(Parser.Tactic.grindParam| - $id:ident) =>
162+ if incremental then
163+ throwErrorAt p "invalid `-` occurrence, it can only used at the `grind` tactic entry point"
154164 let declName ← realizeGlobalConstNoOverloadWithInfo id
155165 if let some declName ← Grind.isCasesAttrCandidate? declName false then
156166 Grind.ensureNotBuiltinCases declName
@@ -160,9 +170,9 @@ public def elabGrindParams (params : Grind.Params) (ps : TSyntaxArray ``Parser.T
160170 else
161171 params := { params with ematch := (← params.ematch.eraseDecl declName) }
162172 | `(Parser.Tactic.grindParam| $[$mod?:grindMod]? $id:ident) =>
163- params ← processParam params p mod? id (minIndexable := false ) (only := only)
173+ params ← processParam params p mod? id (minIndexable := false ) (only := only) (incremental := incremental)
164174 | `(Parser.Tactic.grindParam| ! $[$mod?:grindMod]? $id:ident) =>
165- params ← processParam params p mod? id (minIndexable := true ) (only := only)
175+ params ← processParam params p mod? id (minIndexable := true ) (only := only) (incremental := incremental)
166176 | `(Parser.Tactic.grindParam| #$anchor:hexnum) =>
167177 unless only do
168178 throwErrorAt anchor "invalid anchor, `only` modifier expected"
@@ -172,4 +182,63 @@ public def elabGrindParams (params : Grind.Params) (ps : TSyntaxArray ``Parser.T
172182 if !lax then throw ex
173183 return params
174184
185+ namespace Grind
186+ open Meta Grind
187+
188+ /--
189+ Returns `true` if we should keep the theorem when `only` is used.
190+ We keep
191+ 1- Local theorems. We use anchors to restrict their instantiation.
192+ 2- `match`-equations. They are always active.
193+ -/
194+ def shouldKeep (thm : EMatchTheorem) : GrindM Bool := do
195+ if let .decl declName := thm.origin then
196+ isMatchEqLikeDeclName declName
197+ else
198+ checkAnchorRefsEMatchTheoremProof thm.proof
199+
200+ /--
201+ Removes all theorems that are not `match`-equations nor local theorems.
202+ -/
203+ def filterThms (thms : PArray EMatchTheorem) : GrindM (PArray EMatchTheorem) := do
204+ let mut result := {}
205+ for thm in thms do
206+ if (← shouldKeep thm) then
207+ result := result.push thm
208+ return result
209+
210+ /--
211+ Helper method for processing parameters in tactics such as `finish` and `finish?`
212+ -/
213+ public def withParams (params : Grind.Params) (ps : TSyntaxArray ``Parser.Tactic.grindParam) (only : Bool)
214+ (k : GrindTacticM α) : GrindTacticM α := do
215+ if !only && ps.isEmpty then
216+ k
217+ else
218+ let mut params := params
219+ if only then
220+ params := { params with anchorRefs? := none }
221+ params ← elabGrindParams params ps (only := only) (incremental := true )
222+ let anchorRefs? := params.anchorRefs?
223+ withReader (fun c => { c with params, ctx.anchorRefs? := anchorRefs? }) do
224+ if only then
225+ -- Cleanup main goal before adding new facts
226+ let goal ← getMainGoal
227+ let goal ← liftGrindM do
228+ pure { goal with
229+ -- **TODO** : cleanup injective theorems
230+ ematch.thmMap := {}
231+ ematch.thms := (← filterThms goal.ematch.thms)
232+ ematch.newThms := (← filterThms goal.ematch.newThms)
233+ }
234+ replaceMainGoal [goal]
235+ liftGoalM do
236+ for thm in params.extra do
237+ activateTheorem thm 0
238+ for thm in params.extraInj do
239+ activateInjectiveTheorem thm 0
240+ -- **TODO** : `cases` parameters
241+ k
242+
243+ end Grind
175244end Lean.Elab.Tactic
0 commit comments