Documentation

VCVio.OracleComp.Coercions.SubSpec.Basic

Oracle-signature inclusions #

Polynomial lenses implement oracle-signature inclusions. Cartesian response translations preserve operational possibilities; semantic preservation is expressed separately by the chosen measures.

class OracleSpec.SubSpec {ι : Type u} {τ : Type v} (spec : OracleSpec ι) (superSpec : OracleSpec τ) extends MonadLift (OracleQuery spec) (OracleQuery superSpec) :
Type (max (max u v) (w + 1))

Inclusion of one set of oracles into another, packaged as a polynomial-functor lens between the underlying OracleSpecs. Carries the forward translation onQuery on query inputs and the fiberwise backward translation onResponse on query responses, plus the resulting MonadLift action.

The MonadLift action and the lens data are related by the public coherence equation liftM_eq_lift. Concrete inclusions supply their query action alongside the query and response translations. SubSpec.liftQuery and SubSpec.toLens expose those constructions independently of any measure interpretation.

Informally, spec ⊂ₒ superSpec says that any query to an oracle of spec can be perfectly simulated by a query to an oracle of superSpec. We avoid the built-in Subset notation because we care about the actual data of the mapping (it is needed when defining type coercions), not just its existence.

Instances

    Inclusion of one set of oracles into another, packaged as a polynomial-functor lens between the underlying OracleSpecs. Carries the forward translation onQuery on query inputs and the fiberwise backward translation onResponse on query responses, plus the resulting MonadLift action.

    The MonadLift action and the lens data are related by the public coherence equation liftM_eq_lift. Concrete inclusions supply their query action alongside the query and response translations. SubSpec.liftQuery and SubSpec.toLens expose those constructions independently of any measure interpretation.

    Informally, spec ⊂ₒ superSpec says that any query to an oracle of spec can be perfectly simulated by a query to an oracle of superSpec. We avoid the built-in Subset notation because we care about the actual data of the mapping (it is needed when defining type coercions), not just its existence.

    Instances For
      @[reducible]
      def OracleSpec.SubSpec.liftQuery {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} {α : Type w} [h : spec ⊂ₒ superSpec] (q : OracleQuery spec α) :
      OracleQuery superSpec α

      The lens action on a single query: forward on the input, post-compose the backward fiber on the continuation. Used as the canonical reduced form of liftM q for proofs that need to inspect the resulting query.

      Instances For
        def OracleSpec.SubSpec.toLens {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} (h : spec ⊂ₒ superSpec) :
        spec.toPFunctor.Lens superSpec.toPFunctor

        The polynomial-functor lens between the underlying PFunctors carried by a SubSpec instance. This is the lens-level view of the data; concrete properties (like cartesianness via LawfulSubSpec) are stated on this lens.

        The other half of the data, monadLift, is fixed by liftM_eq_lift to be the standard action of this lens on OracleQuery.

        Instances For
          @[simp]
          theorem OracleSpec.SubSpec.toLens_toFunA {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} (h : spec ⊂ₒ superSpec) :
          @[simp]
          theorem OracleSpec.SubSpec.toLens_toFunB {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} (h : spec ⊂ₒ superSpec) :
          @[reducible]
          def OracleSpec.SubSpec.trans {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} {κ : Type w'} {spec₃ : OracleSpec κ} (h₁ : spec ⊂ₒ superSpec) (h₂ : superSpec ⊂ₒ spec₃) :
          spec ⊂ₒ spec₃

          Transitivity of SubSpec: lens composition.

          Instances For
            @[simp]
            theorem OracleSpec.SubSpec.trans_toLens {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} {κ : Type w'} {spec₃ : OracleSpec κ} (h₁ : spec ⊂ₒ superSpec) (h₂ : superSpec ⊂ₒ spec₃) :
            (h₁.trans h₂).toLens = h₂.toLens ∘ₗ h₁.toLens
            class OracleSpec.LawfulSubSpec {ι : Type u} {τ : Type v} (spec : OracleSpec ι) (superSpec : OracleSpec τ) [h : spec ⊂ₒ superSpec] :

            LawfulSubSpec extends SubSpec with the requirement that the backward translation onResponse is bijective on every fiber. Equivalently: the underlying lens SubSpec.toLens is cartesian in the sense of PFunctor.Lens.IsCartesian, i.e. it is a fiberwise isomorphism over an arbitrary forward map on positions.

            This is strictly weaker than PFunctor.Lens.Equiv, which would also force onQuery to be a bijection. We intentionally only require fiberwise bijectivity because the canonical SubSpec instances embed a small spec into a larger one (e.g. spec₁ ⊂ₒ (spec₁ + spec₂) with onQuery = Sum.inl), and these embeddings are essential to the API.

            Cartesianness preserves operational possibilities and permits transport of uniform measures. Preservation of arbitrary weighted measures is a separate semantic contract. The public LawfulSubSpec.toLens_isCartesian equation exposes the polynomial lens certificate.

            Instances

              Lawful oracle-spec inclusion: a SubSpec whose response translation is bijective on every fiber.

              Instances For
                theorem OracleSpec.LawfulSubSpec.toLens_isCartesian {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} [h : spec ⊂ₒ superSpec] [spec.LawfulSubSpec superSpec] :

                The lens-level statement of LawfulSubSpec: the underlying PFunctor.Lens is cartesian. This makes the dictionary between the oracle-spec layer and the polynomial-functor lens layer explicit.

                class OracleSpec.DisjointSubSpec {ι₁ : Type u} {ι₂ : Type v} {τ : Type w'} (spec₁ : OracleSpec ι₁) (spec₂ : OracleSpec ι₂) (superSpec : OracleSpec τ) [h₁ : spec₁ ⊂ₒ superSpec] [h₂ : spec₂ ⊂ₒ superSpec] :

                Two oracle-spec inclusions into the same ambient spec have disjoint query images.

                Lawfulness concerns bijective response translations, while disjointness says the two lifted query namespaces do not overlap inside the ambient interface.

                Instances

                  Oracle-spec inclusions with disjoint query images in an ambient interface.

                  Instances For
                    theorem OracleComp.liftM_eq_liftM_liftM {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} {α : Type w} [MonadLiftT (OracleQuery spec) (OracleQuery superSpec)] (q : OracleQuery spec α) :

                    Lifting a primitive query through a signature inclusion first translates the query and then inserts it into the target free program.

                    def OracleComp.liftComp {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {α : Type w} (mx : OracleComp spec α) (superSpec : OracleSpec τ) [h : MonadLiftT (OracleQuery spec) (OracleQuery superSpec)] :
                    OracleComp superSpec α

                    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
                      theorem OracleComp.liftComp_def {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {α : Type w} (superSpec : OracleSpec τ) [h : MonadLiftT (OracleQuery spec) (OracleQuery superSpec)] (mx : OracleComp spec α) :
                      mx.liftComp superSpec = simulateQ (fun (t : spec.Domain) => liftM (OracleSpec.query t)) mx
                      @[simp]
                      theorem OracleComp.liftComp_pure {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {α : Type w} (superSpec : OracleSpec τ) [h : MonadLiftT (OracleQuery spec) (OracleQuery superSpec)] (x : α) :
                      (pure x).liftComp superSpec = pure x
                      @[simp]
                      theorem OracleComp.liftComp_query {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {α : Type w} (superSpec : OracleSpec τ) [h : MonadLiftT (OracleQuery spec) (OracleQuery superSpec)] (q : OracleQuery spec α) :
                      theorem OracleComp.liftComp_liftM_query {ι : Type u} {τ : Type v} {spec : OracleSpec ι} (superSpec : OracleSpec τ) [h : MonadLiftT (OracleQuery spec) (OracleQuery superSpec)] (t : spec.Domain) :

                      Signature translation of a primitive query is its query lift.

                      @[simp]
                      theorem OracleComp.liftComp_bind {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {α β : Type w} (superSpec : OracleSpec τ) [h : MonadLiftT (OracleQuery spec) (OracleQuery superSpec)] (mx : OracleComp spec α) (ob : αOracleComp spec β) :
                      (mx >>= ob).liftComp superSpec = do let xmx.liftComp superSpec (ob x).liftComp superSpec
                      @[simp]
                      theorem OracleComp.liftComp_self {ι : Type u} {spec : OracleSpec ι} {α : Type w} (mx : OracleComp spec α) :
                      mx.liftComp spec = mx
                      @[simp]
                      theorem OracleComp.liftComp_map {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {α β : Type w} (superSpec : OracleSpec τ) [h : MonadLiftT (OracleQuery spec) (OracleQuery superSpec)] (mx : OracleComp spec α) (f : αβ) :
                      (f <$> mx).liftComp superSpec = f <$> mx.liftComp superSpec
                      theorem OracleComp.liftComp_bind_pure {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {α β : Type w} (superSpec : OracleSpec τ) [h : MonadLiftT (OracleQuery spec) (OracleQuery superSpec)] (oa : OracleComp spec α) (f : αβ) :
                      (do let aoa pure (f a)).liftComp superSpec = f <$> oa.liftComp superSpec

                      bind-pure form of liftComp_map, matching the term shape produced by do-notation (do let a ← oa; pure (f a)) before any bind_pure_comp normalization.

                      theorem OracleComp.mem_support_of_mem_support_liftComp {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {α : Type w} (superSpec : OracleSpec τ) [h : MonadLiftT (OracleQuery spec) (OracleQuery superSpec)] (oa : OracleComp spec α) (x : α) :
                      x support (oa.liftComp superSpec)x support oa

                      One-directional, assumption-light variant of mem_support_liftComp_iff: under just a query-level lift (no SubSpec or lawfulness assumptions), the support of a lifted computation is bounded by the support of the original. The reverse inclusion can fail without lawfulness, since an arbitrary embedding need not reach all responses of the original oracles.

                      @[simp]
                      theorem OracleComp.liftComp_seq {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {α β : Type w} (superSpec : OracleSpec τ) [h : MonadLiftT (OracleQuery spec) (OracleQuery superSpec)] (og : OracleComp spec (αβ)) (mx : OracleComp spec α) :
                      (og <*> mx).liftComp superSpec = og.liftComp superSpec <*> mx.liftComp superSpec
                      @[simp]
                      theorem OracleComp.liftComp_seqLeft {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {α β : Type w} (superSpec : OracleSpec τ) [h : MonadLiftT (OracleQuery spec) (OracleQuery superSpec)] (mx : OracleComp spec α) (my : OracleComp spec β) :
                      (mx <* my).liftComp superSpec = mx.liftComp superSpec <* my.liftComp superSpec
                      @[simp]
                      theorem OracleComp.liftComp_seqRight {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {α β : Type w} (superSpec : OracleSpec τ) [h : MonadLiftT (OracleQuery spec) (OracleQuery superSpec)] (mx : OracleComp spec α) (my : OracleComp spec β) :
                      (mx *> my).liftComp superSpec = mx.liftComp superSpec *> my.liftComp superSpec
                      theorem OracleComp.support_liftComp {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} {α : Type w} [h : spec ⊂ₒ superSpec] [spec.LawfulSubSpec superSpec] (mx : OracleComp spec α) :
                      support (mx.liftComp superSpec) = support mx

                      Support is preserved by liftComp: lifting a computation to a larger oracle spec does not change which outputs are reachable. This is the support analogue of the native uniform-measure lifting law.

                      theorem OracleComp.mem_support_liftComp_iff {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} {α : Type w} [h : spec ⊂ₒ superSpec] [spec.LawfulSubSpec superSpec] (mx : OracleComp spec α) (x : α) :
                      x support (mx.liftComp superSpec) x support mx
                      @[instance_reducible, instance 100]
                      instance OracleComp.instMonadLiftOfOracleQuery {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} [MonadLift (OracleQuery spec) (OracleQuery superSpec)] :
                      MonadLift (OracleComp spec) (OracleComp superSpec)

                      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-in MonadLiftT.refl (which is definitionally id) wins typeclass resolution. This is what Std.Do.Spec.UnfoldLift.monadLift_refl (a rfl-based lemma) needs in order to peel off spurious self-lifts inside mvcgen-elaborated terms.

                      • For MonadLiftT (OracleQuery spec) (OracleComp superSpec), the built-in high-priority MonadLift (OracleQuery superSpec) (OracleComp superSpec) is tried first by monadLiftTrans and succeeds via the SubSpec chain on OracleQuery, never reaching this instance. Single-query lifts therefore go through the standard "lift query then embed" path with no spurious walk through liftComp.

                      • For MonadLiftT (OracleComp spec) (OracleComp superSpec) with spec ≠ superSpec, the high-priority built-in fails (no MonadLiftT (OracleComp _) (OracleQuery _)), Lean backtracks to this low-priority instance, and the recursive subgoal collapses via MonadLiftT.refl. The result is a single liftComp mx superSpec.

                      @[simp]
                      theorem OracleComp.liftComp_eq_liftM {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} {α : Type w} [MonadLift (OracleQuery spec) (OracleQuery superSpec)] (mx : OracleComp spec α) :
                      mx.liftComp superSpec = liftM mx

                      We choose to actively rewrite liftComp as liftM to enable LawfulMonadLift lemmas.

                      theorem OracleComp.liftM_eq_liftComp_liftM {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} {α : Type w} {κ : Type u_1} {spec₃ : OracleSpec κ} [MonadLift (OracleQuery superSpec) (OracleQuery spec₃)] [MonadLiftT (OracleComp spec) (OracleComp superSpec)] (mx : OracleComp spec α) :
                      liftM mx = (liftM mx).liftComp spec₃

                      Peel the outermost step off a chained OracleComp-level lift: a liftM whose MonadLiftT (OracleComp spec) (OracleComp spec₃) instance is the transitive composition of the query-keyed MonadLift (OracleComp superSpec) (OracleComp spec₃) step with a remaining chain MonadLiftT (OracleComp spec) (OracleComp superSpec) is the liftComp of the remaining lift. Typeclass resolution builds exactly this shape (via instMonadLiftTOfMonadLift) when lifting across two or more OracleSpec.add layers, e.g. OracleComp spec₂ → OracleComp (spec + (spec₁ + spec₂)) through the intermediate spec + spec₂. None of the single-step lemmas (liftComp_eq_liftM, liftComp_query, …) can engage such a chain directly, since their statements bake in the one-step instance.

                      Not @[simp]: with spec = superSpec the remaining chain can be MonadLiftT.refl, and the right-hand side would then re-match the left-hand side. Use via explicit rw, then rewrite the inner lift with liftComp_eq_liftM and proceed with the liftComp API.

                      instance OracleComp.instLawfulMonadLift {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} [MonadLift (OracleQuery spec) (OracleQuery superSpec)] :
                      @[simp]
                      theorem OracleComp.monadLift_eq_self {ι : Type u} {spec : OracleSpec ι} {α : Type u_1} (mx : OracleComp spec α) :
                      monadLift mx = mx

                      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.

                      @[instance_reducible]
                      instance OracleComp.instMonadLiftOptionTOfOracleQuery {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} [MonadLift (OracleQuery spec) (OracleQuery superSpec)] :
                      @[simp]
                      theorem OracleComp.liftM_OptionT_eq {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} {α : Type w} [MonadLift (OracleQuery spec) (OracleQuery superSpec)] (mx : OptionT (OracleComp spec) α) :
                      liftM mx = have impl := fun (t : spec.Domain) => liftM (OracleSpec.query t); simulateQ impl mx
                      theorem OracleComp.liftM_failure {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} {α : Type w} [MonadLift (OracleQuery spec) (OracleQuery superSpec)] :
                      instance OracleComp.instLawfulMonadLiftOptionT {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} [MonadLift (OracleQuery spec) (OracleQuery superSpec)] :
                      @[simp]
                      theorem OracleComp.monadLift_liftM_OptionT {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} {α : Type w} [MonadLift (OracleQuery spec) (OracleQuery superSpec)] (mx : OracleComp spec α) :

                      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).

                      @[instance_reducible]
                      instance OracleComp.instMonadLiftStateTOfOracleQuery {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} {σ : Type u_1} [MonadLift (OracleQuery spec) (OracleQuery superSpec)] :
                      MonadLift (StateT σ (OracleComp spec)) (StateT σ (OracleComp superSpec))
                      @[simp]
                      theorem OracleComp.liftM_StateT_eq {ι : Type u} {τ : Type v} {spec : OracleSpec ι} {superSpec : OracleSpec τ} {α σ : Type w} [MonadLift (OracleQuery spec) (OracleQuery superSpec)] (mx : StateT σ (OracleComp spec) α) :
                      liftM mx = StateT.mk fun (s : σ) => liftM (mx.run s)