Coercions Between Computations With Additional Oracles #
This file defines a isSubSpec relation for pairs of oracleSpec where one can be
thought of as an extension of the other with additional oracles.
The definition consists is a thin wrapper around a MonadLift instance on OracleQuery,
which extends to a lifting operation on OracleComp.
We use the notation spec ⊂ₒ spec' to represent that one set of oracles is a subset of another,
where the non-inclusive subset symbol reflects that we avoid defining this instance reflexively.
Relation defining an inclusion of one set of oracles into another, where the mapping
doesn't affect the underlying probability distribution of the computation.
Informally, spec ⊂ₒ superSpec means that for any query to an oracle of sub_spec,
it can be perfectly simulated by a computation using the oracles of superSpec.
We avoid implementing this via the built-in subset notation as we care about the actual data of the mapping rather than just its existence, which is needed when defining type coercions.
Instances
Transitivity for SubSpec: if spec₁ ⊂ₒ spec₂ and spec₂ ⊂ₒ spec₃,
then spec₁ ⊂ₒ spec₃.
Instances For
LawfulSubSpec extends SubSpec with the requirement that lifting preserves
distributions. The axiom requires that the continuation of each lifted query is a
bijection from the super-range to the sub-range, which guarantees that the uniform
distribution is preserved under the mapping.
- cont_bijective (t : spec.Domain) : Function.Bijective (MonadLift.monadLift (OracleQuery.query t)).snd
Instances
Lift a computation from spec to superSpec using a SubSpec instance on queries.
Usually liftM should be preferred but this can allow more explicit annotation.
Instances For
Extend a lifting on OracleQuery to a lifting on OracleComp.
Registered as a low-priority MonadLift (not MonadLiftT) so that:
For
spec = superSpec, Lean's built-inMonadLiftT.refl(which is definitionallyid) wins typeclass resolution. This is whatStd.Do.Spec.UnfoldLift.monadLift_refl(arfl-based lemma) needs in order to peel off spurious self-lifts insidemvcgen-elaborated terms.For
MonadLiftT (OracleQuery spec) (OracleComp superSpec), the built-in high-priorityMonadLift (OracleQuery superSpec) (OracleComp superSpec)is tried first bymonadLiftTransand succeeds via theSubSpecchain onOracleQuery, never reaching this instance. Single-query lifts therefore go through the standard "lift query then embed" path with no spurious walk throughliftComp.For
MonadLiftT (OracleComp spec) (OracleComp superSpec)withspec ≠ superSpec, the high-priority built-in fails (noMonadLiftT (OracleComp _) (OracleQuery _)), Lean backtracks to this low-priority instance, and the recursive subgoal collapses viaMonadLiftT.refl. The result is a singleliftComp mx superSpec.
We choose to actively rewrite liftComp as liftM to enable LawfulMonadLift lemmas.
Self-lift on OracleComp is definitionally id, supplied by Lean's
built-in MonadLiftT.refl thanks to the low-priority MonadLift instance
above (which causes the parametric path to lose typeclass resolution to
MonadLiftT.refl when spec = superSpec).
Regression smoke-tests for the instance-priority invariants above. The
rfl proofs are the load-bearing signal: if priority drifts so that the
parametric MonadLift beats MonadLiftT.refl, the self-lift stops being
definitionally id and the rfl below breaks. Similarly, the
MonadLiftT synthesis check guards against future refactors that would
remove the transitive lift chain.
Coherence: lifting an OracleComp to a superspec and then into OptionT via the standard
MonadLift equals lifting directly through the transitive MonadLiftT chain (which goes
through the simulateQ-based OptionT MonadLift instance).