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 ∈ (Nat.rfind fun n_1 => Part.some (decide (1 - f (n_1 ::ᵥ v) = 0))).bind fun a => ↑pred (f (a ::ᵥ v))) ↔
    b ∈ Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v))
state_after: n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b : ℕ
⊢ (∃ a ∈ Nat.rfind fun n_1 => Part.some (decide (1 ≤ f (n_1 ::ᵥ v))), b = (f (a ::ᵥ v)).pred) ↔
    ∃ a ∈ Nat.rfind fun n_1 => ↑(some (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome),
      ofNat (Option ℕ) (f (a ::ᵥ v)) = some b

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 ∈ Nat.rfind fun n_1 => Part.some (decide (1 ≤ f (n_1 ::ᵥ v))), b = (f (a ::ᵥ v)).pred) ↔
    ∃ a ∈ Nat.rfind fun n_1 => ↑(some (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome),
      ofNat (Option ℕ) (f (a ::ᵥ v)) = some b
state_after: 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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome))

case refine_2
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
⊢ b = (f (a ::ᵥ v)).pred ↔ 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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome))
state_after: 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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)

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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
state_after: 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 (ofNat (Option ℕ) (f (n ::ᵥ v))).isSome)

tactic: cases f (n ::ᵥ v) <;> simp [Nat.succ_le_succ] <;> rfl
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 (ofNat (Option ℕ) (f (n ::ᵥ v))).isSome)
state_after: no goals

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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
⊢ b = (f (a ::ᵥ v)).pred ↔ ofNat (Option ℕ) (f (a ::ᵥ v)) = some b
state_after: case refine_2
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
this : true ∈ ↑(some (ofNat (Option ℕ) (f (a ::ᵥ v))).isSome)
⊢ b = (f (a ::ᵥ v)).pred ↔ 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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
this : true ∈ ↑(some (ofNat (Option ℕ) (f (a ::ᵥ v))).isSome)
⊢ b = (f (a ::ᵥ v)).pred ↔ ofNat (Option ℕ) (f (a ::ᵥ v)) = some b
state_after: case refine_2
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
this : true = (ofNat (Option ℕ) (f (a ::ᵥ v))).isSome
⊢ b = (f (a ::ᵥ v)).pred ↔ 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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
this : true = (ofNat (Option ℕ) (f (a ::ᵥ v))).isSome
⊢ b = (f (a ::ᵥ v)).pred ↔ ofNat (Option ℕ) (f (a ::ᵥ v)) = some b
state_after: case refine_2
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
⊢ true = (ofNat (Option ℕ) (f (a ::ᵥ v))).isSome → (b = (f (a ::ᵥ v)).pred ↔ 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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
⊢ true = (ofNat (Option ℕ) (f (a ::ᵥ v))).isSome → (b = (f (a ::ᵥ v)).pred ↔ ofNat (Option ℕ) (f (a ::ᵥ v)) = some b)
state_after: 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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
this : true = (ofNat (Option ℕ) 0).isSome
⊢ b = pred 0 ↔ ofNat (Option ℕ) 0 = some b

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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
c : ℕ
this : true = (ofNat (Option ℕ) (c + 1)).isSome
⊢ b = (c + 1).pred ↔ ofNat (Option ℕ) (c + 1) = 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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
c : ℕ
this : true = (ofNat (Option ℕ) (c + 1)).isSome
⊢ b = (c + 1).pred ↔ ofNat (Option ℕ) (c + 1) = some b
state_after: 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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
c : ℕ
this : true = (ofNat (Option ℕ) (c + 1)).isSome
⊢ some (c + 1).pred = some b ↔ ofNat (Option ℕ) (c + 1) = 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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
c : ℕ
this : true = (ofNat (Option ℕ) (c + 1)).isSome
⊢ some (c + 1).pred = some b ↔ ofNat (Option ℕ) (c + 1) = some b
state_after: no goals

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 (ofNat (Option ℕ) (f (n_1 ::ᵥ v))).isSome)
this : true = (ofNat (Option ℕ) 0).isSome
⊢ b = pred 0 ↔ ofNat (Option ℕ) 0 = some b
state_after: no goals