Theorem: Nat.Partrec.Code.exists_code
File: Mathlib/Computability/PartrecCode.lean

tactic: refine ⟨fun h => ?_, ?_⟩
state_before: f : ℕ →. ℕ
⊢ Partrec f ↔ ∃ c, c.eval = f
state_after: case refine_1
f : ℕ →. ℕ
h : Partrec f
⊢ ∃ c, c.eval = f

case refine_2
f : ℕ →. ℕ
⊢ (∃ c, c.eval = f) → Partrec f

tactic: induction h with
| zero => exact ⟨zero, rfl⟩
| succ => exact ⟨succ, rfl⟩
| left => exact ⟨left, rfl⟩
| right => exact ⟨right, rfl⟩
| pair pf pg hf hg =>
  rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
  exact ⟨pair cf cg, rfl⟩
| comp pf pg hf hg =>
  rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
  exact ⟨comp cf cg, rfl⟩
| prec pf pg hf hg =>
  rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
  exact ⟨prec cf cg, rfl⟩
| rfind pf hf =>
  rcases hf with ⟨cf, rfl⟩
  refine ⟨comp (rfind' cf) (pair Code.id zero), ?_⟩
  simp [eval, Seq.seq, pure, PFun.pure, Part.map_id']
state_before: case refine_1
f : ℕ →. ℕ
h : Partrec f
⊢ ∃ c, c.eval = f
state_after: no goals

tactic: exact ⟨zero, rfl⟩
state_before: case refine_1.zero
f : ℕ →. ℕ
⊢ ∃ c, c.eval = pure 0
state_after: no goals

tactic: exact ⟨succ, rfl⟩
state_before: case refine_1.succ
f : ℕ →. ℕ
⊢ ∃ c, c.eval = ↑Nat.succ
state_after: no goals

tactic: exact ⟨left, rfl⟩
state_before: case refine_1.left
f : ℕ →. ℕ
⊢ ∃ c, c.eval = ↑fun n => (unpair n).1
state_after: no goals

tactic: exact ⟨right, rfl⟩
state_before: case refine_1.right
f : ℕ →. ℕ
⊢ ∃ c, c.eval = ↑fun n => (unpair n).2
state_after: no goals

tactic: rcases hf with ⟨cf, rfl⟩
state_before: case refine_1.pair
f f✝ g✝ : ℕ →. ℕ
pf : Partrec f✝
pg : Partrec g✝
hf : ∃ c, c.eval = f✝
hg : ∃ c, c.eval = g✝
⊢ ∃ c, c.eval = fun n => Seq.seq (Nat.pair <$> f✝ n) fun x => g✝ n
state_after: case refine_1.pair.intro
f g✝ : ℕ →. ℕ
pg : Partrec g✝
hg : ∃ c, c.eval = g✝
cf : Code
pf : Partrec cf.eval
⊢ ∃ c, c.eval = fun n => Seq.seq (Nat.pair <$> cf.eval n) fun x => g✝ n

tactic: rcases hg with ⟨cg, rfl⟩
state_before: case refine_1.pair.intro
f g✝ : ℕ →. ℕ
pg : Partrec g✝
hg : ∃ c, c.eval = g✝
cf : Code
pf : Partrec cf.eval
⊢ ∃ c, c.eval = fun n => Seq.seq (Nat.pair <$> cf.eval n) fun x => g✝ n
state_after: case refine_1.pair.intro.intro
f : ℕ →. ℕ
cf : Code
pf : Partrec cf.eval
cg : Code
pg : Partrec cg.eval
⊢ ∃ c, c.eval = fun n => Seq.seq (Nat.pair <$> cf.eval n) fun x => cg.eval n

tactic: exact ⟨pair cf cg, rfl⟩
state_before: case refine_1.pair.intro.intro
f : ℕ →. ℕ
cf : Code
pf : Partrec cf.eval
cg : Code
pg : Partrec cg.eval
⊢ ∃ c, c.eval = fun n => Seq.seq (Nat.pair <$> cf.eval n) fun x => cg.eval n
state_after: no goals

tactic: rcases hf with ⟨cf, rfl⟩
state_before: case refine_1.comp
f f✝ g✝ : ℕ →. ℕ
pf : Partrec f✝
pg : Partrec g✝
hf : ∃ c, c.eval = f✝
hg : ∃ c, c.eval = g✝
⊢ ∃ c, c.eval = fun n => g✝ n >>= f✝
state_after: case refine_1.comp.intro
f g✝ : ℕ →. ℕ
pg : Partrec g✝
hg : ∃ c, c.eval = g✝
cf : Code
pf : Partrec cf.eval
⊢ ∃ c, c.eval = fun n => g✝ n >>= cf.eval

tactic: rcases hg with ⟨cg, rfl⟩
state_before: case refine_1.comp.intro
f g✝ : ℕ →. ℕ
pg : Partrec g✝
hg : ∃ c, c.eval = g✝
cf : Code
pf : Partrec cf.eval
⊢ ∃ c, c.eval = fun n => g✝ n >>= cf.eval
state_after: case refine_1.comp.intro.intro
f : ℕ →. ℕ
cf : Code
pf : Partrec cf.eval
cg : Code
pg : Partrec cg.eval
⊢ ∃ c, c.eval = fun n => cg.eval n >>= cf.eval

tactic: exact ⟨comp cf cg, rfl⟩
state_before: case refine_1.comp.intro.intro
f : ℕ →. ℕ
cf : Code
pf : Partrec cf.eval
cg : Code
pg : Partrec cg.eval
⊢ ∃ c, c.eval = fun n => cg.eval n >>= cf.eval
state_after: no goals

tactic: rcases hf with ⟨cf, rfl⟩
state_before: case refine_1.prec
f f✝ g✝ : ℕ →. ℕ
pf : Partrec f✝
pg : Partrec g✝
hf : ∃ c, c.eval = f✝
hg : ∃ c, c.eval = g✝
⊢ ∃ c,
    c.eval =
      unpaired fun a n =>
        Nat.rec (f✝ a)
          (fun y IH => do
            let i ← IH
            g✝ (Nat.pair a (Nat.pair y i)))
          n
state_after: case refine_1.prec.intro
f g✝ : ℕ →. ℕ
pg : Partrec g✝
hg : ∃ c, c.eval = g✝
cf : Code
pf : Partrec cf.eval
⊢ ∃ c,
    c.eval =
      unpaired fun a n =>
        Nat.rec (cf.eval a)
          (fun y IH => do
            let i ← IH
            g✝ (Nat.pair a (Nat.pair y i)))
          n

tactic: rcases hg with ⟨cg, rfl⟩
state_before: case refine_1.prec.intro
f g✝ : ℕ →. ℕ
pg : Partrec g✝
hg : ∃ c, c.eval = g✝
cf : Code
pf : Partrec cf.eval
⊢ ∃ c,
    c.eval =
      unpaired fun a n =>
        Nat.rec (cf.eval a)
          (fun y IH => do
            let i ← IH
            g✝ (Nat.pair a (Nat.pair y i)))
          n
state_after: case refine_1.prec.intro.intro
f : ℕ →. ℕ
cf : Code
pf : Partrec cf.eval
cg : Code
pg : Partrec cg.eval
⊢ ∃ c,
    c.eval =
      unpaired fun a n =>
        Nat.rec (cf.eval a)
          (fun y IH => do
            let i ← IH
            cg.eval (Nat.pair a (Nat.pair y i)))
          n

tactic: exact ⟨prec cf cg, rfl⟩
state_before: case refine_1.prec.intro.intro
f : ℕ →. ℕ
cf : Code
pf : Partrec cf.eval
cg : Code
pg : Partrec cg.eval
⊢ ∃ c,
    c.eval =
      unpaired fun a n =>
        Nat.rec (cf.eval a)
          (fun y IH => do
            let i ← IH
            cg.eval (Nat.pair a (Nat.pair y i)))
          n
state_after: no goals

tactic: rcases hf with ⟨cf, rfl⟩
state_before: case refine_1.rfind
f f✝ : ℕ →. ℕ
pf : Partrec f✝
hf : ∃ c, c.eval = f✝
⊢ ∃ c, c.eval = fun a => Nat.rfind fun n => (fun m => decide (m = 0)) <$> f✝ (Nat.pair a n)
state_after: case refine_1.rfind.intro
f : ℕ →. ℕ
cf : Code
pf : Partrec cf.eval
⊢ ∃ c, c.eval = fun a => Nat.rfind fun n => (fun m => decide (m = 0)) <$> cf.eval (Nat.pair a n)

tactic: refine ⟨comp (rfind' cf) (pair Code.id zero), ?_⟩
state_before: case refine_1.rfind.intro
f : ℕ →. ℕ
cf : Code
pf : Partrec cf.eval
⊢ ∃ c, c.eval = fun a => Nat.rfind fun n => (fun m => decide (m = 0)) <$> cf.eval (Nat.pair a n)
state_after: case refine_1.rfind.intro
f : ℕ →. ℕ
cf : Code
pf : Partrec cf.eval
⊢ (cf.rfind'.comp (Code.id.pair zero)).eval = fun a =>
    Nat.rfind fun n => (fun m => decide (m = 0)) <$> cf.eval (Nat.pair a n)

tactic: simp [eval, Seq.seq, pure, PFun.pure, Part.map_id']
state_before: case refine_1.rfind.intro
f : ℕ →. ℕ
cf : Code
pf : Partrec cf.eval
⊢ (cf.rfind'.comp (Code.id.pair zero)).eval = fun a =>
    Nat.rfind fun n => (fun m => decide (m = 0)) <$> cf.eval (Nat.pair a n)
state_after: no goals

tactic: rintro ⟨c, rfl⟩
state_before: case refine_2
f : ℕ →. ℕ
⊢ (∃ c, c.eval = f) → Partrec f
state_after: case refine_2.intro
c : Code
⊢ Partrec c.eval

tactic: induction c with
| zero => exact Nat.Partrec.zero
| succ => exact Nat.Partrec.succ
| left => exact Nat.Partrec.left
| right => exact Nat.Partrec.right
| pair cf cg pf pg => exact pf.pair pg
| comp cf cg pf pg => exact pf.comp pg
| prec cf cg pf pg => exact pf.prec pg
| rfind' cf pf => exact pf.rfind'
state_before: case refine_2.intro
c : Code
⊢ Partrec c.eval
state_after: no goals

tactic: exact Nat.Partrec.zero
state_before: case refine_2.intro.zero

⊢ Partrec zero.eval
state_after: no goals

tactic: exact Nat.Partrec.succ
state_before: case refine_2.intro.succ

⊢ Partrec succ.eval
state_after: no goals

tactic: exact Nat.Partrec.left
state_before: case refine_2.intro.left

⊢ Partrec left.eval
state_after: no goals

tactic: exact Nat.Partrec.right
state_before: case refine_2.intro.right

⊢ Partrec right.eval
state_after: no goals

tactic: exact pf.pair pg
state_before: case refine_2.intro.pair
cf cg : Code
pf : Partrec cf.eval
pg : Partrec cg.eval
⊢ Partrec (cf.pair cg).eval
state_after: no goals

tactic: exact pf.comp pg
state_before: case refine_2.intro.comp
cf cg : Code
pf : Partrec cf.eval
pg : Partrec cg.eval
⊢ Partrec (cf.comp cg).eval
state_after: no goals

tactic: exact pf.prec pg
state_before: case refine_2.intro.prec
cf cg : Code
pf : Partrec cf.eval
pg : Partrec cg.eval
⊢ Partrec (cf.prec cg).eval
state_after: no goals

tactic: exact pf.rfind'
state_before: case refine_2.intro.rfind'
cf : Code
pf : Partrec cf.eval
⊢ Partrec cf.rfind'.eval
state_after: no goals