Documentation

Std.Do.PredTrans

Predicate transformers for arbitrary postcondition shapes #

This module defines the type PredTrans ps of predicate transformers for a given ps : PostShape. PredTrans forms the semantic domain of the weakest precondition interpretation WP in which we interpret monadic programs.

A predicate transformer x : PredTrans ps α is a function that takes a postcondition Q : PostCond α ps and returns a precondition x.apply Q : Assertion ps, with the additional monotonicity property that the precondition is stronger the stronger the postcondition is: Q₁ ⊢ₚ Q₂ → x.apply Q₁ ⊢ₛ x.apply Q₂.

Since PredTrans itself forms a monad, we can interpret monadic programs by writing a monad morphism into PredTrans; this is exactly what WP encodes. This module defines interpretations of common monadic operations, such as get, throw, liftM, etc.

def Std.Do.PredTrans.Monotonic {ps : PostShape} {α : Type u} (t : PostCond α psAssertion ps) :

The stronger the postcondition, the stronger the transformed precondition.

Equations
Instances For
    def Std.Do.PredTrans.Conjunctive {ps : PostShape} {α : Type u} (t : PostCond α psAssertion ps) :

    Transforming a conjunction of postconditions is the same as the conjunction of transformed postconditions.

    Equations
    Instances For
      def Std.Do.PredTrans.Conjunctive.mono {ps : PostShape} {α : Type u} (t : PostCond α psAssertion ps) (h : Conjunctive t) :

      Any predicate transformer that is conjunctive is also monotonic.

      Equations
      • =
      Instances For
        structure Std.Do.PredTrans (ps : PostShape) (α : Type u) :

        The type of predicate transformers for a given ps : PostShape and return type α : Type. A predicate transformer x : PredTrans ps α is a function that takes a postcondition Q : PostCond α ps and returns a precondition x.apply Q : Assertion ps, with the additional monotonicity property that the precondition is stronger the stronger the postcondition is: Q₁ ⊢ₚ Q₂ → x.apply Q₁ ⊢ₛ x.apply Q₂.

        Instances For
          theorem Std.Do.PredTrans.ext_iff {ps : PostShape} {α : Type u} {x y : PredTrans ps α} :
          x = y x.apply = y.apply
          theorem Std.Do.PredTrans.ext {ps : PostShape} {α : Type u} {x y : PredTrans ps α} (apply : x.apply = y.apply) :
          x = y
          theorem Std.Do.PredTrans.mono {ps : PostShape} {α : Type u} (t : PredTrans ps α) :
          def Std.Do.PredTrans.le {ps : PostShape} {α : Type u} (x y : PredTrans ps α) :

          Given a fixed postcondition, the stronger predicate transformer will yield a weaker precondition.

          Equations
          Instances For
            def Std.Do.PredTrans.pure {ps : PostShape} {α : Type u} (a : α) :
            PredTrans ps α
            Equations
            Instances For
              def Std.Do.PredTrans.bind {ps : PostShape} {α β : Type u} (x : PredTrans ps α) (f : αPredTrans ps β) :
              PredTrans ps β
              Equations
              Instances For
                def Std.Do.PredTrans.const {ps : PostShape} {α : Type u} (p : Assertion ps) :
                PredTrans ps α
                Equations
                Instances For
                  Equations
                  • One or more equations did not get rendered due to their size.
                  @[simp]
                  theorem Std.Do.PredTrans.pure_apply {ps : PostShape} {α : Type u} (a : α) (Q : PostCond α ps) :
                  (pure a).apply Q = Q.fst a
                  @[simp]
                  theorem Std.Do.PredTrans.Pure_pure_apply {ps : PostShape} {α : Type u} (a : α) (Q : PostCond α ps) :
                  (Pure.pure a).apply Q = Q.fst a
                  @[simp]
                  theorem Std.Do.PredTrans.map_apply {ps : PostShape} {α β : Type u} (f : αβ) (x : PredTrans ps α) (Q : PostCond β ps) :
                  (f <$> x).apply Q = x.apply (fun (a : α) => Q.fst (f a), Q.snd)
                  @[simp]
                  theorem Std.Do.PredTrans.bind_apply {ps : PostShape} {α β : Type u} (x : PredTrans ps α) (f : αPredTrans ps β) (Q : PostCond β ps) :
                  (x >>= f).apply Q = x.apply (fun (a : α) => (f a).apply Q, Q.snd)
                  @[simp]
                  theorem Std.Do.PredTrans.seq_apply {ps : PostShape} {α β : Type u} (f : PredTrans ps (αβ)) (x : PredTrans ps α) (Q : PostCond β ps) :
                  (f <*> x).apply Q = f.apply (fun (g : αβ) => x.apply (fun (a : α) => Q.fst (g a), Q.snd), Q.snd)
                  @[simp]
                  theorem Std.Do.PredTrans.const_apply {ps : PostShape} {α : Type u} (p : Assertion ps) (Q : PostCond α ps) :
                  (const p).apply Q = p
                  theorem Std.Do.PredTrans.bind_mono {ps : PostShape} {α β : Type u} {x y : PredTrans ps α} {f : αPredTrans ps β} (h : x y) :
                  x >>= f y >>= f
                  def Std.Do.PredTrans.pushArg {ps : PostShape} {α σ : Type u} (x : StateT σ (PredTrans ps) α) :
                  Equations
                  • One or more equations did not get rendered due to their size.
                  Instances For
                    def Std.Do.PredTrans.pushExcept {ps : PostShape} {α ε : Type u_1} (x : ExceptT ε (PredTrans ps) α) :
                    Equations
                    • One or more equations did not get rendered due to their size.
                    Instances For
                      @[simp]
                      def Std.Do.PredTrans.pushArg_apply {ps : PostShape} {α σ : Type u} {Q : PostCond α (PostShape.arg σ ps)} (f : σPredTrans ps (α × σ)) :
                      (pushArg f).apply Q = fun (s : σ) => (f s).apply (fun (x : α × σ) => match x with | (a, s) => Q.fst a s, Q.snd)
                      Equations
                      • =
                      Instances For
                        @[simp]
                        def Std.Do.PredTrans.pushExcept_apply {ps : PostShape} {α ε : Type u} {Q : PostCond α (PostShape.except ε ps)} (x : PredTrans ps (Except ε α)) :
                        (pushExcept x).apply Q = x.apply (fun (x : Except ε α) => match x with | Except.ok a => Q.fst a | Except.error e => Q.snd.fst e, Q.snd.snd)
                        Equations
                        • =
                        Instances For
                          def Std.Do.PredTrans.dite_apply {α : Type u} {ps : PostShape} {Q : PostCond α ps} (c : Prop) [Decidable c] (t : cPredTrans ps α) (e : ¬cPredTrans ps α) :
                          (if h : c then t h else e h).apply Q = if h : c then (t h).apply Q else (e h).apply Q
                          Equations
                          • =
                          Instances For
                            def Std.Do.PredTrans.ite_apply {α : Type u} {ps : PostShape} {Q : PostCond α ps} (c : Prop) [Decidable c] (t e : PredTrans ps α) :
                            (if c then t else e).apply Q = if c then t.apply Q else e.apply Q
                            Equations
                            • =
                            Instances For