The eager relational judgment (EasyCrypt's eager logic) #
EasyCrypt's judgment eager [S₁, c₁ ~ c₂, S₂] : P ==> Q means
{P} S₁; c₁ ~ c₂; S₂ {Q} — two independent swapped blocks, leading on the
left program and trailing on the right. We mirror that literally:
`eagerR S₁ S₂ P p q Q := {P} S₁; p ~ q; S₂ {Q}` (as a `prhl2` coupling)
so p is the "eager" side (the block leads) and q the "lazy" side (the block
trails, keeping q's result). The generality of two blocks is load-bearing:
EC's eager seq threads a middle block
(eager[S₁,c₁~c₁',S] → eager[S,c₂~c₂',S₂] → eager[S₁,c₁;c₂~c₁';c₂',S₂]),
which eagerR_seq reproduces. The judgment is a prhl2 judgment about the
two composite programs, so a derivation built from the rules below is a pRHL
derivation.
The bridge #
At equality invariants the eager judgment is program equality of the composites:
prhl2_eq_iff— equality couplings are sound and complete for program equality:prhl2 (=) p q (=) ↔ ∀ σ, p σ = q σ. (Soundness is the diagonal coupling; completeness reads the marginals off the diagonal support, atom by atom.)eagerR_eq_iff_transferBy— the diagonal (S₁ = S₂) equality-invariant judgment is the distributional transfer relation,transferBy S q p.
The equality-invariant rules (eagerR_pure, eagerR_seq, eagerR_while,
eagerR_zoom) are proven through the bridge; eagerR_conseq is native.
EasyCrypt's own eager workflow runs at ={glob …} invariants, which in this
shallow embedding are handled by composing the equality-invariant judgment with
invariant self-couplings (see the abstract-call rule in Logic/EagerProc.lean).
The eager judgment (EasyCrypt's eager [S₁, p ~ q, S₂] : P ==> Q):
{P} S₁; p ~ q; S₂ {Q} as a prhl2 coupling; the trailing block keeps q's
result.
Equations
- S₁.eagerR S₂ P p q Q = GaudisCrypt.ProgramDenotation.prhl2 P (do S₁ p) (do let a ← q S₂ pure a) Q
Instances For
Equality couplings are sound and complete #
Completeness: a coupling with equality pre/post forces pointwise equal distributions — off-diagonal atoms vanish, so the two marginals agree atom by atom.
Soundness: pointwise equal programs couple diagonally.
Equality couplings ↔ program equality.
Introduce an equality-invariant eager judgment from program equality of the two composites (the semantic entry point for per-operation eager lemmas).
Extract program equality of the composites from an equality-invariant eager judgment.
The bridge: the diagonal equality-invariant eager judgment is the
distributional transfer relation (note the side swap: q is the lazy side).
The eager rule set (equality invariants) #
Rule of consequence for the eager judgment (native, any invariants).
EC's eager seq: eager judgments chain under >>= through a middle
block S — eager[S₁,p₁~q₁,S] then eager[S,p₂~q₂,S₂] give
eager[S₁, p₁;p₂ ~ q₁;q₂, S₂].
EC's eager while (same block at both ends): if the condition swaps with
S and the body is eager, the loops are eager.
Zoom-lifting: an eager judgment on the inner state lifts along a lens (the blocks lift with it).
Invariant introduction #
EasyCrypt's invariant-carrying eager rules (eager seq … : R, eager while I,
eager proc I) all decompose the same way, visible in the subgoals their kernel
generates: the equality-invariant eager judgment plus framing
self-couplings of one composite under the invariant (EC's c ~ c / s ~ s : I ==> I side conditions). The two master rules below are that decomposition as
a theorem: an invariant eager judgment is a self-coupling of either composite
glued to the equality judgment by prhl2.trans. The EC-shaped composite rules
(eagerR_seq_inv, eagerR_while_inv, eager_call_inv) derive from them.
Invariant introduction (left): self-couple the eager composite S₁; p
under the invariant, then glue the equality-invariant judgment on the right.
Invariant introduction (right): symmetrically, self-couple the lazy
composite q; S₂ under the invariant.
EC's eager seq with invariants (their four-subgoal form): the two
equality-level eager judgments plus framing self-couplings of the eager-side
pieces, threaded through a middle relation M.
EC's eager while with invariants (their six-subgoal form, coupling
formulation): the equality-level eager judgments for guard and body, plus
framing self-couplings — the block establishes the loop invariant Inv, the
guard couples to agree under it, and the body preserves it.
Endpoint conversion #
Absorb the trailing block into a direct coupling: from a diagonal eager
judgment and losslessness of S, couple the lazy side q directly against
the S-led eager side, with equal results and any S-preserved state
projection g (e.g. ={glob A}) equal on the final states.