@@ -12,6 +12,7 @@ import Mathlib.Tactic.Cache
12
12
import Mathlib.Lean.Meta
13
13
import Mathlib.Tactic.TryThis
14
14
import Mathlib.Control.Basic
15
+ import Mathlib.Tactic.SolveByElim
15
16
16
17
/-!
17
18
# The `rewrites` tactic.
@@ -30,6 +31,20 @@ We could try discharging side goals via `assumption` or `solve_by_elim`.
30
31
31
32
set_option autoImplicit true
32
33
34
+ namespace Lean.Meta
35
+
36
+ /-- Extract the lemma, with arguments, that was used to produce a `RewriteResult`. -/
37
+ -- This assumes that `r.eqProof` was constructed as:
38
+ -- `mkAppN (mkConst ``Eq.ndrec [u1, u2]) #[α, a, motive, h₁, b, h₂]`
39
+ -- and we want `h₂`.
40
+ def RewriteResult.by? (r : RewriteResult) : Option Expr :=
41
+ if r.eqProof.isAppOfArity ``Eq.ndrec 6 then
42
+ r.eqProof.getArg! 5
43
+ else
44
+ none
45
+
46
+ end Lean.Meta
47
+
33
48
namespace Mathlib.Tactic.Rewrites
34
49
35
50
open Lean Meta Std.Tactic.TryThis
@@ -157,6 +172,15 @@ def RewriteResult.computeRfl (r : RewriteResult) : MetaM RewriteResult := do
157
172
catch _ =>
158
173
pure { r with rfl? := some false }
159
174
175
+ /-- Shortcut for calling `solveByElim`. -/
176
+ def solveByElim (goals : List MVarId) (depth : Nat := 6 ) : MetaM PUnit := do
177
+ -- There is only a marginal decrease in performance for using the `symm` option for `solveByElim`.
178
+ -- (measured via `lake build && time lake env lean test/librarySearch.lean`).
179
+ let cfg : SolveByElim.Config :=
180
+ { maxDepth := depth, exfalso := false , symm := true }
181
+ let [] ← SolveByElim.solveByElim.processSyntax cfg false false [] [] #[] goals
182
+ | failure
183
+
160
184
/--
161
185
Find lemmas which can rewrite the goal.
162
186
@@ -206,12 +230,19 @@ def rewritesCore (hyps : Array (Expr × Bool × Nat))
206
230
trace[Tactic.rewrites] m!"considering {if symm then " ←" else ""}{expr}"
207
231
let some result ← try ? do goal.rewrite target expr symm
208
232
| return none
209
- return if result.mvarIds.isEmpty then
210
- some ⟨expr, symm, weight, result, none, ← getMCtx⟩
233
+ if result.mvarIds.isEmpty then
234
+ return some ⟨expr, symm, weight, result, none, ← getMCtx⟩
211
235
else
212
- -- TODO Perhaps allow new goals? Try closing them with solveByElim?
213
- -- A challenge is knowing what suggestions to print if we do so!
214
- none
236
+ -- There are side conditions, which we try to discharge using local hypotheses.
237
+ let some _ ← try ? do solveByElim result.mvarIds | return none
238
+ -- If we succeed, we need to reconstruct the expression to report that we rewrote by.
239
+ let some expr := result.by? | return none
240
+ let expr ← instantiateMVars expr
241
+ let (expr, symm) := if expr.isAppOfArity ``Eq.symm 4 then
242
+ (expr.getArg! 3 , true )
243
+ else
244
+ (expr, false )
245
+ return some ⟨expr, symm, weight, result, none, ← getMCtx⟩
215
246
216
247
/-- Find lemmas which can rewrite the goal. -/
217
248
def rewrites (hyps : Array (Expr × Bool × Nat))
0 commit comments