Lifting Std.Do handler triples to relational triples #
This file generalizes the unary-to-relational bridge in
Relational.FromUnary from pure OracleComp computations to stateful
handlers. It bridges the gap between
Std.Do.Triplespecs forQueryImpl spec (StateT σ (OracleComp spec')), produced bymvcgenand registered via@[spec](e.g.cachingOracle_triple,seededOracle_triple,loggingOracle_triple), andRelTriplecouplings on the.rundistributions of those handlers, consumed byrelTriple_simulateQ_runfor whole-program reasoning.
Main results #
relTriple_run_of_triple— per-call lift: two unaryStd.Do.Triples onStateT σᵢ (OracleComp specᵢ)give aRelTripleon the products of the two.rundistributions, with the relational postcondition the pairwise conjunction of the unary postconditions. This is the stateful analogue ofrelTriple_prod_of_triple.relTriple_simulateQ_run_of_triples— whole-program lift: combines per-call unary triples on two simulator handlers with a synchronization condition relating their postconditions, yielding aRelTriplefor the entiresimulateQ-driven simulation.relTriple_simulateQ_run_of_impl_eq_triple— identical-up-to-invariant lift: takes a unary invariant-preservationStd.Do.Tripleon one handler plus pointwise-equality-on-Inv with the other, and yields anEqRelwhole-program coupling. This is the direct bridge from themvcgenproof style to the support-basedrelTriple_simulateQ_run_of_impl_eq_preservesInv.
The hsync argument is what bridges product (independent) reasoning to
the synchronized coupling expected by relTriple_simulateQ_run: even if
the underlying unary triples are independent, an external sync argument
(determinism of the handler, agreement of random choices, etc.) is needed
to upgrade pairwise postconditions to output equality plus a state
invariant.
The whole-program lift fixes OracleSpec.{0, 0} because the unary
triple_stateT_iff_forall_support bridge in
VCVio.ProgramLogic.Unary.HandlerSpecs is stated at that universe.
Per-call lifts (one transformer layer) #
Per-call lift from two unary Std.Do.Triples to a relational product
coupling on the .run distributions.
Each triple's postcondition is interpreted as a property of the
(value, final_state) pair; the relational postcondition is the
pairwise conjunction. This is the stateful generalization of
relTriple_prod_of_triple.
WriterT analogue of relTriple_run_of_triple.
Two unary Std.Do.Triples on WriterT ωᵢ (OracleComp specᵢ) lift to a
product coupling on the (value, accumulated_log) pairs of the underlying
OracleComp. The starting log of each side is fixed at s₁ : ω₁ and
s₂ : ω₂ and the postconditions are read at Q₁ a (s₁ ++ w) /
Q₂ b (s₂ ++ w) where w is the writer increment produced by the run.
The starting logs default to ∅ for the typical WriterT.run call but
are kept arbitrary so the lemma composes cleanly with prefix-style log
specs (e.g. loggingOracle's log' = log₀ ++ [⟨t, v⟩]).
Monoid-variant of relTriple_run_writerT_of_triple.
For WriterT ωᵢ (OracleComp specᵢ) with [Monoid ωᵢ], two unary
Std.Do.Triples lift to a product coupling on the (value, accumulated_log) pairs where each postcondition is read at
Q₁ a (s₁ * w) / Q₂ b (s₂ * w) (monoid multiplication). Used by
countingOracle / costOracle reasoning.
Whole-program handler lift: given matching unary handler triples on
two simulators with parametric pre/postconditions and a synchronization
condition relating the postconditions, derive a RelTriple on the entire
simulateQ outputs.
The unary triples are quantified over the initial handler state; their
postconditions may depend on it. The synchronization condition hsync
extracts output equality and the state-relation invariant from a paired
instance of the two unary postconditions, which is exactly the bridge
needed by relTriple_simulateQ_run.
WriterT analogue of relTriple_simulateQ_run_of_triples (monoid variant).
Given matching unary Std.Do.Triple specs for two WriterT-based
handlers, a monoid-congruent writer relation R_writer (via hR_one and
hR_mul), and a synchronization condition on per-query postconditions,
derive a whole-program RelTriple on the full (output, writer) outputs
of the two simulations.
The per-query triples are specialized to starting writer 1
(which corresponds to WriterT.run-style entry); their postconditions
are evaluated at the resulting step writer. Typical instantiations are
countingOracle_triple and costOracle_triple with qc₀ = 0 /
s₀ = 1.
Output-projection variant of relTriple_simulateQ_run_writerT_of_triples.
Drops the writer component, leaving only EqRel α on outputs.
Output-projection variant of relTriple_simulateQ_run_of_triples.
Drops the final state from both sides, leaving only a relational equality
on the return values. This is the canonical shape needed for probability
transport (via probOutput_eq_of_relTriple_eqRel), matching
relTriple_simulateQ_run' at the handler-triple layer.
Bridge to support-based simulation lemmas #
The lemmas below convert Std.Do.Triple invariant specs produced by
mvcgen into the support-based hypotheses that the existing
Relational/SimulateQ.lean infrastructure consumes. They're the
recommended entry point from the mvcgen proof style into whole-program
relational reasoning.
Convert a unary Std.Do.Triple invariant-preservation spec into the
support-based preservation hypothesis consumed by
relTriple_simulateQ_run_of_impl_eq_preservesInv and friends.
The mvcgen proof style produces invariant-preservation specs as
Std.Do.Triple judgments; most of the existing SimulateQ.lean
relational infrastructure is phrased in terms of support. This lemma
is the direct translator, lifting over triple_stateT_iff_forall_support.
WriterT analogue of support_preservesInv_of_triple. Converts a
unary Std.Do.Triple invariant-preservation spec for a WriterT-based
handler (with [Monoid ω]) into the WriterPreservesInv hypothesis
consumed by OracleComp.simulateQ_run_writerPreservesInv.
Use this whenever a writer-invariant-preservation proof is available as
an mvcgen-style Std.Do.Triple, and the downstream consumer is a
support-based whole-program lemma.
Whole-program equality coupling when two handlers agree pointwise on
an invariant Inv and the target handler preserves Inv. This is the
Std.Do.Triple-fronted version of
relTriple_simulateQ_run_of_impl_eq_preservesInv: the preservation
hypothesis is supplied via mvcgen-style Std.Do.Triples rather than a
support-based quantifier.