You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: try synthesizing synthetic MVars in mspec (#10644)
This PR explicitly tries to synthesize synthetic MVars in `mspec`. Doing
so resolves a bug triggered by use of the loop invariant lemma for
`Std.PRange`.
public deffindSpec (database : SpecTheorems) (wp : Expr) : MetaM SpecTheorem := do
26
24
let_expr [email protected] _m _ps _instWP _α prog := wp | throwError "target not a wp application {wp}"
27
25
let prog ← instantiateMVarsIfMVarApp prog
28
26
let prog := prog.headBeta
@@ -139,7 +137,7 @@ def dischargeMGoal (goal : MGoal) (goalTag : Name) : n Expr := do
139
137
/--
140
138
Returns the proof and the list of new unassigned MVars.
141
139
-/
142
-
defmSpec (goal : MGoal) (elabSpecAtWP : Expr → n SpecTheorem) (goalTag : Name) : n Expr := do
140
+
public defmSpec (goal : MGoal) (elabSpecAtWP : Expr → n SpecTheorem) (goalTag : Name) : n Expr := do
143
141
-- First instantiate `fun s => ...` in the target via repeated `mintro ∀s`.
144
142
mIntroForallN goal goal.target.consumeMData.getNumHeadLambdas fun goal => do
145
143
-- Elaborate the spec for the wp⟦e⟧ app in the target
@@ -177,11 +175,25 @@ def mSpec (goal : MGoal) (elabSpecAtWP : Expr → n SpecTheorem) (goalTag : Name
177
175
let excessArgs := (args.extract 4 args.size).reverse
178
176
179
177
-- Actually instantiate the specThm using the expected type computed from `wp`.
180
-
let_expr f@Triple m ps instWP α prog P Q := specTy | do liftMetaM (throwError "target not a Triple application {specTy}")
178
+
let_expr f@Triple m ps instWP α prog P Q := specTy
179
+
| liftMetaM <| throwError "target not a Triple application {specTy}"
181
180
let wp' := mkApp5 (mkConst ``WP.wp f.constLevels!) m ps instWP α prog
182
181
unless (← withAssignableSyntheticOpaque <| isDefEq wp wp') do
183
182
Term.throwTypeMismatchError none wp wp' spec
184
183
184
+
-- Try synthesizing synthetic MVars. We don't have the convenience of `TermElabM`, hence
185
+
-- this poor man's version of `TermElabM.synthesizeSyntheticMVars`.
186
+
-- We do so after the def eq call so that instance resolution is likely to succeed.
187
+
-- If it _doesn't_ succeed now, then the spec theorem leaves behind an additional subgoal.
188
+
-- We'll add a trace message if that happens.
189
+
for mvar in mvars do
190
+
let mvar := mvar.mvarId!
191
+
if (← mvar.getKind) matches .synthetic then
192
+
match ← trySynthInstance (← mvar.getType) with
193
+
| .some prf => liftMetaM <| mvar.assign prf
194
+
| .none => continue
195
+
| .undef => liftMetaM <| do trace[Elab.Tactic.Do.spec] "Failed to synthesize synthetic MVar {mvar} from unifying {specTy} against {prog}.\nThis likely leaves behind an additional subgoal."
0 commit comments