Documentation

Std.Do.PostCond

Pre and postconditions #

This module defines Assertion and PostCond, the types which constitute the pre and postconditions of a Hoare triple in the program logic.

Predicate shapes #

Since WP supports arbitrary monads, PostCond must be general enough to cope with state and exceptions. For this reason, PostCond is indexed by a PostShape which is an abstraction of the stack of effects supported by the monad, corresponding directly to StateT and ExceptT layers in a transformer stack. For every StateT σ effect, we get one PostShape.arg σ layer, whereas for every ExceptT ε effect, we get one PostShape.except ε layer. Currently, the only supported base layer is PostShape.pure.

Pre and postconditions #

The type of preconditions Assertion ps is distinct from the type of postconditions PostCond α ps.

This is because postconditions not only specify what happens upon successful termination of the program, but also need to specify a property that holds upon failure. We get one "barrel" for the success case, plus one barrel per PostShape.except layer.

It does not make much sense to talk about failure barrels in the context of preconditions. Hence, Assertion ps is defined such that all PostShape.except layers are discarded from ps, via PostShape.args.

inductive Std.Do.PostShape :
Type (u + 1)

The “shape” of the postconditions that are used to reason about a monad.

A postcondition shape is an abstraction of many possible monadic effects, based on the structure of pure functions that can simulate them. The postcondition shape of a monad is given by its WP instance. This shape is used to determine both its Assertions and its PostConds.

  • pure : PostShape

    The assertions and postconditions in this monad use neither state nor exceptions.

  • arg (σ : Type u) : PostShapePostShape

    The assertions in this monad may mention the current value of a state of type σ, and postconditions may mention the state's final value.

  • except (ε : Type u) : PostShapePostShape

    The postconditions in this monad include assertions about exceptional values of type ε that result from premature termination.

Instances For
    @[reducible, inline]

    Extracts the list of state types under PostShape.arg constructors, discarding exception types.

    The state types determine the shape of assertions in the monad.

    Equations
      Instances For
        @[reducible, inline]

        An assertion about the state fields for a monad whose postcondition shape is ps.

        Concretely, this is an abbreviation for SPred applied to the .args in the given predicate shape, so all theorems about SPred apply.

        Examples:

        example : Assertion (.arg ρ .pure) = (ρ → ULift Prop) := rfl
        example : Assertion (.except ε .pure) = ULift Prop := rfl
        example : Assertion (.arg σ (.except ε .pure)) = (σ → ULift Prop) := rfl
        example : Assertion (.except ε (.arg σ .pure)) = (σ → ULift Prop) := rfl
        
        Equations
          Instances For

            An assertion about each potential exception that's declared in a postcondition shape.

            Examples:

            example : ExceptConds (.pure) = Unit := rfl
            example : ExceptConds (.except ε .pure) = ((ε → ULift Prop) × Unit) := rfl
            example : ExceptConds (.arg σ (.except ε .pure)) = ((ε → ULift Prop) × Unit) := rfl
            example : ExceptConds (.except ε (.arg σ .pure)) = ((ε → σ → ULift Prop) × Unit) := rfl
            
            Equations
              Instances For

                Lifts a proposition p to a set of assertions about the possible exceptions in ps. Each exception's postcondition holds when p is true.

                Equations
                  Instances For

                    An assertion about the possible exceptions in ps that always holds.

                    Equations
                      Instances For

                        An assertion about the possible exceptions in ps that never holds.

                        Equations
                          Instances For
                            @[simp]
                            theorem Std.Do.ExceptConds.fst_const {ε : Type u} {ps : PostShape} (p : Prop) :
                            (const p).fst = fun ( : ε) => p
                            @[simp]
                            theorem Std.Do.ExceptConds.snd_const {ε : Type u} {ps : PostShape} (p : Prop) :
                            @[simp]
                            theorem Std.Do.ExceptConds.fst_true {ε : Type u} {ps : PostShape} :
                            true.fst = fun ( : ε) => True
                            @[simp]
                            @[simp]
                            theorem Std.Do.ExceptConds.fst_false {ε : Type u} {ps : PostShape} :
                            false.fst = fun ( : ε) => False

                            Entailment of exception assertions is defined as pointwise entailment of the assertions for each potential exception.

                            While implication of exception conditions (ExceptConds.imp) is itself an exception condition, entailment is an ordinary proposition.

                            Equations
                              Instances For

                                Entailment of exception assertions is defined as pointwise entailment of the assertions for each potential exception.

                                While implication of exception conditions (ExceptConds.imp) is itself an exception condition, entailment is an ordinary proposition.

                                Equations
                                  Instances For
                                    theorem Std.Do.ExceptConds.entails.trans {ps : PostShape} {x y z : ExceptConds ps} :
                                    x.entails yy.entails zx.entails z

                                    Conjunction of exception assertions is defined as pointwise conjunction of the assertions for each potential exception.

                                    Equations
                                      Instances For

                                        Conjunction of exception assertions is defined as pointwise conjunction of the assertions for each potential exception.

                                        Equations
                                          Instances For
                                            @[simp]
                                            theorem Std.Do.ExceptConds.fst_and {ps : PostShape} {ε : Type u} {x₁ x₂ : ExceptConds (PostShape.except ε ps)} :
                                            (x₁ ∧ₑ x₂).fst = fun (e : ε) => spred(x₁.fst e x₂.fst e)
                                            @[simp]
                                            theorem Std.Do.ExceptConds.snd_and {ps : PostShape} {ε : Type u} {x₁ x₂ : ExceptConds (PostShape.except ε ps)} :
                                            (x₁ ∧ₑ x₂).snd = (x₁.snd ∧ₑ x₂.snd)
                                            theorem Std.Do.ExceptConds.and_eq_left {ps : PostShape} {p q : ExceptConds ps} (h : p.entails q) :
                                            p = (p ∧ₑ q)

                                            Implication of exception assertions is defined as pointwise implication of the assertion for each exception.

                                            Unlike entailment (ExceptConds.entails), which is an ordinary proposition of type Prop, implication of exception assertions is itself an exception assertion.

                                            Equations
                                              Instances For

                                                Implication of exception assertions is defined as pointwise implication of the assertion for each exception.

                                                Unlike entailment (ExceptConds.entails), which is an ordinary proposition of type Prop, implication of exception assertions is itself an exception assertion.

                                                Equations
                                                  Instances For
                                                    @[simp]
                                                    theorem Std.Do.ExceptConds.fst_imp {ps : PostShape} {ε : Type u} {x₁ x₂ : ExceptConds (PostShape.except ε ps)} :
                                                    (x₁ →ₑ x₂).fst = fun (e : ε) => spred(x₁.fst e x₂.fst e)
                                                    @[simp]
                                                    theorem Std.Do.ExceptConds.snd_imp {ps : PostShape} {ε : Type u} {x₁ x₂ : ExceptConds (PostShape.except ε ps)} :
                                                    (x₁ →ₑ x₂).snd = (x₁.snd →ₑ x₂.snd)
                                                    theorem Std.Do.ExceptConds.imp_intro {ps : PostShape} {P Q R : ExceptConds ps} (h : (P ∧ₑ Q).entails R) :
                                                    P.entails (Q →ₑ R)
                                                    theorem Std.Do.ExceptConds.imp_elim {ps : PostShape} {P Q R : ExceptConds ps} (h : P.entails (Q →ₑ R)) :
                                                    (P ∧ₑ Q).entails R
                                                    @[simp]
                                                    theorem Std.Do.ExceptConds.and_imp {ps : PostShape} {x₁ x₂ : ExceptConds ps} :
                                                    (x₁ ∧ₑ (x₁ →ₑ x₂)).entails (x₁ ∧ₑ x₂)
                                                    @[reducible, inline]
                                                    abbrev Std.Do.PostCond (α : Type u) (ps : PostShape) :

                                                    A postcondition for the given predicate shape, with one Assertion for the terminating case and one Assertion for each .except layer in the predicate shape.

                                                    variable (α σ ε : Type)
                                                    example : PostCond α (.arg σ .pure) = ((α → σ → ULift Prop) × PUnit) := rfl
                                                    example : PostCond α (.except ε .pure) = ((α → ULift Prop) × (ε → ULift Prop) × PUnit) := rfl
                                                    example : PostCond α (.arg σ (.except ε .pure)) = ((α → σ → ULift Prop) × (ε → ULift Prop) × PUnit) := rfl
                                                    example : PostCond α (.except ε (.arg σ .pure)) = ((α → σ → ULift Prop) × (ε → σ → ULift Prop) × PUnit) := rfl
                                                    
                                                    Equations
                                                      Instances For

                                                        A postcondition for the given predicate shape, with one Assertion for the terminating case and one Assertion for each .except layer in the predicate shape.

                                                        variable (α σ ε : Type)
                                                        example : PostCond α (.arg σ .pure) = ((α → σ → ULift Prop) × PUnit) := rfl
                                                        example : PostCond α (.except ε .pure) = ((α → ULift Prop) × (ε → ULift Prop) × PUnit) := rfl
                                                        example : PostCond α (.arg σ (.except ε .pure)) = ((α → σ → ULift Prop) × (ε → ULift Prop) × PUnit) := rfl
                                                        example : PostCond α (.except ε (.arg σ .pure)) = ((α → σ → ULift Prop) × (ε → σ → ULift Prop) × PUnit) := rfl
                                                        
                                                        Equations
                                                          Instances For
                                                            @[reducible, inline]
                                                            abbrev Std.Do.PostCond.noThrow {ps : PostShape} {α : Type u} (p : αAssertion ps) :
                                                            PostCond α ps

                                                            A postcondition expressing total correctness. That is, it expresses that the asserted computation finishes without throwing an exception and the result satisfies the given predicate p.

                                                            Equations
                                                              Instances For

                                                                A postcondition expressing total correctness. That is, it expresses that the asserted computation finishes without throwing an exception and the result satisfies the given predicate p.

                                                                Equations
                                                                  Instances For
                                                                    @[reducible, inline]
                                                                    abbrev Std.Do.PostCond.mayThrow {ps : PostShape} {α : Type u} (p : αAssertion ps) :
                                                                    PostCond α ps

                                                                    A postcondition expressing partial correctness. That is, it expresses that if the asserted computation finishes without throwing an exception then the result satisfies the given predicate p. Nothing is asserted when the computation throws an exception.

                                                                    Equations
                                                                      Instances For

                                                                        A postcondition expressing partial correctness. That is, it expresses that if the asserted computation finishes without throwing an exception then the result satisfies the given predicate p. Nothing is asserted when the computation throws an exception.

                                                                        Equations
                                                                          Instances For
                                                                            Equations
                                                                              def Std.Do.PostCond.entails {ps : PostShape} {α : Type u} (p q : PostCond α ps) :

                                                                              Entailment of postconditions.

                                                                              This consists of:

                                                                              • Entailment of the assertion about the return value, for all possible return values.
                                                                              • Entailment of the exception conditions.

                                                                              While implication of postconditions (PostCond.imp) results in a new postcondition, entailment is an ordinary proposition.

                                                                              Equations
                                                                                Instances For

                                                                                  Entailment of postconditions.

                                                                                  This consists of:

                                                                                  • Entailment of the assertion about the return value, for all possible return values.
                                                                                  • Entailment of the exception conditions.

                                                                                  While implication of postconditions (PostCond.imp) results in a new postcondition, entailment is an ordinary proposition.

                                                                                  Equations
                                                                                    Instances For
                                                                                      @[simp]
                                                                                      theorem Std.Do.PostCond.entails.refl {ps : PostShape} {α : Type u} (Q : PostCond α ps) :
                                                                                      theorem Std.Do.PostCond.entails.rfl {ps : PostShape} {α : Type u} {Q : PostCond α ps} :
                                                                                      theorem Std.Do.PostCond.entails.trans {ps : PostShape} {α : Type u} {P Q R : PostCond α ps} (h₁ : P.entails Q) (h₂ : Q.entails R) :
                                                                                      @[simp]
                                                                                      theorem Std.Do.PostCond.entails_noThrow {ps : PostShape} {α : Type u} (p : αAssertion ps) (q : PostCond α ps) :
                                                                                      (noThrow p).entails q ∀ (a : α), p a ⊢ₛ q.fst a
                                                                                      @[simp]
                                                                                      theorem Std.Do.PostCond.entails_mayThrow {ps : PostShape} {α : Type u} (p : PostCond α ps) (q : αAssertion ps) :
                                                                                      p.entails (mayThrow q) ∀ (a : α), p.fst a ⊢ₛ q a
                                                                                      @[reducible, inline]
                                                                                      abbrev Std.Do.PostCond.and {ps : PostShape} {α : Type u} (p q : PostCond α ps) :
                                                                                      PostCond α ps

                                                                                      Conjunction of postconditions.

                                                                                      This is defined pointwise, as the conjunction of the assertions about the return value and the conjunctions of the assertions about each potential exception.

                                                                                      Equations
                                                                                        Instances For

                                                                                          Conjunction of postconditions.

                                                                                          This is defined pointwise, as the conjunction of the assertions about the return value and the conjunctions of the assertions about each potential exception.

                                                                                          Equations
                                                                                            Instances For
                                                                                              @[reducible, inline]
                                                                                              abbrev Std.Do.PostCond.imp {ps : PostShape} {α : Type u} (p q : PostCond α ps) :
                                                                                              PostCond α ps

                                                                                              Implication of postconditions.

                                                                                              This is defined pointwise, as the implication of the assertions about the return value and the implications of each of the assertions about each potential exception.

                                                                                              While entailment of postconditions (PostCond.entails) is an ordinary proposition, implication of postconditions is itself a postcondition.

                                                                                              Equations
                                                                                                Instances For

                                                                                                  Implication of postconditions.

                                                                                                  This is defined pointwise, as the implication of the assertions about the return value and the implications of each of the assertions about each potential exception.

                                                                                                  While entailment of postconditions (PostCond.entails) is an ordinary proposition, implication of postconditions is itself a postcondition.

                                                                                                  Equations
                                                                                                    Instances For
                                                                                                      theorem Std.Do.PostCond.and_imp {α✝ : Type u_1} {ps✝ : PostShape} {P' Q' : PostCond α✝ ps✝} :
                                                                                                      (P'.and (P'.imp Q')).entails (P'.and Q')
                                                                                                      theorem Std.Do.PostCond.and_left_of_entails {ps : PostShape} {α : Type u} {p q : PostCond α ps} (h : p.entails q) :
                                                                                                      p = p.and q