Documentation

CatCryptCore.Core.StdDoBridge

Std.Do / mvcgen bridge for SPComp #

Support-level Std.Do view of SPComp: a Std.Do.WP/Std.Do.WPMonad instance whose weakest precondition is almost-sure (support-level) satisfaction of the postcondition. This makes mvcgen usable for functional-correctness goals about SPComp do-blocks. Quantitative bounds (sdist, advantage) live outside PredTrans — expectation transformers are monotone but not conjunctive, so they cannot inhabit PredTrans.conjunctiveRaw; they belong to the Advantage/sdist layer.

The design mirrors VCVio's proposition-level bridge for OracleComp (VCVio/ProgramLogic/Unary/StdDoBridge.lean).

Post shape #

SPComp α = Heap → SDistr (α × Heap) is the monad StateT Heap (OptionT-over-PMF): failure (SDistr's none) carries no final heap. The structural mirror of that stack is

so assertions are Heap → ULift Prop and postconditions carry a heap-free failure barrel PUnit → ULift Prop. The alternative shape .except PUnit (.arg Heap .pure) would give the failure barrel a Heap argument that the semantics cannot supply (there is no heap at failure), and wp_bind fails for it; with the heap-free barrel both WPMonad laws hold on the nose.

⇓ r => ... (total correctness: the program must not fail) and ⇓? r => ... (partial correctness: nothing asserted on failure) both make sense for this shape; ⇓?-triples coincide with the unary pHoare judgment, and ⇓-triples additionally assert SPComp.NoFail.

Main definitions #

Reached via the CatCrypt.Tactics umbrella through Tactics/VC.lean (ssprove_nofail / ssprove_phoare lower goals into this bridge).

SDistr support lemmas for bind #

Support and failure mass of SDistr.bind, in the ≠ 0 form used by the support-level WP.

theorem CatCrypt.Prob.SDistr.bind_apply_some_ne_zero_iff {α β : Type u} (d : SDistr α) (f : α → SDistr β) (b : β) :
(d.bind f) (some b) ≠ 0 ↔ ∃ (a : α), d (some a) ≠ 0 ∧ (f a) (some b) ≠ 0
theorem CatCrypt.Prob.SDistr.bind_apply_none_ne_zero_iff {α β : Type u} (d : SDistr α) (f : α → SDistr β) :
(d.bind f) none ≠ 0 ↔ d none ≠ 0 ∨ ∃ (a : α), d (some a) ≠ 0 ∧ (f a) none ≠ 0
theorem CatCrypt.Prob.SDistr.pure_apply_some_ne_zero_iff {α : Type u} (x y : α) :
(pure x) (some y) ≠ 0 ↔ x = y

(SDistr.pure x) (some y) ≠ 0 iff x = y (point-mass support).

SPComp-level support lemmas #

theorem CatCrypt.Core.SPComp.bind_apply_some_ne_zero_iff {α β : Type} (c : SPComp α) (f : α → SPComp β) (h : Heap) (b : β) (h'' : Heap) :
(c.bind f h) (some (b, h'')) ≠ 0 ↔ ∃ (a : α) (h' : Heap), (c h) (some (a, h')) ≠ 0 ∧ (f a h') (some (b, h'')) ≠ 0

Support of a bound computation, in ≠ 0 form.

theorem CatCrypt.Core.SPComp.bind_apply_none_ne_zero_iff {α β : Type} (c : SPComp α) (f : α → SPComp β) (h : Heap) :
(c.bind f h) none ≠ 0 ↔ (c h) none ≠ 0 ∨ ∃ (a : α) (h' : Heap), (c h) (some (a, h')) ≠ 0 ∧ (f a h') none ≠ 0

Failure mass of a bound computation, in ≠ 0 form.

The support-level weakest precondition #

def CatCrypt.Core.SPComp.wpProp {α : Type u_1} (c : SPComp α) (post : α → Heap → Prop) :

Support-level (almost-sure) weakest precondition for SPComp: from initial heap h, every outcome (a, h') in the support of c h satisfies post a h'. Says nothing about the failure mass — see the failure barrel of wpSupport for that.

Equations
Instances For
    theorem CatCrypt.Core.SPComp.wpProp_iff_forall_support {α : Type u_1} (c : SPComp α) (post : α → Heap → Prop) (h : Heap) :
    c.wpProp post h ↔ ∀ p ∈ (c h).support, post p.1 p.2

    Adequacy: wpProp is the ∀-over-support statement.

    @[reducible, inline]

    The Std.Do post shape for SPComp: one state layer (Heap) over one heap-free failure layer (PUnit, the subprobability defect of SDistr).

    Equations
    Instances For

      The support-level predicate transformer of an SPComp computation: success barrel = wpProp, failure barrel = guard on nonzero failure mass.

      Equations
      • One or more equations did not get rendered due to their size.
      Instances For
        theorem CatCrypt.Core.SPComp.wpSupport_apply_down {α : Type} (c : SPComp α) (Q : Std.Do.PostCond α spPostShape) (h : Heap) :
        (c.wpSupport.apply Q h).down ↔ (∀ (a : α) (h' : Heap), (c h) (some (a, h')) ≠ 0 → (Q.1 a h').down) ∧ ((c h) none ≠ 0 → (Q.2.1 PUnit.unit).down)

        Unfolding lemma for the support-level WP. Deliberately not @[simp]: mvcgen must keep wp⟦·⟧ opaque and walk via @[spec] lemmas.

        Adequacy: triples vs wpProp, pHoare, NoFail, IsPure #

        theorem CatCrypt.Core.SPComp.triple_of_forall {α : Type} (c : SPComp α) (P : Std.Do.Assertion spPostShape) (Q : Std.Do.PostCond α spPostShape) (hsucc : ∀ (h : Heap), (P h).down → ∀ (a : α) (h' : Heap), (c h) (some (a, h')) ≠ 0 → (Q.1 a h').down) (hfail : ∀ (h : Heap), (P h).down → (c h) none ≠ 0 → (Q.2.1 PUnit.unit).down) :

        A Triple from pointwise success/failure obligations.

        theorem CatCrypt.Core.SPComp.triple_mayThrow_iff {α : Type} (c : SPComp α) (P : Heap → Prop) (post : α → Heap → Prop) :
        ⦃fun (h : Heap) => ⌜P h⌝⦄ c ⦃Std.Do.PostCond.mayThrow fun (a : α) (h : Heap) => ⌜post a h⌝⦄ ↔ ∀ (h : Heap), P h → c.wpProp post h

        Adequacy for partial correctness (⇓?): a mayThrow triple is exactly the universally-quantified wpProp statement. Nothing is asserted about the failure mass.

        theorem CatCrypt.Core.SPComp.triple_noThrow_iff {α : Type} (c : SPComp α) (P : Heap → Prop) (post : α → Heap → Prop) :
        ⦃fun (h : Heap) => ⌜P h⌝⦄ c ⦃Std.Do.PostCond.noThrow fun (a : α) (h : Heap) => ⌜post a h⌝⦄ ↔ ∀ (h : Heap), P h → c.wpProp post h ∧ (c h) none = 0

        Adequacy for total correctness (⇓): a noThrow triple is wpProp plus zero failure mass from every P-heap.

        theorem CatCrypt.Core.SPComp.pHoare_iff_triple {α : Type} (P : Unary.UPre) (c : SPComp α) (Q : Unary.UPost α) :
        Unary.pHoare P c Q ↔ ⦃fun (h : Heap) => ⌜P h⌝⦄ c ⦃Std.Do.PostCond.mayThrow fun (a : α) (h : Heap) => ⌜Q a h⌝⦄

        The unary pHL judgment (CatCrypt.Unary.pHoare) is exactly the partial-correctness (⇓?) Std.Do triple.

        SPComp.NoFail is the trivial total-correctness triple: the failure barrel ⌜False⌝ of noThrow forces zero failure mass.

        theorem CatCrypt.Core.SPComp.isPure_wpProp_iff {α : Type} {c : SPComp α} {d : Prob.SDistr α} (hd : ∀ (h : Heap), c h = d.bind fun (a : α) => Prob.SDistr.pure (a, h)) (post : α → Heap → Prop) (h : Heap) :
        c.wpProp post h ↔ ∀ (a : α), d (some a) ≠ 0 → post a h

        For an IsPure computation with witness distribution d, the support-level WP is the ∀-over-d.support statement at the unchanged heap.

        @[spec] lemmas for the SPComp primitives #

        These let mvcgen walk SPComp do-blocks: the generic Std.Do.Spec.bind / Spec.pure handle the monadic skeleton (via instWPMonad), and these lemmas handle the leaves.

        Spec for SPComp.get: returns the heap's value at l, heap unchanged, never fails.

        Spec for SPComp.set: writes v at l, returns (), never fails.

        Spec for SPComp.sample: the result can be any element of A (uniform has full support), heap unchanged, never fails.

        Spec for SPComp.fail: empty support, always fails — the precondition is the failure barrel.

        Spec for the prefix form SPComp.pure (the generic Std.Do.Spec.pure covers Pure.pure; this covers explicit SPComp.pure leaves).

        Examples: mvcgen-closed functional-correctness triples #

        @[reducible, inline]

        Demo location storing a Bool.

        Equations
        Instances For