Documentation

Std.Internal.Do.WP.Frame

structure Std.Internal.Do.WP.Frames {Prog : Type u} {Value : Type v} {Pred : Type w} {EPred : Type z} [Assertion Pred] [Assertion EPred] [WP Prog Value Pred EPred] {R : Type t} (op : RPredPred) (x : Prog) (F : R) :

x frames the resource F with respect to the operator op : R → Pred → Pred: op F · commutes into the postcondition of wp x for every postcondition.

For the meet op = (· ⊓ ·) with R = Pred and stateful Pred, this means running x preserves the state identified by F. Other operators take a simpler resource, e.g. a cost counter R = Nat.

  • op_wp_le_wp_op (Q : ValuePred) (E : EPred) : Lean.Order.PartialOrder.rel (op F (wp x Q E)) (wp x (fun (a : Value) => op F (Q a)) E)

    When x frames (op F ·), (op F ·) commutes into the postcondition of wp x.

Instances For
    theorem Std.Internal.Do.WP.Frames.op_wp_upperAdjoint_le_wp {Prog : Type u} {Value : Type v} {Pred : Type w} {EPred : Type z} [Assertion Pred] [Assertion EPred] [WP Prog Value Pred EPred] {R : Type t} (op : RPredPred) [∀ (r : R), Lean.Order.PreservesSup (op r)] {x : Prog} {F : R} (hframes : Frames op x F) (Q : ValuePred) (E : EPred) :
    Lean.Order.PartialOrder.rel (op F (wp x (fun (a : Value) => Lean.Order.PreservesSup.upperAdjoint (op F) (Q a)) E)) (wp x Q E)

    The framed spec vcgen applies for x, when each op r preserves Sup: framing x by F makes op F (wp x (fun a => PreservesSup.upperAdjoint (op F) (Q a))) a precondition for wp x Q.

    theorem Std.Internal.Do.WP.Frames.le_frameClosure {Prog : Type u} {Value : Type v} {Pred : Type w} {EPred : Type z} [Assertion Pred] [Assertion EPred] [WP Prog Value Pred EPred] {R : Type t} (op : RPredPred) [∀ (r : R), Lean.Order.PreservesSup (op r)] {x : Prog} (hframes : ∀ (r : R), Frames op x r) {Q : ValuePred} {E : EPred} {pre : Pred} (hpre : Lean.Order.PartialOrder.rel pre (wp x Q E)) :
    Lean.Order.PartialOrder.rel pre (Lean.Order.PreservesSup.frameClosure op (fun (Q : ValuePred) => wp x Q E) Q)

    PreservesSup.le_frameClosure at the wp layer: when x frames every resource r, landing below wp x Q E suffices to land below the frame closure of wp x · E.

    theorem Std.Internal.Do.WP.Frames.of_frameClosure {Prog : Type u} {Value : Type v} {Pred : Type w} {EPred : Type z} [Assertion Pred] [Assertion EPred] [WP Prog Value Pred EPred] {R : Type t} (op : RPredPred) [∀ (r : R), Lean.Order.PreservesSup (op r)] (comp : RRR) (hact : ∀ (r r' : R) (a : Pred), op (comp r r') a = op r (op r' a)) {x : Prog} {F : R} (h : (f : ProgEPred(ValuePred)Pred), ∀ (x : Prog) (Q : ValuePred) (E : EPred), wp x Q E = Lean.Order.PreservesSup.frameClosure op (f x E) Q) :
    Frames op x F

    If wp is built as PreservesSup.frameClosure op over a base post-transformer f x E (the frame rule internalized into wp), then every program frames every resource F with respect to op.

    theorem Std.Internal.Do.WP.Frames.of_conjunctive {Prog : Type u} {Value : Type v} {Pred : Type w} {EPred : Type z} [Assertion Pred] [Assertion EPred] [WP Prog Value Pred EPred] {x : Prog} [WPConjunctive x] {F : Pred} (h : ∀ (E : EPred), Lean.Order.PartialOrder.rel F (wp x (fun (x : Value) => F) E)) :
    Frames (fun (x1 x2 : Pred) => Lean.Order.meet x1 x2) x F

    If wp x is conjunctive, then x frames (F ⊓ ·) when F holds before and after running x.

    @[instance_reducible]
    noncomputable def Std.Internal.Do.WP.of_frameClosure {Prog : Type u} {Value : Type v} {Pred : Type w} {EPred : Type z} [Assertion Pred] [Assertion EPred] {R : Type t} (op : RPredPred) [∀ (r : R), Lean.Order.PreservesSup (op r)] (base : WP Prog Value Pred EPred) :
    WP Prog Value Pred EPred

    Reinterpret a WP so its weakest precondition is the PreservesSup.frameClosure of the base wp over a family of Sup-preserving resource operators op r.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      theorem Std.Internal.Do.WP.of_frameClosure_le_wp_iff {Prog : Type u} {Value : Type v} {Pred : Type w} {EPred : Type z} [Assertion Pred] [Assertion EPred] {R : Type t} (op : RPredPred) [∀ (r : R), Lean.Order.PreservesSup (op r)] (base : WP Prog Value Pred EPred) (x : Prog) (Q : ValuePred) (E : EPred) (pre : Pred) :
      Lean.Order.PartialOrder.rel pre (wp x Q E) ∀ (r : R), Lean.Order.PartialOrder.rel (op r pre) (wp x (fun (a : Value) => op r (Q a)) E)

      Characterization of the WP.of_frameClosure weakest precondition: landing below it is landing below the base wp with every resource op r framed onto the pre- and postcondition.

      theorem Std.Internal.Do.WP.le_wp_of_frameClosure_eq {Prog : Type u} {Value : Type v} {Pred : Type w} {EPred : Type z} [Assertion Pred] [Assertion EPred] {R : Type t} {op : RPredPred} [∀ (r : R), Lean.Order.PreservesSup (op r)] {base I : WP Prog Value Pred EPred} (heq : I = of_frameClosure op base) {x : Prog} {Q : ValuePred} {E : EPred} {pre : Pred} (h : ∀ (r : R), Lean.Order.PartialOrder.rel (op r pre) (wp x (fun (a : Value) => op r (Q a)) E)) :

      Introduction rule for the weakest precondition of a WP.of_frameClosure interpretation, selected by the witness equation heq: land below the base wp with every resource framed on.

      @[instance_reducible]
      noncomputable def Std.Internal.Do.WPMonad.of_frameClosure {m : TypeType} [Monad m] {P : Type u} {E : Type z} [Assertion P] [Assertion E] {R : Type} (op : RPP) [∀ (r : R), Lean.Order.PreservesSup (op r)] {comp : RRR} {e : R} (hact : ∀ (r r' : R) (a : P), op (comp r r') a = op r (op r' a)) (hunit : ∀ (a : P), op e a = a) (base : WPMonad m P E) :
      WPMonad m P E

      Reinterpret a WPMonad m so its weakest precondition is the PreservesSup.frameClosure of the base wp over a family of Sup-preserving resource operators op r that act by comp with unit e. The resource frame rule then holds by construction (WP.Frames.of_frameClosure).

      Equations
      • One or more equations did not get rendered due to their size.
      Instances For