Documentation

Std.Internal.Order.PredTrans

Predicate transformers #

PredTrans Pred EPred α wraps a map from a normal postcondition α → Pred and an exception postcondition EPred to a precondition Pred. The order and the chain-complete suprema are the pointwise ones of the function space.

PredTrans Pred EPred is a monad, so monadic programs can be interpreted by a monad morphism into it. This module provides that monad structure, the apply simp framework of the monadic combinators, the push family that moves a result type into a postcondition, and the standard monad class instances.

structure Lean.Order.PredTrans (Pred : Type u) (EPred : Type v) (α : Type w) :
Type (max (max u v) w)

A predicate transformer from postconditions to preconditions.

Given a return type α, a lattice Pred for assertions, and an exception assertion type EPred, PredTrans Pred EPred α wraps a function (α → Pred) → EPred → Pred.

  • apply : (αPred)EPredPred

    Apply the predicate transformer to a postcondition and exception postcondition.

Instances For
    theorem Lean.Order.PredTrans.ext {Pred : Type u} {EPred : Type v} {α : Type w} {x y : PredTrans Pred EPred α} (h : ∀ (post : αPred) (epost : EPred), x.apply post epost = y.apply post epost) :
    x = y

    Extensionality for predicate transformers.

    theorem Lean.Order.PredTrans.ext_iff {Pred : Type u} {EPred : Type v} {α : Type w} {x y : PredTrans Pred EPred α} :
    x = y ∀ (post : αPred) (epost : EPred), x.apply post epost = y.apply post epost
    @[instance_reducible]
    instance Lean.Order.PredTrans.instPartialOrder {Pred : Type u} {EPred : Type v} {α : Type w} [PartialOrder Pred] :
    PartialOrder (PredTrans Pred EPred α)

    Partial order on predicate transformers, inherited from the function space.

    Equations
    @[instance_reducible]
    instance Lean.Order.PredTrans.instCCPO {Pred : Type u} {EPred : Type v} {α : Type w} [CCPO Pred] :
    CCPO (PredTrans Pred EPred α)

    Chain-complete partial order on predicate transformers, for fixed-point reasoning.

    Equations
    def Lean.Order.PredTrans.monotone {Pred : Type u} {EPred : Type v} {α : Type w} [PartialOrder Pred] [PartialOrder EPred] (pt : PredTrans Pred EPred α) :

    Monotonicity property for a predicate transformer: if both post and epost grow, then the resulting precondition grows.

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

      Monad Structure #

      def Lean.Order.PredTrans.pure {Pred : Type u} {EPred : Type v} {α : Type w} (a : α) :
      PredTrans Pred EPred α

      pure a applies the postcondition to a.

      Equations
      Instances For
        def Lean.Order.PredTrans.bind {Pred : Type u} {EPred : Type v} {α β : Type w} (x : PredTrans Pred EPred α) (f : αPredTrans Pred EPred β) :
        PredTrans Pred EPred β

        bind x f threads the postcondition through the continuation f.

        Equations
        • x.bind f = { apply := fun (post : βPred) (epost : EPred) => x.apply (fun (a : α) => (f a).apply post epost) epost }
        Instances For
          @[instance_reducible]
          instance Lean.Order.PredTrans.instMonad {Pred : Type u} {EPred : Type v} :
          Monad (PredTrans Pred EPred)
          Equations
          • One or more equations did not get rendered due to their size.
          instance Lean.Order.PredTrans.instLawfulMonad {Pred : Type u} {EPred : Type v} :
          LawfulMonad (PredTrans Pred EPred)

          apply_* simp framework #

          Simp lemmas for reducing (expr).apply post epost for each monadic combinator.

          @[simp]
          theorem Lean.Order.PredTrans.apply_pure {Pred : Type u} {EPred : Type v} {α : Type w} (a : α) (post : αPred) (epost : EPred) :
          (pure a).apply post epost = post a

          Unfolding PredTrans.pure through apply.

          @[simp]
          theorem Lean.Order.PredTrans.apply_Pure_pure {Pred : Type u} {EPred : Type v} {α : Type w} (a : α) (post : αPred) (epost : EPred) :
          (Pure.pure a).apply post epost = post a

          Unfolding pure through apply.

          @[simp]
          theorem Lean.Order.PredTrans.apply_bind {Pred : Type u} {EPred : Type v} {α β : Type w} (x : PredTrans Pred EPred α) (f : αPredTrans Pred EPred β) (post : βPred) (epost : EPred) :
          (x.bind f).apply post epost = x.apply (fun (a : α) => (f a).apply post epost) epost

          Unfolding PredTrans.bind through apply.

          @[simp]
          theorem Lean.Order.PredTrans.apply_Bind_bind {Pred : Type u} {EPred : Type v} {α β : Type w} (x : PredTrans Pred EPred α) (f : αPredTrans Pred EPred β) (post : βPred) (epost : EPred) :
          (x >>= f).apply post epost = x.apply (fun (a : α) => (f a).apply post epost) epost

          Unfolding >>= through apply.

          @[simp]
          theorem Lean.Order.PredTrans.apply_Functor_map {Pred : Type u} {EPred : Type v} {α β : Type w} (f : αβ) (x : PredTrans Pred EPred α) (post : βPred) (epost : EPred) :
          (f <$> x).apply post epost = x.apply (post f) epost

          Unfolding <$> through apply.

          @[simp]
          theorem Lean.Order.PredTrans.apply_Seq_seq {Pred : Type u} {EPred : Type v} {α β : Type w} (f : PredTrans Pred EPred (αβ)) (x : PredTrans Pred EPred α) (post : βPred) (epost : EPred) :
          (f <*> x).apply post epost = f.apply (fun (g : αβ) => x.apply (fun (a : α) => post (g a)) epost) epost

          Unfolding <*> through apply.

          @[simp]
          theorem Lean.Order.PredTrans.apply_dite {Pred : Type u} {EPred : Type v} {α : Type w} (c : Prop) [Decidable c] (t : cPredTrans Pred EPred α) (e : ¬cPredTrans Pred EPred α) (post : αPred) (epost : EPred) :
          (if h : c then t h else e h).apply post epost = if h : c then (t h).apply post epost else (e h).apply post epost

          Unfolding dite through apply.

          @[simp]
          theorem Lean.Order.PredTrans.apply_ite {Pred : Type u} {EPred : Type v} {α : Type w} (c : Prop) [Decidable c] (t e : PredTrans Pred EPred α) (post : αPred) (epost : EPred) :
          (if c then t else e).apply post epost = if c then t.apply post epost else e.apply post epost

          Unfolding ite through apply.

          Arguments #

          Combinators that add or remove a state argument.

          def Lean.Order.PredTrans.pushArg {Pred : Type u} {EPred : Type v} {α : Type w} {σ : Type z} (x : σPredTrans Pred EPred (α × σ)) :
          PredTrans (σPred) EPred α

          Adds a state argument to a predicate transformer.

          Given a state-dependent transformer σ → PredTrans Pred EPred (α × σ), produces a transformer over σ → Pred that threads the state through postconditions.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            @[simp]
            theorem Lean.Order.PredTrans.apply_pushArg {Pred : Type u} {EPred : Type v} {α : Type w} {σ : Type z} (x : σPredTrans Pred EPred (α × σ)) (post : ασPred) (epost : EPred) (s : σ) :
            (pushArg x).apply post epost s = (x s).apply (fun (x : α × σ) => match x with | (a, s) => post a s) epost

            Unfolding lemma for pushArg: applies the state-threaded transformer at state s.

            def Lean.Order.PredTrans.popArg {Pred : Type u} {EPred : Type v} {α : Type w} {σ : Type z} (x : PredTrans (σPred) EPred α) (s : σ) :
            PredTrans Pred EPred (α × σ)

            Removes the state argument of a predicate transformer by applying it at state s. The transformed result carries the final state.

            Equations
            • x.popArg s = { apply := fun (post : α × σPred) (epost : EPred) => x.apply (fun (a : α) (s : σ) => post (a, s)) epost s }
            Instances For
              @[simp]
              theorem Lean.Order.PredTrans.apply_popArg {Pred : Type u} {EPred : Type v} {α : Type w} {σ : Type z} (x : PredTrans (σPred) EPred α) (s : σ) (post : α × σPred) (epost : EPred) :
              (x.popArg s).apply post epost = x.apply (fun (a : α) (s : σ) => post (a, s)) epost s

              Unfolding popArg through apply.

              def Lean.Order.PredTrans.liftArg {Pred : Type u} {EPred : Type v} {α : Type w} {σ : Type z} (x : PredTrans Pred EPred α) :
              PredTrans (σPred) EPred α

              Adds a state argument that the predicate transformer ignores.

              Equations
              • x.liftArg = { apply := fun (post : ασPred) (epost : EPred) (s : σ) => x.apply (fun (a : α) => post a s) epost }
              Instances For
                @[simp]
                theorem Lean.Order.PredTrans.apply_liftArg {Pred : Type u} {EPred : Type v} {α : Type w} {σ : Type z} (x : PredTrans Pred EPred α) (post : ασPred) (epost : EPred) (s : σ) :
                x.liftArg.apply post epost s = x.apply (fun (a : α) => post a s) epost

                Unfolding liftArg through apply.

                @[instance_reducible]
                instance Lean.Order.PredTrans.instMonadLiftForall {Pred : Type u} {EPred : Type v} {σ : Type z} :
                MonadLift (PredTrans Pred EPred) (PredTrans (σPred) EPred)
                Equations
                @[simp]
                theorem Lean.Order.PredTrans.apply_monadLift {Pred : Type u} {EPred : Type v} {α : Type w} {σ : Type z} (x : PredTrans Pred EPred α) (post : ασPred) (epost : EPred) (s : σ) :
                (MonadLift.monadLift x).apply post epost s = x.apply (fun (a : α) => post a s) epost

                Unfolding monadLift through apply.

                Results #

                Postconditions for Except and Option results, and the transformer combinators built on them.

                def Lean.Order.pushExcept {α : Type u} {ε : Type v} {Pred : Type w} (post : αPred) (epost : εPred) :
                Except ε αPred

                The postcondition for an Except ε α result: ok a uses post a, and error e uses epost e.

                Equations
                Instances For
                  @[simp]
                  theorem Lean.Order.pushExcept_ok {α : Type u} {ε : Type v} {Pred : Type w} (post : αPred) (epost : εPred) (a : α) :
                  pushExcept post epost (Except.ok a) = post a

                  A normal result uses the normal postcondition.

                  @[simp]
                  theorem Lean.Order.pushExcept_error {α : Type u} {ε : Type v} {Pred : Type w} (post : αPred) (epost : εPred) (e : ε) :
                  pushExcept post epost (Except.error e) = epost e

                  An exceptional result uses the exception postcondition.

                  def Lean.Order.pushOption {α : Type u} {Pred : Type w} (post : αPred) (epost : UnitPred) :
                  Option αPred

                  The postcondition for an Option α result: some a uses post a, and none uses epost ().

                  Equations
                  Instances For
                    @[simp]
                    theorem Lean.Order.pushOption_some {α : Type u} {Pred : Type w} (post : αPred) (epost : UnitPred) (a : α) :
                    pushOption post epost (some a) = post a

                    A present result uses the normal postcondition.

                    @[simp]
                    theorem Lean.Order.pushOption_none {α : Type u} {Pred : Type w} (post : αPred) (epost : UnitPred) :
                    pushOption post epost none = epost ()

                    An absent result uses the absent postcondition.

                    def Lean.Order.PredTrans.pushExceptT {Pred : Type u} {EPred : Type v} {α : Type w} {ε : Type z} (x : PredTrans Pred EPred (Except ε α)) :
                    PredTrans Pred ((εPred) × EPred) α

                    Adds an exception postcondition layer to a predicate transformer, mirroring ExceptT.

                    Given a transformer over Except ε α, produces one over α with an additional exception postcondition for ε. The normal and error postconditions are combined via pushExcept.

                    Equations
                    Instances For
                      @[simp]
                      theorem Lean.Order.PredTrans.apply_pushExceptT {Pred : Type u} {EPred : Type v} {α : Type w} {ε : Type z} (x : PredTrans Pred EPred (Except ε α)) (post : αPred) (epost : (εPred) × EPred) :
                      x.pushExceptT.apply post epost = x.apply (pushExcept post epost.fst) epost.snd

                      Unfolding lemma for pushExceptT.

                      def Lean.Order.PredTrans.pushOptionT {Pred : Type u} {EPred : Type v} {α : Type w} (x : PredTrans Pred EPred (Option α)) :
                      PredTrans Pred ((UnitPred) × EPred) α

                      Adds an early-termination layer to a predicate transformer, mirroring OptionT.

                      Given a transformer over Option α, produces one over α with an additional exception postcondition for the none case.

                      Equations
                      Instances For
                        @[simp]
                        theorem Lean.Order.PredTrans.apply_pushOptionT {Pred : Type u} {EPred : Type v} {α : Type w} (x : PredTrans Pred EPred (Option α)) (post : αPred) (epost : (UnitPred) × EPred) :
                        x.pushOptionT.apply post epost = x.apply (pushOption post epost.fst) epost.snd

                        Unfolding lemma for pushOptionT.

                        Exception Instances #

                        throw and tryCatch on the first exception postcondition, and the combinators that lift the MonadExceptOf instance through further layers.

                        def Lean.Order.PredTrans.throw {Pred : Type u} {EPred : Type v} {α : Type w} {ε : Type z} (e : ε) :
                        PredTrans Pred ((εPred) × EPred) α

                        throw e asserts the first exception postcondition at e.

                        Equations
                        Instances For
                          def Lean.Order.PredTrans.tryCatch {Pred : Type u} {EPred : Type v} {α : Type w} {ε : Type z} (x : PredTrans Pred ((εPred) × EPred) α) (handle : εPredTrans Pred ((εPred) × EPred) α) :
                          PredTrans Pred ((εPred) × EPred) α

                          tryCatch x handle replaces the first exception postcondition of x with the precondition of the handler.

                          Equations
                          • x.tryCatch handle = { apply := fun (post : αPred) (epost : (εPred) × EPred) => x.apply post (fun (e : ε) => (handle e).apply post epost, epost.snd) }
                          Instances For
                            @[instance_reducible]
                            instance Lean.Order.PredTrans.instMonadExceptOfProdForall {Pred : Type u} {EPred : Type v} {ε : Type z} :
                            MonadExceptOf ε (PredTrans Pred ((εPred) × EPred))
                            Equations
                            @[simp]
                            theorem Lean.Order.PredTrans.apply_throw {ε α Pred : Type u} {EPred : Type w} (e : ε) (post : αPred) (epost : (εPred) × EPred) :
                            (MonadExceptOf.throw e).apply post epost = epost.fst e

                            Unfolding throw through apply: the first exception postcondition at the thrown value.

                            @[simp]
                            theorem Lean.Order.PredTrans.apply_tryCatch {ε α Pred : Type u} {EPred : Type w} (x : PredTrans Pred ((εPred) × EPred) α) (handle : εPredTrans Pred ((εPred) × EPred) α) (post : αPred) (epost : (εPred) × EPred) :
                            (MonadExceptOf.tryCatch x handle).apply post epost = x.apply post (fun (e : ε) => (handle e).apply post epost, epost.snd)

                            Unfolding tryCatch through apply: the handler replaces the first exception postcondition.

                            def Lean.Order.PredTrans.liftExcept {Pred : Type u} {EPred : Type v} {α : Type w} {eh : Type z} (x : PredTrans Pred EPred α) :
                            PredTrans Pred (eh × EPred) α

                            Adds a first exception postcondition that the predicate transformer ignores.

                            Equations
                            Instances For
                              @[simp]
                              theorem Lean.Order.PredTrans.apply_liftExcept {Pred : Type u} {EPred : Type v} {α : Type w} {eh : Type z} (x : PredTrans Pred EPred α) (post : αPred) (epost : eh × EPred) :
                              x.liftExcept.apply post epost = x.apply post epost.snd

                              Unfolding liftExcept through apply.

                              def Lean.Order.PredTrans.popExcept {Pred : Type u} {EPred : Type v} {α : Type w} {eh : Type z} (x : PredTrans Pred (eh × EPred) α) (h : eh) :
                              PredTrans Pred EPred α

                              Removes the first exception postcondition of a predicate transformer by fixing it to h.

                              Equations
                              Instances For
                                @[simp]
                                theorem Lean.Order.PredTrans.apply_popExcept {Pred : Type u} {EPred : Type v} {α : Type w} {eh : Type z} (x : PredTrans Pred (eh × EPred) α) (h : eh) (post : αPred) (epost : EPred) :
                                (x.popExcept h).apply post epost = x.apply post (h, epost)

                                Unfolding popExcept through apply.

                                @[instance_reducible]
                                instance Lean.Order.PredTrans.instMonadExceptOfProdForall_1 {ε : Type u} {Pred : Type v} {EPred : Type w} {ε' : Type u} [MonadExceptOf ε (PredTrans Pred EPred)] :
                                MonadExceptOf ε (PredTrans Pred ((ε'Pred) × EPred))
                                Equations
                                • One or more equations did not get rendered due to their size.

                                State Instances #

                                Standard state and reader class instances for PredTrans.

                                def Lean.Order.PredTrans.get {Pred : Type u} {EPred : Type v} {σ : Type z} :
                                PredTrans (σPred) EPred σ

                                get transforms the postcondition into its assertion at the current state.

                                Equations
                                Instances For
                                  def Lean.Order.PredTrans.set {Pred : Type u} {EPred : Type v} {σ : Type z} (s' : σ) :
                                  PredTrans (σPred) EPred PUnit

                                  set s' transforms the postcondition into its assertion at the state s'.

                                  Equations
                                  Instances For
                                    def Lean.Order.PredTrans.modifyGet {Pred : Type u} {EPred : Type v} {σ α : Type z} (f : σα × σ) :
                                    PredTrans (σPred) EPred α

                                    modifyGet f transforms the postcondition into its assertion at the result and state computed by f.

                                    Equations
                                    Instances For
                                      @[instance_reducible]
                                      instance Lean.Order.PredTrans.instMonadStateOfForall {Pred : Type u} {EPred : Type v} {σ : Type z} :
                                      MonadStateOf σ (PredTrans (σPred) EPred)
                                      Equations
                                      @[instance_reducible]
                                      instance Lean.Order.PredTrans.instMonadReaderOfForall {Pred : Type u} {EPred : Type v} {σ : Type z} :
                                      MonadReaderOf σ (PredTrans (σPred) EPred)
                                      Equations
                                      @[simp]
                                      theorem Lean.Order.PredTrans.apply_get {Pred : Type u} {EPred : Type v} {σ : Type z} (post : σσPred) (epost : EPred) (s : σ) :
                                      MonadStateOf.get.apply post epost s = post s s

                                      Unfolding get through apply.

                                      @[simp]
                                      theorem Lean.Order.PredTrans.apply_set {Pred : Type u} {EPred : Type v} {σ : Type z} (s' : σ) (post : PUnitσPred) (epost : EPred) (s : σ) :
                                      (MonadStateOf.set s').apply post epost s = post PUnit.unit s'

                                      Unfolding set through apply.

                                      @[simp]
                                      theorem Lean.Order.PredTrans.apply_modifyGet {Pred : Type u} {EPred : Type v} {σ α : Type z} (f : σα × σ) (post : ασPred) (epost : EPred) (s : σ) :
                                      (MonadStateOf.modifyGet f).apply post epost s = post (f s).fst (f s).snd

                                      Unfolding modifyGet through apply.

                                      @[simp]
                                      theorem Lean.Order.PredTrans.apply_read {Pred : Type u} {EPred : Type v} {σ : Type z} (post : σσPred) (epost : EPred) (s : σ) :
                                      MonadReaderOf.read.apply post epost s = post s s

                                      Unfolding read through apply.

                                      @[instance_reducible]
                                      instance Lean.Order.PredTrans.instMonadExceptOfForall {Pred : Type u} {EPred : Type v} {ε : Type u'} {σ : Type z} [MonadExceptOf ε (PredTrans Pred EPred)] :
                                      MonadExceptOf ε (PredTrans (σPred) EPred)
                                      Equations
                                      • One or more equations did not get rendered due to their size.