l3lab/ntp-mathlib huggingface dataset:
theorem le_stable (s : Seq α) {m n} (h : m ≤ n) : s.get? m = none → s.get? n = none := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
m n : ℕ
h : m ≤ n
⊢ get? s m = none → get? s n = none

Next tactic:
cases' s with f al
theorem le_stable (s : Seq α) {m n} (h : m ≤ n) : s.get? m = none → s.get? n = none := by
  cases' s with f al
  

Proof state:
case mk
α : Type u
β : Type v
γ : Type w
m n : ℕ
h : m ≤ n
f : Stream' (Option α)
al : IsSeq f
⊢ get? { val := f, property := al } m = none → get? { val := f, property := al } n = none

Next tactic:
induction' h with n _ IH
theorem le_stable (s : Seq α) {m n} (h : m ≤ n) : s.get? m = none → s.get? n = none := by
  cases' s with f al
  induction' h with n _ IH
  

Proof state:
case mk.refl
α : Type u
β : Type v
γ : Type w
m n : ℕ
f : Stream' (Option α)
al : IsSeq f
⊢ get? { val := f, property := al } m = none → get? { val := f, property := al } m = none
case mk.step
α : Type u
β : Type v
γ : Type w
m n✝ : ℕ
f : Stream' (Option α)
al : IsSeq f
n : ℕ
a✝ : Nat.le m n
IH : get? { val := f, property := al } m = none → get? { val := f, property := al } n = none
⊢ get? { val := f, property := al } m = none → get? { val := f, property := al } (Nat.succ n) = none

Next tactic:
exacts [id, fun h2 => al (IH h2)]
/-- If `s.get? n = some aₙ` for some value `aₙ`, then there is also some value `aₘ` such
that `s.get? = some aₘ` for `m ≤ n`.
-/
theorem ge_stable (s : Seq α) {aₙ : α} {n m : ℕ} (m_le_n : m ≤ n)
    (s_nth_eq_some : s.get? n = some aₙ) : ∃ aₘ : α, s.get? m = some aₘ :=
  have : s.get? n ≠ none := by 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
aₙ : α
n m : ℕ
m_le_n : m ≤ n
s_nth_eq_some : get? s n = some aₙ
⊢ get? s n ≠ none

Next tactic:
simp [s_nth_eq_some]
theorem not_mem_nil (a : α) : a ∉ @nil α := fun ⟨_, (h : some a = none)⟩ => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
x✝ : a ∈ nil
w✝ : ℕ
h : some a = none
⊢ False

Next tactic:
injection h
theorem eq_or_mem_of_mem_cons {a b : α} : ∀ {s : Seq α}, a ∈ cons b s → a = b ∨ a ∈ s
  | ⟨f, al⟩, h => (Stream'.eq_or_mem_of_mem_cons h).imp_left fun h => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a b : α
f : Stream' (Option α)
al : IsSeq f
h✝ : a ∈ cons b { val := f, property := al }
h : some a = some b
⊢ a = b

Next tactic:
injection h
@[simp]
theorem mem_cons_iff {a b : α} {s : Seq α} : a ∈ cons b s ↔ a = b ∨ a ∈ s :=
  ⟨eq_or_mem_of_mem_cons, by 

Proof state:
α : Type u
β : Type v
γ : Type w
a b : α
s : Seq α
⊢ a = b ∨ a ∈ s → a ∈ cons b s

Next tactic:
rintro (rfl | m) <;> [apply mem_cons; exact mem_cons_of_mem _ m]
@[simp]
theorem mem_cons_iff {a b : α} {s : Seq α} : a ∈ cons b s ↔ a = b ∨ a ∈ s :=
  ⟨eq_or_mem_of_mem_cons, by 

Proof state:
α : Type u
β : Type v
γ : Type w
a b : α
s : Seq α
⊢ a = b ∨ a ∈ s → a ∈ cons b s

Next tactic:
rintro (rfl | m)
@[simp]
theorem mem_cons_iff {a b : α} {s : Seq α} : a ∈ cons b s ↔ a = b ∨ a ∈ s :=
  ⟨eq_or_mem_of_mem_cons, by rintro (rfl | m) <;> [

Proof state:
case inl
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
⊢ a ∈ cons a s

Next tactic:
apply mem_cons
@[simp]
theorem mem_cons_iff {a b : α} {s : Seq α} : a ∈ cons b s ↔ a = b ∨ a ∈ s :=
  ⟨eq_or_mem_of_mem_cons, by rintro (rfl | m) <;> [apply mem_cons; 

Proof state:
case inr
α : Type u
β : Type v
γ : Type w
a b : α
s : Seq α
m : a ∈ s
⊢ a ∈ cons b s

Next tactic:
exact mem_cons_of_mem _ m
theorem destruct_eq_nil {s : Seq α} : destruct s = none → s = nil := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ destruct s = none → s = nil

Next tactic:
dsimp [destruct]
theorem destruct_eq_nil {s : Seq α} : destruct s = none → s = nil := by
  dsimp [destruct]
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ Option.map (fun a' => (a', tail s)) (get? s 0) = none → s = nil

Next tactic:
induction' f0 : get? s 0
theorem destruct_eq_nil {s : Seq α} : destruct s = none → s = nil := by
  dsimp [destruct]
  induction' f0 : get? s 0 <;> 

Proof state:
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
f0 : get? s 0 = none
⊢ Option.map (fun a' => (a', tail s)) none = none → s = nil

Next tactic:
intro h
theorem destruct_eq_nil {s : Seq α} : destruct s = none → s = nil := by
  dsimp [destruct]
  induction' f0 : get? s 0 <;> 

Proof state:
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
val✝ : α
f0 : get? s 0 = some val✝
⊢ Option.map (fun a' => (a', tail s)) (some val✝) = none → s = nil

Next tactic:
intro h
theorem destruct_eq_nil {s : Seq α} : destruct s = none → s = nil := by
  dsimp [destruct]
  induction' f0 : get? s 0 <;> intro h
  · 

Proof state:
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
f0 : get? s 0 = none
h : Option.map (fun a' => (a', tail s)) none = none
⊢ s = nil

Next tactic:
apply Subtype.eq
theorem destruct_eq_nil {s : Seq α} : destruct s = none → s = nil := by
  dsimp [destruct]
  induction' f0 : get? s 0 <;> intro h
  · apply Subtype.eq
    

Proof state:
case none.a
α : Type u
β : Type v
γ : Type w
s : Seq α
f0 : get? s 0 = none
h : Option.map (fun a' => (a', tail s)) none = none
⊢ ↑s = ↑nil

Next tactic:
funext n
theorem destruct_eq_nil {s : Seq α} : destruct s = none → s = nil := by
  dsimp [destruct]
  induction' f0 : get? s 0 <;> intro h
  · apply Subtype.eq
    funext n
    

Proof state:
case none.a.h
α : Type u
β : Type v
γ : Type w
s : Seq α
f0 : get? s 0 = none
h : Option.map (fun a' => (a', tail s)) none = none
n : ℕ
⊢ ↑s n = ↑nil n

Next tactic:
induction' n with n IH
theorem destruct_eq_nil {s : Seq α} : destruct s = none → s = nil := by
  dsimp [destruct]
  induction' f0 : get? s 0 <;> intro h
  · apply Subtype.eq
    funext n
    induction' n with n IH
    

Proof state:
case none.a.h.zero
α : Type u
β : Type v
γ : Type w
s : Seq α
f0 : get? s 0 = none
h : Option.map (fun a' => (a', tail s)) none = none
⊢ ↑s Nat.zero = ↑nil Nat.zero
case none.a.h.succ
α : Type u
β : Type v
γ : Type w
s : Seq α
f0 : get? s 0 = none
h : Option.map (fun a' => (a', tail s)) none = none
n : ℕ
IH : ↑s n = ↑nil n
⊢ ↑s (Nat.succ n) = ↑nil (Nat.succ n)

Next tactic:
exacts [f0, s.2 IH]
theorem destruct_eq_nil {s : Seq α} : destruct s = none → s = nil := by
  dsimp [destruct]
  induction' f0 : get? s 0 <;> intro h
  · apply Subtype.eq
    funext n
    induction' n with n IH
    exacts [f0, s.2 IH]
  · 

Proof state:
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
val✝ : α
f0 : get? s 0 = some val✝
h : Option.map (fun a' => (a', tail s)) (some val✝) = none
⊢ s = nil

Next tactic:
contradiction
theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
s' : Seq α
⊢ destruct s = some (a, s') → s = cons a s'

Next tactic:
dsimp [destruct]
theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' := by
  dsimp [destruct]
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
s' : Seq α
⊢ Option.map (fun a' => (a', tail s)) (get? s 0) = some (a, s') → s = cons a s'

Next tactic:
induction' f0 : get? s 0 with a'
theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' := by
  dsimp [destruct]
  induction' f0 : get? s 0 with a' <;> 

Proof state:
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
s' : Seq α
f0 : get? s 0 = none
⊢ Option.map (fun a' => (a', tail s)) none = some (a, s') → s = cons a s'

Next tactic:
intro h
theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' := by
  dsimp [destruct]
  induction' f0 : get? s 0 with a' <;> 

Proof state:
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
s' : Seq α
a' : α
f0 : get? s 0 = some a'
⊢ Option.map (fun a' => (a', tail s)) (some a') = some (a, s') → s = cons a s'

Next tactic:
intro h
theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' := by
  dsimp [destruct]
  induction' f0 : get? s 0 with a' <;> intro h
  · 

Proof state:
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
s' : Seq α
f0 : get? s 0 = none
h : Option.map (fun a' => (a', tail s)) none = some (a, s')
⊢ s = cons a s'

Next tactic:
contradiction
theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' := by
  dsimp [destruct]
  induction' f0 : get? s 0 with a' <;> intro h
  · contradiction
  · 

Proof state:
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
s' : Seq α
a' : α
f0 : get? s 0 = some a'
h : Option.map (fun a' => (a', tail s)) (some a') = some (a, s')
⊢ s = cons a s'

Next tactic:
cases' s with f al
theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' := by
  dsimp [destruct]
  induction' f0 : get? s 0 with a' <;> intro h
  · contradiction
  · cases' s with f al
    

Proof state:
case some.mk
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0 : get? { val := f, property := al } 0 = some a'
h : Option.map (fun a' => (a', tail { val := f, property := al })) (some a') = some (a, s')
⊢ { val := f, property := al } = cons a s'

Next tactic:
injections _ h1 h2
theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' := by
  dsimp [destruct]
  induction' f0 : get? s 0 with a' <;> intro h
  · contradiction
  · cases' s with f al
    injections _ h1 h2
    

Proof state:
case some.mk
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0 : get? { val := f, property := al } 0 = some a'
h1 : a' = a
h2 : tail { val := f, property := al } = s'
⊢ { val := f, property := al } = cons a s'

Next tactic:
rw [← h2]
theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' := by
  dsimp [destruct]
  induction' f0 : get? s 0 with a' <;> intro h
  · contradiction
  · cases' s with f al
    injections _ h1 h2
    rw [← h2]
    

Proof state:
case some.mk
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0 : get? { val := f, property := al } 0 = some a'
h1 : a' = a
h2 : tail { val := f, property := al } = s'
⊢ { val := f, property := al } = cons a (tail { val := f, property := al })

Next tactic:
apply Subtype.eq
theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' := by
  dsimp [destruct]
  induction' f0 : get? s 0 with a' <;> intro h
  · contradiction
  · cases' s with f al
    injections _ h1 h2
    rw [← h2]
    apply Subtype.eq
    

Proof state:
case some.mk.a
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0 : get? { val := f, property := al } 0 = some a'
h1 : a' = a
h2 : tail { val := f, property := al } = s'
⊢ ↑{ val := f, property := al } = ↑(cons a (tail { val := f, property := al }))

Next tactic:
dsimp [tail, cons]
theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' := by
  dsimp [destruct]
  induction' f0 : get? s 0 with a' <;> intro h
  · contradiction
  · cases' s with f al
    injections _ h1 h2
    rw [← h2]
    apply Subtype.eq
    dsimp [tail, cons]
    

Proof state:
case some.mk.a
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0 : get? { val := f, property := al } 0 = some a'
h1 : a' = a
h2 : tail { val := f, property := al } = s'
⊢ f = some a :: Stream'.tail f

Next tactic:
rw [h1] at f0
theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' := by
  dsimp [destruct]
  induction' f0 : get? s 0 with a' <;> intro h
  · contradiction
  · cases' s with f al
    injections _ h1 h2
    rw [← h2]
    apply Subtype.eq
    dsimp [tail, cons]
    rw [h1] at f0
    

Proof state:
case some.mk.a
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0 : get? { val := f, property := al } 0 = some a
h1 : a' = a
h2 : tail { val := f, property := al } = s'
⊢ f = some a :: Stream'.tail f

Next tactic:
rw [← f0]
theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' := by
  dsimp [destruct]
  induction' f0 : get? s 0 with a' <;> intro h
  · contradiction
  · cases' s with f al
    injections _ h1 h2
    rw [← h2]
    apply Subtype.eq
    dsimp [tail, cons]
    rw [h1] at f0
    rw [← f0]
    

Proof state:
case some.mk.a
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0 : get? { val := f, property := al } 0 = some a
h1 : a' = a
h2 : tail { val := f, property := al } = s'
⊢ f = get? { val := f, property := al } 0 :: Stream'.tail f

Next tactic:
exact (Stream'.eta f).symm
@[simp]
theorem destruct_cons (a : α) : ∀ s, destruct (cons a s) = some (a, s)
  | ⟨f, al⟩ => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option α)
al : IsSeq f
⊢ destruct (cons a { val := f, property := al }) = some (a, { val := f, property := al })

Next tactic:
unfold cons destruct Functor.map
@[simp]
theorem destruct_cons (a : α) : ∀ s, destruct (cons a s) = some (a, s)
  | ⟨f, al⟩ => by
    unfold cons destruct Functor.map
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option α)
al : IsSeq f
⊢ instFunctorOption.1
      (fun a' =>
        (a',
          tail
            { val := some a :: ↑{ val := f, property := al },
              property :=
                (_ :
                  ∀ {n : ℕ},
                    (some a :: ↑{ val := f, property := al }) n = none →
                      (some a :: ↑{ val := f, property := al }) (n + 1) = none) }))
      (get?
        { val := some a :: ↑{ val := f, property := al },
          property :=
            (_ :
              ∀ {n : ℕ},
                (some a :: ↑{ val := f, property := al }) n = none →
                  (some a :: ↑{ val := f, property := al }) (n + 1) = none) }
        0) =
    some (a, { val := f, property := al })

Next tactic:
apply congr_arg fun s => some (a, s)
@[simp]
theorem destruct_cons (a : α) : ∀ s, destruct (cons a s) = some (a, s)
  | ⟨f, al⟩ => by
    unfold cons destruct Functor.map
    apply congr_arg fun s => some (a, s)
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option α)
al : IsSeq f
⊢ tail
      { val := some a :: ↑{ val := f, property := al },
        property :=
          (_ :
            ∀ {n : ℕ},
              (some a :: ↑{ val := f, property := al }) n = none →
                (some a :: ↑{ val := f, property := al }) (n + 1) = none) } =
    { val := f, property := al }

Next tactic:
apply Subtype.eq
@[simp]
theorem destruct_cons (a : α) : ∀ s, destruct (cons a s) = some (a, s)
  | ⟨f, al⟩ => by
    unfold cons destruct Functor.map
    apply congr_arg fun s => some (a, s)
    apply Subtype.eq; 

Proof state:
case a
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option α)
al : IsSeq f
⊢ ↑(tail
        { val := some a :: ↑{ val := f, property := al },
          property :=
            (_ :
              ∀ {n : ℕ},
                (some a :: ↑{ val := f, property := al }) n = none →
                  (some a :: ↑{ val := f, property := al }) (n + 1) = none) }) =
    ↑{ val := f, property := al }

Next tactic:
dsimp [tail]
theorem head_eq_destruct (s : Seq α) : head.{u} s = Prod.fst.{u} <$> destruct.{u} s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ head s = Prod.fst <$> destruct s

Next tactic:
unfold destruct head
theorem head_eq_destruct (s : Seq α) : head.{u} s = Prod.fst.{u} <$> destruct.{u} s := by
  unfold destruct head; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ get? s 0 = Prod.fst <$> (fun a' => (a', tail s)) <$> get? s 0

Next tactic:
cases get? s 0
theorem head_eq_destruct (s : Seq α) : head.{u} s = Prod.fst.{u} <$> destruct.{u} s := by
  unfold destruct head; cases get? s 0 <;> 

Proof state:
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ none = Prod.fst <$> (fun a' => (a', tail s)) <$> none

Next tactic:
rfl
theorem head_eq_destruct (s : Seq α) : head.{u} s = Prod.fst.{u} <$> destruct.{u} s := by
  unfold destruct head; cases get? s 0 <;> 

Proof state:
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
val✝ : α
⊢ some val✝ = Prod.fst <$> (fun a' => (a', tail s)) <$> some val✝

Next tactic:
rfl
@[simp]
theorem head_cons (a : α) (s) : head (cons a s) = some a := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
⊢ head (cons a s) = some a

Next tactic:
rw [head_eq_destruct, destruct_cons, Option.map_eq_map, Option.map_some']
@[simp]
theorem tail_cons (a : α) (s) : tail (cons a s) = s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
⊢ tail (cons a s) = s

Next tactic:
cases' s with f al
@[simp]
theorem tail_cons (a : α) (s) : tail (cons a s) = s := by
  cases' s with f al
  

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

Next tactic:
apply Subtype.eq
@[simp]
theorem tail_cons (a : α) (s) : tail (cons a s) = s := by
  cases' s with f al
  apply Subtype.eq
  

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

Next tactic:
dsimp [tail, cons]
/-- Recursion principle for sequences, compare with `List.recOn`. -/
def recOn {C : Seq α → Sort v} (s : Seq α) (h1 : C nil) (h2 : ∀ x s, C (cons x s)) :
    C s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
C : Seq α → Sort v
s : Seq α
h1 : C nil
h2 : (x : α) → (s : Seq α) → C (cons x s)
⊢ C s

Next tactic:
cases' H : destruct s with v
/-- Recursion principle for sequences, compare with `List.recOn`. -/
def recOn {C : Seq α → Sort v} (s : Seq α) (h1 : C nil) (h2 : ∀ x s, C (cons x s)) :
    C s := by
  cases' H : destruct s with v
  · 

Proof state:
case none
α : Type u
β : Type v
γ : Type w
C : Seq α → Sort v
s : Seq α
h1 : C nil
h2 : (x : α) → (s : Seq α) → C (cons x s)
H : destruct s = none
⊢ C s

Next tactic:
rw [destruct_eq_nil H]
/-- Recursion principle for sequences, compare with `List.recOn`. -/
def recOn {C : Seq α → Sort v} (s : Seq α) (h1 : C nil) (h2 : ∀ x s, C (cons x s)) :
    C s := by
  cases' H : destruct s with v
  · rw [destruct_eq_nil H]
    

Proof state:
case none
α : Type u
β : Type v
γ : Type w
C : Seq α → Sort v
s : Seq α
h1 : C nil
h2 : (x : α) → (s : Seq α) → C (cons x s)
H : destruct s = none
⊢ C nil

Next tactic:
apply h1
/-- Recursion principle for sequences, compare with `List.recOn`. -/
def recOn {C : Seq α → Sort v} (s : Seq α) (h1 : C nil) (h2 : ∀ x s, C (cons x s)) :
    C s := by
  cases' H : destruct s with v
  · rw [destruct_eq_nil H]
    apply h1
  · 

Proof state:
case some
α : Type u
β : Type v
γ : Type w
C : Seq α → Sort v
s : Seq α
h1 : C nil
h2 : (x : α) → (s : Seq α) → C (cons x s)
v : Seq1 α
H : destruct s = some v
⊢ C s

Next tactic:
cases' v with a s'
/-- Recursion principle for sequences, compare with `List.recOn`. -/
def recOn {C : Seq α → Sort v} (s : Seq α) (h1 : C nil) (h2 : ∀ x s, C (cons x s)) :
    C s := by
  cases' H : destruct s with v
  · rw [destruct_eq_nil H]
    apply h1
  · cases' v with a s'
    

Proof state:
case some.mk
α : Type u
β : Type v
γ : Type w
C : Seq α → Sort v
s : Seq α
h1 : C nil
h2 : (x : α) → (s : Seq α) → C (cons x s)
a : α
s' : Seq α
H : destruct s = some (a, s')
⊢ C s

Next tactic:
rw [destruct_eq_cons H]
/-- Recursion principle for sequences, compare with `List.recOn`. -/
def recOn {C : Seq α → Sort v} (s : Seq α) (h1 : C nil) (h2 : ∀ x s, C (cons x s)) :
    C s := by
  cases' H : destruct s with v
  · rw [destruct_eq_nil H]
    apply h1
  · cases' v with a s'
    rw [destruct_eq_cons H]
    

Proof state:
case some.mk
α : Type u
β : Type v
γ : Type w
C : Seq α → Sort v
s : Seq α
h1 : C nil
h2 : (x : α) → (s : Seq α) → C (cons x s)
a : α
s' : Seq α
H : destruct s = some (a, s')
⊢ C (cons a s')

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

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

Next tactic:
cases' M with k e
theorem mem_rec_on {C : Seq α → Prop} {a s} (M : a ∈ s)
    (h1 : ∀ b s', a = b ∨ C s' → C (cons b s')) : C s := by
  cases' M with k e; 

Proof state:
case intro
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k : ℕ
e : (fun b => some a = b) (get (↑s) k)
⊢ C s

Next tactic:
unfold Stream'.get at e
theorem mem_rec_on {C : Seq α → Prop} {a s} (M : a ∈ s)
    (h1 : ∀ b s', a = b ∨ C s' → C (cons b s')) : C s := by
  cases' M with k e; unfold Stream'.get at e
  

Proof state:
case intro
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k : ℕ
e : (fun b => some a = b) (↑s k)
⊢ C s

Next tactic:
induction' k with k IH generalizing s
theorem mem_rec_on {C : Seq α → Prop} {a s} (M : a ∈ s)
    (h1 : ∀ b s', a = b ∨ C s' → C (cons b s')) : C s := by
  cases' M with k e; unfold Stream'.get at e
  induction' k with k IH generalizing s
  · 

Proof state:
case intro.zero
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
s : Seq α
e : some a = ↑s Nat.zero
⊢ C s

Next tactic:
have TH : s = cons a (tail s) := by
      apply destruct_eq_cons
      unfold destruct get? Functor.map
      rw [← e]
      rfl
theorem mem_rec_on {C : Seq α → Prop} {a s} (M : a ∈ s)
    (h1 : ∀ b s', a = b ∨ C s' → C (cons b s')) : C s := by
  cases' M with k e; unfold Stream'.get at e
  induction' k with k IH generalizing s
  · have TH : s = cons a (tail s) := by
      

Proof state:
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
s : Seq α
e : some a = ↑s Nat.zero
⊢ s = cons a (tail s)

Next tactic:
apply destruct_eq_cons
theorem mem_rec_on {C : Seq α → Prop} {a s} (M : a ∈ s)
    (h1 : ∀ b s', a = b ∨ C s' → C (cons b s')) : C s := by
  cases' M with k e; unfold Stream'.get at e
  induction' k with k IH generalizing s
  · have TH : s = cons a (tail s) := by
      apply destruct_eq_cons
      

Proof state:
case a
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
s : Seq α
e : some a = ↑s Nat.zero
⊢ destruct s = some (a, tail s)

Next tactic:
unfold destruct get? Functor.map
theorem mem_rec_on {C : Seq α → Prop} {a s} (M : a ∈ s)
    (h1 : ∀ b s', a = b ∨ C s' → C (cons b s')) : C s := by
  cases' M with k e; unfold Stream'.get at e
  induction' k with k IH generalizing s
  · have TH : s = cons a (tail s) := by
      apply destruct_eq_cons
      unfold destruct get? Functor.map
      

Proof state:
case a
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
s : Seq α
e : some a = ↑s Nat.zero
⊢ instFunctorOption.1 (fun a' => (a', tail s)) (↑s 0) = some (a, tail s)

Next tactic:
rw [← e]
theorem mem_rec_on {C : Seq α → Prop} {a s} (M : a ∈ s)
    (h1 : ∀ b s', a = b ∨ C s' → C (cons b s')) : C s := by
  cases' M with k e; unfold Stream'.get at e
  induction' k with k IH generalizing s
  · have TH : s = cons a (tail s) := by
      apply destruct_eq_cons
      unfold destruct get? Functor.map
      rw [← e]
      

Proof state:
case a
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
s : Seq α
e : some a = ↑s Nat.zero
⊢ instFunctorOption.1 (fun a' => (a', tail s)) (some a) = some (a, tail s)

Next tactic:
rfl
theorem mem_rec_on {C : Seq α → Prop} {a s} (M : a ∈ s)
    (h1 : ∀ b s', a = b ∨ C s' → C (cons b s')) : C s := by
  cases' M with k e; unfold Stream'.get at e
  induction' k with k IH generalizing s
  · have TH : s = cons a (tail s) := by
      apply destruct_eq_cons
      unfold destruct get? Functor.map
      rw [← e]
      rfl
    

Proof state:
case intro.zero
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
s : Seq α
e : some a = ↑s Nat.zero
TH : s = cons a (tail s)
⊢ C s

Next tactic:
rw [TH]