Theorem: Partrec.fix
File: Mathlib/Computability/Partrec.lean

tactic: let F : α → ℕ →. Sum σ α := fun a n =>
  n.rec (some (Sum.inr a)) fun _ IH => IH.bind fun s => Sum.casesOn s (fun _ => Part.some s) f
state_before: α : Type u_1
β : Type ?u.267253
γ : Type ?u.267256
σ : Type u_2
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α →. σ ⊕ α
hf : Partrec f
⊢ Partrec (PFun.fix f)

tactic: have hF : Partrec₂ F :=
  Partrec.nat_rec snd (sum_inr.comp fst).partrec
    (sum_casesOn_right (snd.comp snd) (snd.comp <| snd.comp fst).to₂ (hf.comp snd).to₂).to₂
state_before: α : Type u_1
β : Type ?u.267253
γ : Type ?u.267256
σ : Type u_2
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α →. σ ⊕ α
hf : Partrec f
F : α → ℕ →. σ ⊕ α :=
  fun a n =>
    Nat.rec (Part.some (Sum.inr a)) (fun x IH => Part.bind IH fun s => Sum.casesOn s (fun x => Part.some s) f) n
⊢ Partrec (PFun.fix f)

tactic: let p a n := @Part.map _ Bool (fun s => Sum.casesOn s (fun _ => true) fun _ => false) (F a n)
state_before: α : Type u_1
β : Type ?u.267253
γ : Type ?u.267256
σ : Type u_2
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α →. σ ⊕ α
hf : Partrec f
F : α → ℕ →. σ ⊕ α :=
  fun a n =>
    Nat.rec (Part.some (Sum.inr a)) (fun x IH => Part.bind IH fun s => Sum.casesOn s (fun x => Part.some s) f) n
hF : Partrec₂ F
⊢ Partrec (PFun.fix f)

tactic: have hp : Partrec₂ p :=
  hF.map ((sum_casesOn Computable.id (const true).to₂ (const false).to₂).comp snd).to₂
state_before: α : Type u_1
β : Type ?u.267253
γ : Type ?u.267256
σ : Type u_2
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α →. σ ⊕ α
hf : Partrec f
F : α → ℕ →. σ ⊕ α :=
  fun a n =>
    Nat.rec (Part.some (Sum.inr a)) (fun x IH => Part.bind IH fun s => Sum.casesOn s (fun x => Part.some s) f) n
hF : Partrec₂ F
p : α → ℕ → Part Bool := fun a n => Part.map (fun s => Sum.casesOn s (fun x => true) fun x => false) (F a n)
⊢ Partrec (PFun.fix f)

tactic: exact (hp.rfind.bind (hF.bind (sum_casesOn_right snd snd.to₂ none.to₂).to₂).to₂).of_eq fun a =>
  ext fun b => by simp; apply fix_aux f
state_before: α : Type u_1
β : Type ?u.267253
γ : Type ?u.267256
σ : Type u_2
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α →. σ ⊕ α
hf : Partrec f
F : α → ℕ →. σ ⊕ α :=
  fun a n =>
    Nat.rec (Part.some (Sum.inr a)) (fun x IH => Part.bind IH fun s => Sum.casesOn s (fun x => Part.some s) f) n
hF : Partrec₂ F
p : α → ℕ → Part Bool := fun a n => Part.map (fun s => Sum.casesOn s (fun x => true) fun x => false) (F a n)
hp : Partrec₂ p
⊢ Partrec (PFun.fix f)

tactic: simp
state_before: α : Type u_1
β : Type ?u.267253
γ : Type ?u.267256
σ : Type u_2
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α →. σ ⊕ α
hf : Partrec f
F : α → ℕ →. σ ⊕ α :=
  fun a n =>
    Nat.rec (Part.some (Sum.inr a)) (fun x IH => Part.bind IH fun s => Sum.casesOn s (fun x => Part.some s) f) n
hF : Partrec₂ F
p : α → ℕ → Part Bool := fun a n => Part.map (fun s => Sum.casesOn s (fun x => true) fun x => false) (F a n)
hp : Partrec₂ p
a : α
b : σ
⊢ (b ∈
      Part.bind (Nat.rfind (p a)) fun b =>
        Part.bind (F (a, b).fst (a, b).snd) fun b_1 =>
          Sum.casesOn ((a, b), b_1).snd (fun b_2 => Part.some (((a, b), b_1), b_2).snd) fun b => Part.none) ↔
    b ∈ PFun.fix f a

tactic: apply fix_aux f
state_before: α : Type u_1
β : Type ?u.267253
γ : Type ?u.267256
σ : Type u_2
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α →. σ ⊕ α
hf : Partrec f
F : α → ℕ →. σ ⊕ α :=
  fun a n =>
    Nat.rec (Part.some (Sum.inr a)) (fun x IH => Part.bind IH fun s => Sum.casesOn s (fun x => Part.some s) f) n
hF : Partrec₂ F
p : α → ℕ → Part Bool := fun a n => Part.map (fun s => Sum.casesOn s (fun x => true) fun x => false) (F a n)
hp : Partrec₂ p
a : α
b : σ
⊢ (∃ a_1,
      ((∃ a_2,
            Sum.inl a_2 ∈
              Nat.rec (Part.some (Sum.inr a))
                (fun x IH => Part.bind IH fun s => Sum.rec (fun val => Part.some s) (fun val => f val) s) a_1) ∧
          ∀ {m : ℕ},
            m < a_1 →
              ∃ b,
                Sum.inr b ∈
                  Nat.rec (Part.some (Sum.inr a))
                    (fun x IH => Part.bind IH fun s => Sum.rec (fun val => Part.some s) (fun val => f val) s) m) ∧
        Sum.inl b ∈
          Nat.rec (Part.some (Sum.inr a))
            (fun x IH => Part.bind IH fun s => Sum.rec (fun val => Part.some s) (fun val => f val) s) a_1) ↔
    b ∈ PFun.fix f a