Theorem: Stream'.Seq1.join_join
File: Mathlib/Data/Seq/Seq.lean

tactic: apply
  Seq.eq_of_bisim fun s1 s2 =>
    ∃ s SS,
      s1 = Seq.append s (Seq.join (Seq.join SS)) ∧ s2 = Seq.append s (Seq.join (Seq.map join SS))
state_before: α : Type u
β : Type v
γ : Type w
SS : Seq (Seq1 (Seq1 α))
⊢ Seq.join (Seq.join SS) = Seq.join (Seq.map join SS)

tactic: intro s1 s2 h
state_before: case bisim
α : Type u
β : Type v
γ : Type w
SS : Seq (Seq1 (Seq1 α))
⊢ Seq.IsBisimulation fun s1 s2 =>
    ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))

tactic: apply recOn s <;> simp
state_before: α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS : Seq (Seq1 (Seq1 α))
⊢ BisimO (fun s1 s2 => ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS)))
    (destruct (append s (Seq.join (Seq.join SS)))) (destruct (append s (Seq.join (Seq.map join SS))))

tactic: apply recOn SS <;> simp
state_before: case h1
α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS : Seq (Seq1 (Seq1 α))
⊢ match destruct (Seq.join (Seq.join SS)), destruct (Seq.join (Seq.map join SS)) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
  | x, x_1 => False

tactic: intro S SS
state_before: case h1.h2
α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS : Seq (Seq1 (Seq1 α))
⊢ ∀ (x : Seq1 (Seq1 α)) (s : Seq (Seq1 (Seq1 α))),
    match destruct (Seq.join (Seq.join (Seq.cons x s))), destruct (Seq.join (Seq.cons (join x) (Seq.map join s))) with
    | none, none => True
    | some (a, s), some (a', s') =>
      a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
    | x, x_1 => False

tactic: cases' S with s S
state_before: case h1.h2
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS✝ : Seq (Seq1 (Seq1 α))
S : Seq1 (Seq1 α)
SS : Seq (Seq1 (Seq1 α))
⊢ match destruct (Seq.join (Seq.join (Seq.cons S SS))), destruct (Seq.join (Seq.cons (join S) (Seq.map join SS))) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
  | x, x_1 => False

tactic: cases' s with x s
state_before: case h1.h2.mk
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
s : Seq1 α
S : Seq (Seq1 α)
⊢ match destruct (Seq.join (Seq.join (Seq.cons (s, S) SS))),
    destruct (Seq.join (Seq.cons (join (s, S)) (Seq.map join SS))) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
  | x, x_1 => False

tactic: simp [map]
state_before: case h1.h2.mk.mk
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ match destruct (Seq.join (Seq.join (Seq.cons ((x, s), S) SS))),
    destruct (Seq.join (Seq.cons (join ((x, s), S)) (Seq.map join SS))) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
  | x, x_1 => False

tactic: apply recOn s <;> simp
state_before: case h1.h2.mk.mk
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ match some (x, append s (append (Seq.join S) (Seq.join (Seq.join SS)))),
    destruct (Seq.join (Seq.cons (join ((x, s), S)) (Seq.map join SS))) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
  | x, x_1 => False

tactic: exact ⟨_, _, rfl, rfl⟩
state_before: case h1.h2.mk.mk.h1
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ ∃ s SS_1,
    append (Seq.join S) (Seq.join (Seq.join SS)) = append s (Seq.join (Seq.join SS_1)) ∧
      append (Seq.join S) (Seq.join (Seq.map join SS)) = append s (Seq.join (Seq.map join SS_1))

tactic: intro x s
state_before: case h1.h2.mk.mk.h2
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ ∀ (x : α) (s : Seq α),
    ∃ s_1 SS_1,
      Seq.cons x (append s (append (Seq.join S) (Seq.join (Seq.join SS)))) = append s_1 (Seq.join (Seq.join SS_1)) ∧
        Seq.cons x (append s (append (Seq.join S) (Seq.join (Seq.map join SS)))) =
          append s_1 (Seq.join (Seq.map join SS_1))

tactic: refine' ⟨Seq.cons x (append s (Seq.join S)), SS, _, _⟩ <;> simp
state_before: case h1.h2.mk.mk.h2
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝¹ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x✝ : α
s✝ : Seq α
x : α
s : Seq α
⊢ ∃ s_1 SS_1,
    Seq.cons x (append s (append (Seq.join S) (Seq.join (Seq.join SS)))) = append s_1 (Seq.join (Seq.join SS_1)) ∧
      Seq.cons x (append s (append (Seq.join S) (Seq.join (Seq.map join SS)))) =
        append s_1 (Seq.join (Seq.map join SS_1))

tactic: intro _ s
state_before: case h2
α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS : Seq (Seq1 (Seq1 α))
⊢ α →
    ∀ (s : Seq α),
      ∃ s_1 SS_1,
        append s (Seq.join (Seq.join SS)) = append s_1 (Seq.join (Seq.join SS_1)) ∧
          append s (Seq.join (Seq.map join SS)) = append s_1 (Seq.join (Seq.map join SS_1))

tactic: exact ⟨s, SS, rfl, rfl⟩
state_before: case h2
α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS : Seq (Seq1 (Seq1 α))
x✝ : α
s : Seq α
⊢ ∃ s_1 SS_1,
    append s (Seq.join (Seq.join SS)) = append s_1 (Seq.join (Seq.join SS_1)) ∧
      append s (Seq.join (Seq.map join SS)) = append s_1 (Seq.join (Seq.map join SS_1))

tactic: refine' ⟨nil, SS, _, _⟩ <;> simp
state_before: case r
α : Type u
β : Type v
γ : Type w
SS : Seq (Seq1 (Seq1 α))
⊢ ∃ s SS_1,
    Seq.join (Seq.join SS) = append s (Seq.join (Seq.join SS_1)) ∧
      Seq.join (Seq.map join SS) = append s (Seq.join (Seq.map join SS_1))