Theorem: Computation.ret_bind
File: Mathlib/Data/Seq/Computation.lean

tactic: apply
  eq_of_bisim fun c₁ c₂ => c₁ = bind (pure a) f ∧ c₂ = f a ∨ c₁ = corec (Bind.f f) (Sum.inr c₂)
state_before: α : Type u
β : Type v
γ : Type w
a : α
f : α → Computation β
⊢ bind (pure a) f = f a

tactic: intro c₁ c₂ h
state_before: case bisim
α : Type u
β : Type v
γ : Type w
a : α
f : α → Computation β
⊢ IsBisimulation fun c₁ c₂ => c₁ = bind (pure a) f ∧ c₂ = f a ∨ c₁ = corec (Bind.f f) (Sum.inr c₂)

tactic: exact
  match c₁, c₂, h with
  | _, _, Or.inl ⟨rfl, rfl⟩ => by
    simp [bind, Bind.f]
    cases' destruct (f a) with b cb <;> simp [Bind.g]
  | _, c, Or.inr rfl => by
    simp [Bind.f]
    cases' destruct c with b cb <;> simp [Bind.g]
state_before: case bisim
α : Type u
β : Type v
γ : Type w
a : α
f : α → Computation β
c₁ c₂ : Computation β
h : c₁ = bind (pure a) f ∧ c₂ = f a ∨ c₁ = corec (Bind.f f) (Sum.inr c₂)
⊢ BisimO (fun c₁ c₂ => c₁ = bind (pure a) f ∧ c₂ = f a ∨ c₁ = corec (Bind.f f) (Sum.inr c₂)) (destruct c₁) (destruct c₂)

tactic: simp [bind, Bind.f]
state_before: α : Type u
β : Type v
γ : Type w
a : α
f : α → Computation β
c₁ c₂ : Computation β
h : c₁ = bind (pure a) f ∧ c₂ = f a ∨ c₁ = corec (Bind.f f) (Sum.inr c₂)
⊢ BisimO (fun c₁ c₂ => c₁ = bind (pure a) f ∧ c₂ = f a ∨ c₁ = corec (Bind.f f) (Sum.inr c₂))
    (destruct (bind (pure a) f)) (destruct (f a))

tactic: cases' destruct (f a) with b cb <;> simp [Bind.g]
state_before: α : Type u
β : Type v
γ : Type w
a : α
f : α → Computation β
c₁ c₂ : Computation β
h : c₁ = bind (pure a) f ∧ c₂ = f a ∨ c₁ = corec (Bind.f f) (Sum.inr c₂)
⊢ match
    match Bind.g (destruct (f a)) with
    | Sum.inl a => Sum.inl a
    | Sum.inr b =>
      Sum.inr
        (corec
          (fun x =>
            match x with
            | Sum.inl ca =>
              match destruct ca with
              | Sum.inl a => Bind.g (destruct (f a))
              | Sum.inr ca' => Sum.inr (Sum.inl ca')
            | Sum.inr cb => Bind.g (destruct cb))
          b),
    destruct (f a) with
  | Sum.inl a, Sum.inl a' => a = a'
  | Sum.inr s, Sum.inr s' =>
    s =
          corec
            (fun x =>
              match x with
              | Sum.inl ca =>
                match destruct ca with
                | Sum.inl a => Bind.g (destruct (f a))
                | Sum.inr ca' => Sum.inr (Sum.inl ca')
              | Sum.inr cb => Bind.g (destruct cb))
            (Sum.inl (pure a)) ∧
        s' = f a ∨
      s =
        corec
          (fun x =>
            match x with
            | Sum.inl ca =>
              match destruct ca with
              | Sum.inl a => Bind.g (destruct (f a))
              | Sum.inr ca' => Sum.inr (Sum.inl ca')
            | Sum.inr cb => Bind.g (destruct cb))
          (Sum.inr s')
  | x, x_1 => False

tactic: simp [Bind.f]
state_before: α : Type u
β : Type v
γ : Type w
a : α
f : α → Computation β
c₁ c₂ : Computation β
h : c₁ = bind (pure a) f ∧ c₂ = f a ∨ c₁ = corec (Bind.f f) (Sum.inr c₂)
c : Computation β
⊢ BisimO (fun c₁ c₂ => c₁ = bind (pure a) f ∧ c₂ = f a ∨ c₁ = corec (Bind.f f) (Sum.inr c₂))
    (destruct (corec (Bind.f f) (Sum.inr c))) (destruct c)

tactic: cases' destruct c with b cb <;> simp [Bind.g]
state_before: α : Type u
β : Type v
γ : Type w
a : α
f : α → Computation β
c₁ c₂ : Computation β
h : c₁ = bind (pure a) f ∧ c₂ = f a ∨ c₁ = corec (Bind.f f) (Sum.inr c₂)
c : Computation β
⊢ match
    match Bind.g (destruct c) with
    | Sum.inl a => Sum.inl a
    | Sum.inr b =>
      Sum.inr
        (corec
          (fun x =>
            match x with
            | Sum.inl ca =>
              match destruct ca with
              | Sum.inl a => Bind.g (destruct (f a))
              | Sum.inr ca' => Sum.inr (Sum.inl ca')
            | Sum.inr cb => Bind.g (destruct cb))
          b),
    destruct c with
  | Sum.inl a, Sum.inl a' => a = a'
  | Sum.inr s, Sum.inr s' =>
    s = bind (pure a) f ∧ s' = f a ∨
      s =
        corec
          (fun x =>
            match x with
            | Sum.inl ca =>
              match destruct ca with
              | Sum.inl a => Bind.g (destruct (f a))
              | Sum.inr ca' => Sum.inr (Sum.inl ca')
            | Sum.inr cb => Bind.g (destruct cb))
          (Sum.inr s')
  | x, x_1 => False

tactic: simp
state_before: case r
α : Type u
β : Type v
γ : Type w
a : α
f : α → Computation β
⊢ bind (pure a) f = bind (pure a) f ∧ f a = f a ∨ bind (pure a) f = corec (Bind.f f) (Sum.inr (f a))