Relational monad algebras #
This file introduces a two-monad relational analogue of MAlgOrdered:
MAlgRelOrdered m₁ m₂ lwith a relational weakest-precondition operatorrwp.- Generic relational triple rules (
pure,consequence,bind,map). - Asynchronous (one-sided) bind rules
relWP_bind_left_le/relWP_bind_right_leand theirTripleforms, recovering Maillard et al.'s asynchronous shapes. - Structural pure rules for
if,dite,Option.elim,Sum.elim. - Side-lifting instances for heterogeneous stacks (
StateT,OptionT,ExceptT). StrictBindsubclass capturing strict relational effect observations (in the sense of Maillard et al.) together withStateTlifts that preserve it.
The framework is the predicate-transformer specialization of Maillard et al.'s
simple framework (POPL 2020, §2): the relational specification monad is fixed
to (α → β → l) → l and the relational effect observation is inlined as the
rwp field. Coupling-based OracleComp instances live downstream in
VCVio/ProgramLogic/Relational/Basic.lean and
VCVio/ProgramLogic/Relational/Quantitative.lean.
Attribution:
- Loom repository: https://github.com/verse-lab/loom
- POPL 2026 paper: Foundational Multi-Modal Program Verifiers, Vladimir Gladshtein, George Pîrlea, Qiyuan Zhao, Vitaly Kurin, Ilya Sergey. DOI: https://doi.org/10.1145/3776719
- POPL 2020 paper: The Next 700 Relational Program Logics, Kenji Maillard, Cătălin Hriţcu, Exequiel Rivas, Antoine Van Muylder. DOI: https://doi.org/10.1145/3371072
Ordered relational monad algebra between two monads.
- rwp {α β : Type u} : m₁ α → m₂ β → (α → β → l) → l
Relational weakest precondition.
Pure rule for the relational weakest precondition.
- rwp_mono {α β : Type u} {x : m₁ α} {y : m₂ β} {post post' : α → β → l} (hpost : ∀ (a : α) (b : β), post a b ≤ post' a b) : rwp x y post ≤ rwp x y post'
Monotonicity in the relational postcondition.
- rwp_bind_le {α β γ δ : Type u} (x : m₁ α) (y : m₂ β) (f : α → m₁ γ) (g : β → m₂ δ) (post : γ → δ → l) : (rwp x y fun (a : α) (b : β) => rwp (f a) (g b) post) ≤ rwp (x >>= f) (y >>= g) post
Sequential composition rule for relational WPs.
Instances
Relational weakest precondition induced by MAlgRelOrdered.
Instances For
Mapping on the left program is monotone for relational WP.
Mapping on the right program is monotone for relational WP.
Triple form of relWP_map_left.
Triple form of relWP_map_right.
Asynchronous (one-sided) bind rules #
These are the relational counterparts of SSProve's apply_left /
apply_right (theories/Relational/GenericRulesSimple.v) and Maillard
et al.'s asynchronous bind shapes (Eqs. 5–6 of The Next 700 Relational
Program Logics). They let one side bind without forcing the other side
to bind in lockstep, by absorbing the inactive side as a pure. Both are
direct consequences of relWP_bind_le and lawful right-unit.
Asynchronous bind on the left: the right side performs no bind step.
Asynchronous bind on the right: the left side performs no bind step.
Triple form of relWP_bind_left_le: chain a left-side bind against
a right-side that stays inert.
Triple form of relWP_bind_right_le: chain a right-side bind against
a left-side that stays inert.
Structural pure rules #
Generic case-split rules that let vcgen/rvcgen-style proofs peel
boolean, decidable-propositional, dependent-if, Option, and Sum
case splits without unfolding rwp. These are the relational analogues
of SSProve's if_rule / nat_rect_rule
(theories/Relational/GenericRulesSimple.v) and Maillard et al.'s R1
rules. The nat_rect analogue is intentionally omitted: Lean's
induction n is the idiomatic substitute.
Boolean if-then-else with the same scrutinee on both sides.
Decidable propositional if-then-else with the same scrutinee on both sides.
Dependent if-then-else with the same scrutinee on both sides.
Option.elim with the same scrutinee on both sides.
Sum.elim with the same scrutinee on both sides.
Left StateT lift for heterogeneous relational algebras.
Right StateT lift for heterogeneous relational algebras.
Two-sided StateT instance: both sides carry their own state.
The postcondition takes both output values and both final states.
Right OptionT lift (interpreting none as ⊥).
Left OptionT lift (interpreting none as ⊥).
Right ExceptT lift (interpreting exceptions as ⊥).
Left ExceptT lift (interpreting exceptions as ⊥).
Strict bind subclass #
Maillard et al.'s "simple framework" distinguishes lax relational
effect observations (the bind law is an inequality) from strict ones
(the bind law is an equality). The default MAlgRelOrdered class
records only the lax form via rwp_bind_le; the strict subclass
StrictBind adds the equality. Strictness holds when the underlying
relational specification monad is deterministic in both arguments
(Reader-, Writer-, plain-State-style without sampling), and is
preserved by every StateT lift in this file. The coupling-based
OracleComp instances are intrinsically lax because the optimal
coupling for a composite computation can be more precise than the
sequential composition of optimal couplings.
A MAlgRelOrdered instance whose rwp bind law is an equality, not just an
inequality. This is the strict relational effect observation in the sense of
Maillard et al. (Def. 2 of The Next 700 Relational Program Logics).
- rwp_bind {α β γ δ : Type u} (x : m₁ α) (y : m₂ β) (f : α → m₁ γ) (g : β → m₂ δ) (post : γ → δ → l) : (rwp x y fun (a : α) (b : β) => rwp (f a) (g b) post) = rwp (x >>= f) (y >>= g) post
Strict bind law: relational WP of a sequenced computation equals the iterated relational WP.
Instances
Strict version of relWP_bind_le: under StrictBind the bind law is an
equality, so the relational WP of a sequenced computation can be rewritten in
either direction.
Strictness lifts through the left StateT instance.
Strictness lifts through the right StateT instance.
Strictness lifts through the two-sided StateT instance.
Anchored subclass #
A relational logic is anchored (with respect to a unary algebra on each side) when
relational reasoning collapses to unary reasoning whenever one of the two computations
is a pure value. The two coherence axioms
rwp_pure_left a y post = wp y (post a)rwp_pure_right x b post = wp x (fun a => post a b)
freeze the relational rwp to the underlying unary wp at one of the two corners,
recovering Maillard et al.'s "two unary triples + a relational triple" pattern from
[The Next 700 Relational Program Logics, POPL 2020] without committing to the full
relative-monad machinery. They are precisely the ingredient missing from the lossy
exception lifts (see instExceptTLeft / instExceptTRight above): once anchored, one
can derive honest exception combinators wpExc (unary) and rwpExc (relational)
that track success and failure separately rather than collapsing failures to ⊥.
Anchoring is independent of StrictBind. The coupling-based OracleComp instance is
anchored (Dirac couplings are unique) but is not strict, while a deterministic
specification monad is strict and anchored.
A MAlgRelOrdered instance that anchors the relational WP to the unary WPs of
the two sides at pure. The two axioms are the relational analogues of the coupling
identities IsCoupling c (pure a) q ↔ c = (a, ·) <$> q (and symmetrically on the
right): once one side is a Dirac, the relational WP collapses to the unary WP of the
other side, specialized at the Dirac point.
- rwp_pure_left {α β : Type u} (a : α) (y : m₂ β) (post : α → β → l) : rwp (pure a) y post = MAlgOrdered.wp y (post a)
Left anchoring: when the left computation is
pure a, the relational WP equals the unary WP of the right computation evaluated at the postcondition specialized ata. - rwp_pure_right {α β : Type u} (x : m₁ α) (b : β) (post : α → β → l) : rwp x (pure b) post = MAlgOrdered.wp x fun (a : α) => post a b
Right anchoring: when the right computation is
pure b, the relational WP equals the unary WP of the left computation evaluated at the postcondition specialized atb.
Instances
RelWP-flavoured restatement of the left anchoring axiom.
RelWP-flavoured restatement of the right anchoring axiom.