l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> 

Proof state:
case intro.intro.intro.intro.h1.h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
s : WSeq α
S : WSeq (WSeq α)
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join (append (cons s S) T))))
    (Computation.destruct (destruct (append (join (cons s S)) (join T))))

Next tactic:
simp
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> 

Proof state:
case intro.intro.intro.intro.h1.h3
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T S : WSeq (WSeq α)
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join (append (think S) T))))
    (Computation.destruct (destruct (append (join (think S)) (join T))))

Next tactic:
simp
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · 

Proof state:
case intro.intro.intro.intro.h1.h1
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join T))) (Computation.destruct (destruct (join T)))

Next tactic:
induction' T using WSeq.recOn with s T T
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> 

Proof state:
case intro.intro.intro.intro.h1.h1.h1
α : Type u
β : Type v
γ : Type w
S T : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join nil))) (Computation.destruct (destruct (join nil)))

Next tactic:
simp
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> 

Proof state:
case intro.intro.intro.intro.h1.h1.h2
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : WSeq α
T : WSeq (WSeq α)
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join (cons s T)))) (Computation.destruct (destruct (join (cons s T))))

Next tactic:
simp
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> 

Proof state:
case intro.intro.intro.intro.h1.h1.h3
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join (think T)))) (Computation.destruct (destruct (join (think T))))

Next tactic:
simp
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> simp
      · 

Proof state:
case intro.intro.intro.intro.h1.h1.h2
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : WSeq α
T : WSeq (WSeq α)
⊢ ∃ s_1 S T_1,
    destruct (append s (join T)) = destruct (append s_1 (join (append S T_1))) ∧
      destruct (append s (join T)) = destruct (append s_1 (append (join S) (join T_1)))

Next tactic:
refine' ⟨s, nil, T, _, _⟩
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> simp
      · refine' ⟨s, nil, T, _, _⟩ <;> 

Proof state:
case intro.intro.intro.intro.h1.h1.h2.refine'_1
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : WSeq α
T : WSeq (WSeq α)
⊢ destruct (append s (join T)) = destruct (append s (join (append nil T)))

Next tactic:
simp
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> simp
      · refine' ⟨s, nil, T, _, _⟩ <;> 

Proof state:
case intro.intro.intro.intro.h1.h1.h2.refine'_2
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : WSeq α
T : WSeq (WSeq α)
⊢ destruct (append s (join T)) = destruct (append s (append (join nil) (join T)))

Next tactic:
simp
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> simp
      · refine' ⟨s, nil, T, _, _⟩ <;> simp
      · 

Proof state:
case intro.intro.intro.intro.h1.h1.h3
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
⊢ ∃ s S T_1,
    destruct (join T) = destruct (append s (join (append S T_1))) ∧
      destruct (join T) = destruct (append s (append (join S) (join T_1)))

Next tactic:
refine' ⟨nil, nil, T, _, _⟩
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> simp
      · refine' ⟨s, nil, T, _, _⟩ <;> simp
      · refine' ⟨nil, nil, T, _, _⟩ <;> 

Proof state:
case intro.intro.intro.intro.h1.h1.h3.refine'_1
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
⊢ destruct (join T) = destruct (append nil (join (append nil T)))

Next tactic:
simp
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> simp
      · refine' ⟨s, nil, T, _, _⟩ <;> simp
      · refine' ⟨nil, nil, T, _, _⟩ <;> 

Proof state:
case intro.intro.intro.intro.h1.h1.h3.refine'_2
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
⊢ destruct (join T) = destruct (append nil (append (join nil) (join T)))

Next tactic:
simp
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> simp
      · refine' ⟨s, nil, T, _, _⟩ <;> simp
      · refine' ⟨nil, nil, T, _, _⟩ <;> simp
    · 

Proof state:
case intro.intro.intro.intro.h1.h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
s : WSeq α
S : WSeq (WSeq α)
⊢ ∃ s_1 S_1 T_1,
    destruct (append s (join (append S T))) = destruct (append s_1 (join (append S_1 T_1))) ∧
      destruct (append s (append (join S) (join T))) = destruct (append s_1 (append (join S_1) (join T_1)))

Next tactic:
exact ⟨s, S, T, rfl, rfl⟩
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> simp
      · refine' ⟨s, nil, T, _, _⟩ <;> simp
      · refine' ⟨nil, nil, T, _, _⟩ <;> simp
    · exact ⟨s, S, T, rfl, rfl⟩
    · 

Proof state:
case intro.intro.intro.intro.h1.h3
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T S : WSeq (WSeq α)
⊢ ∃ s S_1 T_1,
    destruct (join (append S T)) = destruct (append s (join (append S_1 T_1))) ∧
      destruct (append (join S) (join T)) = destruct (append s (append (join S_1) (join T_1)))

Next tactic:
refine' ⟨nil, S, T, _, _⟩
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> simp
      · refine' ⟨s, nil, T, _, _⟩ <;> simp
      · refine' ⟨nil, nil, T, _, _⟩ <;> simp
    · exact ⟨s, S, T, rfl, rfl⟩
    · refine' ⟨nil, S, T, _, _⟩ <;> 

Proof state:
case intro.intro.intro.intro.h1.h3.refine'_1
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T S : WSeq (WSeq α)
⊢ destruct (join (append S T)) = destruct (append nil (join (append S T)))

Next tactic:
simp
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> simp
      · refine' ⟨s, nil, T, _, _⟩ <;> simp
      · refine' ⟨nil, nil, T, _, _⟩ <;> simp
    · exact ⟨s, S, T, rfl, rfl⟩
    · refine' ⟨nil, S, T, _, _⟩ <;> 

Proof state:
case intro.intro.intro.intro.h1.h3.refine'_2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T S : WSeq (WSeq α)
⊢ destruct (append (join S) (join T)) = destruct (append nil (append (join S) (join T)))

Next tactic:
simp
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> simp
      · refine' ⟨s, nil, T, _, _⟩ <;> simp
      · refine' ⟨nil, nil, T, _, _⟩ <;> simp
    · exact ⟨s, S, T, rfl, rfl⟩
    · refine' ⟨nil, S, T, _, _⟩ <;> simp
  · 

Proof state:
case intro.intro.intro.intro.h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
S T : WSeq (WSeq α)
a : α
s : WSeq α
⊢ ∃ s_1 S_1 T_1,
    append s (join (append S T)) = append s_1 (join (append S_1 T_1)) ∧
      append s (append (join S) (join T)) = append s_1 (append (join S_1) (join T_1))

Next tactic:
exact ⟨s, S, T, rfl, rfl⟩
@[simp]
theorem join_append (S T : WSeq (WSeq α)) : join (append S T) ~ʷ append (join S) (join T) := by
  refine'
    ⟨fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
      ⟨nil, S, T, by simp, by simp⟩, _⟩
  intro s1 s2 h
  apply
    liftRel_rec
      (fun c1 c2 =>
        ∃ (s : WSeq α) (S T : _),
          c1 = destruct (append s (join (append S T))) ∧
            c2 = destruct (append s (append (join S) (join T))))
      _ _ _
      (let ⟨s, S, T, h1, h2⟩ := h
      ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
  rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
  induction' s using WSeq.recOn with a s s <;> simp
  · induction' S using WSeq.recOn with s S S <;> simp
    · induction' T using WSeq.recOn with s T T <;> simp
      · refine' ⟨s, nil, T, _, _⟩ <;> simp
      · refine' ⟨nil, nil, T, _, _⟩ <;> simp
    · exact ⟨s, S, T, rfl, rfl⟩
    · refine' ⟨nil, S, T, _, _⟩ <;> simp
  · exact ⟨s, S, T, rfl, rfl⟩
  · 

Proof state:
case intro.intro.intro.intro.h3
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
S T : WSeq (WSeq α)
s : WSeq α
⊢ ∃ s_1 S_1 T_1,
    destruct (append s (join (append S T))) = destruct (append s_1 (join (append S_1 T_1))) ∧
      destruct (append s (append (join S) (join T))) = destruct (append s_1 (append (join S_1) (join T_1)))

Next tactic:
exact ⟨s, S, T, rfl, rfl⟩
@[simp]
theorem bind_ret (f : α → β) (s) : bind s (ret ∘ f) ~ʷ map f s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
s : WSeq α
⊢ bind s (ret ∘ f) ~ʷ map f s

Next tactic:
dsimp [bind]
@[simp]
theorem bind_ret (f : α → β) (s) : bind s (ret ∘ f) ~ʷ map f s := by
  dsimp [bind]
  

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
s : WSeq α
⊢ join (map (ret ∘ f) s) ~ʷ map f s

Next tactic:
rw [map_comp]