l3lab/ntp-mathlib huggingface dataset:
theorem le_stable (s : Computation α) {a m n} (h : m ≤ n) : s.1 m = some a → s.1 n = some a := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
m n : ℕ
h : m ≤ n
⊢ ↑s m = some a → ↑s n = some a

Next tactic:
cases' s with f al
theorem le_stable (s : Computation α) {a m n} (h : m ≤ n) : s.1 m = some a → s.1 n = some a := by
  cases' s with f al
  

Proof state:
case mk
α : Type u
β : Type v
γ : Type w
a : α
m n : ℕ
h : m ≤ n
f : Stream' (Option α)
al : ∀ ⦃n : ℕ⦄ ⦃a : α⦄, f n = some a → f (n + 1) = some a
⊢ ↑{ val := f, property := al } m = some a → ↑{ val := f, property := al } n = some a

Next tactic:
induction' h with n _ IH
theorem le_stable (s : Computation α) {a m n} (h : m ≤ n) : s.1 m = some a → s.1 n = some a := by
  cases' s with f al
  induction' h with n _ IH
  

Proof state:
case mk.refl
α : Type u
β : Type v
γ : Type w
a : α
m n : ℕ
f : Stream' (Option α)
al : ∀ ⦃n : ℕ⦄ ⦃a : α⦄, f n = some a → f (n + 1) = some a
⊢ ↑{ val := f, property := al } m = some a → ↑{ val := f, property := al } m = some a
case mk.step
α : Type u
β : Type v
γ : Type w
a : α
m n✝ : ℕ
f : Stream' (Option α)
al : ∀ ⦃n : ℕ⦄ ⦃a : α⦄, f n = some a → f (n + 1) = some a
n : ℕ
a✝ : Nat.le m n
IH : ↑{ val := f, property := al } m = some a → ↑{ val := f, property := al } n = some a
⊢ ↑{ val := f, property := al } m = some a → ↑{ val := f, property := al } (Nat.succ n) = some a

Next tactic:
exacts [id, fun h2 => al (IH h2)]
theorem mem_unique {s : Computation α} {a b : α} : a ∈ s → b ∈ s → a = b
  | ⟨m, ha⟩, ⟨n, hb⟩ => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a b : α
m : ℕ
ha : (fun b => some a = b) (Stream'.get (↑s) m)
n : ℕ
hb : (fun b_1 => some b = b_1) (Stream'.get (↑s) n)
⊢ a = b

Next tactic:
injection
      (le_stable s (le_max_left m n) ha.symm).symm.trans (le_stable s (le_max_right m n) hb.symm)
theorem terminates_def (s : Computation α) : Terminates s ↔ ∃ n, (s.1 n).isSome :=
  ⟨fun ⟨⟨a, n, h⟩⟩ =>
    ⟨n, by
      

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
x✝ : Terminates s
a : α
n : ℕ
h : (fun b => some a = b) (Stream'.get (↑s) n)
⊢ Option.isSome (↑s n) = true

Next tactic:
dsimp [Stream'.get] at h
theorem terminates_def (s : Computation α) : Terminates s ↔ ∃ n, (s.1 n).isSome :=
  ⟨fun ⟨⟨a, n, h⟩⟩ =>
    ⟨n, by
      dsimp [Stream'.get] at h
      

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
x✝ : Terminates s
a : α
n : ℕ
h : some a = ↑s n
⊢ Option.isSome (↑s n) = true

Next tactic:
rw [← h]
theorem terminates_def (s : Computation α) : Terminates s ↔ ∃ n, (s.1 n).isSome :=
  ⟨fun ⟨⟨a, n, h⟩⟩ =>
    ⟨n, by
      dsimp [Stream'.get] at h
      rw [← h]
      

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
x✝ : Terminates s
a : α
n : ℕ
h : some a = ↑s n
⊢ Option.isSome (some a) = true

Next tactic:
exact rfl
theorem of_think_mem {s : Computation α} {a} : a ∈ think s → a ∈ s
  | ⟨n, h⟩ => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
n : ℕ
h : (fun b => some a = b) (Stream'.get (↑(think s)) n)
⊢ a ∈ s

Next tactic:
cases' n with n'
theorem of_think_mem {s : Computation α} {a} : a ∈ think s → a ∈ s
  | ⟨n, h⟩ => by
    cases' n with n'
    · 

Proof state:
case zero
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
h : some a = Stream'.get (↑(think s)) Nat.zero
⊢ a ∈ s

Next tactic:
contradiction
theorem of_think_mem {s : Computation α} {a} : a ∈ think s → a ∈ s
  | ⟨n, h⟩ => by
    cases' n with n'
    · contradiction
    · 

Proof state:
case succ
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
n' : ℕ
h : some a = Stream'.get (↑(think s)) (Nat.succ n')
⊢ a ∈ s

Next tactic:
exact ⟨n', h⟩
theorem not_mem_empty (a : α) : a ∉ empty α := fun ⟨n, h⟩ => by 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
x✝ : a ∈ empty α
n : ℕ
h : (fun b => some a = b) (Stream'.get (↑(empty α)) n)
⊢ False

Next tactic:
contradiction
theorem eq_empty_of_not_terminates {s} (H : ¬Terminates s) : s = empty α := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
H : ¬Terminates s
⊢ s = empty α

Next tactic:
apply Subtype.eq
theorem eq_empty_of_not_terminates {s} (H : ¬Terminates s) : s = empty α := by
  apply Subtype.eq; 

Proof state:
case a
α : Type u
β : Type v
γ : Type w
s : Computation α
H : ¬Terminates s
⊢ ↑s = ↑(empty α)

Next tactic:
funext n
theorem eq_empty_of_not_terminates {s} (H : ¬Terminates s) : s = empty α := by
  apply Subtype.eq; funext n
  

Proof state:
case a.h
α : Type u
β : Type v
γ : Type w
s : Computation α
H : ¬Terminates s
n : ℕ
⊢ ↑s n = ↑(empty α) n

Next tactic:
induction' h : s.val n with _
theorem eq_empty_of_not_terminates {s} (H : ¬Terminates s) : s = empty α := by
  apply Subtype.eq; funext n
  induction' h : s.val n with _; · 

Proof state:
case a.h.none
α : Type u
β : Type v
γ : Type w
s : Computation α
H : ¬Terminates s
n : ℕ
h : ↑s n = none
⊢ none = ↑(empty α) n

Next tactic:
rfl
theorem eq_empty_of_not_terminates {s} (H : ¬Terminates s) : s = empty α := by
  apply Subtype.eq; funext n
  induction' h : s.val n with _; · rfl
  

Proof state:
case a.h.some
α : Type u
β : Type v
γ : Type w
s : Computation α
H : ¬Terminates s
n : ℕ
val✝ : α
h : ↑s n = some val✝
⊢ some val✝ = ↑(empty α) n

Next tactic:
refine' absurd _ H
theorem eq_empty_of_not_terminates {s} (H : ¬Terminates s) : s = empty α := by
  apply Subtype.eq; funext n
  induction' h : s.val n with _; · rfl
  refine' absurd _ H; 

Proof state:
case a.h.some
α : Type u
β : Type v
γ : Type w
s : Computation α
H : ¬Terminates s
n : ℕ
val✝ : α
h : ↑s n = some val✝
⊢ Terminates s

Next tactic:
exact ⟨⟨_, _, h.symm⟩⟩
theorem mem_of_get_eq {a} : get s = a → a ∈ s := by 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
h : Terminates s
a : α
⊢ get s = a → a ∈ s

Next tactic:
intro h
theorem mem_of_get_eq {a} : get s = a → a ∈ s := by intro h; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
h✝ : Terminates s
a : α
h : get s = a
⊢ a ∈ s

Next tactic:
rw [← h]
theorem mem_of_get_eq {a} : get s = a → a ∈ s := by intro h; rw [← h]; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
h✝ : Terminates s
a : α
h : get s = a
⊢ get s ∈ s

Next tactic:
apply get_mem
theorem mem_of_promises {a} (p : s ~> a) : a ∈ s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
h : Terminates s
a : α
p : s ~> a
⊢ a ∈ s

Next tactic:
cases' h with h
theorem mem_of_promises {a} (p : s ~> a) : a ∈ s := by
  cases' h with h
  

Proof state:
case mk
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
p : s ~> a
h : ∃ a, a ∈ s
⊢ a ∈ s

Next tactic:
cases' h with a' h
theorem mem_of_promises {a} (p : s ~> a) : a ∈ s := by
  cases' h with h
  cases' h with a' h
  

Proof state:
case mk.intro
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
p : s ~> a
a' : α
h : a' ∈ s
⊢ a ∈ s

Next tactic:
rw [p h]
theorem mem_of_promises {a} (p : s ~> a) : a ∈ s := by
  cases' h with h
  cases' h with a' h
  rw [p h]
  

Proof state:
case mk.intro
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
p : s ~> a
a' : α
h : a' ∈ s
⊢ a' ∈ s

Next tactic:
exact h
theorem results_of_terminates' (s : Computation α) [T : Terminates s] {a} (h : a ∈ s) :
    Results s a (length s) := by 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
T : Terminates s
a : α
h : a ∈ s
⊢ Results s a (length s)

Next tactic:
rw [← get_eq_of_mem _ h]
theorem results_of_terminates' (s : Computation α) [T : Terminates s] {a} (h : a ∈ s) :
    Results s a (length s) := by rw [← get_eq_of_mem _ h]; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
T : Terminates s
a : α
h : a ∈ s
⊢ Results s (get s) (length s)

Next tactic:
apply results_of_terminates
theorem Results.len_unique {s : Computation α} {a b m n} (h1 : Results s a m) (h2 : Results s b n) :
    m = n := by 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a b : α
m n : ℕ
h1 : Results s a m
h2 : Results s b n
⊢ m = n

Next tactic:
haveI := h1.terminates
theorem Results.len_unique {s : Computation α} {a b m n} (h1 : Results s a m) (h2 : Results s b n) :
    m = n := by haveI := h1.terminates; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a b : α
m n : ℕ
h1 : Results s a m
h2 : Results s b n
this : Terminates s
⊢ m = n

Next tactic:
haveI := h2.terminates
theorem Results.len_unique {s : Computation α} {a b m n} (h1 : Results s a m) (h2 : Results s b n) :
    m = n := by haveI := h1.terminates; haveI := h2.terminates; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a b : α
m n : ℕ
h1 : Results s a m
h2 : Results s b n
this✝ this : Terminates s
⊢ m = n

Next tactic:
rw [← h1.length, h2.length]
@[simp]
theorem length_think (s : Computation α) [h : Terminates s] : length (think s) = length s + 1 := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
h : Terminates s
⊢ length (think s) = length s + 1

Next tactic:
apply le_antisymm
@[simp]
theorem length_think (s : Computation α) [h : Terminates s] : length (think s) = length s + 1 := by
  apply le_antisymm
  · 

Proof state:
case a
α : Type u
β : Type v
γ : Type w
s : Computation α
h : Terminates s
⊢ length (think s) ≤ length s + 1

Next tactic:
exact Nat.find_min' _ (Nat.find_spec ((terminates_def _).1 h))
@[simp]
theorem length_think (s : Computation α) [h : Terminates s] : length (think s) = length s + 1 := by
  apply le_antisymm
  · exact Nat.find_min' _ (Nat.find_spec ((terminates_def _).1 h))
  · 

Proof state:
case a
α : Type u
β : Type v
γ : Type w
s : Computation α
h : Terminates s
⊢ length s + 1 ≤ length (think s)

Next tactic:
have : (Option.isSome ((think s).val (length (think s))) : Prop) :=
      Nat.find_spec ((terminates_def _).1 s.think_terminates)
@[simp]
theorem length_think (s : Computation α) [h : Terminates s] : length (think s) = length s + 1 := by
  apply le_antisymm
  · exact Nat.find_min' _ (Nat.find_spec ((terminates_def _).1 h))
  · have : (Option.isSome ((think s).val (length (think s))) : Prop) :=
      Nat.find_spec ((terminates_def _).1 s.think_terminates)
    

Proof state:
case a
α : Type u
β : Type v
γ : Type w
s : Computation α
h : Terminates s
this : Option.isSome (↑(think s) (length (think s))) = true
⊢ length s + 1 ≤ length (think s)

Next tactic:
revert this
@[simp]
theorem length_think (s : Computation α) [h : Terminates s] : length (think s) = length s + 1 := by
  apply le_antisymm
  · exact Nat.find_min' _ (Nat.find_spec ((terminates_def _).1 h))
  · have : (Option.isSome ((think s).val (length (think s))) : Prop) :=
      Nat.find_spec ((terminates_def _).1 s.think_terminates)
    revert this; 

Proof state:
case a
α : Type u
β : Type v
γ : Type w
s : Computation α
h : Terminates s
⊢ Option.isSome (↑(think s) (length (think s))) = true → length s + 1 ≤ length (think s)

Next tactic:
cases' length (think s) with n
@[simp]
theorem length_think (s : Computation α) [h : Terminates s] : length (think s) = length s + 1 := by
  apply le_antisymm
  · exact Nat.find_min' _ (Nat.find_spec ((terminates_def _).1 h))
  · have : (Option.isSome ((think s).val (length (think s))) : Prop) :=
      Nat.find_spec ((terminates_def _).1 s.think_terminates)
    revert this; cases' length (think s) with n <;> 

Proof state:
case a.zero
α : Type u
β : Type v
γ : Type w
s : Computation α
h : Terminates s
⊢ Option.isSome (↑(think s) Nat.zero) = true → length s + 1 ≤ Nat.zero

Next tactic:
intro this
@[simp]
theorem length_think (s : Computation α) [h : Terminates s] : length (think s) = length s + 1 := by
  apply le_antisymm
  · exact Nat.find_min' _ (Nat.find_spec ((terminates_def _).1 h))
  · have : (Option.isSome ((think s).val (length (think s))) : Prop) :=
      Nat.find_spec ((terminates_def _).1 s.think_terminates)
    revert this; cases' length (think s) with n <;> 

Proof state:
case a.succ
α : Type u
β : Type v
γ : Type w
s : Computation α
h : Terminates s
n : ℕ
⊢ Option.isSome (↑(think s) (Nat.succ n)) = true → length s + 1 ≤ Nat.succ n

Next tactic:
intro this
@[simp]
theorem length_think (s : Computation α) [h : Terminates s] : length (think s) = length s + 1 := by
  apply le_antisymm
  · exact Nat.find_min' _ (Nat.find_spec ((terminates_def _).1 h))
  · have : (Option.isSome ((think s).val (length (think s))) : Prop) :=
      Nat.find_spec ((terminates_def _).1 s.think_terminates)
    revert this; cases' length (think s) with n <;> intro this
    · 

Proof state:
case a.zero
α : Type u
β : Type v
γ : Type w
s : Computation α
h : Terminates s
this : Option.isSome (↑(think s) Nat.zero) = true
⊢ length s + 1 ≤ Nat.zero

Next tactic:
simp [think, Stream'.cons] at this
@[simp]
theorem length_think (s : Computation α) [h : Terminates s] : length (think s) = length s + 1 := by
  apply le_antisymm
  · exact Nat.find_min' _ (Nat.find_spec ((terminates_def _).1 h))
  · have : (Option.isSome ((think s).val (length (think s))) : Prop) :=
      Nat.find_spec ((terminates_def _).1 s.think_terminates)
    revert this; cases' length (think s) with n <;> intro this
    · simp [think, Stream'.cons] at this
    · 

Proof state:
case a.succ
α : Type u
β : Type v
γ : Type w
s : Computation α
h : Terminates s
n : ℕ
this : Option.isSome (↑(think s) (Nat.succ n)) = true
⊢ length s + 1 ≤ Nat.succ n

Next tactic:
apply Nat.succ_le_succ
@[simp]
theorem length_think (s : Computation α) [h : Terminates s] : length (think s) = length s + 1 := by
  apply le_antisymm
  · exact Nat.find_min' _ (Nat.find_spec ((terminates_def _).1 h))
  · have : (Option.isSome ((think s).val (length (think s))) : Prop) :=
      Nat.find_spec ((terminates_def _).1 s.think_terminates)
    revert this; cases' length (think s) with n <;> intro this
    · simp [think, Stream'.cons] at this
    · apply Nat.succ_le_succ
      

Proof state:
case a.succ.a
α : Type u
β : Type v
γ : Type w
s : Computation α
h : Terminates s
n : ℕ
this : Option.isSome (↑(think s) (Nat.succ n)) = true
⊢ length s ≤ n

Next tactic:
apply Nat.find_min'
@[simp]
theorem length_think (s : Computation α) [h : Terminates s] : length (think s) = length s + 1 := by
  apply le_antisymm
  · exact Nat.find_min' _ (Nat.find_spec ((terminates_def _).1 h))
  · have : (Option.isSome ((think s).val (length (think s))) : Prop) :=
      Nat.find_spec ((terminates_def _).1 s.think_terminates)
    revert this; cases' length (think s) with n <;> intro this
    · simp [think, Stream'.cons] at this
    · apply Nat.succ_le_succ
      apply Nat.find_min'
      

Proof state:
case a.succ.a.h
α : Type u
β : Type v
γ : Type w
s : Computation α
h : Terminates s
n : ℕ
this : Option.isSome (↑(think s) (Nat.succ n)) = true
⊢ Option.isSome (↑s n) = true

Next tactic:
apply this
theorem results_think {s : Computation α} {a n} (h : Results s a n) : Results (think s) a (n + 1) :=
  haveI := h.terminates
  ⟨think_mem h.mem, by 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
n : ℕ
h : Results s a n
this : Terminates s
⊢ length (think s) = n + 1

Next tactic:
rw [length_think, h.length]
theorem of_results_think {s : Computation α} {a n} (h : Results (think s) a n) :
    ∃ m, Results s a m ∧ n = m + 1 := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
n : ℕ
h : Results (think s) a n
⊢ ∃ m, Results s a m ∧ n = m + 1

Next tactic:
haveI := of_think_terminates h.terminates
theorem of_results_think {s : Computation α} {a n} (h : Results (think s) a n) :
    ∃ m, Results s a m ∧ n = m + 1 := by
  haveI := of_think_terminates h.terminates
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
n : ℕ
h : Results (think s) a n
this : Terminates s
⊢ ∃ m, Results s a m ∧ n = m + 1

Next tactic:
have := results_of_terminates' _ (of_think_mem h.mem)
theorem of_results_think {s : Computation α} {a n} (h : Results (think s) a n) :
    ∃ m, Results s a m ∧ n = m + 1 := by
  haveI := of_think_terminates h.terminates
  have := results_of_terminates' _ (of_think_mem h.mem)
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
n : ℕ
h : Results (think s) a n
this✝ : Terminates s
this : Results s a (length s)
⊢ ∃ m, Results s a m ∧ n = m + 1

Next tactic:
exact ⟨_, this, Results.len_unique h (results_think this)⟩
@[simp]
theorem results_think_iff {s : Computation α} {a n} : Results (think s) a (n + 1) ↔ Results s a n :=
  ⟨fun h => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
n : ℕ
h : Results (think s) a (n + 1)
⊢ Results s a n

Next tactic:
let ⟨n', r, e⟩ := of_results_think h
@[simp]
theorem results_think_iff {s : Computation α} {a n} : Results (think s) a (n + 1) ↔ Results s a n :=
  ⟨fun h => by
    let ⟨n', r, e⟩ := of_results_think h
    

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
n : ℕ
h : Results (think s) a (n + 1)
n' : ℕ
r : Results s a n'
e : n + 1 = n' + 1
⊢ Results s a n

Next tactic:
injection e with h'
@[simp]
theorem results_think_iff {s : Computation α} {a n} : Results (think s) a (n + 1) ↔ Results s a n :=
  ⟨fun h => by
    let ⟨n', r, e⟩ := of_results_think h
    injection e with h'; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
n : ℕ
h : Results (think s) a (n + 1)
n' : ℕ
r : Results s a n'
h' : Nat.add n 0 = Nat.add n' 0
⊢ Results s a n

Next tactic:
rw [Nat.add, Nat.add] at h'
@[simp]
theorem results_think_iff {s : Computation α} {a n} : Results (think s) a (n + 1) ↔ Results s a n :=
  ⟨fun h => by
    let ⟨n', r, e⟩ := of_results_think h
    injection e with h'; rw [Nat.add, Nat.add] at h'; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
n : ℕ
h : Results (think s) a (n + 1)
n' : ℕ
r : Results s a n'
h' : n = n'
⊢ Results s a n

Next tactic:
rwa [h']
theorem results_thinkN_pure (a : α) (n) : Results (thinkN (pure a) n) a n := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
⊢ Results (thinkN (pure a) n) a n

Next tactic:
have := results_thinkN n (results_pure a)
theorem results_thinkN_pure (a : α) (n) : Results (thinkN (pure a) n) a n := by
  have := results_thinkN n (results_pure a); 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
this : Results (thinkN (pure a) n) a (0 + n)
⊢ Results (thinkN (pure a) n) a n

Next tactic:
rwa [Nat.zero_add] at this
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Computation α
a : α
n : ℕ
h : Results s a n
⊢ s = thinkN (pure a) n

Next tactic:
revert s
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
⊢ ∀ {s : Computation α}, Results s a n → s = thinkN (pure a) n

Next tactic:
induction' n with n IH
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  induction' n with n IH <;> 

Proof state:
case zero
α : Type u
β : Type v
γ : Type w
a : α
⊢ ∀ {s : Computation α}, Results s a Nat.zero → s = thinkN (pure a) Nat.zero

Next tactic:
intro s
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  induction' n with n IH <;> 

Proof state:
case succ
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : Computation α}, Results s a n → s = thinkN (pure a) n
⊢ ∀ {s : Computation α}, Results s a (Nat.succ n) → s = thinkN (pure a) (Nat.succ n)

Next tactic:
intro s
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  induction' n with n IH <;> intro s <;> 

Proof state:
case zero
α : Type u
β : Type v
γ : Type w
a : α
s : Computation α
⊢ Results s a Nat.zero → s = thinkN (pure a) Nat.zero

Next tactic:
apply recOn s (fun a' => _) fun s => _
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  induction' n with n IH <;> intro s <;> 

Proof state:
case succ
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : Computation α}, Results s a n → s = thinkN (pure a) n
s : Computation α
⊢ Results s a (Nat.succ n) → s = thinkN (pure a) (Nat.succ n)

Next tactic:
apply recOn s (fun a' => _) fun s => _
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  induction' n with n IH <;> intro s <;> apply recOn s (fun a' => _) fun s => _ <;> 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
s : Computation α
⊢ ∀ (a' : α), Results (pure a') a Nat.zero → pure a' = thinkN (pure a) Nat.zero

Next tactic:
intro a h
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  induction' n with n IH <;> intro s <;> apply recOn s (fun a' => _) fun s => _ <;> 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
s : Computation α
⊢ ∀ (s : Computation α), Results (think s) a Nat.zero → think s = thinkN (pure a) Nat.zero

Next tactic:
intro a h
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  induction' n with n IH <;> intro s <;> apply recOn s (fun a' => _) fun s => _ <;> 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : Computation α}, Results s a n → s = thinkN (pure a) n
s : Computation α
⊢ ∀ (a' : α), Results (pure a') a (Nat.succ n) → pure a' = thinkN (pure a) (Nat.succ n)

Next tactic:
intro a h
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  induction' n with n IH <;> intro s <;> apply recOn s (fun a' => _) fun s => _ <;> 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : Computation α}, Results s a n → s = thinkN (pure a) n
s : Computation α
⊢ ∀ (s : Computation α), Results (think s) a (Nat.succ n) → think s = thinkN (pure a) (Nat.succ n)

Next tactic:
intro a h
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  induction' n with n IH <;> intro s <;> apply recOn s (fun a' => _) fun s => _ <;> intro a h
  · 

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
s : Computation α
a : α
h : Results (pure a) a✝ Nat.zero
⊢ pure a = thinkN (pure a✝) Nat.zero

Next tactic:
rw [← eq_of_pure_mem h.mem]
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  induction' n with n IH <;> intro s <;> apply recOn s (fun a' => _) fun s => _ <;> intro a h
  · rw [← eq_of_pure_mem h.mem]
    

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
s : Computation α
a : α
h : Results (pure a) a✝ Nat.zero
⊢ pure a✝ = thinkN (pure a✝) Nat.zero

Next tactic:
rfl
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  induction' n with n IH <;> intro s <;> apply recOn s (fun a' => _) fun s => _ <;> intro a h
  · rw [← eq_of_pure_mem h.mem]
    rfl
  · 

Proof state:
α : Type u
β : Type v
γ : Type w
a✝ : α
s a : Computation α
h : Results (think a) a✝ Nat.zero
⊢ think a = thinkN (pure a✝) Nat.zero

Next tactic:
cases' of_results_think h with n h
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  induction' n with n IH <;> intro s <;> apply recOn s (fun a' => _) fun s => _ <;> intro a h
  · rw [← eq_of_pure_mem h.mem]
    rfl
  · cases' of_results_think h with n h
    

Proof state:
case intro
α : Type u
β : Type v
γ : Type w
a✝ : α
s a : Computation α
h✝ : Results (think a) a✝ Nat.zero
n : ℕ
h : Results a a✝ n ∧ Nat.zero = n + 1
⊢ think a = thinkN (pure a✝) Nat.zero

Next tactic:
cases h
theorem eq_thinkN {s : Computation α} {a n} (h : Results s a n) : s = thinkN (pure a) n := by
  revert s
  induction' n with n IH <;> intro s <;> apply recOn s (fun a' => _) fun s => _ <;> intro a h
  · rw [← eq_of_pure_mem h.mem]
    rfl
  · cases' of_results_think h with n h
    cases h
    

Proof state:
case intro.intro
α : Type u
β : Type v
γ : Type w
a✝ : α
s a : Computation α
h : Results (think a) a✝ Nat.zero
n : ℕ
left✝ : Results a a✝ n
right✝ : Nat.zero = n + 1
⊢ think a = thinkN (pure a✝) Nat.zero

Next tactic:
contradiction