Frame inference procedure protocol #
This note describes the protocol between vcgen's solver and a frame inference procedure, and the
metadata that is passed around.
The job of the frame inference procedure is to decide whether to frame the goal, and if so, how to
frame it, by assigning metavariables ?frame and ?footprint and producing the proofs supporting
that split.
?frame is the part of P that prog preserves. ?footprint is the part of P that fits the
spec's precondition. W is the weakest footprint the rule leaves.
goal : P ⊑ wp prog Q E s⃗
│ frame rule, introducing ?frame
▼
split VC : P ⊑ (op ?frame W) s⃗ side goal: Frames op prog ?frame
where W = wp prog (fun a => adj (op ?frame) (Q a)) E
│ spec rule, at a target the frameproc named
▼
spec target : ?footprint ⊑ W t⃗
where
pre VC : ?footprint ⊑ specP
post VCs : ...
Protocol #
- Solver. Look up the candidate specs for
progand take the highest priority one. A spec with a conjunctive precondition applies directly: no frameproc runs. Otherwise, look up the frameproc for the program type. The goal, the selected spec, and the matchedframesclause, if any, go to the frameproc. - Frameproc, phase one. Answer
decline, or answercommitand namet⃗, the state the spec runs at. The length oft⃗picks the rule. - Solver. On
decline, apply the spec to the goal and hand back its subgoals. - Solver. On
commit, apply the frame rule to a copy of the goal. This yields?frame,W, the split VC and the side goal. - Solver. Apply the spec at
?footprint ⊑ W t⃗. On failure, drop the copy and try the next candidate. - Solver. Pass
?frame,?footprint,W,specP, the pre VC and the proof of the spec target to the frameproc. - Frameproc, phase two. Choose
?frame. Sometimes onlyspecPsays which. - Frameproc. Prove the split VC, composing the spec target's proof under
op. It can leave?frameopen, but never the split VC. - Frameproc. Discharge the pre VC when its own work proved it. Otherwise the solver forwards it.
- Solver. Assign the goal from the copy and return the remaining goals.
Requirements #
- The separation logic frameproc must assign the logical variables of
specP. It matches?l ↦ ?vagainst the goal precondition, and that match fixes?land?v. - The assignment of e.g.,
?land?vrequires domain knowledge and cannot easily be reconstructed by e.g.,rfl. Thus, the assignment produced by the frameproc must persist. t⃗cannot depend onspecP. Only the solver producesspecP, and it needs the length oft⃗first.- A frameproc that declines must be as fast as if there were no frameproc mechanism at all.
- When the spec rule fails, the solver tries the next candidate. Backtracking after failure must be fast.
- Emitted VCs are born with as few assigned metavariables as possible, so that sharing is kept.
- The frameproc always discharges the split VC, so the spec target's proof is always used, and every emitted VC is a hole of the final proof. The meet frameproc proves its split VC with shared code that supports excess state arguments.
- A pinned frame is consumed by the framing that lands, never by an attempt. A candidate that
falls through must leave the
framesclause for the next candidate.
What a frameproc sees in phase one, in the order of the goal pre ⊑ wp prog Q E s⃗.
- pre : Expr
The goal's precondition
P. - le : Expr
The goal's entailment relation, with carrier and order instance applied. Apply it to two operands to state an entailment.
- unframedApp : WPApp
The goal's
wpapplication. ItsexcessArgsare the state argumentss⃗. The frame a
framesclause pinned at this call site, if any.The name of the spec being applied, if it has one. Useful to key a footprint off.
- mkOpApp : Meta.Sym.SymM Expr
Builds the frame operator
op : R → Pred → Pred, hash-consed.
Instances For
What the solver hands to phase two: the goal after framing, with the spec applied at the
footprint target ?footprint ⊑ W t⃗.
- frame : MVarId
The schematic frame
?frame. Assign it, or leave it open and it becomes a goal. - footprint : MVarId
The open footprint
?footprint. Assign it to the part ofprethat pays the spec. - framedApp : WPApp
- specPre : Expr
The spec's precondition, with the spec's logical variables live: assignments made while matching against it persist.
- preVC : MVarId
The VC
?footprint ⊑ specPre. Discharge it when your own work proves it. Otherwise it becomes a goal. - specProof : Expr
The proof of the footprint target
?footprint ⊑ W t⃗. - splitLatticeOp? : MVarId → Meta.Grind.GrindM (Option (List MVarId))
Decompose an entailment goal
x ⊑ (op …) s⃗through the lattice split registered for the operator head.nonewhen no split is registered or the rule does not apply.
Instances For
What phase two returns: a proof of the split VC pre ⊑ (op ?frame W) s⃗, and the goals the
frameproc itself created. Goals of the frame rule and of the spec need no forwarding.
- splitVCProof : Expr
The split VC proof. Compose
FrameGoal.specProofunder the frame operator. The goals the frameproc created, for example a guard it could not discharge.
Instances For
Phase one's answer. decline leaves the spec to apply without any frame. commit names t⃗,
the state the spec runs at, and continues in phase two once the solver applied the frame rule and
the spec; see FrameGoal. There is no way back after commit: when nothing needs framing, frame
the unit of the operator instead.
- decline : FrameDecision
- commit (excessStates : Array Expr) (k : FrameGoal → Meta.Grind.GrindM FrameSplit) : FrameDecision
Instances For
A frame inference procedure. Phase one sees the goal through FrameInferenceInfo and answers
a FrameDecision. The spec's precondition is only visible in phase two, after commit.
Equations
Instances For
A frame backward rule together with the positions of the schematic frame and the split VC in the applied rule's goal list, fixed at rule construction.
- rule : Meta.Sym.BackwardRule
- splitVCIdx : Nat
- frameIdx : Nat
Position of the schematic frame (of type
R).
Instances For
A frame inference procedure registered with @[frameproc], together with its frame operator.
vcgen selects the one whose prog matches the goal program's monad.
- prog : Name
Head constant of the program type (the monad) this procedure frames.
- opHead : Name
Head constant of the frame operator, locating the split VC in the frame rule.
Builds the frame operator (head constant
opHead) applied to the goal's assertion type.The resource type
Rof the operatorop : R → Pred → Pred.- proc : FrameInferenceProc
The frame inference metaprogram.
Instances For
The registered frame inference procedures, indexed by the program monad's head constant.
- byProg : Std.HashMap Name FrameProc
Instances For
Instances For
Commit to frame, take the whole precondition as the footprint, and discharge the split VC
with FrameGoal.splitLatticeOp?. Fits any frameproc whose operator has a registered lattice split,
for example the default meet frame.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Default frame inference procedure: frame the resource a frames clause pinned, and decline
otherwise.
Equations
- One or more equations did not get rendered due to their size.