Documentation

VCVio.OracleComp.OracleComp

Computations with Oracle Access #

A value oa : OracleComp spec α represents a computation with return type α, with access to any of the oracles specified by spec : OracleSpec. Returning a value x corresponds to the computation pure' α x. The computation queryBind' i t α ou represents querying the oracle corresponding to index i on input t, getting a result u : spec.range i, and then running ou u. We also allow for a failure' operation for quitting out. These operations induce Monad and Alternative instances on OracleComp spec.

pure' α a gives a monadic pure operation, while a more general >>= operator is derived by induction on the first computation (see OracleComp.bind). This importantly allows us to define a LawfulMonad instance on OracleComp spec, which isn't possible if a general bind operator is included in the main syntax.

We also define simple operations like coin : OracleComp coinSpec Bool for flipping a fair coin, and $[0..n] : ProbComp (Fin (n + 1)) for selecting from an inclusive range.

Note that the monadic structure on OracleComp exists only for a fixed OracleSpec, so it isn't possible to combine computations where one has a superset of oracles of the other. We later introduce a set of type coercions that mitigate this for most common cases, such as calling a computation with spec as part of a computation with spec ++ spec'.

inductive OracleSpec.OracleQuery {ι : Type u} (spec : OracleSpec ι) :
Type v → Type (max u v)

An OracleQuery to one of the oracles in spec, bundling an index and the input to use for querying that oracle, implemented as a dependent pair. Implemented as a functor with the oracle output type as the constructor result.

Instances For
    def OracleSpec.OracleQuery.defaultOutput {ι : Type u} {spec : OracleSpec ι} {α : Type v} [(i : ι) → Inhabited (spec.range i)] (q : spec.OracleQuery α) :
    α
    Equations
      Instances For
        def OracleSpec.OracleQuery.index {ι : Type u} {spec : OracleSpec ι} {α : Type v} (q : spec.OracleQuery α) :
        ι
        Equations
          Instances For
            @[simp]
            theorem OracleSpec.OracleQuery.index_query {ι : Type u} {spec : OracleSpec ι} (i : ι) (t : spec.domain i) :
            (query i t).index = i
            def OracleSpec.OracleQuery.input {ι : Type u} {spec : OracleSpec ι} {α : Type v} (q : spec.OracleQuery α) :
            spec.domain q.index
            Equations
              Instances For
                @[simp]
                theorem OracleSpec.OracleQuery.input_query {ι : Type u} {spec : OracleSpec ι} (i : ι) (t : spec.domain i) :
                (query i t).input = t
                @[simp]
                theorem OracleSpec.OracleQuery.range_index {ι : Type u} {spec : OracleSpec ι} {α : Type v} (q : spec.OracleQuery α) :
                spec.range q.index = α
                theorem OracleSpec.OracleQuery.eq_query_index_input {ι : Type u} {spec : OracleSpec ι} {α : Type v} (q : spec.OracleQuery α) :
                q = query q.index q.input
                def OracleSpec.OracleQuery.rangeDecidableEq {ι : Type u} {spec : OracleSpec ι} {α : Type v} [spec.DecidableEq] :
                spec.OracleQuery αDecidableEq α
                Equations
                  Instances For
                    def OracleSpec.OracleQuery.rangeFintype {ι : Type u} {spec : OracleSpec ι} {α : Type v} [spec.FiniteRange] :
                    spec.OracleQuery αFintype α
                    Equations
                      Instances For
                        def OracleSpec.OracleQuery.rangeInhabited {ι : Type u} {spec : OracleSpec ι} {α : Type v} [spec.FiniteRange] :
                        spec.OracleQuery αInhabited α
                        Equations
                          Instances For
                            instance OracleSpec.OracleQuery.instDecidableEqOfDomain {ι : Type u} {spec : OracleSpec ι} [ : DecidableEq ι] [hd : (i : ι) → DecidableEq (spec.domain i)] {α : Type u} :
                            Equations
                              def OracleComp {ι : Type u} (spec : OracleSpec ι) :
                              Type w → Type (max u (v + 1) w)

                              OracleComp spec α represents computations with oracle access to oracles in spec, where the final return value has type α. The basic computation is just an OracleQuery, augmented with pure and bind by FreeMonad, and failure is also added after by the OptionT transformer.

                              In practive computations in OracleComp spec α have have one of three forms:

                              • return x to succeed with some x : α as the result.
                              • do u ← query i t; oa u where oa is a continutation to run with the query result
                              • failure which terminates the computation early See OracleComp.inductionOn for an explicit induction principle.
                              Equations
                                Instances For
                                  @[reducible, inline]
                                  abbrev ProbComp :
                                  Type z → Type (max z 1)

                                  Simplified notation for computations with no oracles besides random inputs.

                                  Equations
                                    Instances For
                                      instance OracleComp.instInhabited {ι : Type u} {spec : OracleSpec ι} {α : Type v} :
                                      Equations
                                        def OracleComp.lift {ι : Type u} {spec : OracleSpec ι} {α : Type v} (q : spec.OracleQuery α) :
                                        OracleComp spec α

                                        Lift a query by first lifting to the free moand and then to the option.

                                        Equations
                                          Instances For

                                            Automatically coerce an OracleQuery spec α to an OracleComp spec α.

                                            Equations

                                              Lift a function on oracle queries to one on oracle computations.

                                              Equations
                                                theorem OracleComp.liftM_def {ι : Type u} {spec : OracleSpec ι} {α : Type v} (q : spec.OracleQuery α) :
                                                theorem OracleComp.lift_query_def {ι : Type u} {spec : OracleSpec ι} {α : Type v} (q : spec.OracleQuery α) :

                                                Alias of OracleComp.liftM_def.

                                                theorem OracleComp.liftM_query_eq_liftM_liftM {ι : Type u} {spec : OracleSpec ι} {m : Type v → Type z} [MonadLift (OracleComp spec) m] {α : Type v} (q : spec.OracleQuery α) :
                                                @[simp]
                                                theorem OracleComp.liftM_query_stateT {ι : Type u} {spec : OracleSpec ι} {σ α : Type v} (q : spec.OracleQuery α) :
                                                @[simp]
                                                theorem OracleComp.liftM_query_writerT {ι : Type u} {spec : OracleSpec ι} {ω : Type v} [Monoid ω] {α : Type v} (q : spec.OracleQuery α) :
                                                @[simp]
                                                theorem OracleComp.liftM_query_readerT {ι : Type u} {spec : OracleSpec ι} {ρ α : Type v} (q : spec.OracleQuery α) :
                                                theorem OracleComp.query_bind_eq_roll {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (q : spec.OracleQuery α) (ob : αOracleComp spec β) :
                                                theorem OracleComp.pure_def {ι : Type u} {spec : OracleSpec ι} {α : Type v} (x : α) :
                                                theorem OracleComp.bind_def {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (oa : OracleComp spec α) (ob : αOracleComp spec β) :
                                                oa >>= ob = OptionT.bind oa ob
                                                theorem OracleComp.failure_def {ι : Type u} {spec : OracleSpec ι} {α : Type v} :
                                                theorem OracleComp.orElse_def {ι : Type u} {spec : OracleSpec ι} {α : Type v} (oa oa' : OracleComp spec α) :
                                                (oa <|> oa') = OptionT.mk do let __do_liftOptionT.run oa match __do_lift with | some a => pure (some a) | x => OptionT.run oa'
                                                theorem OracleComp.bind_congr' {ι : Type u} {spec : OracleSpec ι} {α β : Type v} {oa oa' : OracleComp spec α} {ob ob' : αOracleComp spec β} (h : oa = oa') (h' : ∀ (x : α), ob x = ob' x) :
                                                oa >>= ob = oa' >>= ob'
                                                @[reducible, inline]

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

                                                Equations
                                                  Instances For
                                                    @[reducible, inline]

                                                    $[0..n] is the computation choosing a random value in the given range, inclusively. By making this range inclusive we avoid the case of choosing from the empty range.

                                                    Equations
                                                      Instances For
                                                        @[reducible, inline]
                                                        Equations
                                                          Instances For
                                                            @[simp]
                                                            theorem OracleComp.guard_eq {ι : Type} {spec : OracleSpec ι} (p : Prop) [Decidable p] :
                                                            theorem OracleComp.ite_bind {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (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 : ∀ (i : ι) (t : spec.domain i) (oa : spec.range iOracleComp spec α), (∀ (u : spec.range i), C (oa u))C (liftM (OracleSpec.query i t) >>= oa)) (failure : C failure) (oa : OracleComp spec α) :
                                                            C oa

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

                                                            • return x / pure x for any x
                                                            • do let u ← query i t; oa u (with inductive results for oa u)
                                                            • failure 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.
                                                            Equations
                                                              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 : ∀ (i : ι) (t : spec.domain i) (oa : spec.range iOracleComp spec α), (∀ (u : spec.range i), C (oa u))C (liftM (OracleSpec.query i t) >>= oa)) (failure : C failure) :
                                                                C oa
                                                                Equations
                                                                  Instances For
                                                                    def OracleComp.construct {ι : Type u} {spec : OracleSpec ι} {α : Type v} {C : OracleComp spec αType u_1} (pure : (a : α) → C (pure a)) (query_bind : {β : Type v} → (q : spec.OracleQuery β) → (oa : βOracleComp spec α) → ((u : β) → C (oa u))C (liftM q >>= oa)) (failure : C failure) (oa : OracleComp spec α) :
                                                                    C oa

                                                                    NOTE: if inductionOn could work with Sort u instead of Prop we wouldn't need this, not clear to me why lean doesn't like unifying the Prop and Type cases.

                                                                    If the output type of C is a monad then OracleComp.mapM is usually preferable.

                                                                    Equations
                                                                      Instances For
                                                                        def OracleComp.construct' {ι : Type u} {spec : OracleSpec ι} {α : Type v} {C : OracleComp spec αType u_1} (pure : (a : α) → C (pure a)) (query_bind : (i : ι) → (t : spec.domain i) → (oa : spec.range iOracleComp spec α) → ((u : spec.range i) → C (oa u))C (liftM (OracleSpec.query i t) >>= oa)) (failure : C failure) (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. NOTE: may be better to just use this universally in all cases? avoids duplicating lemmas below.

                                                                        Equations
                                                                          Instances For
                                                                            @[simp]
                                                                            theorem OracleComp.construct_pure {ι : Type u} {spec : OracleSpec ι} {α : Type v} {C : OracleComp spec αType w} (h_pure : (a : α) → C (pure a)) (h_query_bind : {β : Type v} → (q : spec.OracleQuery β) → (oa : βOracleComp spec α) → ((u : β) → C (oa u))C (liftM q >>= oa)) (h_failure : C failure) (x : α) :
                                                                            OracleComp.construct h_pure (fun {β : Type v} => h_query_bind) h_failure (pure x) = h_pure x
                                                                            @[simp]
                                                                            theorem OracleComp.construct_failure {ι : Type u} {spec : OracleSpec ι} {α : Type v} {C : OracleComp spec αType w} (h_pure : (a : α) → C (pure a)) (h_query_bind : {β : Type v} → (q : spec.OracleQuery β) → (oa : βOracleComp spec α) → ((u : β) → C (oa u))C (liftM q >>= oa)) (h_failure : C failure) :
                                                                            OracleComp.construct h_pure (fun {β : Type v} => h_query_bind) h_failure failure = h_failure
                                                                            @[simp]
                                                                            theorem OracleComp.construct_query {ι : Type u} {spec : OracleSpec ι} {α : Type v} {C : OracleComp spec αType w} (h_pure : (a : α) → C (pure a)) (h_query_bind : {β : Type v} → (q : spec.OracleQuery β) → (oa : βOracleComp spec α) → ((u : β) → C (oa u))C (liftM q >>= oa)) (h_failure : C failure) (q : spec.OracleQuery α) :
                                                                            OracleComp.construct h_pure (fun {β : Type v} => h_query_bind) h_failure (liftM q) = h_query_bind q pure h_pure
                                                                            theorem OracleComp.construct_liftM {ι : Type u} {spec : OracleSpec ι} {α : Type v} {C : OracleComp spec αType w} (h_pure : (a : α) → C (pure a)) (h_query_bind : {β : Type v} → (q : spec.OracleQuery β) → (oa : βOracleComp spec α) → ((u : β) → C (oa u))C (liftM q >>= oa)) (h_failure : C failure) (q : spec.OracleQuery α) :
                                                                            OracleComp.construct h_pure (fun {β : Type v} => h_query_bind) h_failure (liftM q) = h_query_bind q pure h_pure

                                                                            Alias of OracleComp.construct_query.

                                                                            @[simp]
                                                                            theorem OracleComp.construct_query_bind {ι : Type u} {spec : OracleSpec ι} {α β : Type v} {C : OracleComp spec αType w} (h_pure : (a : α) → C (pure a)) (h_query_bind : {β : Type v} → (q : spec.OracleQuery β) → (oa : βOracleComp spec α) → ((u : β) → C (oa u))C (liftM q >>= oa)) (h_failure : C failure) (q : spec.OracleQuery β) (oa : βOracleComp spec α) :
                                                                            OracleComp.construct h_pure (fun {β : Type v} => h_query_bind) h_failure (liftM q >>= oa) = h_query_bind q oa fun (u : β) => OracleComp.construct h_pure (fun {β : Type v} => h_query_bind) h_failure (oa u)
                                                                            @[simp]
                                                                            theorem OracleComp.construct_roll {ι : Type u} {spec : OracleSpec ι} {α β : Type v} {C : OracleComp spec αType w} (h_pure : (a : α) → C (pure a)) (h_query_bind : {β : Type v} → (q : spec.OracleQuery β) → (oa : βOracleComp spec α) → ((u : β) → C (oa u))C (liftM q >>= oa)) (h_failure : C failure) (q : spec.OracleQuery β) (oa : βOracleComp spec α) :
                                                                            OracleComp.construct h_pure (fun {β : Type v} => h_query_bind) h_failure (OptionT.mk (FreeMonad.roll q oa)) = h_query_bind q oa fun (u : β) => OracleComp.construct h_pure (fun {β : Type v} => h_query_bind) h_failure (oa u)
                                                                            def OracleComp.isPure {ι : Type u} {spec : OracleSpec ι} {α : Type v} :
                                                                            OracleComp spec αBool

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

                                                                            Equations
                                                                              Instances For
                                                                                def OracleComp.isFailure {ι : Type u} {spec : OracleSpec ι} {α : Type v} :
                                                                                OracleComp spec αBool

                                                                                Returns true for computations that fail else false.

                                                                                Equations
                                                                                  Instances For
                                                                                    @[simp]
                                                                                    theorem OracleComp.isPure_pure {ι : Type u} {spec : OracleSpec ι} {α : Type v} (x : α) :
                                                                                    @[simp]
                                                                                    theorem OracleComp.isPure_query_bind {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (q : spec.OracleQuery β) (oa : βOracleComp spec α) :
                                                                                    @[simp]
                                                                                    theorem OracleComp.isPure_failure {ι : Type u} {spec : OracleSpec ι} {α : Type v} :
                                                                                    @[simp]
                                                                                    theorem OracleComp.isFailure_pure {ι : Type u} {spec : OracleSpec ι} {α : Type v} (x : α) :
                                                                                    @[simp]
                                                                                    theorem OracleComp.isFailure_query_bind {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (q : spec.OracleQuery β) (oa : βOracleComp spec α) :
                                                                                    @[simp]
                                                                                    theorem OracleComp.isFailure_failure {ι : Type u} {spec : OracleSpec ι} {α : Type v} :
                                                                                    theorem OracleComp.exists_eq_of_isPure {ι : Type u} {spec : OracleSpec ι} {α : Type v} {oa : OracleComp spec α} (h : oa.isPure = true) :
                                                                                    ∃ (x : α), oa = pure x
                                                                                    theorem OracleComp.eq_failure_of_isFailure {ι : Type u} {spec : OracleSpec ι} {α : Type v} {oa : OracleComp spec α} (h : oa.isFailure = true) :
                                                                                    @[simp]
                                                                                    theorem OracleComp.pure_ne_query {ι : Type u} {spec : OracleSpec ι} {β : Type v} (y : β) (q : spec.OracleQuery β) :
                                                                                    @[simp]
                                                                                    theorem OracleComp.query_ne_pure {ι : Type u} {spec : OracleSpec ι} {β : Type v} (y : β) (q : spec.OracleQuery β) :
                                                                                    @[simp]
                                                                                    theorem OracleComp.pure_ne_query_bind {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (x : α) (q : spec.OracleQuery β) (oa : βOracleComp spec α) :
                                                                                    pure x liftM q >>= oa
                                                                                    @[simp]
                                                                                    theorem OracleComp.query_bind_ne_pure {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (x : α) (q : spec.OracleQuery β) (oa : βOracleComp spec α) :
                                                                                    liftM q >>= oa pure x
                                                                                    @[simp]
                                                                                    theorem OracleComp.pure_ne_failure {ι : Type u} {spec : OracleSpec ι} {α : Type v} (x : α) :
                                                                                    @[simp]
                                                                                    theorem OracleComp.failure_ne_pure {ι : Type u} {spec : OracleSpec ι} {α : Type v} (x : α) :
                                                                                    @[simp]
                                                                                    theorem OracleComp.failure_ne_query_bind {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (q : spec.OracleQuery β) (oa : βOracleComp spec α) :
                                                                                    @[simp]
                                                                                    theorem OracleComp.query_bind_ne_failure {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (q : spec.OracleQuery β) (oa : βOracleComp spec α) :
                                                                                    @[simp]
                                                                                    theorem OracleComp.query_ne_failure {ι : Type u} {spec : OracleSpec ι} {β : Type v} (q : spec.OracleQuery β) :
                                                                                    @[simp]
                                                                                    theorem OracleComp.failure_ne_query {ι : Type u} {spec : OracleSpec ι} {β : Type v} (q : spec.OracleQuery β) :
                                                                                    theorem OracleComp.pure_eq_query_iff_false {ι : Type u} {spec : OracleSpec ι} {β : Type v} (y : β) (q : spec.OracleQuery β) :
                                                                                    theorem OracleComp.query_eq_pure_iff_false {ι : Type u} {spec : OracleSpec ι} {β : Type v} (y : β) (q : spec.OracleQuery β) :
                                                                                    def OracleComp.mapM {ι : Type u} {spec : OracleSpec ι} {α : Type v} {m : Type v → Type w} [Monad m] (fail : {α : Type v} → m α) (query_map : {α : Type v} → spec.OracleQuery αm α) (oa : OracleComp spec α) :
                                                                                    m α

                                                                                    Implement all queries in a computation using some other monad m, preserving the pure and bind operations, giving a computation in the new monad. The function qm specifies how to replace the queries in the computation, and fail is used whenever failure is encountered. If the final output type has an Alternative instance then simulate is usually preffered.

                                                                                    Equations
                                                                                      Instances For
                                                                                        @[simp]
                                                                                        theorem OracleComp.mapM_pure {ι : Type u} {spec : OracleSpec ι} {α : Type v} {m : Type v → Type w} [Monad m] (fail : {α : Type v} → m α) (qm : {α : Type v} → spec.OracleQuery αm α) (x : α) :
                                                                                        OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) (pure x) = pure x
                                                                                        @[simp]
                                                                                        theorem OracleComp.mapM_failure {ι : Type u} {spec : OracleSpec ι} {α : Type v} {m : Type v → Type w} [Monad m] (fail : {α : Type v} → m α) (qm : {α : Type v} → spec.OracleQuery αm α) :
                                                                                        OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) failure = fail
                                                                                        @[simp]
                                                                                        theorem OracleComp.mapM_query {ι : Type u} {spec : OracleSpec ι} {α : Type v} {m : Type v → Type w} [Monad m] (fail : {α : Type v} → m α) (qm : {α : Type v} → spec.OracleQuery αm α) [LawfulMonad m] (q : spec.OracleQuery α) :
                                                                                        OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) (liftM q) = qm q
                                                                                        @[simp]
                                                                                        theorem OracleComp.mapM_query_bind {ι : Type u} {spec : OracleSpec ι} {α β : Type v} {m : Type v → Type w} [Monad m] (fail : {α : Type v} → m α) (qm : {α : Type v} → spec.OracleQuery αm α) (q : spec.OracleQuery α) (ob : αOracleComp spec β) :
                                                                                        OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) (liftM q >>= ob) = do let xqm q OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) (ob x)
                                                                                        theorem OracleComp.mapM_bind {ι : Type u} {spec : OracleSpec ι} {α β : Type v} {m : Type v → Type w} [Monad m] (fail : {α : Type v} → m α) (qm : {α : Type v} → spec.OracleQuery αm α) [LawfulMonad m] (oa : OracleComp spec α) (ob : αOracleComp spec β) (hfail : ∀ (f : αm β), fail >>= f = fail) :
                                                                                        OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) (oa >>= ob) = do let xOracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) oa OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) (ob x)
                                                                                        @[simp]
                                                                                        theorem OracleComp.mapM_bind' {ι : Type u} {spec : OracleSpec ι} {α β : Type v} {m : Type v → Type w} [AlternativeMonad m] [LawfulMonad m] [LawfulAlternative m] (qm : {α : Type v} → spec.OracleQuery αm α) (oa : OracleComp spec α) (ob : αOracleComp spec β) :
                                                                                        OracleComp.mapM (fun {α : Type v} => failure) (fun {α : Type v} => qm) (oa >>= ob) = do let xOracleComp.mapM (fun {α : Type v} => failure) (fun {α : Type v} => qm) oa OracleComp.mapM (fun {α : Type v} => failure) (fun {α : Type v} => qm) (ob x)
                                                                                        theorem OracleComp.mapM_map {ι : Type u} {spec : OracleSpec ι} {α β : Type v} {m : Type v → Type w} [Monad m] (fail : {α : Type v} → m α) (qm : {α : Type v} → spec.OracleQuery αm α) [LawfulMonad m] (oa : OracleComp spec α) (f : αβ) (hfail : ∀ (f : αβ), f <$> fail = fail) :
                                                                                        OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) (f <$> oa) = f <$> OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) oa
                                                                                        @[simp]
                                                                                        theorem OracleComp.mapM_map' {ι : Type u} {spec : OracleSpec ι} {α β : Type v} {m : Type v → Type w} [AlternativeMonad m] [LawfulAlternative m] [LawfulMonad m] (qm : {α : Type v} → spec.OracleQuery αm α) (oa : OracleComp spec α) (f : αβ) :
                                                                                        OracleComp.mapM (fun {α : Type v} => failure) (fun {α : Type v} => qm) (f <$> oa) = f <$> OracleComp.mapM (fun {α : Type v} => failure) (fun {α : Type v} => qm) oa
                                                                                        theorem OracleComp.mapM_seq {ι : Type u} {spec : OracleSpec ι} {α β : Type v} {m : Type v → Type w} [Monad m] (fail : {α : Type v} → m α) (qm : {α : Type v} → spec.OracleQuery αm α) [LawfulMonad m] (og : OracleComp spec (αβ)) (oa : OracleComp spec α) (hfail : ∀ (f : (αβ)m β), fail >>= f = fail) (hfail' : ∀ (f : αβ), f <$> fail = fail) :
                                                                                        OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) (og <*> oa) = OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) og <*> OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) oa
                                                                                        @[simp]
                                                                                        theorem OracleComp.mapM_ite {ι : Type u} {spec : OracleSpec ι} {α : Type v} {m : Type v → Type w} [Monad m] (fail : {α : Type v} → m α) (qm : {α : Type v} → spec.OracleQuery αm α) (p : Prop) [Decidable p] (oa oa' : OracleComp spec α) :
                                                                                        OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) (if p then oa else oa') = if p then OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) oa else OracleComp.mapM (fun {α : Type v} => fail) (fun {α : Type v} => qm) oa'
                                                                                        def OracleComp.defaultResult {ι : Type u} {spec : OracleSpec ι} {α : Type v} [spec.FiniteRange] (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. Returns none if the default path would lead to failure.

                                                                                        Equations
                                                                                          Instances For
                                                                                            def OracleComp.totalQueries {ι : Type u} {spec : OracleSpec ι} [spec.FiniteRange] {α : 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.

                                                                                            Equations
                                                                                              Instances For
                                                                                                @[simp]
                                                                                                theorem OracleComp.pure_inj {ι : Type u} {spec : OracleSpec ι} {α : Type v} (x y : α) :
                                                                                                pure x = pure y x = y
                                                                                                @[simp]
                                                                                                theorem OracleComp.liftM_inj {ι : Type u} {spec : OracleSpec ι} {α : Type v} (q q' : spec.OracleQuery α) :
                                                                                                liftM q = liftM q' q = q'
                                                                                                @[simp]
                                                                                                theorem OracleComp.query_inj {ι : Type u} {spec : OracleSpec ι} (i : ι) (t t' : spec.domain i) :
                                                                                                @[simp]
                                                                                                theorem OracleComp.queryBind_inj {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (q q' : spec.OracleQuery α) (ob ob' : αOracleComp spec β) :
                                                                                                liftM q >>= ob = liftM q' >>= ob' q = q' ob = ob'
                                                                                                @[simp]
                                                                                                theorem OracleComp.bind_eq_pure_iff {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (oa : OracleComp spec α) (ob : αOracleComp spec β) (y : β) :
                                                                                                oa >>= ob = pure y ∃ (x : α), oa = pure x ob x = pure y
                                                                                                @[simp]
                                                                                                theorem OracleComp.pure_eq_bind_iff {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (oa : OracleComp spec α) (ob : αOracleComp spec β) (y : β) :
                                                                                                pure y = oa >>= ob ∃ (x : α), oa = pure x ob x = pure y
                                                                                                theorem OracleComp.bind_eq_pure {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (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.

                                                                                                theorem OracleComp.pure_eq_bind {ι : Type u} {spec : OracleSpec ι} {α β : Type v} (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.

                                                                                                instance OracleComp.instDecidableEq {ι : Type u} {spec : OracleSpec ι} {α : Type v} [spec.FiniteRange] [hd : (i : ι) → DecidableEq (spec.domain i)] [ : DecidableEq ι] [h : DecidableEq α] :

                                                                                                If the oracle indexing-type ι, output type α, and domains of all oracles have DecidableEq then OracleComp spec α also has DecidableEq.

                                                                                                Equations