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

tactic: induction h
state_before: f : ℕ →. ℕ
h : Partrec f
⊢ ∃ c, eval c = f

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

case succ
f : ℕ →. ℕ
⊢ ∃ c, eval c = ↑Nat.succ

case left
f : ℕ →. ℕ
⊢ ∃ c, eval c = ↑fun n => (unpair n).fst

case right
f : ℕ →. ℕ
⊢ ∃ c, eval c = ↑fun n => (unpair n).snd

case pair
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c, eval c = fun n => Seq.seq (Nat.pair <$> f✝ n) fun x => g✝ n

case comp
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c, eval c = fun n => g✝ n >>= f✝

case prec
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c,
    eval c =
      unpaired fun a n =>
        Nat.rec (f✝ a)
          (fun y IH => do
            let i ← IH
            g✝ (Nat.pair a (Nat.pair y i)))
          n

case rfind
f f✝ : ℕ →. ℕ
a✝ : Partrec f✝
a_ih✝ : ∃ c, eval c = f✝
⊢ ∃ c, eval c = fun a => Nat.rfind fun n => (fun m => decide (m = 0)) <$> f✝ (Nat.pair a n)

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

case left
f : ℕ →. ℕ
⊢ ∃ c, eval c = ↑fun n => (unpair n).fst

case right
f : ℕ →. ℕ
⊢ ∃ c, eval c = ↑fun n => (unpair n).snd

case pair
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c, eval c = fun n => Seq.seq (Nat.pair <$> f✝ n) fun x => g✝ n

case comp
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c, eval c = fun n => g✝ n >>= f✝

case prec
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c,
    eval c =
      unpaired fun a n =>
        Nat.rec (f✝ a)
          (fun y IH => do
            let i ← IH
            g✝ (Nat.pair a (Nat.pair y i)))
          n

case rfind
f f✝ : ℕ →. ℕ
a✝ : Partrec f✝
a_ih✝ : ∃ c, eval c = f✝
⊢ ∃ c, eval c = fun a => Nat.rfind fun n => (fun m => decide (m = 0)) <$> f✝ (Nat.pair a n)

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

case right
f : ℕ →. ℕ
⊢ ∃ c, eval c = ↑fun n => (unpair n).snd

case pair
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c, eval c = fun n => Seq.seq (Nat.pair <$> f✝ n) fun x => g✝ n

case comp
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c, eval c = fun n => g✝ n >>= f✝

case prec
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c,
    eval c =
      unpaired fun a n =>
        Nat.rec (f✝ a)
          (fun y IH => do
            let i ← IH
            g✝ (Nat.pair a (Nat.pair y i)))
          n

case rfind
f f✝ : ℕ →. ℕ
a✝ : Partrec f✝
a_ih✝ : ∃ c, eval c = f✝
⊢ ∃ c, eval c = fun a => Nat.rfind fun n => (fun m => decide (m = 0)) <$> f✝ (Nat.pair a n)

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

case pair
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c, eval c = fun n => Seq.seq (Nat.pair <$> f✝ n) fun x => g✝ n

case comp
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c, eval c = fun n => g✝ n >>= f✝

case prec
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c,
    eval c =
      unpaired fun a n =>
        Nat.rec (f✝ a)
          (fun y IH => do
            let i ← IH
            g✝ (Nat.pair a (Nat.pair y i)))
          n

case rfind
f f✝ : ℕ →. ℕ
a✝ : Partrec f✝
a_ih✝ : ∃ c, eval c = f✝
⊢ ∃ c, eval c = fun a => Nat.rfind fun n => (fun m => decide (m = 0)) <$> f✝ (Nat.pair a n)

tactic: case pair f g pf pg hf hg =>
  rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
  exact ⟨pair cf cg, rfl⟩
state_before: case pair
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c, eval c = fun n => Seq.seq (Nat.pair <$> f✝ n) fun x => g✝ n

case comp
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c, eval c = fun n => g✝ n >>= f✝

case prec
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c,
    eval c =
      unpaired fun a n =>
        Nat.rec (f✝ a)
          (fun y IH => do
            let i ← IH
            g✝ (Nat.pair a (Nat.pair y i)))
          n

case rfind
f f✝ : ℕ →. ℕ
a✝ : Partrec f✝
a_ih✝ : ∃ c, eval c = f✝
⊢ ∃ c, eval c = fun a => Nat.rfind fun n => (fun m => decide (m = 0)) <$> f✝ (Nat.pair a n)

tactic: case comp f g pf pg hf hg =>
  rcases hf with ⟨cf, rfl⟩; rcases hg with ⟨cg, rfl⟩
  exact ⟨comp cf cg, rfl⟩
state_before: case comp
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c, eval c = fun n => g✝ n >>= f✝

case prec
f f✝ g✝ : ℕ →. ℕ
a✝¹ : Partrec f✝
a✝ : Partrec g✝
a_ih✝¹ : ∃ c, eval c = f✝
a_ih✝ : ∃ c, eval c = g✝
⊢ ∃ c,
    eval c =
      unpaired fun a n =>
        Nat.rec (f✝ a)
          (fun y IH => do
            let i ← IH
            g✝ (Nat.pair a (Nat.pair y i)))
          n

case rfind
f f✝ : ℕ →. ℕ
a✝ : Partrec f✝
a_ih✝ : ∃ c, eval c = f✝
⊢ ∃ c, eval c = fun a => Nat.rfind fun n => (fun m => decide (m = 0)) <$> f✝ (Nat.pair a n)

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

case rfind
f f✝ : ℕ →. ℕ
a✝ : Partrec f✝
a_ih✝ : ∃ c, eval c = f✝
⊢ ∃ c, eval c = fun a => Nat.rfind fun n => (fun m => decide (m = 0)) <$> f✝ (Nat.pair a n)

tactic: case rfind f 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 rfind
f f✝ : ℕ →. ℕ
a✝ : Partrec f✝
a_ih✝ : ∃ c, eval c = f✝
⊢ ∃ c, eval c = fun a => Nat.rfind fun n => (fun m => decide (m = 0)) <$> f✝ (Nat.pair a n)

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

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

tactic: exact ⟨left, rfl⟩
state_before: f : ℕ →. ℕ
⊢ ∃ c, eval c = ↑fun n => (unpair n).fst

tactic: exact ⟨right, rfl⟩
state_before: f : ℕ →. ℕ
⊢ ∃ c, eval c = ↑fun n => (unpair n).snd

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

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

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

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

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

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

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

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

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

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

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

tactic: rcases h with ⟨c, rfl⟩
state_before: f : ℕ →. ℕ
h : ∃ c, eval c = f
⊢ Partrec f

tactic: induction c
state_before: case intro
c : Code
⊢ Partrec (eval c)

tactic: case zero => exact Nat.Partrec.zero
state_before: case intro.zero

⊢ Partrec (eval zero)

case intro.succ

⊢ Partrec (eval succ)

case intro.left

⊢ Partrec (eval left)

case intro.right

⊢ Partrec (eval right)

case intro.pair
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (pair a✝¹ a✝))

case intro.comp
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (comp a✝¹ a✝))

case intro.prec
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (prec a✝¹ a✝))

case intro.rfind'
a✝ : Code
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (rfind' a✝))

tactic: case succ => exact Nat.Partrec.succ
state_before: case intro.succ

⊢ Partrec (eval succ)

case intro.left

⊢ Partrec (eval left)

case intro.right

⊢ Partrec (eval right)

case intro.pair
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (pair a✝¹ a✝))

case intro.comp
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (comp a✝¹ a✝))

case intro.prec
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (prec a✝¹ a✝))

case intro.rfind'
a✝ : Code
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (rfind' a✝))

tactic: case left => exact Nat.Partrec.left
state_before: case intro.left

⊢ Partrec (eval left)

case intro.right

⊢ Partrec (eval right)

case intro.pair
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (pair a✝¹ a✝))

case intro.comp
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (comp a✝¹ a✝))

case intro.prec
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (prec a✝¹ a✝))

case intro.rfind'
a✝ : Code
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (rfind' a✝))

tactic: case right => exact Nat.Partrec.right
state_before: case intro.right

⊢ Partrec (eval right)

case intro.pair
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (pair a✝¹ a✝))

case intro.comp
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (comp a✝¹ a✝))

case intro.prec
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (prec a✝¹ a✝))

case intro.rfind'
a✝ : Code
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (rfind' a✝))

tactic: case pair cf cg pf pg => exact pf.pair pg
state_before: case intro.pair
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (pair a✝¹ a✝))

case intro.comp
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (comp a✝¹ a✝))

case intro.prec
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (prec a✝¹ a✝))

case intro.rfind'
a✝ : Code
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (rfind' a✝))

tactic: case comp cf cg pf pg => exact pf.comp pg
state_before: case intro.comp
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (comp a✝¹ a✝))

case intro.prec
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (prec a✝¹ a✝))

case intro.rfind'
a✝ : Code
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (rfind' a✝))

tactic: case prec cf cg pf pg => exact pf.prec pg
state_before: case intro.prec
a✝¹ a✝ : Code
a_ih✝¹ : Partrec (eval a✝¹)
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (prec a✝¹ a✝))

case intro.rfind'
a✝ : Code
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (rfind' a✝))

tactic: case rfind' cf pf => exact pf.rfind'
state_before: case intro.rfind'
a✝ : Code
a_ih✝ : Partrec (eval a✝)
⊢ Partrec (eval (rfind' a✝))

tactic: exact Nat.Partrec.zero
state_before: ⊢ Partrec (eval zero)

tactic: exact Nat.Partrec.succ
state_before: ⊢ Partrec (eval succ)

tactic: exact Nat.Partrec.left
state_before: ⊢ Partrec (eval left)

tactic: exact Nat.Partrec.right
state_before: ⊢ Partrec (eval right)

tactic: exact pf.pair pg
state_before: cf cg : Code
pf : Partrec (eval cf)
pg : Partrec (eval cg)
⊢ Partrec (eval (pair cf cg))

tactic: exact pf.comp pg
state_before: cf cg : Code
pf : Partrec (eval cf)
pg : Partrec (eval cg)
⊢ Partrec (eval (comp cf cg))

tactic: exact pf.prec pg
state_before: cf cg : Code
pf : Partrec (eval cf)
pg : Partrec (eval cg)
⊢ Partrec (eval (prec cf cg))

tactic: exact pf.rfind'
state_before: cf : Code
pf : Partrec (eval cf)
⊢ Partrec (eval (rfind' cf))