l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem ofList_append (l l' : List α) : ofList (l ++ l') = append (ofList l) (ofList l') := by
  induction l <;> 

Proof state:
case cons
α : Type u
β : Type v
γ : Type w
l' : List α
head✝ : α
tail✝ : List α
tail_ih✝ : ↑(tail✝ ++ l') = append ↑tail✝ ↑l'
⊢ ↑(head✝ :: tail✝ ++ l') = append ↑(head✝ :: tail✝) ↑l'

Next tactic:
simp [*]
@[simp]
theorem ofStream_append (l : List α) (s : Stream' α) :
    ofStream (l ++ₛ s) = append (ofList l) (ofStream s) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
s : Stream' α
⊢ ↑(l ++ₛ s) = append ↑l ↑s

Next tactic:
induction l
@[simp]
theorem ofStream_append (l : List α) (s : Stream' α) :
    ofStream (l ++ₛ s) = append (ofList l) (ofStream s) := by
  induction l <;> 

Proof state:
case nil
α : Type u
β : Type v
γ : Type w
s : Stream' α
⊢ ↑([] ++ₛ s) = append ↑[] ↑s

Next tactic:
simp [*, Stream'.nil_append_stream, Stream'.cons_append_stream]
@[simp]
theorem ofStream_append (l : List α) (s : Stream' α) :
    ofStream (l ++ₛ s) = append (ofList l) (ofStream s) := by
  induction l <;> 

Proof state:
case cons
α : Type u
β : Type v
γ : Type w
s : Stream' α
head✝ : α
tail✝ : List α
tail_ih✝ : ↑(tail✝ ++ₛ s) = append ↑tail✝ ↑s
⊢ ↑(head✝ :: tail✝ ++ₛ s) = append ↑(head✝ :: tail✝) ↑s

Next tactic:
simp [*, Stream'.nil_append_stream, Stream'.cons_append_stream]
theorem dropn_tail (s : Seq α) (n) : drop (tail s) n = drop s (n + 1) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ drop (tail s) n = drop s (n + 1)

Next tactic:
rw [add_comm]
theorem dropn_tail (s : Seq α) (n) : drop (tail s) n = drop s (n + 1) := by
  rw [add_comm]; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ drop (tail s) n = drop s (1 + n)

Next tactic:
symm
theorem dropn_tail (s : Seq α) (n) : drop (tail s) n = drop s (n + 1) := by
  rw [add_comm]; symm; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ drop s (1 + n) = drop (tail s) n

Next tactic:
apply dropn_add
@[simp]
theorem head_dropn (s : Seq α) (n) : head (drop s n) = get? s n := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ head (drop s n) = get? s n

Next tactic:
induction' n with n IH generalizing s
@[simp]
theorem head_dropn (s : Seq α) (n) : head (drop s n) = get? s n := by
  induction' n with n IH generalizing s; · 

Proof state:
case zero
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ head (drop s Nat.zero) = get? s Nat.zero

Next tactic:
rfl
@[simp]
theorem head_dropn (s : Seq α) (n) : head (drop s n) = get? s n := by
  induction' n with n IH generalizing s; · rfl
  

Proof state:
case succ
α : Type u
β : Type v
γ : Type w
n : ℕ
IH : ∀ (s : Seq α), head (drop s n) = get? s n
s : Seq α
⊢ head (drop s (Nat.succ n)) = get? s (Nat.succ n)

Next tactic:
rw [Nat.succ_eq_add_one, ← get?_tail, ← dropn_tail]
@[simp]
theorem head_dropn (s : Seq α) (n) : head (drop s n) = get? s n := by
  induction' n with n IH generalizing s; · rfl
  rw [Nat.succ_eq_add_one, ← get?_tail, ← dropn_tail]; 

Proof state:
case succ
α : Type u
β : Type v
γ : Type w
n : ℕ
IH : ∀ (s : Seq α), head (drop s n) = get? s n
s : Seq α
⊢ head (drop (tail s) n) = get? (tail s) n

Next tactic:
apply IH
theorem exists_of_mem_map {f} {b : β} : ∀ {s : Seq α}, b ∈ map f s → ∃ a, a ∈ s ∧ f a = b :=
  fun {s} h => by 

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
s : Seq α
h : b ∈ map f s
⊢ ∃ a, a ∈ s ∧ f a = b

Next tactic:
match s with
  | ⟨g, al⟩ =>
    let ⟨o, om, oe⟩ := @Stream'.exists_of_mem_map _ _ (Option.map f) (some b) g h
    cases' o with a
    · injection oe
    · injection oe with h'; exact ⟨a, om, h'⟩
theorem exists_of_mem_map {f} {b : β} : ∀ {s : Seq α}, b ∈ map f s → ∃ a, a ∈ s ∧ f a = b :=
  fun {s} h => by match s with
  | ⟨g, al⟩ =>
    

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
s : Seq α
g : Stream' (Option α)
al : IsSeq g
h : b ∈ map f { val := g, property := al }
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b

Next tactic:
let ⟨o, om, oe⟩ := @Stream'.exists_of_mem_map _ _ (Option.map f) (some b) g h
theorem exists_of_mem_map {f} {b : β} : ∀ {s : Seq α}, b ∈ map f s → ∃ a, a ∈ s ∧ f a = b :=
  fun {s} h => by match s with
  | ⟨g, al⟩ =>
    let ⟨o, om, oe⟩ := @Stream'.exists_of_mem_map _ _ (Option.map f) (some b) g h
    

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
s : Seq α
g : Stream' (Option α)
al : IsSeq g
h : b ∈ map f { val := g, property := al }
o : Option α
om : o ∈ g
oe : Option.map f o = some b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b

Next tactic:
cases' o with a
theorem exists_of_mem_map {f} {b : β} : ∀ {s : Seq α}, b ∈ map f s → ∃ a, a ∈ s ∧ f a = b :=
  fun {s} h => by match s with
  | ⟨g, al⟩ =>
    let ⟨o, om, oe⟩ := @Stream'.exists_of_mem_map _ _ (Option.map f) (some b) g h
    cases' o with a
    · 

Proof state:
case none
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
s : Seq α
g : Stream' (Option α)
al : IsSeq g
h : b ∈ map f { val := g, property := al }
om : none ∈ g
oe : Option.map f none = some b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b

Next tactic:
injection oe
theorem exists_of_mem_map {f} {b : β} : ∀ {s : Seq α}, b ∈ map f s → ∃ a, a ∈ s ∧ f a = b :=
  fun {s} h => by match s with
  | ⟨g, al⟩ =>
    let ⟨o, om, oe⟩ := @Stream'.exists_of_mem_map _ _ (Option.map f) (some b) g h
    cases' o with a
    · injection oe
    · 

Proof state:
case some
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
s : Seq α
g : Stream' (Option α)
al : IsSeq g
h : b ∈ map f { val := g, property := al }
a : α
om : some a ∈ g
oe : Option.map f (some a) = some b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b

Next tactic:
injection oe with h'
theorem exists_of_mem_map {f} {b : β} : ∀ {s : Seq α}, b ∈ map f s → ∃ a, a ∈ s ∧ f a = b :=
  fun {s} h => by match s with
  | ⟨g, al⟩ =>
    let ⟨o, om, oe⟩ := @Stream'.exists_of_mem_map _ _ (Option.map f) (some b) g h
    cases' o with a
    · injection oe
    · injection oe with h'; 

Proof state:
case some
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
s : Seq α
g : Stream' (Option α)
al : IsSeq g
h : b ∈ map f { val := g, property := al }
a : α
om : some a ∈ g
h' : f a = b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b

Next tactic:
exact ⟨a, om, h'⟩
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h : a ∈ append s₁ s₂
⊢ a ∈ s₁ ∨ a ∈ s₂

Next tactic:
have := h
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; 

Proof state:
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h this : a ∈ append s₁ s₂
⊢ a ∈ s₁ ∨ a ∈ s₂

Next tactic:
revert this
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  

Proof state:
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h : a ∈ append s₁ s₂
⊢ a ∈ append s₁ s₂ → a ∈ s₁ ∨ a ∈ s₂

Next tactic:
generalize e : append s₁ s₂ = ss
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; 

Proof state:
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h : a ∈ append s₁ s₂
ss : Seq α
e : append s₁ s₂ = ss
⊢ a ∈ ss → a ∈ s₁ ∨ a ∈ s₂

Next tactic:
intro h
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; 

Proof state:
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h✝ : a ∈ append s₁ s₂
ss : Seq α
e : append s₁ s₂ = ss
h : a ∈ ss
⊢ a ∈ s₁ ∨ a ∈ s₂

Next tactic:
revert s₁
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  

Proof state:
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
⊢ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = ss → a ∈ s₁ ∨ a ∈ s₂

Next tactic:
apply mem_rec_on h _
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  

Proof state:
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
⊢ ∀ (b : α) (s' : Seq α),
    (a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂) →
      ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = cons b s' → a ∈ s₁ ∨ a ∈ s₂

Next tactic:
intro b s' o s₁
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  

Proof state:
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
⊢ a ∈ append s₁ s₂ → append s₁ s₂ = cons b s' → a ∈ s₁ ∨ a ∈ s₂

Next tactic:
apply s₁.recOn _ fun c t₁ => _
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · 

Proof state:
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
⊢ a ∈ append nil s₂ → append nil s₂ = cons b s' → a ∈ nil ∨ a ∈ s₂

Next tactic:
intro m _
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · intro m _
    

Proof state:
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
m : a ∈ append nil s₂
e✝ : append nil s₂ = cons b s'
⊢ a ∈ nil ∨ a ∈ s₂

Next tactic:
apply Or.inr
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · intro m _
    apply Or.inr
    

Proof state:
case h
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
m : a ∈ append nil s₂
e✝ : append nil s₂ = cons b s'
⊢ a ∈ s₂

Next tactic:
simpa using m
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · intro m _
    apply Or.inr
    simpa using m
  · 

Proof state:
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
⊢ ∀ (c : α) (t₁ : Seq α), a ∈ append (cons c t₁) s₂ → append (cons c t₁) s₂ = cons b s' → a ∈ cons c t₁ ∨ a ∈ s₂

Next tactic:
intro c t₁ m e
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · intro m _
    apply Or.inr
    simpa using m
  · intro c t₁ m e
    

Proof state:
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
⊢ a ∈ cons c t₁ ∨ a ∈ s₂

Next tactic:
have this := congr_arg destruct e
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · intro m _
    apply Or.inr
    simpa using m
  · intro c t₁ m e
    have this := congr_arg destruct e
    

Proof state:
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
⊢ a ∈ cons c t₁ ∨ a ∈ s₂

Next tactic:
cases' show a = c ∨ a ∈ append t₁ s₂ by simpa using m with e' m
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · intro m _
    apply Or.inr
    simpa using m
  · intro c t₁ m e
    have this := congr_arg destruct e
    cases' show a = c ∨ a ∈ append t₁ s₂ by 

Proof state:
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
⊢ a = c ∨ a ∈ append t₁ s₂

Next tactic:
simpa using m
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · intro m _
    apply Or.inr
    simpa using m
  · intro c t₁ m e
    have this := congr_arg destruct e
    cases' show a = c ∨ a ∈ append t₁ s₂ by simpa using m with e' m
    · 

Proof state:
case inl
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
e' : a = c
⊢ a ∈ cons c t₁ ∨ a ∈ s₂

Next tactic:
rw [e']
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · intro m _
    apply Or.inr
    simpa using m
  · intro c t₁ m e
    have this := congr_arg destruct e
    cases' show a = c ∨ a ∈ append t₁ s₂ by simpa using m with e' m
    · rw [e']
      

Proof state:
case inl
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
e' : a = c
⊢ c ∈ cons c t₁ ∨ c ∈ s₂

Next tactic:
exact Or.inl (mem_cons _ _)
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · intro m _
    apply Or.inr
    simpa using m
  · intro c t₁ m e
    have this := congr_arg destruct e
    cases' show a = c ∨ a ∈ append t₁ s₂ by simpa using m with e' m
    · rw [e']
      exact Or.inl (mem_cons _ _)
    · 

Proof state:
case inr
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m✝ : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
m : a ∈ append t₁ s₂
⊢ a ∈ cons c t₁ ∨ a ∈ s₂

Next tactic:
cases' show c = b ∧ append t₁ s₂ = s' by simpa with i1 i2
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · intro m _
    apply Or.inr
    simpa using m
  · intro c t₁ m e
    have this := congr_arg destruct e
    cases' show a = c ∨ a ∈ append t₁ s₂ by simpa using m with e' m
    · rw [e']
      exact Or.inl (mem_cons _ _)
    · cases' show c = b ∧ append t₁ s₂ = s' by 

Proof state:
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m✝ : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
m : a ∈ append t₁ s₂
⊢ c = b ∧ append t₁ s₂ = s'

Next tactic:
simpa
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · intro m _
    apply Or.inr
    simpa using m
  · intro c t₁ m e
    have this := congr_arg destruct e
    cases' show a = c ∨ a ∈ append t₁ s₂ by simpa using m with e' m
    · rw [e']
      exact Or.inl (mem_cons _ _)
    · cases' show c = b ∧ append t₁ s₂ = s' by simpa with i1 i2
      

Proof state:
case inr.intro
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m✝ : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
m : a ∈ append t₁ s₂
i1 : c = b
i2 : append t₁ s₂ = s'
⊢ a ∈ cons c t₁ ∨ a ∈ s₂

Next tactic:
cases' o with e' IH
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · intro m _
    apply Or.inr
    simpa using m
  · intro c t₁ m e
    have this := congr_arg destruct e
    cases' show a = c ∨ a ∈ append t₁ s₂ by simpa using m with e' m
    · rw [e']
      exact Or.inl (mem_cons _ _)
    · cases' show c = b ∧ append t₁ s₂ = s' by simpa with i1 i2
      cases' o with e' IH
      · 

Proof state:
case inr.intro.inl
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' s₁ : Seq α
c : α
t₁ : Seq α
m✝ : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
m : a ∈ append t₁ s₂
i1 : c = b
i2 : append t₁ s₂ = s'
e' : a = b
⊢ a ∈ cons c t₁ ∨ a ∈ s₂

Next tactic:
simp [i1, e']
theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by
  have := h; revert this
  generalize e : append s₁ s₂ = ss; intro h; revert s₁
  apply mem_rec_on h _
  intro b s' o s₁
  apply s₁.recOn _ fun c t₁ => _
  · intro m _
    apply Or.inr
    simpa using m
  · intro c t₁ m e
    have this := congr_arg destruct e
    cases' show a = c ∨ a ∈ append t₁ s₂ by simpa using m with e' m
    · rw [e']
      exact Or.inl (mem_cons _ _)
    · cases' show c = b ∧ append t₁ s₂ = s' by simpa with i1 i2
      cases' o with e' IH
      · simp [i1, e']
      · 

Proof state:
case inr.intro.inr
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' s₁ : Seq α
c : α
t₁ : Seq α
m✝ : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
m : a ∈ append t₁ s₂
i1 : c = b
i2 : append t₁ s₂ = s'
IH : ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
⊢ a ∈ cons c t₁ ∨ a ∈ s₂

Next tactic:
exact Or.imp_left (mem_cons_of_mem _) (IH m i2)
theorem mem_append_left {s₁ s₂ : Seq α} {a : α} (h : a ∈ s₁) : a ∈ append s₁ s₂ := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h : a ∈ s₁
⊢ a ∈ append s₁ s₂

Next tactic:
apply mem_rec_on h
theorem mem_append_left {s₁ s₂ : Seq α} {a : α} (h : a ∈ s₁) : a ∈ append s₁ s₂ := by
  apply mem_rec_on h; 

Proof state:
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h : a ∈ s₁
⊢ ∀ (b : α) (s' : Seq α), a = b ∨ a ∈ append s' s₂ → a ∈ append (cons b s') s₂

Next tactic:
intros
theorem mem_append_left {s₁ s₂ : Seq α} {a : α} (h : a ∈ s₁) : a ∈ append s₁ s₂ := by
  apply mem_rec_on h; intros; 

Proof state:
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h : a ∈ s₁
b✝ : α
s'✝ : Seq α
a✝ : a = b✝ ∨ a ∈ append s'✝ s₂
⊢ a ∈ append (cons b✝ s'✝) s₂

Next tactic:
simp [*]
@[simp]
theorem enum_cons (s : Seq α) (x : α) :
    enum (cons x s) = cons (0, x) (map (Prod.map Nat.succ id) (enum s)) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
x : α
⊢ enum (cons x s) = cons (0, x) (map (Prod.map Nat.succ id) (enum s))

Next tactic:
ext ⟨n⟩ : 1
@[simp]
theorem enum_cons (s : Seq α) (x : α) :
    enum (cons x s) = cons (0, x) (map (Prod.map Nat.succ id) (enum s)) := by
  ext ⟨n⟩ : 1
  · 

Proof state:
case h.zero
α : Type u
β : Type v
γ : Type w
s : Seq α
x : α
⊢ get? (enum (cons x s)) Nat.zero = get? (cons (0, x) (map (Prod.map Nat.succ id) (enum s))) Nat.zero

Next tactic:
simp
@[simp]
theorem enum_cons (s : Seq α) (x : α) :
    enum (cons x s) = cons (0, x) (map (Prod.map Nat.succ id) (enum s)) := by
  ext ⟨n⟩ : 1
  · simp
  · 

Proof state:
case h.succ
α : Type u
β : Type v
γ : Type w
s : Seq α
x : α
n✝ : ℕ
⊢ get? (enum (cons x s)) (Nat.succ n✝) = get? (cons (0, x) (map (Prod.map Nat.succ id) (enum s))) (Nat.succ n✝)

Next tactic:
simp only [get?_enum, get?_cons_succ, map_get?, Option.map_map]
@[simp]
theorem enum_cons (s : Seq α) (x : α) :
    enum (cons x s) = cons (0, x) (map (Prod.map Nat.succ id) (enum s)) := by
  ext ⟨n⟩ : 1
  · simp
  · simp only [get?_enum, get?_cons_succ, map_get?, Option.map_map]
    

Proof state:
case h.succ
α : Type u
β : Type v
γ : Type w
s : Seq α
x : α
n✝ : ℕ
⊢ Option.map (Prod.mk (Nat.succ n✝)) (get? s n✝) = Option.map (Prod.map Nat.succ id ∘ Prod.mk n✝) (get? s n✝)

Next tactic:
congr
theorem map_id : ∀ s : Seq1 α, map id s = s
  | ⟨a, s⟩ => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
⊢ map id (a, s) = (a, s)

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

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

Next tactic:
dsimp [join]
@[simp]
theorem join_cons (a b : α) (s S) :
    join ((a, Seq.cons b s), S) = (a, Seq.join (Seq.cons (b, s) S)) := by
  dsimp [join]; 

Proof state:
α : Type u
β : Type v
γ : Type w
a b : α
s : Seq α
S : Seq (Seq1 α)
⊢ (match destruct (Seq.cons b s) with
    | none => (a, Seq.join S)
    | some s' => (a, Seq.join (Seq.cons s' S))) =
    (a, Seq.join (Seq.cons (b, s) S))

Next tactic:
rw [destruct_cons]
@[simp]
theorem join_map_ret (s : Seq α) : Seq.join (Seq.map ret s) = s := by
  

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

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

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

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

Proof state:
case H
α : 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 s))) (destruct s)

Next tactic:
apply recOn s