Documentation

VCVio.ProgramLogic.Unary.HoareTriple

Quantitative Hoare triples for OracleComp #

The construction is based on a Loom-style ordered monad algebra (MAlgOrdered) instantiated for OracleComp spec with carrier ℝ≥0∞.

API contract #

noncomputable def OracleComp.ProgramLogic.μ {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] (oa : OracleComp spec ENNReal) :

Expectation-style algebra for oracle computations returning ℝ≥0∞.

Equations
    Instances For
      noncomputable instance OracleComp.ProgramLogic.instMAlgOrdered {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] :
      Equations
        @[reducible, inline]
        noncomputable abbrev OracleComp.ProgramLogic.wp {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) (post : αENNReal) :

        Quantitative weakest precondition for OracleComp.

        Equations
          Instances For
            @[reducible, inline]
            noncomputable abbrev OracleComp.ProgramLogic.Triple {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (pre : ENNReal) (oa : OracleComp spec α) (post : αENNReal) :

            Quantitative Hoare-style triple for OracleComp.

            Equations
              Instances For
                @[simp]
                theorem OracleComp.ProgramLogic.wp_pure {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (x : α) (post : αENNReal) :
                wp (pure x) post = post x
                @[simp]
                theorem OracleComp.ProgramLogic.wp_ite {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (c : Prop) [Decidable c] (oa ob : OracleComp spec α) (post : αENNReal) :
                wp (if c then oa else ob) post = if c then wp oa post else wp ob post
                @[simp]
                theorem OracleComp.ProgramLogic.wp_dite {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (c : Prop) [Decidable c] (oa : cOracleComp spec α) (ob : ¬cOracleComp spec α) (post : αENNReal) :
                wp (dite c oa ob) post = if h : c then wp (oa h) post else wp (ob h) post
                theorem OracleComp.ProgramLogic.wp_bind {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α β : Type} (oa : OracleComp spec α) (ob : αOracleComp spec β) (post : βENNReal) :
                wp (oa >>= ob) post = wp oa fun (x : α) => wp (ob x) post
                theorem OracleComp.ProgramLogic.wp_replicate_zero {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) (post : List αENNReal) :
                wp (replicate 0 oa) post = post []
                theorem OracleComp.ProgramLogic.wp_replicate_succ {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) (n : ) (post : List αENNReal) :
                wp (replicate (n + 1) oa) post = wp oa fun (x : α) => wp (replicate n oa) fun (xs : List α) => post (x :: xs)
                theorem OracleComp.ProgramLogic.wp_list_mapM_nil {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α β : Type} (f : αOracleComp spec β) (post : List βENNReal) :
                wp (List.mapM f []) post = post []
                theorem OracleComp.ProgramLogic.wp_list_mapM_cons {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α β : Type} (x : α) (xs : List α) (f : αOracleComp spec β) (post : List βENNReal) :
                wp (List.mapM f (x :: xs)) post = wp (f x) fun (y : β) => wp (List.mapM f xs) fun (ys : List β) => post (y :: ys)
                theorem OracleComp.ProgramLogic.wp_list_foldlM_nil {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α σ : Type} (f : σαOracleComp spec σ) (init : σ) (post : σENNReal) :
                wp (List.foldlM f init []) post = post init
                theorem OracleComp.ProgramLogic.wp_list_foldlM_cons {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α σ : Type} (x : α) (xs : List α) (f : σαOracleComp spec σ) (init : σ) (post : σENNReal) :
                wp (List.foldlM f init (x :: xs)) post = wp (f init x) fun (s : σ) => wp (List.foldlM f s xs) post
                theorem OracleComp.ProgramLogic.wp_mono {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) {post post' : αENNReal} (hpost : ∀ (x : α), post x post' x) :
                wp oa post wp oa post'
                theorem OracleComp.ProgramLogic.wp_map {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α β : Type} (f : αβ) (oa : OracleComp spec α) (post : βENNReal) :
                wp (f <$> oa) post = wp oa (post f)
                theorem OracleComp.ProgramLogic.wp_eq_tsum {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) (post : αENNReal) :
                wp oa post = ∑' (x : α), Pr[=x | oa] * post x

                General unfolding: wp as weighted sum over output probabilities.

                @[simp]
                theorem OracleComp.ProgramLogic.wp_const {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) (c : ENNReal) :
                (wp oa fun (x : α) => c) = c
                theorem OracleComp.ProgramLogic.wp_add {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) (f g : αENNReal) :
                (wp oa fun (x : α) => f x + g x) = wp oa f + wp oa g
                theorem OracleComp.ProgramLogic.wp_mul_const {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) (c : ENNReal) (f : αENNReal) :
                (wp oa fun (x : α) => c * f x) = c * wp oa f
                theorem OracleComp.ProgramLogic.wp_const_mul {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) (f : αENNReal) (c : ENNReal) :
                (wp oa fun (x : α) => f x * c) = wp oa f * c
                theorem OracleComp.ProgramLogic.triple_conseq {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} {pre pre' : ENNReal} {oa : OracleComp spec α} {post post' : αENNReal} (hpre : pre' pre) (hpost : ∀ (x : α), post x post' x) :
                Triple pre oa postTriple pre' oa post'
                theorem OracleComp.ProgramLogic.triple_bind {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α β : Type} {pre : ENNReal} {oa : OracleComp spec α} {cut : αENNReal} {ob : αOracleComp spec β} {post : βENNReal} (hoa : Triple pre oa cut) (hob : ∀ (x : α), Triple (cut x) (ob x) post) :
                Triple pre (oa >>= ob) post
                theorem OracleComp.ProgramLogic.triple_bind_wp {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α β : Type} {pre : ENNReal} {oa : OracleComp spec α} {ob : αOracleComp spec β} {post : βENNReal} (h : Triple pre oa fun (x : α) => wp (ob x) post) :
                Triple pre (oa >>= ob) post
                theorem OracleComp.ProgramLogic.triple_pure {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (x : α) (post : αENNReal) :
                Triple (post x) (pure x) post
                theorem OracleComp.ProgramLogic.triple_zero {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) (post : αENNReal) :
                Triple 0 oa post

                A quantitative triple with precondition 0 is always true.

                theorem OracleComp.ProgramLogic.triple_ite {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} {c : Prop} [Decidable c] {pre : ENNReal} {oa ob : OracleComp spec α} {post : αENNReal} (ht : cTriple pre oa post) (hf : ¬cTriple pre ob post) :
                Triple pre (if c then oa else ob) post
                theorem OracleComp.ProgramLogic.triple_dite {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} {c : Prop} [Decidable c] {pre : ENNReal} {oa : cOracleComp spec α} {ob : ¬cOracleComp spec α} {post : αENNReal} (ht : ∀ (h : c), Triple pre (oa h) post) (hf : ∀ (h : ¬c), Triple pre (ob h) post) :
                Triple pre (dite c oa ob) post
                theorem OracleComp.ProgramLogic.probEvent_eq_wp_indicator {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) (p : αProp) [DecidablePred p] :
                Pr[p | oa] = wp oa fun (x : α) => if p x then 1 else 0

                probEvent as a WP of an indicator postcondition.

                theorem OracleComp.ProgramLogic.probOutput_eq_wp_indicator {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) [DecidableEq α] (x : α) :
                Pr[=x | oa] = wp oa fun (y : α) => if y = x then 1 else 0

                probOutput as a WP of a singleton-indicator postcondition.

                theorem OracleComp.ProgramLogic.wp_liftM_query {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] (t : spec.Domain) (post : spec.Range tENNReal) :
                wp (liftM (query t)) post = ∑' (u : spec.Range t), 1 / (Fintype.card (spec.Range t)) * post u

                liftM query form of wp_query.

                theorem OracleComp.ProgramLogic.wp_query {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] (t : spec.Domain) (post : spec.Range tENNReal) :
                wp (liftM (query t)) post = ∑' (u : spec.Range t), 1 / (Fintype.card (spec.Range t)) * post u

                Quantitative WP rule for a uniform oracle query.

                theorem OracleComp.ProgramLogic.wp_uniformSample {α : Type} [SampleableType α] (post : αENNReal) :
                wp ($ᵗα) post = ∑' (x : α), Pr[=x | $ᵗα] * post x
                theorem OracleComp.ProgramLogic.triple_probEvent_indicator {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) (p : αProp) [DecidablePred p] :
                Triple Pr[p | oa] oa fun (x : α) => if p x then 1 else 0

                Indicator-event probability as an exact quantitative triple.

                theorem OracleComp.ProgramLogic.triple_probOutput_indicator {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) [DecidableEq α] (x : α) :
                Triple Pr[=x | oa] oa fun (y : α) => if y = x then 1 else 0

                Singleton-output probability as an exact quantitative triple.

                @[simp]
                theorem OracleComp.ProgramLogic.probEvent_mem_support {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) :
                Pr[fun (x : α) => x support oa | oa] = 1

                The support event of an OracleComp occurs almost surely.

                theorem OracleComp.ProgramLogic.triple_probEvent_eq_one {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) (p : αProp) [DecidablePred p] (h : Pr[p | oa] = 1) :
                Triple 1 oa fun (x : α) => if p x then 1 else 0

                Exact probability-1 events are exact quantitative triples.

                theorem OracleComp.ProgramLogic.triple_probOutput_eq_one {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) [DecidableEq α] (x : α) (h : Pr[=x | oa] = 1) :
                Triple 1 oa fun (y : α) => if y = x then 1 else 0

                Exact probability-1 singleton outputs are exact quantitative triples.

                theorem OracleComp.ProgramLogic.probOutput_eq_one_iff_triple {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) [DecidableEq α] (x : α) :
                Pr[=x | oa] = 1 Triple 1 oa fun (y : α) => if y = x then 1 else 0

                Pr[= x | oa] = 1Triple 1 oa (indicator). Bridge for qvcgen probability lowering.

                theorem OracleComp.ProgramLogic.triple_support {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} (oa : OracleComp spec α) [DecidablePred fun (x : α) => x support oa] :
                Triple 1 oa fun (x : α) => if x support oa then 1 else 0

                Support membership is a useful default cut function for support-sensitive bind proofs.

                Loop stepping rules (Triple-level) #

                theorem OracleComp.ProgramLogic.triple_replicate_succ {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} {pre : ENNReal} {oa : OracleComp spec α} {n : } {post : List αENNReal} (h : Triple pre oa fun (x : α) => wp (replicate n oa) fun (xs : List α) => post (x :: xs)) :
                Triple pre (replicate (n + 1) oa) post
                theorem OracleComp.ProgramLogic.triple_list_mapM_cons {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α β : Type} {pre : ENNReal} {x : α} {xs : List α} {f : αOracleComp spec β} {post : List βENNReal} (h : Triple pre (f x) fun (y : β) => wp (List.mapM f xs) fun (ys : List β) => post (y :: ys)) :
                Triple pre (List.mapM f (x :: xs)) post
                theorem OracleComp.ProgramLogic.triple_list_foldlM_cons {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α σ : Type} {pre : ENNReal} {x : α} {xs : List α} {f : σαOracleComp spec σ} {init : σ} {post : σENNReal} (h : Triple pre (f init x) fun (s : σ) => wp (List.foldlM f s xs) post) :
                Triple pre (List.foldlM f init (x :: xs)) post

                Loop invariant rules #

                theorem OracleComp.ProgramLogic.triple_replicate_inv {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} {I : ENNReal} {oa : OracleComp spec α} {n : } (hstep : Triple I oa fun (x : α) => I) :
                Triple I (replicate n oa) fun (x : List α) => I

                Constant invariant through bounded iteration via replicate.

                theorem OracleComp.ProgramLogic.triple_list_foldlM_inv {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α σ : Type} {I : σENNReal} {f : σαOracleComp spec σ} {l : List α} {s₀ : σ} (hstep : ∀ (s : σ), xl, Triple (I s) (f s x) I) :
                Triple (I s₀) (List.foldlM f s₀ l) I

                Indexed invariant through List.foldlM.

                theorem OracleComp.ProgramLogic.triple_list_mapM_inv {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α β : Type} {I : ENNReal} {f : αOracleComp spec β} {l : List α} (hstep : xl, Triple I (f x) fun (x : β) => I) :
                Triple I (List.mapM f l) fun (x : List β) => I

                Constant invariant through List.mapM.

                theorem OracleComp.ProgramLogic.triple_replicate {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} {I pre : ENNReal} {oa : OracleComp spec α} {n : } {post : List αENNReal} (hpre : pre I) (hpost : ∀ (xs : List α), I post xs) (hstep : Triple I oa fun (x : α) => I) :
                Triple pre (replicate n oa) post

                replicate invariant with consequence: bridges arbitrary pre/post to the invariant.

                theorem OracleComp.ProgramLogic.triple_list_foldlM {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α σ : Type} {I : σENNReal} {f : σαOracleComp spec σ} {l : List α} {s₀ : σ} {pre : ENNReal} {post : σENNReal} (hpre : pre I s₀) (hpost : ∀ (s : σ), I s post s) (hstep : ∀ (s : σ), xl, Triple (I s) (f s x) I) :
                Triple pre (List.foldlM f s₀ l) post

                List.foldlM invariant with consequence.

                theorem OracleComp.ProgramLogic.triple_list_mapM {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α β : Type} {I : ENNReal} {f : αOracleComp spec β} {l : List α} {pre : ENNReal} {post : List βENNReal} (hpre : pre I) (hpost : ∀ (ys : List β), I post ys) (hstep : xl, Triple I (f x) fun (x : β) => I) :
                Triple pre (List.mapM f l) post

                List.mapM invariant with consequence.

                Congruence under evalDist equality #

                theorem OracleComp.ProgramLogic.probOutput_congr_evalDist {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} {oa ob : OracleComp spec α} (h : evalDist oa = evalDist ob) (x : α) :
                Pr[=x | oa] = Pr[=x | ob]
                theorem OracleComp.ProgramLogic.μ_congr_evalDist {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {oa ob : OracleComp spec ENNReal} (h : evalDist oa = evalDist ob) :
                μ oa = μ ob
                theorem OracleComp.ProgramLogic.wp_congr_evalDist {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {α : Type} {oa ob : OracleComp spec α} (h : evalDist oa = evalDist ob) (post : αENNReal) :
                wp oa post = wp ob post
                theorem OracleComp.ProgramLogic.μ_cross_congr_evalDist {ι : Type u} {spec : OracleSpec ι} [spec.Fintype] [spec.Inhabited] {ι' : Type u_1} {spec' : OracleSpec ι'} [spec'.Fintype] [spec'.Inhabited] {oa : OracleComp spec' ENNReal} {ob : OracleComp spec ENNReal} (h : evalDist oa = evalDist ob) :
                μ oa = μ ob