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

tactic: apply
  Computation.eq_of_bisim
    (fun c1 c2 =>
      ∃ s t, c1 = destruct (append s t) ∧ c2 = (destruct s).bind (destruct_append.aux t))
    _ ⟨s, t, rfl, rfl⟩
state_before: α : Type u
β : Type v
γ : Type w
s t : WSeq α
⊢ (s.append t).destruct = s.destruct.bind (destruct_append.aux t)
state_after: α : Type u
β : Type v
γ : Type w
s t : WSeq α
⊢ Computation.IsBisimulation fun c1 c2 =>
    ∃ s t, c1 = (s.append t).destruct ∧ c2 = s.destruct.bind (destruct_append.aux t)

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

tactic: rcases h with ⟨s, t, h⟩
state_before: α : Type u
β : Type v
γ : Type w
s t : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
h : ∃ s t, c1 = (s.append t).destruct ∧ c2 = s.destruct.bind (destruct_append.aux t)
⊢ Computation.BisimO (fun c1 c2 => ∃ s t, c1 = (s.append t).destruct ∧ c2 = s.destruct.bind (destruct_append.aux t))
    c1.destruct c2.destruct
state_after: case intro.intro
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s t : WSeq α
h : c1 = (s.append t).destruct ∧ c2 = s.destruct.bind (destruct_append.aux t)
⊢ Computation.BisimO (fun c1 c2 => ∃ s t, c1 = (s.append t).destruct ∧ c2 = s.destruct.bind (destruct_append.aux t))
    c1.destruct c2.destruct

tactic: rw [h.left, h.right]
state_before: case intro.intro
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s t : WSeq α
h : c1 = (s.append t).destruct ∧ c2 = s.destruct.bind (destruct_append.aux t)
⊢ Computation.BisimO (fun c1 c2 => ∃ s t, c1 = (s.append t).destruct ∧ c2 = s.destruct.bind (destruct_append.aux t))
    c1.destruct c2.destruct
state_after: case intro.intro
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s t : WSeq α
h : c1 = (s.append t).destruct ∧ c2 = s.destruct.bind (destruct_append.aux t)
⊢ Computation.BisimO (fun c1 c2 => ∃ s t, c1 = (s.append t).destruct ∧ c2 = s.destruct.bind (destruct_append.aux t))
    (s.append t).destruct.destruct (s.destruct.bind (destruct_append.aux t)).destruct

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

case intro.intro.h3
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
t s : WSeq α
h : c1 = (s.think.append t).destruct ∧ c2 = s.think.destruct.bind (destruct_append.aux t)
⊢ ∃ s_1 t_1,
    (s.append t).destruct = (s_1.append t_1).destruct ∧
      s.destruct.bind (destruct_append.aux t) = s_1.destruct.bind (destruct_append.aux t_1)

tactic: induction' t using WSeq.recOn with b t t <;> simp
state_before: case intro.intro.h1
α : Type u
β : Type v
γ : Type w
s t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
t : WSeq α
h : c1 = (nil.append t).destruct ∧ c2 = nil.destruct.bind (destruct_append.aux t)
⊢ match t.destruct.destruct, t.destruct.destruct with
  | Sum.inl a, Sum.inl a' => a = a'
  | Sum.inr s, Sum.inr s' => ∃ s_1 t, s = (s_1.append t).destruct ∧ s' = s_1.destruct.bind (destruct_append.aux t)
  | x, x_1 => False
state_after: case intro.intro.h1.h3
α : Type u
β : Type v
γ : Type w
s t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
t : WSeq α
h : c1 = (nil.append t.think).destruct ∧ c2 = nil.destruct.bind (destruct_append.aux t.think)
⊢ ∃ s t_1, t.destruct = (s.append t_1).destruct ∧ t.destruct = s.destruct.bind (destruct_append.aux t_1)

tactic: refine ⟨nil, t, ?_, ?_⟩ <;> simp
state_before: case intro.intro.h1.h3
α : Type u
β : Type v
γ : Type w
s t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
t : WSeq α
h : c1 = (nil.append t.think).destruct ∧ c2 = nil.destruct.bind (destruct_append.aux t.think)
⊢ ∃ s t_1, t.destruct = (s.append t_1).destruct ∧ t.destruct = s.destruct.bind (destruct_append.aux t_1)
state_after: no goals

tactic: exact ⟨s, t, rfl, rfl⟩
state_before: case intro.intro.h3
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
t s : WSeq α
h : c1 = (s.think.append t).destruct ∧ c2 = s.think.destruct.bind (destruct_append.aux t)
⊢ ∃ s_1 t_1,
    (s.append t).destruct = (s_1.append t_1).destruct ∧
      s.destruct.bind (destruct_append.aux t) = s_1.destruct.bind (destruct_append.aux t_1)
state_after: no goals