File: .lake/packages/batteries/Batteries/Classes/SatisfiesM.lean

full_name: SatisfiesM
code: /--
`SatisfiesM p (x : m α)` lifts propositions over a monad. It asserts that `x` may as well
have the type `x : m {a // p a}`, because there exists some `m {a // p a}` whose image is `x`.
So `p` is the postcondition of the monadic value.
-/
def SatisfiesM {m : Type u → Type v} [Functor m] (p : α → Prop) (x : m α) : Prop 
goal: Prop

full_name: SatisfiesM.of_true
code: /-- If `p` is always true, then every `x` satisfies it. -/
theorem of_true [Applicative m] [LawfulApplicative m] {x : m α}
    (h : ∀ a, p a) : SatisfiesM p x 
goal: SatisfiesM p x

full_name: SatisfiesM.trivial
code: /--
If `p` is always true, then every `x` satisfies it.
(This is the strongest postcondition version of `of_true`.)
-/
protected theorem trivial [Applicative m] [LawfulApplicative m] {x : m α} :
  SatisfiesM (fun _ => True) x 
goal: SatisfiesM (fun x => True) x

full_name: SatisfiesM.imp
code: /-- The `SatisfiesM p x` predicate is monotonic in `p`. -/
theorem imp [Functor m] [LawfulFunctor m] {x : m α}
    (h : SatisfiesM p x) (H : ∀ {a}, p a → q a) : SatisfiesM q x 
goal: SatisfiesM q x

full_name: SatisfiesM.map
code: /-- `SatisfiesM` distributes over `<$>`, general version. -/
protected theorem map [Functor m] [LawfulFunctor m] {x : m α}
    (hx : SatisfiesM p x) (hf : ∀ {a}, p a → q (f a)) : SatisfiesM q (f <$> x) 
goal: ∀ {α_1 : Type u_1} {q : α_1 → Prop} {f : α → α_1} [inst : Functor m] [inst_1 : LawfulFunctor m] {x : m α},
  SatisfiesM p x → (∀ {a : α}, p a → q (f a)) → SatisfiesM q (f <$> x)

full_name: SatisfiesM.map_post
code: /--
`SatisfiesM` distributes over `<$>`, strongest postcondition version.
(Use this for reasoning forward from assumptions.)
-/
theorem map_post [Functor m] [LawfulFunctor m] {x : m α}
    (hx : SatisfiesM p x) : SatisfiesM (fun b => ∃ a, p a ∧ b = f a) (f <$> x) 
goal: ∀ {α_1 : Type u_1} {f : α → α_1} [inst : Functor m] [inst_1 : LawfulFunctor m] {x : m α},
  SatisfiesM p x → SatisfiesM (fun b => ∃ a, p a ∧ b = f a) (f <$> x)

full_name: SatisfiesM.map_pre
code: /--
`SatisfiesM` distributes over `<$>`, weakest precondition version.
(Use this for reasoning backward from the goal.)
-/
theorem map_pre [Functor m] [LawfulFunctor m] {x : m α}
    (hx : SatisfiesM (fun a => p (f a)) x) : SatisfiesM p (f <$> x) 
goal: ∀ {α_1 : Type u_1} {p : α_1 → Prop} {f : α → α_1} [inst : Functor m] [inst_1 : LawfulFunctor m] {x : m α},
  SatisfiesM (fun a => p (f a)) x → SatisfiesM p (f <$> x)

full_name: SatisfiesM.mapConst
code: /-- `SatisfiesM` distributes over `mapConst`, general version. -/
protected theorem mapConst [Functor m] [LawfulFunctor m] {x : m α}
    (hx : SatisfiesM q x) (ha : ∀ {b}, q b → p a) : SatisfiesM p (Functor.mapConst a x) 
goal: ∀ {α_1 : Type u_1} {p : α_1 → Prop} {a : α_1} [inst : Functor m] [inst_1 : LawfulFunctor m] {x : m α},
  SatisfiesM q x → (∀ {b : α}, q b → p a) → SatisfiesM p (Functor.mapConst a x)

full_name: SatisfiesM.pure
code: /-- `SatisfiesM` distributes over `pure`, general version / weakest precondition version. -/
protected theorem pure [Applicative m] [LawfulApplicative m]
    (h : p a) : SatisfiesM (m := m) p (pure a) 
goal: ∀ {α : Type u_1} {p : α → Prop} {a : α} [inst : Applicative m] [inst_1 : LawfulApplicative m],
  p a → SatisfiesM p (pure a)

full_name: SatisfiesM.seq
code: /-- `SatisfiesM` distributes over `<*>`, general version. -/
protected theorem seq [Applicative m] [LawfulApplicative m] {x : m α}
    (hf : SatisfiesM p₁ f) (hx : SatisfiesM p₂ x)
    (H : ∀ {f a}, p₁ f → p₂ a → q (f a)) : SatisfiesM q (f <*> x) 
goal: ∀ {α_1 : Type u_1} {p₁ : (α → α_1) → Prop} {f : m (α → α_1)} {p₂ : α → Prop} {q : α_1 → Prop} [inst : Applicative m]
  [inst_1 : LawfulApplicative m] {x : m α},
  SatisfiesM p₁ f →
    SatisfiesM p₂ x → (∀ {f : α → α_1} {a : α}, p₁ f → p₂ a → q (f a)) → SatisfiesM q (Seq.seq f fun x_1 => x)

full_name: SatisfiesM.seq_post
code: /-- `SatisfiesM` distributes over `<*>`, strongest postcondition version. -/
protected theorem seq_post [Applicative m] [LawfulApplicative m] {x : m α}
    (hf : SatisfiesM p₁ f) (hx : SatisfiesM p₂ x) :
    SatisfiesM (fun c => ∃ f a, p₁ f ∧ p₂ a ∧ c = f a) (f <*> x) 
goal: ∀ {α_1 : Type u_1} {p₁ : (α → α_1) → Prop} {f : m (α → α_1)} {p₂ : α → Prop} [inst : Applicative m]
  [inst_1 : LawfulApplicative m] {x : m α},
  SatisfiesM p₁ f → SatisfiesM p₂ x → SatisfiesM (fun c => ∃ f a, p₁ f ∧ p₂ a ∧ c = f a) (Seq.seq f fun x_1 => x)

full_name: SatisfiesM.seq_pre
code: /--
`SatisfiesM` distributes over `<*>`, weakest precondition version 1.
(Use this when `x` and the goal are known and `f` is a subgoal.)
-/
protected theorem seq_pre [Applicative m] [LawfulApplicative m] {x : m α}
    (hf : SatisfiesM (fun f => ∀ {a}, p₂ a → q (f a)) f) (hx : SatisfiesM p₂ x) :
    SatisfiesM q (f <*> x) 
goal: ∀ {α_1 : Type u_1} {q : α_1 → Prop} {f : m (α → α_1)} [inst : Applicative m] [inst_1 : LawfulApplicative m] {x : m α},
  SatisfiesM (fun f => ∀ {a : α}, p₂ a → q (f a)) f → SatisfiesM p₂ x → SatisfiesM q (Seq.seq f fun x_1 => x)

full_name: SatisfiesM.seq_pre'
code: /--
`SatisfiesM` distributes over `<*>`, weakest precondition version 2.
(Use this when `f` and the goal are known and `x` is a subgoal.)
-/
protected theorem seq_pre' [Applicative m] [LawfulApplicative m] {x : m α}
    (hf : SatisfiesM p₁ f) (hx : SatisfiesM (fun a => ∀ {f}, p₁ f → q (f a)) x) :
    SatisfiesM q (f <*> x) 
goal: ∀ {α_1 : Type u_1} {p₁ : (α → α_1) → Prop} {f : m (α → α_1)} {q : α_1 → Prop} [inst : Applicative m]
  [inst_1 : LawfulApplicative m] {x : m α},
  SatisfiesM p₁ f → SatisfiesM (fun a => ∀ {f : α → α_1}, p₁ f → q (f a)) x → SatisfiesM q (Seq.seq f fun x_1 => x)

full_name: SatisfiesM.seqLeft
code: /-- `SatisfiesM` distributes over `<*`, general version. -/
protected theorem seqLeft [Applicative m] [LawfulApplicative m] {x : m α}
    (hx : SatisfiesM p₁ x) (hy : SatisfiesM p₂ y)
    (H : ∀ {a b}, p₁ a → p₂ b → q a) : SatisfiesM q (x <* y) 
goal: ∀ {a : Type u_1} {p₂ : a → Prop} {y : m a} {q : α → Prop} [inst : Applicative m] [inst_1 : LawfulApplicative m]
  {x : m α},
  SatisfiesM p₁ x →
    SatisfiesM p₂ y → (∀ {a_1 : α} {b : a}, p₁ a_1 → p₂ b → q a_1) → SatisfiesM q (SeqLeft.seqLeft x fun x => y)

full_name: SatisfiesM.seqRight
code: /-- `SatisfiesM` distributes over `*>`, general version. -/
protected theorem seqRight [Applicative m] [LawfulApplicative m] {x : m α}
    (hx : SatisfiesM p₁ x) (hy : SatisfiesM p₂ y)
    (H : ∀ {a b}, p₁ a → p₂ b → q b) : SatisfiesM q (x *> y) 
goal: ∀ {a : Type u_1} {p₂ : a → Prop} {y : m a} {q : a → Prop} [inst : Applicative m] [inst_1 : LawfulApplicative m]
  {x : m α},
  SatisfiesM p₁ x →
    SatisfiesM p₂ y → (∀ {a_1 : α} {b : a}, p₁ a_1 → p₂ b → q b) → SatisfiesM q (SeqRight.seqRight x fun x => y)

full_name: SatisfiesM.bind
code: /-- `SatisfiesM` distributes over `>>=`, general version. -/
protected theorem bind [Monad m] [LawfulMonad m] {f : α → m β}
    (hx : SatisfiesM p x) (hf : ∀ a, p a → SatisfiesM q (f a)) :
    SatisfiesM q (x >>= f) 
goal: SatisfiesM q (x >>= f)

full_name: SatisfiesM.bind_pre
code: /-- `SatisfiesM` distributes over `>>=`, weakest precondition version. -/
protected theorem bind_pre [Monad m] [LawfulMonad m] {f : α → m β}
    (hx : SatisfiesM (fun a => SatisfiesM q (f a)) x) :
    SatisfiesM q (x >>= f) 
goal: SatisfiesM q (x >>= f)

full_name: SatisfiesM_Id_eq
code: @[simp] theorem SatisfiesM_Id_eq : SatisfiesM (m := Id) p x ↔ p x 
goal: ∀ {type : Type u_1} {p : type → Prop} {x : Id type}, SatisfiesM p x ↔ p x

full_name: SatisfiesM_Option_eq
code: @[simp] theorem SatisfiesM_Option_eq : SatisfiesM (m := Option) p x ↔ ∀ a, x = some a → p a 
goal: ∀ {α : Type u_1} {p : α → Prop} {x : Option α}, SatisfiesM p x ↔ ∀ (a : α), x = some a → p a

full_name: SatisfiesM_Except_eq
code: @[simp] theorem SatisfiesM_Except_eq : SatisfiesM (m := Except ε) p x ↔ ∀ a, x = .ok a → p a 
goal: ∀ {α : Type u_2} {p : α → Prop} {x : Except ε α}, SatisfiesM p x ↔ ∀ (a : α), x = Except.ok a → p a

full_name: SatisfiesM_ReaderT_eq
code: @[simp] theorem SatisfiesM_ReaderT_eq [Monad m] :
    SatisfiesM (m := ReaderT ρ m) p x ↔ ∀ s, SatisfiesM p (x s) 
goal: ∀ {α : Type u_1} {p : α → Prop} {x : ReaderT ρ m α} [inst : Monad m], SatisfiesM p x ↔ ∀ (s : ρ), SatisfiesM p (x s)

full_name: SatisfiesM_StateRefT_eq
code: theorem SatisfiesM_StateRefT_eq [Monad m] :
    SatisfiesM (m := StateRefT' ω σ m) p x ↔ ∀ s, SatisfiesM p (x s) 
goal: ∀ {α : Type} {p : α → Prop} {x : StateRefT' ω σ m α} [inst : Monad m],
  SatisfiesM p x ↔ ∀ (s : ST.Ref ω σ), SatisfiesM p (x s)

full_name: SatisfiesM_StateT_eq
code: @[simp] theorem SatisfiesM_StateT_eq [Monad m] [LawfulMonad m] :
    SatisfiesM (m := StateT ρ m) (α := α) p x ↔ ∀ s, SatisfiesM (m := m) (p ·.1) (x s) 
goal: SatisfiesM p x ↔ ∀ (s : ρ), SatisfiesM (fun x => p x.fst) (x s)

full_name: SatisfiesM_ExceptT_eq
code: @[simp] theorem SatisfiesM_ExceptT_eq [Monad m] [LawfulMonad m] :
    SatisfiesM (m := ExceptT ρ m) (α := α) p x ↔ SatisfiesM (m := m) (∀ a, · = .ok a → p a) x 
goal: SatisfiesM p x ↔ SatisfiesM (fun x => ∀ (a : α), x = Except.ok a → p a) x