Skip to content

Commit db2f165

Browse files
authored
perf: instantiate only the entailment sides in mvcgen' solve (#14072)
This PR avoids re-instantiating the whole `solve` target on every iteration of `mvcgen'` VC generation, with no change in behaviour. A rule application only ever leaves a metavariable-application head on the two sides of the entailment (for instance a lattice-split operand), so `solve` instantiates just those sides for its shape tests instead of running `instantiateMVars` over the full target on every step; `elimTopPre` instantiates the precondition it inspects. Stacked on #14071.
1 parent e50f19c commit db2f165

2 files changed

Lines changed: 8 additions & 9 deletions

File tree

src/Lean/Elab/Tactic/Do/Internal/VCGen/Entails.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ where the reduction is sound; entailments at an abstract lattice carrier pass th
9191
public def elimTopPre (goal : MVarId) : VCGenM MVarId := do
9292
let some (.sort .zero, _, pre, _) := (← goal.getType).app4? ``Lean.Order.PartialOrder.rel
9393
| return goal
94-
unless pre.isAppOf ``Lean.Order.top do return goal
94+
unless (← instantiateMVarsIfMVarApp pre).isAppOf ``Lean.Order.top do return goal
9595
let .goals [goal] ← (← read).backwardRules.elimPre.apply goal
9696
| throwError "Failed to strip the `⊤ ⊑` wrapper of {goal}"
9797
return goal

src/Lean/Elab/Tactic/Do/Internal/VCGen/Solve.lean

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -351,16 +351,9 @@ The function performs the following steps in order:
351351
-/
352352
public def solve (scope : VCGen.Scope) (goal : MVarId) : VCGenM SolveResult := goal.withContext do
353353
if ← outOfFuel then return .stop .outOfFuel
354-
let mut goal := goal
355-
let mut target ← goal.getType
354+
let target ← goal.getType
356355
trace[Elab.Tactic.Do.vcgen] "🎯 Target: {target}"
357356

358-
if target.hasExprMVar then
359-
-- Rule application may have assigned metavariables in the target; re-normalise so the
360-
-- syntactic shape tests below see the assigned form.
361-
target ← instantiateMVars target
362-
goal ← goal.replaceTargetDefEq target
363-
364357
-- Phase 1: simplify `target` until it is of the form `pre ⊑ rhs`.
365358
if let some gs ← forallIntro? goal target then return .goals scope gs
366359
if let some g ← targetLetIntro? goal target then return .goals scope [g]
@@ -371,6 +364,12 @@ public def solve (scope : VCGen.Scope) (goal : MVarId) : VCGenM SolveResult := g
371364
let_expr PartialOrder.rel α inst pre rhs := target
372365
| return .stop (.noEntailment target)
373366

367+
-- A previous rule application may have assigned the entailment's sides to fresh metavariables
368+
-- (e.g. a lattice-split operand). Instantiate those heads so the shape tests below see the
369+
-- assigned form.
370+
let pre ← instantiateMVarsIfMVarApp pre
371+
let rhs ← instantiateMVarsIfMVarApp rhs
372+
374373
-- Phase 2: close reflexive goals, then drive `pre` toward `⊤`, lifting any pure content so a
375374
-- later spec application sees a `⊤` precondition.
376375
if let some gs ← rfl? goal then return .goals scope gs

0 commit comments

Comments
 (0)