l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem join_map_ret (s : Seq α) : Seq.join (Seq.map ret s) = s := by
  apply coinduction2 s; intro s; apply recOn s <;> 

Proof state:
case H.h1
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ BisimO (fun s1 s2 => ∃ s, s1 = Seq.join (Seq.map ret s) ∧ s2 = s) (destruct (Seq.join (Seq.map ret nil)))
    (destruct nil)

Next tactic:
simp [ret]
@[simp]
theorem join_map_ret (s : Seq α) : Seq.join (Seq.map ret s) = s := by
  apply coinduction2 s; intro s; apply recOn s <;> 

Proof state:
case H.h2
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ ∀ (x : α) (s : Seq α),
    BisimO (fun s1 s2 => ∃ s, s1 = Seq.join (Seq.map ret s) ∧ s2 = s) (destruct (Seq.join (Seq.map ret (Seq.cons x s))))
      (destruct (Seq.cons x s))

Next tactic:
simp [ret]
@[simp]
theorem bind_ret (f : α → β) : ∀ s, bind s (ret ∘ f) = map f s
  | ⟨a, s⟩ => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
⊢ bind (a, s) (ret ∘ f) = map f (a, s)

Next tactic:
dsimp [bind, map]
@[simp]
theorem bind_ret (f : α → β) : ∀ s, bind s (ret ∘ f) = map f s
  | ⟨a, s⟩ => by
    dsimp [bind, map]
    -- Porting note: Was `rw [map_comp]; simp [Function.comp, ret]`
    

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
⊢ join (ret (f a), Seq.map (ret ∘ f) s) = (f a, Seq.map f s)

Next tactic:
rw [map_comp, ret]
@[simp]
theorem bind_ret (f : α → β) : ∀ s, bind s (ret ∘ f) = map f s
  | ⟨a, s⟩ => by
    dsimp [bind, map]
    -- Porting note: Was `rw [map_comp]; simp [Function.comp, ret]`
    rw [map_comp, ret]
    

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
⊢ join ((f a, nil), Seq.map ret (Seq.map f s)) = (f a, Seq.map f s)

Next tactic:
simp
@[simp]
theorem ret_bind (a : α) (f : α → Seq1 β) : bind (ret a) f = f a := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
f : α → Seq1 β
⊢ bind (ret a) f = f a

Next tactic:
simp only [bind, map, ret._eq_1, map_nil]
@[simp]
theorem ret_bind (a : α) (f : α → Seq1 β) : bind (ret a) f = f a := by
  simp only [bind, map, ret._eq_1, map_nil]
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
f : α → Seq1 β
⊢ join (f a, nil) = f a

Next tactic:
cases' f a with a s
@[simp]
theorem ret_bind (a : α) (f : α → Seq1 β) : bind (ret a) f = f a := by
  simp only [bind, map, ret._eq_1, map_nil]
  cases' f a with a s
  

Proof state:
case mk
α : Type u
β : Type v
γ : Type w
a✝ : α
f : α → Seq1 β
a : β
s : Seq β
⊢ join ((a, s), nil) = (a, s)

Next tactic:
apply recOn s
@[simp]
theorem ret_bind (a : α) (f : α → Seq1 β) : bind (ret a) f = f a := by
  simp only [bind, map, ret._eq_1, map_nil]
  cases' f a with a s
  apply recOn s <;> 

Proof state:
case mk.h1
α : Type u
β : Type v
γ : Type w
a✝ : α
f : α → Seq1 β
a : β
s : Seq β
⊢ join ((a, nil), nil) = (a, nil)

Next tactic:
intros
@[simp]
theorem ret_bind (a : α) (f : α → Seq1 β) : bind (ret a) f = f a := by
  simp only [bind, map, ret._eq_1, map_nil]
  cases' f a with a s
  apply recOn s <;> 

Proof state:
case mk.h2
α : Type u
β : Type v
γ : Type w
a✝ : α
f : α → Seq1 β
a : β
s : Seq β
⊢ ∀ (x : β) (s : Seq β), join ((a, Seq.cons x s), nil) = (a, Seq.cons x s)

Next tactic:
intros
@[simp]
theorem ret_bind (a : α) (f : α → Seq1 β) : bind (ret a) f = f a := by
  simp only [bind, map, ret._eq_1, map_nil]
  cases' f a with a s
  apply recOn s <;> intros <;> 

Proof state:
case mk.h1
α : Type u
β : Type v
γ : Type w
a✝ : α
f : α → Seq1 β
a : β
s : Seq β
⊢ join ((a, nil), nil) = (a, nil)

Next tactic:
simp
@[simp]
theorem ret_bind (a : α) (f : α → Seq1 β) : bind (ret a) f = f a := by
  simp only [bind, map, ret._eq_1, map_nil]
  cases' f a with a s
  apply recOn s <;> intros <;> 

Proof state:
case mk.h2
α : Type u
β : Type v
γ : Type w
a✝ : α
f : α → Seq1 β
a : β
s : Seq β
x✝ : β
s✝ : Seq β
⊢ join ((a, Seq.cons x✝ s✝), nil) = (a, Seq.cons x✝ s✝)

Next tactic:
simp
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
S : Seq (Seq1 α)
⊢ Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S)

Next 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))
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · 

Proof state:
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))

Next tactic:
intro s1 s2 h
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    

Proof state:
case bisim
α : 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))
⊢ 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 s1) (destruct s2)

Next tactic:
exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · apply recOn S <;> simp
          · intro x S
            cases' x with a s; simp [map]
            exact ⟨_, _, rfl, rfl⟩
        · intro _ s
          refine' ⟨s, S, rfl, rfl⟩
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        

Proof state:
α : 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))))

Next tactic:
apply recOn s
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> 

Proof state:
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 α)
⊢ 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 nil (Seq.map f (Seq.join S)))) (destruct (append nil (Seq.join (Seq.map (map f) S))))

Next tactic:
simp
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> 

Proof state:
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 β),
    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 (Seq.cons x s) (Seq.map f (Seq.join S))))
      (destruct (append (Seq.cons x s) (Seq.join (Seq.map (map f) S))))

Next tactic:
simp
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · 

Proof state:
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

Next tactic:
apply recOn S
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · apply recOn S <;> 

Proof state:
case h1.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 nil)), destruct (Seq.join (Seq.map (map f) nil)) 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

Next tactic:
simp
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · apply recOn S <;> 

Proof state:
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.map (map f) (Seq.cons x 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

Next tactic:
simp
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · apply recOn S <;> simp
          · 

Proof state:
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

Next tactic:
intro x S
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · apply recOn S <;> simp
          · intro x S
            

Proof state:
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

Next tactic:
cases' x with a s
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · apply recOn S <;> simp
          · intro x S
            cases' x with a s; 

Proof state:
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

Next tactic:
simp [map]
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · apply recOn S <;> simp
          · intro x S
            cases' x with a s; simp [map]
            

Proof state:
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 (map f) S)) = append s_1 (Seq.join (Seq.map (map f) S_1))

Next tactic:
exact ⟨_, _, rfl, rfl⟩
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · apply recOn S <;> simp
          · intro x S
            cases' x with a s; simp [map]
            exact ⟨_, _, rfl, rfl⟩
        · 

Proof state:
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))

Next tactic:
intro _ s
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · apply recOn S <;> simp
          · intro x S
            cases' x with a s; simp [map]
            exact ⟨_, _, rfl, rfl⟩
        · intro _ s
          

Proof state:
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))

Next tactic:
refine' ⟨s, S, rfl, rfl⟩
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · apply recOn S <;> simp
          · intro x S
            cases' x with a s; simp [map]
            exact ⟨_, _, rfl, rfl⟩
        · intro _ s
          refine' ⟨s, S, rfl, rfl⟩
  · 

Proof state:
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))

Next tactic:
refine' ⟨nil, S, _, _⟩
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · apply recOn S <;> simp
          · intro x S
            cases' x with a s; simp [map]
            exact ⟨_, _, rfl, rfl⟩
        · intro _ s
          refine' ⟨s, S, rfl, rfl⟩
  · refine' ⟨nil, S, _, _⟩ <;> 

Proof state:
case r.refine'_1
α : Type u
β : Type v
γ : Type w
f : α → β
S : Seq (Seq1 α)
⊢ Seq.map f (Seq.join S) = append nil (Seq.map f (Seq.join S))

Next tactic:
simp
@[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, S, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · apply recOn S <;> simp
          · intro x S
            cases' x with a s; simp [map]
            exact ⟨_, _, rfl, rfl⟩
        · intro _ s
          refine' ⟨s, S, rfl, rfl⟩
  · refine' ⟨nil, S, _, _⟩ <;> 

Proof state:
case r.refine'_2
α : Type u
β : Type v
γ : Type w
f : α → β
S : Seq (Seq1 α)
⊢ Seq.join (Seq.map (map f) S) = append nil (Seq.join (Seq.map (map f) S))

Next tactic:
simp
@[simp]
theorem map_join (f : α → β) : ∀ S, map f (join S) = join (map (map f) S)
  | ((a, s), S) => by 

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ map f (join ((a, s), S)) = join (map (map f) ((a, s), S))

Next tactic:
apply recOn s
@[simp]
theorem map_join (f : α → β) : ∀ S, map f (join S) = join (map (map f) S)
  | ((a, s), S) => by apply recOn s <;> 

Proof state:
case h1
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ map f (join ((a, nil), S)) = join (map (map f) ((a, nil), S))

Next tactic:
intros
@[simp]
theorem map_join (f : α → β) : ∀ S, map f (join S) = join (map (map f) S)
  | ((a, s), S) => by apply recOn s <;> 

Proof state:
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ ∀ (x : α) (s : Seq α), map f (join ((a, Seq.cons x s), S)) = join (map (map f) ((a, Seq.cons x s), S))

Next tactic:
intros
@[simp]
theorem map_join (f : α → β) : ∀ S, map f (join S) = join (map (map f) S)
  | ((a, s), S) => by apply recOn s <;> intros <;> 

Proof state:
case h1
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ map f (join ((a, nil), S)) = join (map (map f) ((a, nil), S))

Next tactic:
simp [map]
@[simp]
theorem map_join (f : α → β) : ∀ S, map f (join S) = join (map (map f) S)
  | ((a, s), S) => by apply recOn s <;> intros <;> 

Proof state:
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
S : Seq (Seq1 α)
x✝ : α
s✝ : Seq α
⊢ map f (join ((a, Seq.cons x✝ s✝), S)) = join (map (map f) ((a, Seq.cons x✝ s✝), S))

Next tactic:
simp [map]
@[simp]
theorem join_join (SS : Seq (Seq1 (Seq1 α))) :
    Seq.join (Seq.join SS) = Seq.join (Seq.map join SS) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
SS : Seq (Seq1 (Seq1 α))
⊢ Seq.join (Seq.join SS) = Seq.join (Seq.map join SS)

Next 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))
@[simp]
theorem join_join (SS : Seq (Seq1 (Seq1 α))) :
    Seq.join (Seq.join SS) = Seq.join (Seq.map join SS) := by
  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))
  · 

Proof state:
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))

Next tactic:
intro s1 s2 h
@[simp]
theorem join_join (SS : Seq (Seq1 (Seq1 α))) :
    Seq.join (Seq.join SS) = Seq.join (Seq.map join SS) := by
  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))
  · intro s1 s2 h
    

Proof state:
case bisim
α : 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))
⊢ BisimO (fun s1 s2 => ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS)))
    (destruct s1) (destruct s2)

Next tactic:
exact
      match s1, s2, h with
      | _, _, ⟨s, SS, rfl, rfl⟩ => by
        apply recOn s <;> simp
        · apply recOn SS <;> simp
          · intro S SS
            cases' S with s S; cases' s with x s; simp [map]
            apply recOn s <;> simp
            · exact ⟨_, _, rfl, rfl⟩
            · intro x s
              refine' ⟨Seq.cons x (append s (Seq.join S)), SS, _, _⟩ <;> simp
        · intro _ s
          exact ⟨s, SS, rfl, rfl⟩
@[simp]
theorem join_join (SS : Seq (Seq1 (Seq1 α))) :
    Seq.join (Seq.join SS) = Seq.join (Seq.map join SS) := by
  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))
  · intro s1 s2 h
    exact
      match s1, s2, h with
      | _, _, ⟨s, SS, rfl, rfl⟩ => by
        

Proof state:
α : 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))))

Next tactic:
apply recOn s