Documentation

VCVio.OracleComp.OracleComp

Computations with Oracle Access #

def OracleComp {ι : Type u} (spec : OracleSpec ι) :
Type w → Type (max u v w)

OracleComp spec α represents computations with oracle access to oracles in spec, where the final return value has type α, represented as a free monad over the PFunctor corresponding to spec.

Instances For
    @[reducible, match_pattern]
    def OracleComp.queryBind {ι : Type u} {spec : OracleSpec ι} {α : Type u_1} (t : spec.Domain) (k : spec.Range tOracleComp spec α) :
    OracleComp spec α

    Make one oracle query at input t, then continue with k on the response.

    This is the PFunctor.FreeM.roll constructor specialized to OracleComp; the @[match_pattern] attribute makes it usable both as a term and as a match pattern.

    Instances For
      @[implicit_reducible]
      instance OracleComp.instMonad {ι : Type u} (spec : OracleSpec ι) :
      @[implicit_reducible]
      @[reducible]
      def OracleComp.lift {ι : Type u_1} {spec : OracleSpec ι} {α : Type u_3} (q : OracleQuery spec α) :
      OracleComp spec α

      Manually lift an OracleQuery to an OracleComp.

      Instances For
        theorem OracleComp.liftM_def {α : Type v} {ι : Type u} {spec : OracleSpec ι} (q : OracleQuery spec α) :
        @[simp]
        theorem OracleComp.liftM_ne_pure {α : Type v} {ι : Type u} {spec : OracleSpec ι} (q : OracleQuery spec α) (x : α) :
        @[simp]
        theorem OracleComp.pure_ne_liftM {α : Type v} {ι : Type u} {spec : OracleSpec ι} (x : α) (q : OracleQuery spec α) :
        @[simp]
        theorem OracleComp.liftM_map {α β : Type v} {ι : Type u} {spec : OracleSpec ι} (q : OracleQuery spec α) (f : αβ) :
        liftM (f <$> q) = f <$> liftM q
        @[inline]

        coin is the computation representing a coin flip, given a coin flipping oracle.

        Instances For
          theorem OracleComp.pure_def {α : Type v} {ι : Type u} {spec : OracleSpec ι} (x : α) :
          theorem OracleComp.bind_def {α β : Type v} {ι : Type u} {spec : OracleSpec ι} (oa : OracleComp spec α) (ob : αOracleComp spec β) :
          def OracleComp.casesOn {ι : Type u} {spec : OracleSpec ι} {α : Type u_2} {motive : OracleComp spec αSort u_1} (oa : OracleComp spec α) (pure : (x : α) → motive (PFunctor.FreeM.pure x)) (queryBind : (t : spec.Domain) → (k : spec.Range tOracleComp spec α) → motive (queryBind t k)) :
          motive oa

          Cases eliminator on OracleComp exposing the high-level pure / queryBind alternatives. Registered as the default cases eliminator so that cases oa with | pure x => ... | queryBind t k => ... works transparently on top of the free-monad substrate.

          Instances For
            def OracleComp.recOn {ι : Type u} {spec : OracleSpec ι} {α : Type u_2} {motive : OracleComp spec αSort u_1} (oa : OracleComp spec α) (pure : (x : α) → motive (PFunctor.FreeM.pure x)) (queryBind : (t : spec.Domain) → (k : spec.Range tOracleComp spec α) → ((u : spec.Range t) → motive (k u))motive (queryBind t k)) :
            motive oa

            Structural recursion eliminator on OracleComp exposing the high-level pure / queryBind alternatives, with an induction hypothesis on every continuation in the queryBind case. Registered as the default induction eliminator so that induction oa with | pure x => ... | queryBind t k ih => ... works transparently on top of the free-monad substrate.

            Instances For
              theorem OracleComp.failure_def {α : Type v} {ι : Type u} {spec : OracleSpec ι} :
              theorem OracleComp.orElse_def {α : Type v} {ι : Type u} {spec : OracleSpec ι} (oa oa' : OptionT (OracleComp spec) α) :
              (oa <|> oa') = OptionT.mk do let __do_liftoa.run match __do_lift with | some a => pure (some a) | x => oa'.run
              theorem OracleComp.bind_congr' {α β : Type v} {ι : Type u} {spec : OracleSpec ι} {oa oa' : OracleComp spec α} {ob ob' : αOracleComp spec β} (h : oa = oa') (h' : ∀ (x : α), ob x = ob' x) :
              oa >>= ob = oa' >>= ob'
              @[simp]
              theorem OracleComp.guard_eq {ι : Type u} {spec : OracleSpec ι} (p : Prop) [Decidable p] :
              theorem OracleComp.ite_bind {α β : Type v} {ι : Type u} {spec : OracleSpec ι} (p : Prop) [Decidable p] (oa oa' : OracleComp spec α) (ob : αOracleComp spec β) :
              (if p then oa else oa') >>= ob = if p then oa >>= ob else oa' >>= ob
              def OracleComp.inductionOn {ι : Type u} {spec : OracleSpec ι} {α : Type v} {C : OracleComp spec αProp} (pure : ∀ (a : α), C (pure a)) (query_bind : ∀ (t : spec.Domain) (oa : spec.Range tOracleComp spec α), (∀ (u : spec.Range t), C (oa u))C (liftM (OracleSpec.query t) >>= oa)) (oa : OracleComp spec α) :
              C oa

              Nicer induction rule for OracleComp that uses monad notation. Allows inductive definitions on computations by considering the two cases:

              • return x / pure x for any x
              • do let u ← query i t; oa u (with inductive results for oa u) See oracleComp_emptySpec_equiv for an example of using this in a proof. If the final result needs to be a Type and not a Prop, see OracleComp.construct.
              Instances For
                def OracleComp.inductionOnOptional {ι : Type u} {spec : OracleSpec ι} {α : Type v} {C : OptionT (OracleComp spec) αProp} (pure : ∀ (a : α), C (pure a)) (query_bind : ∀ (t : spec.Domain) (oa : spec.Range tOptionT (OracleComp spec) α), (∀ (u : spec.Range t), C (oa u))C (liftM (OracleSpec.query t) >>= oa)) (failure : C failure) (oa : OptionT (OracleComp spec) α) :
                C oa

                Version of OracleComp.inductionOn that includes an OptionT in the monad stack and requires an explicit case to handle failure.

                Instances For
                  def OracleComp.induction {ι : Type u} {spec : OracleSpec ι} {α : Type v} {C : OracleComp spec αProp} (oa : OracleComp spec α) (pure : ∀ (a : α), C (pure a)) (query_bind : ∀ (t : spec.Domain) (oa : spec.Range tOracleComp spec α), (∀ (u : spec.Range t), C (oa u))C (liftM (OracleSpec.query t) >>= oa)) :
                  C oa

                  Version of OracleComp.inductionOn with the computation at the start.

                  Instances For
                    def OracleComp.inductionOptional {ι : Type u} {spec : OracleSpec ι} {α : Type v} {C : OptionT (OracleComp spec) αProp} (oa : OptionT (OracleComp spec) α) (pure : ∀ (a : α), C (pure a)) (query_bind : ∀ (t : spec.Domain) (oa : spec.Range tOptionT (OracleComp spec) α), (∀ (u : spec.Range t), C (oa u))C (liftM (OracleSpec.query t) >>= oa)) (failure : C failure) :
                    C oa

                    Version of OracleComp.inductionOnOptional with the computation at the start.

                    Instances For
                      def OracleComp.construct {ι : Type u} {spec : OracleSpec ι} {α : Type v} {C : OracleComp spec αType u_1} (pure : (a : α) → C (pure a)) (query_bind : (t : spec.Domain) → (oa : spec.Range tOracleComp spec α) → ((u : spec.Range t) → C (oa u))C (liftM (OracleSpec.query t) >>= oa)) (oa : OracleComp spec α) :
                      C oa

                      Version of construct with automatic induction on the query in when defining the query_bind case. Can be useful with spec.DecidableEq and spec.FiniteRange. mapM/simulateQ is usually preferable to this if the object being constructed is a monad.

                      Instances For
                        @[simp]
                        theorem OracleComp.construct_pure {ι : Type u} {spec : OracleSpec ι} {α : Type v} (x : α) {C : OracleComp spec αType u_1} (h_pure : (a : α) → C (pure a)) (h_query_bind : (t : spec.Domain) → (oa : spec.Range tOracleComp spec α) → ((u : spec.Range t) → C (oa u))C (liftM (OracleSpec.query t) >>= oa)) :
                        OracleComp.construct h_pure h_query_bind (pure x) = h_pure x
                        @[simp]
                        theorem OracleComp.construct_query {ι : Type u} {spec : OracleSpec ι} (t : spec.Domain) {C : OracleComp spec (spec.Range t)Type u_1} (h_pure : (u : spec.Range t) → C (pure u)) (h_query_bind : (t' : spec.Domain) → (oa : spec.Range t'OracleComp spec (spec.Range t)) → ((u : spec.Range t') → C (oa u))C (liftM (OracleSpec.query t') >>= oa)) :
                        OracleComp.construct h_pure h_query_bind (liftM (OracleSpec.query t)) = h_query_bind t pure h_pure
                        @[simp]
                        theorem OracleComp.construct_query_bind {ι : Type u} {spec : OracleSpec ι} {α : Type v} (t : spec.Domain) (mx : spec.Range tOracleComp spec α) {C : OracleComp spec αType u_1} (h_pure : (a : α) → C (pure a)) (h_query_bind : (t : spec.Domain) → (mx : spec.Range tOracleComp spec α) → ((u : spec.Range t) → C (mx u))C (liftM (OracleSpec.query t) >>= mx)) :
                        OracleComp.construct h_pure h_query_bind (liftM (OracleSpec.query t) >>= mx) = h_query_bind t mx fun (u : spec.Range t) => OracleComp.construct h_pure h_query_bind (mx u)
                        def OracleComp.isPure {ι : Type u} {spec : OracleSpec ι} {α : Type u_1} :
                        OracleComp spec αBool

                        Returns true for computations that don't query any oracles or fail, else false.

                        Instances For
                          @[simp]
                          theorem OracleComp.isPure_pure {α : Type v} {ι : Type u} {spec : OracleSpec ι} (x : α) :
                          @[simp]
                          theorem OracleComp.isPure_query {ι : Type u} {spec : OracleSpec ι} (t : spec.Domain) :
                          @[simp]
                          theorem OracleComp.isPure_query_bind {α : Type v} {ι : Type u} {spec : OracleSpec ι} (t : spec.Domain) (ou : spec.Range tOracleComp spec α) :
                          @[simp]
                          theorem OracleComp.pure_ne_query {ι : Type u} {spec : OracleSpec ι} (t : spec.Domain) (u : spec.Range t) :
                          @[simp]
                          theorem OracleComp.query_ne_pure {ι : Type u} {spec : OracleSpec ι} (t : spec.Domain) (u : spec.Range t) :
                          theorem OracleComp.pure_eq_query_iff_false {ι : Type u} {spec : OracleSpec ι} (t : spec.Domain) (u : spec.Range t) :
                          theorem OracleComp.query_eq_pure_iff_false {ι : Type u} {spec : OracleSpec ι} (t : spec.Domain) (u : spec.Range t) :
                          def OracleComp.defaultResult {α : Type v} {ι : Type u} {spec : OracleSpec ι} [spec.Inhabited] (oa : OracleComp spec α) :
                          α

                          Given a computation oa : OracleComp spec α, construct a value x : α, by assuming each query returns the default value given by the Inhabited instance.

                          Instances For
                            def OracleComp.totalQueries {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] {α : Type v} (oa : OracleComp spec α) :

                            Total number of queries in a computation across all possible execution paths. Can be a helpful alternative to sizeOf when proving recursive calls terminate.

                            Instances For
                              @[simp]
                              theorem OracleComp.pure_inj {α : Type v} {ι : Type u} {spec : OracleSpec ι} (x y : α) :
                              pure x = pure y x = y

                              Two pure computations are equal iff they return the same value.

                              @[simp]
                              theorem OracleComp.bind_eq_pure_iff {α β : Type v} {ι : Type u} {spec : OracleSpec ι} (oa : OracleComp spec α) (ob : αOracleComp spec β) (y : β) :
                              oa >>= ob = pure y ∃ (x : α), oa = pure x ob x = pure y

                              Binding two computations gives a pure operation iff the first computation is pure and the second computation does something pure with the result.

                              @[simp]
                              theorem OracleComp.pure_eq_bind_iff {α β : Type v} {ι : Type u} {spec : OracleSpec ι} (oa : OracleComp spec α) (ob : αOracleComp spec β) (y : β) :
                              pure y = oa >>= ob ∃ (x : α), oa = pure x ob x = pure y

                              Binding two computations gives a pure operation iff the first computation is pure and the second computation does something pure with the result.

                              theorem OracleComp.bind_eq_pure {α β : Type v} {ι : Type u} {spec : OracleSpec ι} (oa : OracleComp spec α) (ob : αOracleComp spec β) (y : β) :
                              (∃ (x : α), oa = pure x ob x = pure y)oa >>= ob = pure y

                              Alias of the reverse direction of OracleComp.bind_eq_pure_iff.


                              Binding two computations gives a pure operation iff the first computation is pure and the second computation does something pure with the result.

                              theorem OracleComp.pure_eq_bind {α β : Type v} {ι : Type u} {spec : OracleSpec ι} (oa : OracleComp spec α) (ob : αOracleComp spec β) (y : β) :
                              (∃ (x : α), oa = pure x ob x = pure y)pure y = oa >>= ob

                              Alias of the reverse direction of OracleComp.pure_eq_bind_iff.


                              Binding two computations gives a pure operation iff the first computation is pure and the second computation does something pure with the result.