Oracle State Invariants for Shared-Oracle Simulations #
This module provides minimal, model-agnostic infrastructure for reasoning about
shared, stateful oracle simulations (ROM/AGM/hybrids) via a user-supplied invariant
Inv : σ → Prop on oracle states.
We use support-based formulations (rather than Pr[ ...] = 1) to keep downstream
proofs lightweight.
Main definitions #
InitSatisfiesInv— every sampled initial state satisfies the invariantQueryImpl.PreservesInv— every oracle query implementation step preservesInvOracleComp.simulateQ_run_preservesInv— simulating any oracle computation with a preserving implementation preservesInvon the final stateStateT.StatePreserving— computation never changes the stateStateT.PreservesInv— computation preserves an invariant on the stateStateT.NeverFailsUnder— computation does not fail under an invariantStateT.OutputIndependent— output distribution is independent of the initial state under an invariantStateT.outputIndependent_after_preservesInv— non-interference: output-independent computation remains so after sequencing with an invariant-preserving computationQueryImpl.WriterPreservesInv— every oracle query implementation step preserves an invariantInv : ω → Propon the accumulated writer output (forWriterT ωhandlers with[Monoid ω])OracleComp.simulateQ_run_writerPreservesInv— simulating any oracle computation with a writer-invariant-preserving implementation preservesInvon the final accumulated writer value
PreservesInv impl Inv means every oracle query implementation step preserves Inv
on all reachable post-states (support-based).
Instances For
If impl preserves Inv, then simulating any oracle computation with simulateQ impl
preserves Inv on the final state (support-wise).
If so' preserves Inv, then so' ∘ₛ so also preserves Inv for any so.
InitSatisfiesInv init Inv means every possible initial state sampled by init
satisfies Inv (support-based).
Instances For
StateT invariant properties #
These properties are useful for non-interference arguments in sequential composition proofs.
They are stated for general StateT σ ProbComp computations.
StatePreserving mx means mx never changes the state: for every starting state σ0,
every outcome in the support of mx.run σ0 has final state equal to σ0.
Instances For
NeverFailsUnder mx Inv means that starting from any state satisfying Inv, the computation
does not fail (its failure probability is 0).
Instances For
OutputIndependent mx Inv means the output distribution of mx does not depend on the
initial state, as long as the initial state satisfies Inv.
This is distributional equality of run' (which discards the final state).
Instances For
If mx is output-independent on Inv, and my preserves Inv and never fails, then the
output distribution of mx is unchanged by running my first and then running mx on the
resulting state.
WriterT invariant properties #
These properties mirror QueryImpl.PreservesInv / OracleComp.simulateQ_run_preservesInv
for handlers that accumulate a writer log in a monoid ω (as opposed to threading state
through StateT). Typical use-cases include countingOracle (with ω = QueryCount ι)
and costOracle (with an arbitrary Monoid ω).
WriterPreservesInv impl Inv means every oracle query implementation step preserves
Inv on the accumulated writer: starting from any s₀ satisfying Inv, every reachable
post-writer s₀ * w (for (a, w) in the support of (impl t).run) also satisfies Inv.
Instances For
WriterPreservesInv from an unconditional per-query witness. Analogous
to PreservesInv.of_forall: if every reachable increment z.2 satisfies
Inv (s₀ * z.2) for any starting s₀ regardless of whether Inv s₀
holds, then Inv is preserved.
WriterPreservesInv from a multiplicatively-closed predicate.
If Inv holds on every writer increment w produced by a single query
(hPerQuery) and is closed under * (hClosed), then Inv is
preserved across the whole simulation. This is the canonical builder for
writer invariants: pick a submonoid-like predicate, show every per-query
increment lands in it, and you're done.
Note on composition. Unlike PreservesInv.compose, we do not provide a
compose analogue for WriterPreservesInv: the definition is keyed to a
single spec appearing both as the source of queries and as the inner
OracleComp spec monad of the writer. Composition via ∘ₛ changes the
query spec but not the inner writer monad, so the composite signature no
longer matches WriterPreservesInv's. The intended idiom is to compose
on the underlying OracleComp layer (e.g. via simulateQ_compose) and
then apply simulateQ_run_writerPreservesInv to the composite computation.
If impl preserves the writer invariant Inv, then simulating any oracle computation
with simulateQ impl preserves Inv on the final accumulated writer (support-wise).