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

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

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

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

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

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

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

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

tactic: exact ⟨_, _, rfl, rfl⟩
state_before: case h1.h2.mk
α : Type u
β : Type v
γ : Type w
f : α → β
S✝¹ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s✝ : Seq β
S✝ S : Seq (Seq1 α)
a : α
s : Seq α
⊢ ∃ s_1 S_1,
    append (Seq.map f s) (Seq.map f (Seq.join S)) = append s_1 (Seq.map f (Seq.join S_1)) ∧
      append (Seq.map f s)
          (Seq.join
            (Seq.map
              (fun x =>
                match x with
                | (a, s) => (f a, Seq.map f s))
              S)) =
        append s_1
          (Seq.join
            (Seq.map
              (fun x =>
                match x with
                | (a, s) => (f a, Seq.map f s))
              S_1))

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

tactic: refine' ⟨s, S, rfl, rfl⟩
state_before: case h2
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s✝ : Seq β
S : Seq (Seq1 α)
x✝ : β
s : Seq β
⊢ ∃ s_1 S_1,
    append s (Seq.map f (Seq.join S)) = append s_1 (Seq.map f (Seq.join S_1)) ∧
      append s (Seq.join (Seq.map (map f) S)) = append s_1 (Seq.join (Seq.map (map f) S_1))

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