Theorem: Nat.Partrec'.rfindOpt
File: Mathlib/Computability/Halting.lean

tactic: simp only [Nat.rfindOpt, exists_prop, tsub_eq_zero_iff_le, PFun.coe_val, Part.mem_bind_iff,
  Part.mem_some_iff, Option.mem_def, Part.mem_coe]
state_before: n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b : ℕ
⊢ (b ∈ Part.bind (Nat.rfind fun n_1 => Part.some (decide (1 - f (n_1 ::ᵥ v) = 0))) fun a => ↑pred (f (a ::ᵥ v))) ↔
    b ∈ Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v))

tactic: refine'
  exists_congr fun a => (and_congr (iff_of_eq _) Iff.rfl).trans (and_congr_right fun h => _)
state_before: n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b : ℕ
⊢ (∃ a, (a ∈ Nat.rfind fun n_1 => Part.some (decide (1 ≤ f (n_1 ::ᵥ v)))) ∧ b = pred (f (a ::ᵥ v))) ↔
    ∃ a,
      (a ∈ Nat.rfind fun n_1 => ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))) ∧
        ofNat (Option ℕ) (f (a ::ᵥ v)) = some b

tactic: congr
state_before: case refine'_1
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
⊢ (a ∈ Nat.rfind fun n_1 => Part.some (decide (1 ≤ f (n_1 ::ᵥ v)))) =
    (a ∈ Nat.rfind fun n_1 => ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v))))))

tactic: funext n
state_before: case refine'_1.e_a.e_p
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
⊢ (fun n_1 => Part.some (decide (1 ≤ f (n_1 ::ᵥ v)))) = fun n_1 =>
    ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))

tactic: simp only [Part.some_inj, PFun.coe_val]
state_before: case refine'_1.e_a.e_p.h
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n✝
b a n : ℕ
⊢ Part.some (decide (1 ≤ f (n ::ᵥ v))) = ↑(some (Option.isSome (ofNat (Option ℕ) (f (n ::ᵥ v)))))

tactic: cases f (n ::ᵥ v) <;> simp [Nat.succ_le_succ]
state_before: case refine'_1.e_a.e_p.h
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n✝
b a n : ℕ
⊢ Part.some (decide (1 ≤ f (n ::ᵥ v))) = ↑(some (Option.isSome (ofNat (Option ℕ) (f (n ::ᵥ v)))))

tactic: rfl
state_before: case refine'_1.e_a.e_p.h.succ
n✝¹ : ℕ
f : Vector ℕ (n✝¹ + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n✝¹
b a n n✝ : ℕ
⊢ true = Option.isSome (ofNat (Option ℕ) (succ n✝))

tactic: have := Nat.rfind_spec h
state_before: case refine'_2
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
⊢ b = pred (f (a ::ᵥ v)) ↔ ofNat (Option ℕ) (f (a ::ᵥ v)) = some b

tactic: simp only [Part.coe_some, Part.mem_some_iff] at this
state_before: case refine'_2
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
this : true ∈ ↑(some (Option.isSome (ofNat (Option ℕ) (f (a ::ᵥ v)))))
⊢ b = pred (f (a ::ᵥ v)) ↔ ofNat (Option ℕ) (f (a ::ᵥ v)) = some b

tactic: revert this
state_before: case refine'_2
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
this : true = Option.isSome (ofNat (Option ℕ) (f (a ::ᵥ v)))
⊢ b = pred (f (a ::ᵥ v)) ↔ ofNat (Option ℕ) (f (a ::ᵥ v)) = some b

tactic: cases' f (a ::ᵥ v) with c <;> intro this
state_before: case refine'_2
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
⊢ true = Option.isSome (ofNat (Option ℕ) (f (a ::ᵥ v))) →
    (b = pred (f (a ::ᵥ v)) ↔ ofNat (Option ℕ) (f (a ::ᵥ v)) = some b)

tactic: rw [← Option.some_inj, eq_comm]
state_before: case refine'_2.succ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
c : ℕ
this : true = Option.isSome (ofNat (Option ℕ) (succ c))
⊢ b = pred (succ c) ↔ ofNat (Option ℕ) (succ c) = some b

tactic: rfl
state_before: case refine'_2.succ
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
c : ℕ
this : true = Option.isSome (ofNat (Option ℕ) (succ c))
⊢ some (pred (succ c)) = some b ↔ ofNat (Option ℕ) (succ c) = some b

tactic: cases this
state_before: case refine'_2.zero
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
this : true = Option.isSome (ofNat (Option ℕ) zero)
⊢ b = pred zero ↔ ofNat (Option ℕ) zero = some b