l3lab/ntp-mathlib huggingface dataset:
theorem map_comp (f : α → β) (g : β → γ) : ∀ s : Seq α, map (g ∘ f) s = map g (map f s)
  | ⟨s, al⟩ => by
    apply Subtype.eq; dsimp [map]
    

Proof state:
case a
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : Stream' (Option α)
al : IsSeq s
⊢ Stream'.map (Option.map (g ∘ f)) s = Stream'.map (Option.map g ∘ Option.map f) s

Next tactic:
apply congr_arg fun f : _ → Option γ => Stream'.map f s
theorem map_comp (f : α → β) (g : β → γ) : ∀ s : Seq α, map (g ∘ f) s = map g (map f s)
  | ⟨s, al⟩ => by
    apply Subtype.eq; dsimp [map]
    apply congr_arg fun f : _ → Option γ => Stream'.map f s
    

Proof state:
case a
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : Stream' (Option α)
al : IsSeq s
⊢ Option.map (g ∘ f) = Option.map g ∘ Option.map f

Next tactic:
ext ⟨⟩
theorem map_comp (f : α → β) (g : β → γ) : ∀ s : Seq α, map (g ∘ f) s = map g (map f s)
  | ⟨s, al⟩ => by
    apply Subtype.eq; dsimp [map]
    apply congr_arg fun f : _ → Option γ => Stream'.map f s
    ext ⟨⟩ <;> 

Proof state:
case a.h.none.a
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : Stream' (Option α)
al : IsSeq s
a✝ : γ
⊢ a✝ ∈ Option.map (g ∘ f) none ↔ a✝ ∈ (Option.map g ∘ Option.map f) none

Next tactic:
rfl
theorem map_comp (f : α → β) (g : β → γ) : ∀ s : Seq α, map (g ∘ f) s = map g (map f s)
  | ⟨s, al⟩ => by
    apply Subtype.eq; dsimp [map]
    apply congr_arg fun f : _ → Option γ => Stream'.map f s
    ext ⟨⟩ <;> 

Proof state:
case a.h.some.a
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : Stream' (Option α)
al : IsSeq s
val✝ : α
a✝ : γ
⊢ a✝ ∈ Option.map (g ∘ f) (some val✝) ↔ a✝ ∈ (Option.map g ∘ Option.map f) (some val✝)

Next tactic:
rfl
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
s t : Seq α
⊢ map f (append s t) = append (map f s) (map f t)

Next tactic:
apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
s t : Seq α
⊢ IsBisimulation fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)

Next tactic:
intro s1 s2 h
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  intro s1 s2 h
  

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
s t : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
⊢ BisimO (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) (destruct s1) (destruct s2)

Next tactic:
exact
    match s1, s2, h with
    | _, _, ⟨s, t, rfl, rfl⟩ => by
      apply recOn s <;> simp
      · apply recOn t <;> simp
        · intro _ t
          refine' ⟨nil, t, _, _⟩ <;> simp
      · intro _ s
        refine' ⟨s, t, rfl, rfl⟩
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  intro s1 s2 h
  exact
    match s1, s2, h with
    | _, _, ⟨s, t, rfl, rfl⟩ => by
      

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ BisimO (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) (destruct (map f (append s t)))
    (destruct (append (map f s) (map f t)))

Next tactic:
apply recOn s
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  intro s1 s2 h
  exact
    match s1, s2, h with
    | _, _, ⟨s, t, rfl, rfl⟩ => by
      apply recOn s <;> 

Proof state:
case h1
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ BisimO (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t))
    (destruct (map f (append nil t))) (destruct (append (map f nil) (map f t)))

Next tactic:
simp
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  intro s1 s2 h
  exact
    match s1, s2, h with
    | _, _, ⟨s, t, rfl, rfl⟩ => by
      apply recOn s <;> 

Proof state:
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ ∀ (x : α) (s : Seq α),
    BisimO (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t))
      (destruct (map f (append (cons x s) t))) (destruct (append (map f (cons x s)) (map f t)))

Next tactic:
simp
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  intro s1 s2 h
  exact
    match s1, s2, h with
    | _, _, ⟨s, t, rfl, rfl⟩ => by
      apply recOn s <;> simp
      · 

Proof state:
case h1
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ match destruct (map f t), destruct (map f t) with
  | none, none => True
  | some (a, s), some (a', s') => a = a' ∧ ∃ s_1 t, s = map f (append s_1 t) ∧ s' = append (map f s_1) (map f t)
  | x, x_1 => False

Next tactic:
apply recOn t
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  intro s1 s2 h
  exact
    match s1, s2, h with
    | _, _, ⟨s, t, rfl, rfl⟩ => by
      apply recOn s <;> simp
      · apply recOn t <;> 

Proof state:
case h1.h1
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ match destruct (map f nil), destruct (map f nil) with
  | none, none => True
  | some (a, s), some (a', s') => a = a' ∧ ∃ s_1 t, s = map f (append s_1 t) ∧ s' = append (map f s_1) (map f t)
  | x, x_1 => False

Next tactic:
simp
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  intro s1 s2 h
  exact
    match s1, s2, h with
    | _, _, ⟨s, t, rfl, rfl⟩ => by
      apply recOn s <;> simp
      · apply recOn t <;> 

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

Next tactic:
simp
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  intro s1 s2 h
  exact
    match s1, s2, h with
    | _, _, ⟨s, t, rfl, rfl⟩ => by
      apply recOn s <;> simp
      · apply recOn t <;> simp
        · 

Proof state:
case h1.h2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ α → ∀ (s : Seq α), ∃ s_1 t, map f s = map f (append s_1 t) ∧ map f s = append (map f s_1) (map f t)

Next tactic:
intro _ t
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  intro s1 s2 h
  exact
    match s1, s2, h with
    | _, _, ⟨s, t, rfl, rfl⟩ => by
      apply recOn s <;> simp
      · apply recOn t <;> simp
        · intro _ t
          

Proof state:
case h1.h2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝¹ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t✝ : Seq α
x✝ : α
t : Seq α
⊢ ∃ s t_1, map f t = map f (append s t_1) ∧ map f t = append (map f s) (map f t_1)

Next tactic:
refine' ⟨nil, t, _, _⟩
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  intro s1 s2 h
  exact
    match s1, s2, h with
    | _, _, ⟨s, t, rfl, rfl⟩ => by
      apply recOn s <;> simp
      · apply recOn t <;> simp
        · intro _ t
          refine' ⟨nil, t, _, _⟩ <;> 

Proof state:
case h1.h2.refine'_1
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝¹ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t✝ : Seq α
x✝ : α
t : Seq α
⊢ map f t = map f (append nil t)

Next tactic:
simp
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  intro s1 s2 h
  exact
    match s1, s2, h with
    | _, _, ⟨s, t, rfl, rfl⟩ => by
      apply recOn s <;> simp
      · apply recOn t <;> simp
        · intro _ t
          refine' ⟨nil, t, _, _⟩ <;> 

Proof state:
case h1.h2.refine'_2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝¹ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t✝ : Seq α
x✝ : α
t : Seq α
⊢ map f t = append (map f nil) (map f t)

Next tactic:
simp
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  intro s1 s2 h
  exact
    match s1, s2, h with
    | _, _, ⟨s, t, rfl, rfl⟩ => by
      apply recOn s <;> simp
      · apply recOn t <;> simp
        · intro _ t
          refine' ⟨nil, t, _, _⟩ <;> simp
      · 

Proof state:
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ α →
    ∀ (s : Seq α),
      ∃ s_1 t_1,
        map f (append s t) = map f (append s_1 t_1) ∧ append (map f s) (map f t) = append (map f s_1) (map f t_1)

Next tactic:
intro _ s
@[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by
  apply
    eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _
      ⟨s, t, rfl, rfl⟩
  intro s1 s2 h
  exact
    match s1, s2, h with
    | _, _, ⟨s, t, rfl, rfl⟩ => by
      apply recOn s <;> simp
      · apply recOn t <;> simp
        · intro _ t
          refine' ⟨nil, t, _, _⟩ <;> simp
      · intro _ s
        

Proof state:
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝¹ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s✝ t : Seq α
x✝ : α
s : Seq α
⊢ ∃ s_1 t_1, map f (append s t) = map f (append s_1 t_1) ∧ append (map f s) (map f t) = append (map f s_1) (map f t_1)

Next tactic:
refine' ⟨s, t, rfl, rfl⟩
theorem join_cons_nil (a : α) (S) : join (cons (a, nil) S) = cons a (join S) :=
  destruct_eq_cons <| by 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
S : Seq (Seq1 α)
⊢ destruct (join (cons (a, nil) S)) = some (a, join S)

Next tactic:
simp [join]
theorem join_cons_cons (a b : α) (s S) :
    join (cons (a, cons b s) S) = cons a (join (cons (b, s) S)) :=
  destruct_eq_cons <| by 

Proof state:
α : Type u
β : Type v
γ : Type w
a b : α
s : Seq α
S : Seq (Seq1 α)
⊢ destruct (join (cons (a, cons b s) S)) = some (a, join (cons (b, s) S))

Next tactic:
simp [join]
@[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) := by
  

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

Next tactic:
apply
    eq_of_bisim
      (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      _ (Or.inr ⟨a, s, S, rfl, rfl⟩)
@[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) := by
  apply
    eq_of_bisim
      (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      _ (Or.inr ⟨a, s, S, rfl, rfl⟩)
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ IsBisimulation fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))

Next tactic:
intro s1 s2 h
@[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) := by
  apply
    eq_of_bisim
      (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      _ (Or.inr ⟨a, s, S, rfl, rfl⟩)
  intro s1 s2 h
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
S : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))) (destruct s1)
    (destruct s2)

Next tactic:
exact
    match s1, s2, h with
    | s, _, Or.inl <| Eq.refl s => by
      apply recOn s; · trivial
      · intro x s
        rw [destruct_cons]
        exact ⟨rfl, Or.inl rfl⟩
    | _, _, Or.inr ⟨a, s, S, rfl, rfl⟩ => by
      apply recOn s
      · simp [join_cons_cons, join_cons_nil]
      · intro x s
        simp [join_cons_cons, join_cons_nil]
        refine' Or.inr ⟨x, s, S, rfl, rfl⟩
@[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) := by
  apply
    eq_of_bisim
      (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      _ (Or.inr ⟨a, s, S, rfl, rfl⟩)
  intro s1 s2 h
  exact
    match s1, s2, h with
    | s, _, Or.inl <| Eq.refl s => by
      

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
s✝ : Seq α
S : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
s : Seq α
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))) (destruct s)
    (destruct s)

Next tactic:
apply recOn s
@[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) := by
  apply
    eq_of_bisim
      (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      _ (Or.inr ⟨a, s, S, rfl, rfl⟩)
  intro s1 s2 h
  exact
    match s1, s2, h with
    | s, _, Or.inl <| Eq.refl s => by
      apply recOn s; · 

Proof state:
case h1
α : Type u
β : Type v
γ : Type w
a : α
s✝ : Seq α
S : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
s : Seq α
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))) (destruct nil)
    (destruct nil)

Next tactic:
trivial
@[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) := by
  apply
    eq_of_bisim
      (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      _ (Or.inr ⟨a, s, S, rfl, rfl⟩)
  intro s1 s2 h
  exact
    match s1, s2, h with
    | s, _, Or.inl <| Eq.refl s => by
      apply recOn s; · trivial
      · 

Proof state:
case h2
α : Type u
β : Type v
γ : Type w
a : α
s✝ : Seq α
S : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
s : Seq α
⊢ ∀ (x : α) (s : Seq α),
    BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      (destruct (cons x s)) (destruct (cons x s))

Next tactic:
intro x s
@[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) := by
  apply
    eq_of_bisim
      (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      _ (Or.inr ⟨a, s, S, rfl, rfl⟩)
  intro s1 s2 h
  exact
    match s1, s2, h with
    | s, _, Or.inl <| Eq.refl s => by
      apply recOn s; · trivial
      · intro x s
        

Proof state:
case h2
α : Type u
β : Type v
γ : Type w
a : α
s✝¹ : Seq α
S : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
s✝ : Seq α
x : α
s : Seq α
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
    (destruct (cons x s)) (destruct (cons x s))

Next tactic:
rw [destruct_cons]
@[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) := by
  apply
    eq_of_bisim
      (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      _ (Or.inr ⟨a, s, S, rfl, rfl⟩)
  intro s1 s2 h
  exact
    match s1, s2, h with
    | s, _, Or.inl <| Eq.refl s => by
      apply recOn s; · trivial
      · intro x s
        rw [destruct_cons]
        

Proof state:
case h2
α : Type u
β : Type v
γ : Type w
a : α
s✝¹ : Seq α
S : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
s✝ : Seq α
x : α
s : Seq α
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))) (some (x, s))
    (some (x, s))

Next tactic:
exact ⟨rfl, Or.inl rfl⟩
@[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) := by
  apply
    eq_of_bisim
      (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      _ (Or.inr ⟨a, s, S, rfl, rfl⟩)
  intro s1 s2 h
  exact
    match s1, s2, h with
    | s, _, Or.inl <| Eq.refl s => by
      apply recOn s; · trivial
      · intro x s
        rw [destruct_cons]
        exact ⟨rfl, Or.inl rfl⟩
    | _, _, Or.inr ⟨a, s, S, rfl, rfl⟩ => by
      

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
s✝ : Seq α
S✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
    (destruct (join (cons (a, s) S))) (destruct (cons a (append s (join S))))

Next tactic:
apply recOn s
@[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) := by
  apply
    eq_of_bisim
      (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      _ (Or.inr ⟨a, s, S, rfl, rfl⟩)
  intro s1 s2 h
  exact
    match s1, s2, h with
    | s, _, Or.inl <| Eq.refl s => by
      apply recOn s; · trivial
      · intro x s
        rw [destruct_cons]
        exact ⟨rfl, Or.inl rfl⟩
    | _, _, Or.inr ⟨a, s, S, rfl, rfl⟩ => by
      apply recOn s
      · 

Proof state:
case h1
α : Type u
β : Type v
γ : Type w
a✝ : α
s✝ : Seq α
S✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
    (destruct (join (cons (a, nil) S))) (destruct (cons a (append nil (join S))))

Next tactic:
simp [join_cons_cons, join_cons_nil]
@[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) := by
  apply
    eq_of_bisim
      (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      _ (Or.inr ⟨a, s, S, rfl, rfl⟩)
  intro s1 s2 h
  exact
    match s1, s2, h with
    | s, _, Or.inl <| Eq.refl s => by
      apply recOn s; · trivial
      · intro x s
        rw [destruct_cons]
        exact ⟨rfl, Or.inl rfl⟩
    | _, _, Or.inr ⟨a, s, S, rfl, rfl⟩ => by
      apply recOn s
      · simp [join_cons_cons, join_cons_nil]
      · 

Proof state:
case h2
α : Type u
β : Type v
γ : Type w
a✝ : α
s✝ : Seq α
S✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ ∀ (x : α) (s : Seq α),
    BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      (destruct (join (cons (a, cons x s) S))) (destruct (cons a (append (cons x s) (join S))))

Next tactic:
intro x s
@[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) := by
  apply
    eq_of_bisim
      (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      _ (Or.inr ⟨a, s, S, rfl, rfl⟩)
  intro s1 s2 h
  exact
    match s1, s2, h with
    | s, _, Or.inl <| Eq.refl s => by
      apply recOn s; · trivial
      · intro x s
        rw [destruct_cons]
        exact ⟨rfl, Or.inl rfl⟩
    | _, _, Or.inr ⟨a, s, S, rfl, rfl⟩ => by
      apply recOn s
      · simp [join_cons_cons, join_cons_nil]
      · intro x s
        

Proof state:
case h2
α : Type u
β : Type v
γ : Type w
a✝ : α
s✝¹ : Seq α
S✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
a : α
s✝ : Seq α
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
    (destruct (join (cons (a, cons x s) S))) (destruct (cons a (append (cons x s) (join S))))

Next tactic:
simp [join_cons_cons, join_cons_nil]
@[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) := by
  apply
    eq_of_bisim
      (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      _ (Or.inr ⟨a, s, S, rfl, rfl⟩)
  intro s1 s2 h
  exact
    match s1, s2, h with
    | s, _, Or.inl <| Eq.refl s => by
      apply recOn s; · trivial
      · intro x s
        rw [destruct_cons]
        exact ⟨rfl, Or.inl rfl⟩
    | _, _, Or.inr ⟨a, s, S, rfl, rfl⟩ => by
      apply recOn s
      · simp [join_cons_cons, join_cons_nil]
      · intro x s
        simp [join_cons_cons, join_cons_nil]
        

Proof state:
case h2
α : Type u
β : Type v
γ : Type w
a✝ : α
s✝¹ : Seq α
S✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
a : α
s✝ : Seq α
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ join (cons (x, s) S) = cons x (append s (join S)) ∨
    ∃ a s_1 S_1,
      join (cons (x, s) S) = join (cons (a, s_1) S_1) ∧ cons x (append s (join S)) = cons a (append s_1 (join S_1))

Next tactic:
refine' Or.inr ⟨x, s, S, rfl, rfl⟩
@[simp]
theorem join_append (S T : Seq (Seq1 α)) : join (append S T) = append (join S) (join T) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
S T : Seq (Seq1 α)
⊢ join (append S T) = append (join S) (join T)

Next 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))
@[simp]
theorem join_append (S T : Seq (Seq1 α)) : join (append S T) = append (join S) (join T) := by
  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))
  · 

Proof state:
case bisim
α : Type u
β : Type v
γ : Type w
S T : Seq (Seq1 α)
⊢ IsBisimulation fun s1 s2 => ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))

Next tactic:
intro s1 s2 h