Theorem: Stream'.Seq.join_append
File: Mathlib/Data/Seq/Seq.lean

tactic: apply
  eq_of_bisim fun s1 s2 =>
    ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
state_before: α : Type u
β : Type v
γ : Type w
S T : Seq (Seq1 α)
⊢ (S.append T).join = S.join.append T.join
state_after: case bisim
α : Type u
β : Type v
γ : Type w
S T : Seq (Seq1 α)
⊢ IsBisimulation fun s1 s2 => ∃ s S T, s1 = s.append (S.append T).join ∧ s2 = s.append (S.join.append T.join)

case r
α : Type u
β : Type v
γ : Type w
S T : Seq (Seq1 α)
⊢ ∃ s S_1 T_1,
    (S.append T).join = s.append (S_1.append T_1).join ∧ S.join.append T.join = s.append (S_1.join.append T_1.join)

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

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

case h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = s.append (S.append T).join ∧ s2 = s.append (S.join.append T.join)
s : Seq α
S T : Seq (Seq1 α)
⊢ α →
    ∀ (s : Seq α),
      ∃ s_1 S_1 T_1,
        s.append (S.append T).join = s_1.append (S_1.append T_1).join ∧
          s.append (S.join.append T.join) = s_1.append (S_1.join.append T_1.join)

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

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

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

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

tactic: simp
state_before: case h1.h1.h1
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = s.append (S.append T).join ∧ s2 = s.append (S.join.append T.join)
s : Seq α
S T : Seq (Seq1 α)
⊢ match nil.join.destruct, nil.join.destruct with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S T, s = s_1.append (S.append T).join ∧ s' = s_1.append (S.join.append T.join)
  | x, x_1 => False
state_after: no goals

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

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

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

tactic: refine ⟨s, nil, T, ?_, ?_⟩ <;> simp
state_before: case h1.h1.h2.mk
α : Type u
β : Type v
γ : Type w
S✝ T✝¹ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = s.append (S.append T).join ∧ s2 = s.append (S.join.append T.join)
s✝ : Seq α
S T✝ T : Seq (Seq1 α)
a : α
s : Seq α
⊢ ∃ s_1 S T_1, s.append T.join = s_1.append (S.append T_1).join ∧ s.append T.join = s_1.append (S.join.append T_1.join)
state_after: no goals

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

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

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

tactic: intro _ s
state_before: case h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = s.append (S.append T).join ∧ s2 = s.append (S.join.append T.join)
s : Seq α
S T : Seq (Seq1 α)
⊢ α →
    ∀ (s : Seq α),
      ∃ s_1 S_1 T_1,
        s.append (S.append T).join = s_1.append (S_1.append T_1).join ∧
          s.append (S.join.append T.join) = s_1.append (S_1.join.append T_1.join)
state_after: case h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = s.append (S.append T).join ∧ s2 = s.append (S.join.append T.join)
s✝ : Seq α
S T : Seq (Seq1 α)
x✝ : α
s : Seq α
⊢ ∃ s_1 S_1 T_1,
    s.append (S.append T).join = s_1.append (S_1.append T_1).join ∧
      s.append (S.join.append T.join) = s_1.append (S_1.join.append T_1.join)

tactic: exact ⟨s, S, T, rfl, rfl⟩
state_before: case h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = s.append (S.append T).join ∧ s2 = s.append (S.join.append T.join)
s✝ : Seq α
S T : Seq (Seq1 α)
x✝ : α
s : Seq α
⊢ ∃ s_1 S_1 T_1,
    s.append (S.append T).join = s_1.append (S_1.append T_1).join ∧
      s.append (S.join.append T.join) = s_1.append (S_1.join.append T_1.join)
state_after: no goals

tactic: refine ⟨nil, S, T, ?_, ?_⟩ <;> simp
state_before: case r
α : Type u
β : Type v
γ : Type w
S T : Seq (Seq1 α)
⊢ ∃ s S_1 T_1,
    (S.append T).join = s.append (S_1.append T_1).join ∧ S.join.append T.join = s.append (S_1.join.append T_1.join)
state_after: no goals