Documentation

Complexity.Languages.Probabilistic.QueryCount

Query budgets #

OracleComp.IsCostBounded cost program n says that on every path through the tree of calls of program, whatever the answers, the calls cost at most n in total, where a call q costs cost q. This is the library's notion of a query budget; the others are instances of it.

Budgets are proved and used by induction on the program. They are preserved by sequencing (IsCostBounded.bind), add over costs (IsCostBounded.add), and compose with handlers whose calls are budgeted in turn (IsCostBounded.run_interpret). Against every stateful oracle, the calls that OracleComp.withTranscript records respect the budget (IsCostBounded.transcript_cost_le). A budget says nothing about running time.

Main definitions #

Main results #

inductive Cslib.OracleComp.IsCostBounded {ι : Type u} {spec : OracleSpec ι} {α : Type v} (cost : ι → ℕ) :
OracleComp spec α → ℕ → Prop

The calls of the program cost at most n in total on every path, whatever the answers, where a call q costs cost q.

Instances For
    @[reducible, inline]
    abbrev Cslib.OracleComp.IsQueryBounded {ι : Type u} {spec : OracleSpec ι} {α : Type v} (program : OracleComp spec α) (n : ℕ) :

    The program makes at most n oracle calls on every path, whatever the answers.

    Instances For
      theorem Cslib.OracleComp.IsCostBounded.mono {ι : Type u} {spec : OracleSpec ι} {α : Type v} {cost : ι → ℕ} {program : OracleComp spec α} {n m : ℕ} (h : IsCostBounded cost program n) (hnm : n ≤ m) :
      IsCostBounded cost program m

      A larger budget is still a budget.

      theorem Cslib.OracleComp.IsCostBounded.liftBind_iff {ι : Type u} {spec : OracleSpec ι} {α : Type v} {cost : ι → ℕ} {q : ι} {cont : spec q → OracleComp spec α} {n : ℕ} :
      IsCostBounded cost (PFunctor.FreeM.liftBind q cont) n ↔ cost q ≤ n ∧ ∀ (a : spec q), IsCostBounded cost (cont a) (n - cost q)

      A budget for a call's continuations, from a budget for the call.

      theorem Cslib.OracleComp.IsCostBounded.query {ι : Type u} {spec : OracleSpec ι} {cost : ι → ℕ} (q : ι) :

      One call costs its cost.

      theorem Cslib.OracleComp.IsCostBounded.bind {ι : Type u} {spec : OracleSpec ι} {α β : Type v} {cost : ι → ℕ} {program : OracleComp spec α} {next : α → OracleComp spec β} {n m : ℕ} (h : IsCostBounded cost program n) (hnext : ∀ (a : α), IsCostBounded cost (next a) m) :
      IsCostBounded cost (program >>= next) (n + m)

      Budgets add under sequencing.

      theorem Cslib.OracleComp.IsCostBounded.of_forall_cost_eq_zero {ι : Type u} {spec : OracleSpec ι} {α : Type v} {cost : ι → ℕ} (hcost : ∀ (q : ι), cost q = 0) (program : OracleComp spec α) :
      IsCostBounded cost program 0

      Calls that cost nothing fit in a zero budget.

      theorem Cslib.OracleComp.IsCostBounded.of_le {ι : Type u} {spec : OracleSpec ι} {α : Type v} {cost cost' : ι → ℕ} {program : OracleComp spec α} {n : ℕ} (h : IsCostBounded cost program n) (hcost : ∀ (q : ι), cost' q ≤ cost q) :
      IsCostBounded cost' program n

      A budget for a cost is one for every smaller cost.

      theorem Cslib.OracleComp.IsCostBounded.add {ι : Type u} {spec : OracleSpec ι} {α : Type v} {cost cost' : ι → ℕ} {program : OracleComp spec α} {n n' : ℕ} (h : IsCostBounded cost program n) (h' : IsCostBounded cost' program n') :
      IsCostBounded (fun (q : ι) => cost q + cost' q) program (n + n')

      Budgets for two costs give a budget for their sum.

      theorem Cslib.OracleComp.IsCostBounded.interpret {ι : Type u} {spec : OracleSpec ι} {α : Type v} {cost : ι → ℕ} {κ : Type u} {target : OracleSpec κ} {cost' : κ → ℕ} {handler : (q : ι) → OracleComp target (spec q)} (hhandler : ∀ (q : ι), IsCostBounded cost' (handler q) (cost q)) {program : OracleComp spec α} {n : ℕ} (h : IsCostBounded cost program n) :
      IsCostBounded cost' (OracleComp.interpret handler program) n

      A program whose calls are replaced by programs over another interface, each call q costing at most cost q there, costs at most n there when its own calls cost at most n.

      theorem Cslib.OracleComp.IsCostBounded.run_interpret {ι : Type u} {spec : OracleSpec ι} {α : Type v} {cost : ι → ℕ} {κ : Type u} {target : OracleSpec κ} {cost' : κ → ℕ} {σ : Type v} {handler : (q : ι) → StateT σ (OracleComp target) (spec q)} (hhandler : ∀ (q : ι) (s : σ), IsCostBounded cost' ((handler q).run s) (cost q)) {program : OracleComp spec α} {n : ℕ} (h : IsCostBounded cost program n) (s : σ) :
      IsCostBounded cost' ((OracleComp.interpret handler program).run s) n

      A program run through a stateful handler, each of whose calls q costs at most cost q on the target interface, costs at most n there when its own calls cost at most n.

      @[simp]
      theorem Cslib.OracleComp.isCostBounded_map_iff {ι : Type u} {spec : OracleSpec ι} {α β : Type v} {cost : ι → ℕ} (f : α → β) (program : OracleComp spec α) (n : ℕ) :
      IsCostBounded cost (f <$> program) n ↔ IsCostBounded cost program n

      Postprocessing the result makes no call.

      Every call satisfies a predicate #

      def Cslib.OracleComp.QueriesSatisfy {ι : Type u} {spec : OracleSpec ι} {α : Type v} (p : ι → Prop) (program : OracleComp spec α) :

      Every call of program, on every path and whatever the answers, satisfies p: the calls outside p have a zero budget.

      Instances For
        theorem Cslib.OracleComp.QueriesSatisfy.liftBind_iff {ι : Type u} {spec : OracleSpec ι} {α : Type v} {p : ι → Prop} {q : ι} {cont : spec q → OracleComp spec α} :
        QueriesSatisfy p (PFunctor.FreeM.liftBind q cont) ↔ p q ∧ ∀ (a : spec q), QueriesSatisfy p (cont a)

        A call followed by its continuations satisfies p exactly when the call and every continuation do.

        theorem Cslib.OracleComp.QueriesSatisfy.pure {ι : Type u} {spec : OracleSpec ι} {α : Type v} {p : ι → Prop} (a : α) :

        Returning a value makes no call.

        theorem Cslib.OracleComp.QueriesSatisfy.query {ι : Type u} {spec : OracleSpec ι} {p : ι → Prop} {q : ι} (hq : p q) :

        A single call satisfies p when its query does.

        theorem Cslib.OracleComp.QueriesSatisfy.bind {ι : Type u} {spec : OracleSpec ι} {α β : Type v} {p : ι → Prop} {program : OracleComp spec α} {next : α → OracleComp spec β} (h : QueriesSatisfy p program) (hnext : ∀ (a : α), QueriesSatisfy p (next a)) :
        QueriesSatisfy p (program >>= next)

        Sequencing preserves the predicate.

        theorem Cslib.OracleComp.QueriesSatisfy.of_forall {ι : Type u} {spec : OracleSpec ι} {α : Type v} {p : ι → Prop} (hp : ∀ (q : ι), p q) (program : OracleComp spec α) :
        QueriesSatisfy p program

        Every program satisfies a predicate that holds for every call.

        theorem Cslib.OracleComp.QueriesSatisfy.mono {ι : Type u} {spec : OracleSpec ι} {α : Type v} {p p' : ι → Prop} {program : OracleComp spec α} (h : QueriesSatisfy p program) (hp : ∀ (q : ι), p q → p' q) :
        QueriesSatisfy p' program

        A weaker predicate is still satisfied.

        @[simp]
        theorem Cslib.OracleComp.queriesSatisfy_map_iff {ι : Type u} {spec : OracleSpec ι} {α β : Type v} {p : ι → Prop} (f : α → β) (program : OracleComp spec α) :
        QueriesSatisfy p (f <$> program) ↔ QueriesSatisfy p program

        Postprocessing the result makes no call.

        Logged calls respect the budget #

        theorem Cslib.OracleComp.IsCostBounded.transcript_cost_le {Query : Type u} {Response : Query → Type u} {State γ : Type u} {cost : Query → ℕ} {program : OracleComp Response γ} {n : ℕ} (h : IsCostBounded cost program n) (oracle : (q : Query) → StateT State PMF (Response q)) {s s' : State} {result : γ} {transcript : Transcript Response} (hmem : (result, s', transcript) ∈ ((OracleComp.interpret (withTranscript oracle) program).run (s, [])).support) :
        (List.map (fun (entry : (q : Query) × Response q) => cost entry.fst) transcript).sum ≤ n

        Against every stateful oracle, the calls recorded on a supported run cost at most the budget.

        theorem Cslib.OracleComp.IsQueryBounded.length_transcript_le {Query : Type u} {Response : Query → Type u} {State γ : Type u} {program : OracleComp Response γ} {n : ℕ} (h : program.IsQueryBounded n) (oracle : (q : Query) → StateT State PMF (Response q)) {s s' : State} {result : γ} {transcript : Transcript Response} (hmem : (result, s', transcript) ∈ ((interpret (withTranscript oracle) program).run (s, [])).support) :
        List.length transcript ≤ n

        Against every stateful oracle, a supported run records at most n calls.

        theorem Cslib.OracleComp.QueriesSatisfy.forall_mem_transcript {Query : Type u} {Response : Query → Type u} {State γ : Type u} {p : Query → Prop} {program : OracleComp Response γ} (h : QueriesSatisfy p program) (oracle : (q : Query) → StateT State PMF (Response q)) {s s' : State} {result : γ} {transcript : Transcript Response} (hmem : (result, s', transcript) ∈ ((interpret (withTranscript oracle) program).run (s, [])).support) (entry : (q : Query) × Response q) :
        entry ∈ transcript → p entry.fst

        Against every stateful oracle, every call recorded on a supported run satisfies p.