Theorem: Stream'.WSeq.destruct_flatten
File: Mathlib/Data/Seq/WSeq.lean

tactic: refine
  Computation.eq_of_bisim
    (fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct) ?_
    (Or.inr ⟨c, rfl, rfl⟩)
state_before: α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
⊢ (flatten c).destruct = c >>= destruct
state_after: α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
⊢ Computation.IsBisimulation fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = (flatten c).destruct ∧ c2 = c.bind destruct

tactic: intro c1 c2 h
state_before: α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
⊢ Computation.IsBisimulation fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = (flatten c).destruct ∧ c2 = c.bind destruct
state_after: α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = (flatten c).destruct ∧ c2 = c.bind destruct
⊢ Computation.BisimO (fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = (flatten c).destruct ∧ c2 = c.bind destruct) c1.destruct
    c2.destruct

tactic: cases c.destruct <;> simp
state_before: α : Type u
β : Type v
γ : Type w
c✝ : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = (flatten c).destruct ∧ c2 = c.bind destruct
c : Computation (Option (α × WSeq α))
⊢ Computation.BisimO (fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = (flatten c).destruct ∧ c2 = c.bind destruct) c.destruct
    c.destruct
state_after: no goals

tactic: induction' c using Computation.recOn with a c' <;> simp
state_before: α : Type u
β : Type v
γ : Type w
c✝ : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = (flatten c).destruct ∧ c2 = c.bind destruct
c : Computation (WSeq α)
⊢ Computation.BisimO (fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = (flatten c).destruct ∧ c2 = c.bind destruct)
    (flatten c).destruct.destruct (c.bind destruct).destruct
state_after: case h1
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = (flatten c).destruct ∧ c2 = c.bind destruct
a : WSeq α
⊢ match a.destruct.destruct, a.destruct.destruct with
  | Sum.inl a, Sum.inl a' => a = a'
  | Sum.inr s, Sum.inr s' => s = s' ∨ ∃ c, s = (flatten c).destruct ∧ s' = c.bind destruct
  | x, x_1 => False

case h2
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = (flatten c).destruct ∧ c2 = c.bind destruct
c' : Computation (WSeq α)
⊢ (flatten c').destruct = c'.bind destruct ∨
    ∃ c, (flatten c').destruct = (flatten c).destruct ∧ c'.bind destruct = c.bind destruct

tactic: cases (destruct a).destruct <;> simp
state_before: case h1
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = (flatten c).destruct ∧ c2 = c.bind destruct
a : WSeq α
⊢ match a.destruct.destruct, a.destruct.destruct with
  | Sum.inl a, Sum.inl a' => a = a'
  | Sum.inr s, Sum.inr s' => s = s' ∨ ∃ c, s = (flatten c).destruct ∧ s' = c.bind destruct
  | x, x_1 => False
state_after: no goals

tactic: exact Or.inr ⟨c', rfl, rfl⟩
state_before: case h2
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = (flatten c).destruct ∧ c2 = c.bind destruct
c' : Computation (WSeq α)
⊢ (flatten c').destruct = c'.bind destruct ∨
    ∃ c, (flatten c').destruct = (flatten c).destruct ∧ c'.bind destruct = c.bind destruct
state_after: no goals