l3lab/ntp-mathlib huggingface dataset:
theorem destruct_some_of_destruct_tail_some {s : WSeq α} {a} (h : some a ∈ destruct (tail s)) :
    ∃ a', some a' ∈ destruct s := by
  unfold tail Functor.map at h; simp only [destruct_flatten] at h
  rcases exists_of_mem_bind h with ⟨t, tm, td⟩; clear h
  rcases Computation.exists_of_mem_map tm with ⟨t', ht', ht2⟩; clear tm
  cases' t' with t' <;> rw [← ht2] at td <;> simp only [destruct_nil] at td
  · 

Proof state:
case intro.intro.intro.intro.none
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
t : WSeq α
ht' : none ∈ destruct s
ht2 : Option.rec nil Prod.snd none = t
td : some a ∈ Computation.pure none
⊢ ∃ a', some a' ∈ destruct s

Next tactic:
have := mem_unique td (ret_mem _)
theorem destruct_some_of_destruct_tail_some {s : WSeq α} {a} (h : some a ∈ destruct (tail s)) :
    ∃ a', some a' ∈ destruct s := by
  unfold tail Functor.map at h; simp only [destruct_flatten] at h
  rcases exists_of_mem_bind h with ⟨t, tm, td⟩; clear h
  rcases Computation.exists_of_mem_map tm with ⟨t', ht', ht2⟩; clear tm
  cases' t' with t' <;> rw [← ht2] at td <;> simp only [destruct_nil] at td
  · have := mem_unique td (ret_mem _)
    

Proof state:
case intro.intro.intro.intro.none
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
t : WSeq α
ht' : none ∈ destruct s
ht2 : Option.rec nil Prod.snd none = t
td : some a ∈ Computation.pure none
this : some a = none
⊢ ∃ a', some a' ∈ destruct s

Next tactic:
contradiction
theorem destruct_some_of_destruct_tail_some {s : WSeq α} {a} (h : some a ∈ destruct (tail s)) :
    ∃ a', some a' ∈ destruct s := by
  unfold tail Functor.map at h; simp only [destruct_flatten] at h
  rcases exists_of_mem_bind h with ⟨t, tm, td⟩; clear h
  rcases Computation.exists_of_mem_map tm with ⟨t', ht', ht2⟩; clear tm
  cases' t' with t' <;> rw [← ht2] at td <;> simp only [destruct_nil] at td
  · have := mem_unique td (ret_mem _)
    contradiction
  · 

Proof state:
case intro.intro.intro.intro.some
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
t : WSeq α
t' : α × WSeq α
td : some a ∈ destruct t'.2
ht' : some t' ∈ destruct s
ht2 : Option.rec nil Prod.snd (some t') = t
⊢ ∃ a', some a' ∈ destruct s

Next tactic:
exact ⟨_, ht'⟩
theorem head_some_of_head_tail_some {s : WSeq α} {a} (h : some a ∈ head (tail s)) :
    ∃ a', some a' ∈ head s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : some a ∈ head (tail s)
⊢ ∃ a', some a' ∈ head s

Next tactic:
unfold head at h
theorem head_some_of_head_tail_some {s : WSeq α} {a} (h : some a ∈ head (tail s)) :
    ∃ a', some a' ∈ head s := by
  unfold head at h
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (tail s))
⊢ ∃ a', some a' ∈ head s

Next tactic:
rcases Computation.exists_of_mem_map h with ⟨o, md, e⟩
theorem head_some_of_head_tail_some {s : WSeq α} {a} (h : some a ∈ head (tail s)) :
    ∃ a', some a' ∈ head s := by
  unfold head at h
  rcases Computation.exists_of_mem_map h with ⟨o, md, e⟩; 

Proof state:
case intro.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (tail s))
o : Option (α × WSeq α)
md : o ∈ destruct (tail s)
e : Prod.fst <$> o = some a
⊢ ∃ a', some a' ∈ head s

Next tactic:
clear h
theorem head_some_of_head_tail_some {s : WSeq α} {a} (h : some a ∈ head (tail s)) :
    ∃ a', some a' ∈ head s := by
  unfold head at h
  rcases Computation.exists_of_mem_map h with ⟨o, md, e⟩; clear h
  

Proof state:
case intro.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
o : Option (α × WSeq α)
md : o ∈ destruct (tail s)
e : Prod.fst <$> o = some a
⊢ ∃ a', some a' ∈ head s

Next tactic:
cases' o with o <;> [injection e; injection e with h']
theorem head_some_of_head_tail_some {s : WSeq α} {a} (h : some a ∈ head (tail s)) :
    ∃ a', some a' ∈ head s := by
  unfold head at h
  rcases Computation.exists_of_mem_map h with ⟨o, md, e⟩; clear h
  

Proof state:
case intro.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
o : Option (α × WSeq α)
md : o ∈ destruct (tail s)
e : Prod.fst <$> o = some a
⊢ ∃ a', some a' ∈ head s

Next tactic:
cases' o with o
theorem head_some_of_head_tail_some {s : WSeq α} {a} (h : some a ∈ head (tail s)) :
    ∃ a', some a' ∈ head s := by
  unfold head at h
  rcases Computation.exists_of_mem_map h with ⟨o, md, e⟩; clear h
  cases' o with o <;> [

Proof state:
case intro.intro.none
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
md : none ∈ destruct (tail s)
e : Prod.fst <$> none = some a
⊢ ∃ a', some a' ∈ head s

Next tactic:
injection e
theorem head_some_of_head_tail_some {s : WSeq α} {a} (h : some a ∈ head (tail s)) :
    ∃ a', some a' ∈ head s := by
  unfold head at h
  rcases Computation.exists_of_mem_map h with ⟨o, md, e⟩; clear h
  cases' o with o <;> [injection e; 

Proof state:
case intro.intro.some
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
o : α × WSeq α
md : some o ∈ destruct (tail s)
e : Prod.fst <$> some o = some a
⊢ ∃ a', some a' ∈ head s

Next tactic:
injection e with h'
theorem head_some_of_head_tail_some {s : WSeq α} {a} (h : some a ∈ head (tail s)) :
    ∃ a', some a' ∈ head s := by
  unfold head at h
  rcases Computation.exists_of_mem_map h with ⟨o, md, e⟩; clear h
  cases' o with o <;> [injection e; injection e with h']; 

Proof state:
case intro.intro.some
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
o : α × WSeq α
md : some o ∈ destruct (tail s)
h' : o.1 = a
⊢ ∃ a', some a' ∈ head s

Next tactic:
clear h'
theorem head_some_of_head_tail_some {s : WSeq α} {a} (h : some a ∈ head (tail s)) :
    ∃ a', some a' ∈ head s := by
  unfold head at h
  rcases Computation.exists_of_mem_map h with ⟨o, md, e⟩; clear h
  cases' o with o <;> [injection e; injection e with h']; clear h'
  

Proof state:
case intro.intro.some
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
o : α × WSeq α
md : some o ∈ destruct (tail s)
⊢ ∃ a', some a' ∈ head s

Next tactic:
cases' destruct_some_of_destruct_tail_some md with a am
theorem head_some_of_head_tail_some {s : WSeq α} {a} (h : some a ∈ head (tail s)) :
    ∃ a', some a' ∈ head s := by
  unfold head at h
  rcases Computation.exists_of_mem_map h with ⟨o, md, e⟩; clear h
  cases' o with o <;> [injection e; injection e with h']; clear h'
  cases' destruct_some_of_destruct_tail_some md with a am
  

Proof state:
case intro.intro.some.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a✝ : α
o : α × WSeq α
md : some o ∈ destruct (tail s)
a : α × WSeq α
am : some a ∈ destruct s
⊢ ∃ a', some a' ∈ head s

Next tactic:
exact ⟨_, Computation.mem_map (@Prod.fst α (WSeq α) <$> ·) am⟩
theorem head_some_of_get?_some {s : WSeq α} {a n} (h : some a ∈ get? s n) :
    ∃ a', some a' ∈ head s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
n : ℕ
h : some a ∈ get? s n
⊢ ∃ a', some a' ∈ head s

Next tactic:
induction n generalizing a with
  | zero => exact ⟨_, h⟩
  | succ n IH =>
      let ⟨a', h'⟩ := head_some_of_head_tail_some h
      exact IH h'
theorem head_some_of_get?_some {s : WSeq α} {a n} (h : some a ∈ get? s n) :
    ∃ a', some a' ∈ head s := by
  induction n generalizing a with
  

Proof state:
case zero
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : some a ∈ get? s Nat.zero
⊢ ∃ a', some a' ∈ head s

Next tactic:
| zero => exact ⟨_, h⟩
theorem head_some_of_get?_some {s : WSeq α} {a n} (h : some a ∈ get? s n) :
    ∃ a', some a' ∈ head s := by
  induction n generalizing a with
  | zero => 

Proof state:
case zero
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : some a ∈ get? s Nat.zero
⊢ ∃ a', some a' ∈ head s

Next tactic:
exact ⟨_, h⟩
theorem head_some_of_get?_some {s : WSeq α} {a n} (h : some a ∈ get? s n) :
    ∃ a', some a' ∈ head s := by
  induction n generalizing a with
  | zero => exact ⟨_, h⟩
  

Proof state:
case succ
α : Type u
β : Type v
γ : Type w
s : WSeq α
n : ℕ
IH : ∀ {a : α}, some a ∈ get? s n → ∃ a', some a' ∈ head s
a : α
h : some a ∈ get? s (Nat.succ n)
⊢ ∃ a', some a' ∈ head s

Next tactic:
| succ n IH =>
      let ⟨a', h'⟩ := head_some_of_head_tail_some h
      exact IH h'
theorem head_some_of_get?_some {s : WSeq α} {a n} (h : some a ∈ get? s n) :
    ∃ a', some a' ∈ head s := by
  induction n generalizing a with
  | zero => exact ⟨_, h⟩
  | succ n IH =>
      

Proof state:
case succ
α : Type u
β : Type v
γ : Type w
s : WSeq α
n : ℕ
IH : ∀ {a : α}, some a ∈ get? s n → ∃ a', some a' ∈ head s
a : α
h : some a ∈ get? s (Nat.succ n)
⊢ ∃ a', some a' ∈ head s

Next tactic:
let ⟨a', h'⟩ := head_some_of_head_tail_some h
theorem head_some_of_get?_some {s : WSeq α} {a n} (h : some a ∈ get? s n) :
    ∃ a', some a' ∈ head s := by
  induction n generalizing a with
  | zero => exact ⟨_, h⟩
  | succ n IH =>
      let ⟨a', h'⟩ := head_some_of_head_tail_some h
      

Proof state:
case succ
α : Type u
β : Type v
γ : Type w
s : WSeq α
n : ℕ
IH : ∀ {a : α}, some a ∈ get? s n → ∃ a', some a' ∈ head s
a : α
h : some a ∈ get? s (Nat.succ n)
a' : α
h' : some a' ∈ head (drop s n)
⊢ ∃ a', some a' ∈ head s

Next tactic:
exact IH h'
instance productive_tail (s : WSeq α) [Productive s] : Productive (tail s) :=
  ⟨fun n => by 

Proof state:
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
⊢ Terminates (get? (tail s) n)

Next tactic:
rw [get?_tail]
instance productive_tail (s : WSeq α) [Productive s] : Productive (tail s) :=
  ⟨fun n => by rw [get?_tail]; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
⊢ Terminates (get? s (n + 1))

Next tactic:
infer_instance
instance productive_dropn (s : WSeq α) [Productive s] (n) : Productive (drop s n) :=
  ⟨fun m => by 

Proof state:
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n m : ℕ
⊢ Terminates (get? (drop s n) m)

Next tactic:
rw [← get?_add]
instance productive_dropn (s : WSeq α) [Productive s] (n) : Productive (drop s n) :=
  ⟨fun m => by rw [← get?_add]; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n m : ℕ
⊢ Terminates (get? s (n + m))

Next tactic:
infer_instance
/-- Given a productive weak sequence, we can collapse all the `think`s to
  produce a sequence. -/
def toSeq (s : WSeq α) [Productive s] : Seq α :=
  ⟨fun n => (get? s n).get,
   fun {n} h => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : (fun n => Computation.get (get? s n)) n = none
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none

Next tactic:
cases e : Computation.get (get? s (n + 1))
/-- Given a productive weak sequence, we can collapse all the `think`s to
  produce a sequence. -/
def toSeq (s : WSeq α) [Productive s] : Seq α :=
  ⟨fun n => (get? s n).get,
   fun {n} h => by
    cases e : Computation.get (get? s (n + 1))
    · 

Proof state:
case none
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : (fun n => Computation.get (get? s n)) n = none
e : Computation.get (get? s (n + 1)) = none
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none

Next tactic:
assumption
/-- Given a productive weak sequence, we can collapse all the `think`s to
  produce a sequence. -/
def toSeq (s : WSeq α) [Productive s] : Seq α :=
  ⟨fun n => (get? s n).get,
   fun {n} h => by
    cases e : Computation.get (get? s (n + 1))
    · assumption
    

Proof state:
case some
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : (fun n => Computation.get (get? s n)) n = none
val✝ : α
e : Computation.get (get? s (n + 1)) = some val✝
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none

Next tactic:
have := Computation.mem_of_get_eq _ e
/-- Given a productive weak sequence, we can collapse all the `think`s to
  produce a sequence. -/
def toSeq (s : WSeq α) [Productive s] : Seq α :=
  ⟨fun n => (get? s n).get,
   fun {n} h => by
    cases e : Computation.get (get? s (n + 1))
    · assumption
    have := Computation.mem_of_get_eq _ e
    

Proof state:
case some
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : (fun n => Computation.get (get? s n)) n = none
val✝ : α
e : Computation.get (get? s (n + 1)) = some val✝
this : some val✝ ∈ get? s (n + 1)
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none

Next tactic:
simp? [get?] at this h says simp only [get?] at this h
/-- Given a productive weak sequence, we can collapse all the `think`s to
  produce a sequence. -/
def toSeq (s : WSeq α) [Productive s] : Seq α :=
  ⟨fun n => (get? s n).get,
   fun {n} h => by
    cases e : Computation.get (get? s (n + 1))
    · assumption
    have := Computation.mem_of_get_eq _ e
    simp? [get?] at this h says 

Proof state:
case some
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : (fun n => Computation.get (get? s n)) n = none
val✝ : α
e : Computation.get (get? s (n + 1)) = some val✝
this : some val✝ ∈ get? s (n + 1)
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none

Next tactic:
simp only [get?] at this h
/-- Given a productive weak sequence, we can collapse all the `think`s to
  produce a sequence. -/
def toSeq (s : WSeq α) [Productive s] : Seq α :=
  ⟨fun n => (get? s n).get,
   fun {n} h => by
    cases e : Computation.get (get? s (n + 1))
    · assumption
    have := Computation.mem_of_get_eq _ e
    simp? [get?] at this h says simp only [get?] at this h
    

Proof state:
case some
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : Computation.get (head (drop s n)) = none
val✝ : α
e : Computation.get (get? s (n + 1)) = some val✝
this : some val✝ ∈ head (drop s (n + 1))
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none

Next tactic:
cases' head_some_of_head_tail_some this with a' h'
/-- Given a productive weak sequence, we can collapse all the `think`s to
  produce a sequence. -/
def toSeq (s : WSeq α) [Productive s] : Seq α :=
  ⟨fun n => (get? s n).get,
   fun {n} h => by
    cases e : Computation.get (get? s (n + 1))
    · assumption
    have := Computation.mem_of_get_eq _ e
    simp? [get?] at this h says simp only [get?] at this h
    cases' head_some_of_head_tail_some this with a' h'
    

Proof state:
case some.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : Computation.get (head (drop s n)) = none
val✝ : α
e : Computation.get (get? s (n + 1)) = some val✝
this : some val✝ ∈ head (drop s (n + 1))
a' : α
h' : some a' ∈ head (drop s (Nat.add n 0))
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none

Next tactic:
have := mem_unique h' (@Computation.mem_of_get_eq _ _ _ _ h)
/-- Given a productive weak sequence, we can collapse all the `think`s to
  produce a sequence. -/
def toSeq (s : WSeq α) [Productive s] : Seq α :=
  ⟨fun n => (get? s n).get,
   fun {n} h => by
    cases e : Computation.get (get? s (n + 1))
    · assumption
    have := Computation.mem_of_get_eq _ e
    simp? [get?] at this h says simp only [get?] at this h
    cases' head_some_of_head_tail_some this with a' h'
    have := mem_unique h' (@Computation.mem_of_get_eq _ _ _ _ h)
    

Proof state:
case some.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : Computation.get (head (drop s n)) = none
val✝ : α
e : Computation.get (get? s (n + 1)) = some val✝
this✝ : some val✝ ∈ head (drop s (n + 1))
a' : α
h' : some a' ∈ head (drop s (Nat.add n 0))
this : some a' = none
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none

Next tactic:
contradiction
theorem get?_terminates_le {s : WSeq α} {m n} (h : m ≤ n) :
    Terminates (get? s n) → Terminates (get? s m) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : WSeq α
m n : ℕ
h : m ≤ n
⊢ Terminates (get? s n) → Terminates (get? s m)

Next tactic:
induction' h with m' _ IH
theorem get?_terminates_le {s : WSeq α} {m n} (h : m ≤ n) :
    Terminates (get? s n) → Terminates (get? s m) := by
  induction' h with m' _ IH
  

Proof state:
case refl
α : Type u
β : Type v
γ : Type w
s : WSeq α
m n : ℕ
⊢ Terminates (get? s m) → Terminates (get? s m)
case step
α : Type u
β : Type v
γ : Type w
s : WSeq α
m n m' : ℕ
a✝ : Nat.le m m'
IH : Terminates (get? s m') → Terminates (get? s m)
⊢ Terminates (get? s (Nat.succ m')) → Terminates (get? s m)

Next tactic:
exacts [id, fun T => IH (@head_terminates_of_head_tail_terminates _ _ T)]
theorem mem_rec_on {C : WSeq α → Prop} {a s} (M : a ∈ s) (h1 : ∀ b s', a = b ∨ C s' → C (cons b s'))
    (h2 : ∀ s, C s → C (think s)) : C s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
⊢ C s

Next tactic:
apply Seq.mem_rec_on M
theorem mem_rec_on {C : WSeq α → Prop} {a s} (M : a ∈ s) (h1 : ∀ b s', a = b ∨ C s' → C (cons b s'))
    (h2 : ∀ s, C s → C (think s)) : C s := by
  apply Seq.mem_rec_on M
  

Proof state:
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
⊢ ∀ (b : Option α) (s' : Seq (Option α)), some a = b ∨ C s' → C (Seq.cons b s')

Next tactic:
intro o s' h
theorem mem_rec_on {C : WSeq α → Prop} {a s} (M : a ∈ s) (h1 : ∀ b s', a = b ∨ C s' → C (cons b s'))
    (h2 : ∀ s, C s → C (think s)) : C s := by
  apply Seq.mem_rec_on M
  intro o s' h; 

Proof state:
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
o : Option α
s' : Seq (Option α)
h : some a = o ∨ C s'
⊢ C (Seq.cons o s')

Next tactic:
cases' o with b
theorem mem_rec_on {C : WSeq α → Prop} {a s} (M : a ∈ s) (h1 : ∀ b s', a = b ∨ C s' → C (cons b s'))
    (h2 : ∀ s, C s → C (think s)) : C s := by
  apply Seq.mem_rec_on M
  intro o s' h; cases' o with b
  · 

Proof state:
case none
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
h : some a = none ∨ C s'
⊢ C (Seq.cons none s')

Next tactic:
apply h2
theorem mem_rec_on {C : WSeq α → Prop} {a s} (M : a ∈ s) (h1 : ∀ b s', a = b ∨ C s' → C (cons b s'))
    (h2 : ∀ s, C s → C (think s)) : C s := by
  apply Seq.mem_rec_on M
  intro o s' h; cases' o with b
  · apply h2
    

Proof state:
case none.a
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
h : some a = none ∨ C s'
⊢ C s'

Next tactic:
cases h
theorem mem_rec_on {C : WSeq α → Prop} {a s} (M : a ∈ s) (h1 : ∀ b s', a = b ∨ C s' → C (cons b s'))
    (h2 : ∀ s, C s → C (think s)) : C s := by
  apply Seq.mem_rec_on M
  intro o s' h; cases' o with b
  · apply h2
    cases h
    · 

Proof state:
case none.a.inl
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
h✝ : some a = none
⊢ C s'

Next tactic:
contradiction
theorem mem_rec_on {C : WSeq α → Prop} {a s} (M : a ∈ s) (h1 : ∀ b s', a = b ∨ C s' → C (cons b s'))
    (h2 : ∀ s, C s → C (think s)) : C s := by
  apply Seq.mem_rec_on M
  intro o s' h; cases' o with b
  · apply h2
    cases h
    · contradiction
    · 

Proof state:
case none.a.inr
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
h✝ : C s'
⊢ C s'

Next tactic:
assumption
theorem mem_rec_on {C : WSeq α → Prop} {a s} (M : a ∈ s) (h1 : ∀ b s', a = b ∨ C s' → C (cons b s'))
    (h2 : ∀ s, C s → C (think s)) : C s := by
  apply Seq.mem_rec_on M
  intro o s' h; cases' o with b
  · apply h2
    cases h
    · contradiction
    · assumption
  · 

Proof state:
case some
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
b : α
h : some a = some b ∨ C s'
⊢ C (Seq.cons (some b) s')

Next tactic:
apply h1
theorem mem_rec_on {C : WSeq α → Prop} {a s} (M : a ∈ s) (h1 : ∀ b s', a = b ∨ C s' → C (cons b s'))
    (h2 : ∀ s, C s → C (think s)) : C s := by
  apply Seq.mem_rec_on M
  intro o s' h; cases' o with b
  · apply h2
    cases h
    · contradiction
    · assumption
  · apply h1
    

Proof state:
case some.a
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
b : α
h : some a = some b ∨ C s'
⊢ a = b ∨ C s'

Next tactic:
apply Or.imp_left _ h
theorem mem_rec_on {C : WSeq α → Prop} {a s} (M : a ∈ s) (h1 : ∀ b s', a = b ∨ C s' → C (cons b s'))
    (h2 : ∀ s, C s → C (think s)) : C s := by
  apply Seq.mem_rec_on M
  intro o s' h; cases' o with b
  · apply h2
    cases h
    · contradiction
    · assumption
  · apply h1
    apply Or.imp_left _ h
    

Proof state:
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
b : α
h : some a = some b ∨ C s'
⊢ some a = some b → a = b

Next tactic:
intro h
theorem mem_rec_on {C : WSeq α → Prop} {a s} (M : a ∈ s) (h1 : ∀ b s', a = b ∨ C s' → C (cons b s'))
    (h2 : ∀ s, C s → C (think s)) : C s := by
  apply Seq.mem_rec_on M
  intro o s' h; cases' o with b
  · apply h2
    cases h
    · contradiction
    · assumption
  · apply h1
    apply Or.imp_left _ h
    intro h
    

Proof state:
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
b : α
h✝ : some a = some b ∨ C s'
h : some a = some b
⊢ a = b

Next tactic:
injection h
@[simp]
theorem mem_think (s : WSeq α) (a) : a ∈ think s ↔ a ∈ s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
⊢ a ∈ think s ↔ a ∈ s

Next tactic:
cases' s with f al
@[simp]
theorem mem_think (s : WSeq α) (a) : a ∈ think s ↔ a ∈ s := by
  cases' s with f al
  

Proof state:
case mk
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
⊢ a ∈ think { val := f, property := al } ↔ a ∈ { val := f, property := al }

Next tactic:
change (some (some a) ∈ some none::f) ↔ some (some a) ∈ f
@[simp]
theorem mem_think (s : WSeq α) (a) : a ∈ think s ↔ a ∈ s := by
  cases' s with f al
  change (some (some a) ∈ some none::f) ↔ some (some a) ∈ f
  

Proof state:
case mk
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
⊢ some (some a) ∈ some none :: f ↔ some (some a) ∈ f

Next tactic:
constructor
@[simp]
theorem mem_think (s : WSeq α) (a) : a ∈ think s ↔ a ∈ s := by
  cases' s with f al
  change (some (some a) ∈ some none::f) ↔ some (some a) ∈ f
  constructor <;> 

Proof state:
case mk.mp
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
⊢ some (some a) ∈ some none :: f → some (some a) ∈ f

Next tactic:
intro h
@[simp]
theorem mem_think (s : WSeq α) (a) : a ∈ think s ↔ a ∈ s := by
  cases' s with f al
  change (some (some a) ∈ some none::f) ↔ some (some a) ∈ f
  constructor <;> 

Proof state:
case mk.mpr
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
⊢ some (some a) ∈ f → some (some a) ∈ some none :: f

Next tactic:
intro h
@[simp]
theorem mem_think (s : WSeq α) (a) : a ∈ think s ↔ a ∈ s := by
  cases' s with f al
  change (some (some a) ∈ some none::f) ↔ some (some a) ∈ f
  constructor <;> intro h
  · 

Proof state:
case mk.mp
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
h : some (some a) ∈ some none :: f
⊢ some (some a) ∈ f

Next tactic:
apply (Stream'.eq_or_mem_of_mem_cons h).resolve_left
@[simp]
theorem mem_think (s : WSeq α) (a) : a ∈ think s ↔ a ∈ s := by
  cases' s with f al
  change (some (some a) ∈ some none::f) ↔ some (some a) ∈ f
  constructor <;> intro h
  · apply (Stream'.eq_or_mem_of_mem_cons h).resolve_left
    

Proof state:
case mk.mp
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
h : some (some a) ∈ some none :: f
⊢ ¬some (some a) = some none

Next tactic:
intro