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

Proof steps:
state_before: m : Type u_1 → Type u_2
α β : Type u_1
p : α → Prop
x : m α
q : β → Prop
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → m β
hx : SatisfiesM p x
hf : ∀ (a : α), p a → SatisfiesM q (f a)
⊢ SatisfiesM q (x >>= f)
state_after: m : Type u_1 → Type u_2
α β : Type u_1
p : α → Prop
x✝ : m α
q : β → Prop
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → m β
hx : SatisfiesM p x✝
hf : ∀ (a : α), p a → SatisfiesM q (f a)
x : m { a // p a }
⊢ SatisfiesM q (Subtype.val <$> x >>= f)
tactic: match x, hx with | _, ⟨x, rfl⟩ => ?_
state_before: m : Type u_1 → Type u_2
α β : Type u_1
p : α → Prop
x✝ : m α
q : β → Prop
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → m β
hx : SatisfiesM p x✝
hf : ∀ (a : α), p a → SatisfiesM q (f a)
x : m { a // p a }
⊢ SatisfiesM q (Subtype.val <$> x >>= f)
state_after: m : Type u_1 → Type u_2
α β : Type u_1
p : α → Prop
x✝ : m α
q : β → Prop
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → m β
hx : SatisfiesM p x✝
hf : ∀ (a : α), p a → SatisfiesM q (f a)
x : m { a // p a }
g : (a : α) → p a → { x // Subtype.val <$> x = f a }
⊢ SatisfiesM q (Subtype.val <$> x >>= f)
tactic: have g a ha := Classical.indefiniteDescription _ (hf a ha)
state_before: m : Type u_1 → Type u_2
α β : Type u_1
p : α → Prop
x✝ : m α
q : β → Prop
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → m β
hx : SatisfiesM p x✝
hf : ∀ (a : α), p a → SatisfiesM q (f a)
x : m { a // p a }
g : (a : α) → p a → { x // Subtype.val <$> x = f a }
⊢ SatisfiesM q (Subtype.val <$> x >>= f)
state_after: m : Type u_1 → Type u_2
α β : Type u_1
p : α → Prop
x✝ : m α
q : β → Prop
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → m β
hx : SatisfiesM p x✝
hf : ∀ (a : α), p a → SatisfiesM q (f a)
x : m { a // p a }
g : (a : α) → p a → { x // Subtype.val <$> x = f a }
⊢ (Subtype.val <$> do
      let x ← x
      match x with
        | ⟨a, h⟩ => (g a h).val) =
    Subtype.val <$> x >>= f
tactic: refine ⟨x >>= fun ⟨a, h⟩ => g a h, ?_⟩
state_before: m : Type u_1 → Type u_2
α β : Type u_1
p : α → Prop
x✝ : m α
q : β → Prop
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → m β
hx : SatisfiesM p x✝
hf : ∀ (a : α), p a → SatisfiesM q (f a)
x : m { a // p a }
g : (a : α) → p a → { x // Subtype.val <$> x = f a }
⊢ (Subtype.val <$> do
      let x ← x
      match x with
        | ⟨a, h⟩ => (g a h).val) =
    Subtype.val <$> x >>= f
state_after: m : Type u_1 → Type u_2
α β : Type u_1
p : α → Prop
x✝ : m α
q : β → Prop
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → m β
hx : SatisfiesM p x✝
hf : ∀ (a : α), p a → SatisfiesM q (f a)
x : m { a // p a }
g : (a : α) → p a → { x // Subtype.val <$> x = f a }
⊢ (do
      let x ← x
      let a ← (g x.val ⋯).val
      pure a.val) =
    do
    let x ← x
    f x.val
tactic: simp [← bind_pure_comp]
state_before: m : Type u_1 → Type u_2
α β : Type u_1
p : α → Prop
x✝ : m α
q : β → Prop
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → m β
hx : SatisfiesM p x✝
hf : ∀ (a : α), p a → SatisfiesM q (f a)
x : m { a // p a }
g : (a : α) → p a → { x // Subtype.val <$> x = f a }
⊢ (do
      let x ← x
      let a ← (g x.val ⋯).val
      pure a.val) =
    do
    let x ← x
    f x.val
state_after: case e_a
m : Type u_1 → Type u_2
α β : Type u_1
p : α → Prop
x✝ : m α
q : β → Prop
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → m β
hx : SatisfiesM p x✝
hf : ∀ (a : α), p a → SatisfiesM q (f a)
x : m { a // p a }
g : (a : α) → p a → { x // Subtype.val <$> x = f a }
⊢ (fun x => do
      let a ← (g x.val ⋯).val
      pure a.val) =
    fun x => f x.val
tactic: congr
state_before: case e_a
m : Type u_1 → Type u_2
α β : Type u_1
p : α → Prop
x✝ : m α
q : β → Prop
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → m β
hx : SatisfiesM p x✝
hf : ∀ (a : α), p a → SatisfiesM q (f a)
x : m { a // p a }
g : (a : α) → p a → { x // Subtype.val <$> x = f a }
⊢ (fun x => do
      let a ← (g x.val ⋯).val
      pure a.val) =
    fun x => f x.val
state_after: case e_a.h
m : Type u_1 → Type u_2
α β : Type u_1
p : α → Prop
x✝ : m α
q : β → Prop
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → m β
hx : SatisfiesM p x✝
hf : ∀ (a : α), p a → SatisfiesM q (f a)
x : m { a // p a }
g : (a : α) → p a → { x // Subtype.val <$> x = f a }
a : α
h : p a
⊢ (do
      let a ← (g ⟨a, h⟩.val ⋯).val
      pure a.val) =
    f ⟨a, h⟩.val
tactic: funext ⟨a, h⟩
state_before: case e_a.h
m : Type u_1 → Type u_2
α β : Type u_1
p : α → Prop
x✝ : m α
q : β → Prop
inst✝¹ : Monad m
inst✝ : LawfulMonad m
f : α → m β
hx : SatisfiesM p x✝
hf : ∀ (a : α), p a → SatisfiesM q (f a)
x : m { a // p a }
g : (a : α) → p a → { x // Subtype.val <$> x = f a }
a : α
h : p a
⊢ (do
      let a ← (g ⟨a, h⟩.val ⋯).val
      pure a.val) =
    f ⟨a, h⟩.val
state_after: no goals
tactic: simp [← (g a h).2, ← bind_pure_comp]