Weakest Preconditions Over the Free Monad #
This file provides the extrinsic verification-condition substrate for FreeM P,
in two coupled layers:
Syntactic wp. An
OpSpec P lassigns each operationa : P.Aa predicate transformer(P.B a → l) → lover an ordered carrierl, saying what one call toaguarantees.FreeM.wpFold Φfolds these per-operation specs over a free tree, leaving the operations uninterpreted. Every monotone spec induces an ordered monad algebraOpSpec.toMAlgOrdered, so the wholeMAlgOrdered.wp/Triplerule set applies;wp_toMAlgOrderedidentifies the inducedwpwithwpFold.Semantic wp.
FreeM.wpVia sis the weakest precondition of the program interpreted through a handlers : Handler m Pinto a monad carrying an ordered algebra. The soundness theoremswpFold_le_wpVia/wpFold_eq_wpViasay that per-operation specs that (under-)approximate the handler's wp give syntactic wps that (under-)approximate the semantic wp — the generic engine behind handler-specification reasoning.
The canonical Prop-carrier specs OpSpec.demonic ("every response") and
OpSpec.angelic ("some response") recover the support-based judgments of
PolyFun.PFunctor.Free.Support: wpFold_demonic_iff_allOutputs and
wpFold_angelic_iff_someOutput identify their folds with AllOutputs and
SomeOutput, so trivial-precondition ("always" / "never") triples and the
syntactic wp theory agree.
Per-operation specifications #
A per-operation predicate-transformer specification for the interface P over
an ordered carrier l: at each position a, transform a postcondition on the
directions of a into a precondition.
Instances For
Monotonicity of a per-operation spec in its continuation.
Instances For
The demonic ("all responses") spec on the Prop carrier: a call to a
guarantees only that every response satisfies the continuation.
Instances For
The demonic specification restricted to admitted responses: a call to a
guarantees that every response satisfying allows a satisfies the continuation.
This specification is intentionally a partial-correctness condition. If no response is admitted at a position, its obligation is vacuous; progress or non-vacuity must be supplied separately by an operational layer.
Instances For
The angelic ("some response") spec on the Prop carrier: a call to a
guarantees that some response satisfies the continuation.
Instances For
The angelic specification restricted to admitted responses: a call can continue
along any response satisfying allows.
Instances For
Syntactic weakest precondition #
Fold a per-operation spec over a free tree: the syntactic weakest
precondition of x for postcondition post, with operations uninterpreted.
Instances For
Weakest preconditions compose through sequencing across result universes.
The rest of the do fragment #
wpFold is a fold, so every combinator do-notation elaborates to reduces to wpFold_bind and
wpFold_pure; the equations below state the results directly so simp need not rediscover
them.
Reachable outputs under an operationalization #
Outputs reachable when each operation may return exactly the responses admitted by
allows. This is the set view of the angelic predicate transformer, not a generic
interpretation of MonadAttach.CanReturn.
Instances For
Structural reachability when every typed response is admitted.
Instances For
The angelic fold is existential quantification over reachable outputs.
Reachability through sequencing with independent result universes.
Mapping leaf values maps the set of outputs reachable under the same responses.
Functor mapping preserves the admitted response policy and maps reachable results.
A path is admitted when every direction on it is admitted at its operation.
Instances For
The terminal path has no response constraints.
An admitted node path takes an admitted response and an admitted continuation path.
Reachability is witnessed by an admitted root-to-leaf path.
Running the powerset handler gives the same reachable outputs.
Full-response reachability agrees with the free tree's attachment predicate.
Admitted-response leaf contracts #
Every leaf reachable by choosing admitted responses satisfies accept.
This is the relation-restricted demonic weakest precondition, not a termination or progress assertion. In particular, a query with no admitted response satisfies every leaf contract vacuously.
Instances For
Weakening the required leaf predicate preserves whole-tree conformance.
Mapping a function changes only the predicate imposed on returned leaves.
Whole-tree result conformance composes through monadic sequencing.
The relation-restricted demonic WP quantifies over the reachable outputs.
Interpreting a finite free program through leaf-conforming free handlers preserves its admitted-response leaf contract.
Unlike the map and bind laws above, the program result type shares the source
interface's direction universe. This is exactly the homogeneous result
constraint of the upstream FreeM.liftM; the target interface's position and
direction universes remain independent.
A free handler whose admitted outputs respect the source response constraint
cannot introduce new reachable results. This is the operational counterpart of
leavesSatisfyUnder_liftM.
Interpreting free operations by free programs cannot create new leaf values.
The induced ordered monad algebra #
Every monotone per-operation spec over a complete lattice induces an ordered
monad algebra on FreeM P, giving the full MAlgOrdered.wp/Triple rule set
for free.
Instances For
The MAlgOrdered.wp induced by a per-operation spec is its syntactic fold.
Semantic weakest precondition through a handler #
The semantic weakest precondition of a free program interpreted through a handler into a monad carrying an ordered algebra.
Instances For
The semantic precondition of a single operation is the handler's precondition.
Soundness of per-operation specs against a handler: specs that lower-bound the handler's wp at every operation give a syntactic wp lower-bounding the semantic wp of the interpreted program.
Exact per-operation specs give the semantic wp exactly.
Coherence with the canonical support #
With every response admitted, the restricted leaf contract is the canonical all-outputs judgment.
The demonic fold is the "always" judgment over the canonical support.
The angelic fold is the "some output" judgment over the canonical support.
The demonic fold of a negated postcondition is the "never" judgment.
Coherence with the interpreted program's support #
The section above relates the syntactic fold to the support of the free tree. This one
closes the other half: it relates the semantic wpVia to the support of the interpreted
program, which is what a handler-specification consumer actually reasons about.
The carrier is Prop, so these live at the ground direction universe: MAlgOrdered m l
forces l : Type uB, and Prop : Type 0.
The semantic keystone. wpVia is by definition the algebra's wp of the
interpreted program, so under the demonic Prop algebra it is the "always" judgment on
that program. One rewrite, but it is the step that turns every statement about wpVia
into a statement about which outputs the interpreted program can actually return.
The angelic companion.
Specs discharge support facts about the interpreted program. Composing the
keystone with wpFold_le_wpVia: a per-operation spec that under-approximates the
handler's wp turns a syntactic fold into a guarantee about every output the handler
can actually produce. This is the shape a handler-specification layer consumes.
The demonic fold at the canonical spec already implies the interpreted guarantee,
whenever the handler validates that spec. Specializes the previous theorem to
OpSpec.demonic: the handler must establish every postcondition that holds for all typed
responses. This constrains its outputs to the operation's response type; it does not claim
that the handler can produce every response.