Strongest Postcondition Tactics #
This file provides tactics for strongest postcondition reasoning in pRHL,
analogous to EasyCrypt's sp tactic.
Main tactics #
ssprove_sp- process deterministic prefix forwards, computing the SPssprove_sp_step- process one SP step from the head
What EasyCrypt does #
EasyCrypt's sp processes the deterministic prefix of programs forwards,
updating the precondition to reflect the operations consumed. It is the
forward dual of wp.
How it maps to SPComp #
In our monadic setting, prefix consumption means decomposing
set l v >>= k or get l >>= k at the HEAD of the program using
rHoare_bind + sync rules. The precondition gets updated.
| SPComp head | SP transformation |
|---|---|
pure v >>= k | Substitute v, precondition unchanged |
set l v >>= k | Consume set, precondition updated with heap set |
get l >>= k | Consume get, precondition gains knowledge of heap value |
sample, fail | Stop — non-deterministic |
References #
- EasyCrypt: ecSp tactic
SP Rules: Consuming Head Operations into Precondition #
SP for pure a >>= k at the head of both programs.
Both programs start with pure a >>= k₁ and pure b >>= k₂.
Since pure a >>= k = k a, we reduce to k₁ a and k₂ b
with the same precondition (possibly strengthened).
SP for set l v >>= k at the head of both programs.
Both programs start with set l v >>= k. After consuming the set,
the precondition is updated: instead of requiring Φ h₁ h₂, we
require Φ (h₁.set l v) (h₂.set l v).
SP for get l >>= k at the head of both programs.
Both programs start with get l >>= k. After consuming the get,
we universally quantify over the value read and add the knowledge
that the heap value equals the read value.
Requires that the precondition implies both heaps agree at l.
SP Tactics #
ssprove_sp_step processes one deterministic operation at the head
of both programs, updating the precondition.
It tries (in order):
pure >>= k— substitute the valueset l v >>= k— consume the set, update preconditionget l >>= k— consume the get, add value knowledge- One-sided put (left or right)
- One-sided get (left or right)
Equations
- CatCrypt.Tactics.tacticSsprove_sp_step = Lean.ParserDescr.node `CatCrypt.Tactics.tacticSsprove_sp_step 1024 (Lean.ParserDescr.nonReservedSymbol "ssprove_sp_step" false)
Instances For
ssprove_sp processes the deterministic prefix of both programs
forwards, computing the strongest postcondition.
It normalizes code first, then repeatedly peels off deterministic
head operations (pure, set, get) from both sides, updating
the precondition.
The tactic stops at sample, fail, or any non-deterministic operation.
Example:
-- Before ssprove_sp:
-- rHoare Φ (do SPComp.set l v; sample Bool) (do SPComp.set l v; sample Bool) Ψ
-- After ssprove_sp:
-- rHoare (fun h₁ h₂ => Φ (h₁.set l v) (h₂.set l v)) (sample Bool) (sample Bool) Ψ
Equations
- CatCrypt.Tactics.tacticSsprove_sp = Lean.ParserDescr.node `CatCrypt.Tactics.tacticSsprove_sp 1024 (Lean.ParserDescr.nonReservedSymbol "ssprove_sp" false)