l3lab/ntp-mathlib huggingface dataset:
theorem of_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) : Partrec f := by
  induction hf with
  | zero => exact zero
  | succ => exact succ
  | left => exact left
  | right => exact right
  | pair _ _ pf pg =>
    refine' (pf.pair pg).of_eq_tot fun n => _
    simp [Seq.seq]
  | comp _ _ pf pg =>
    refine' (pf.comp pg).of_eq_tot fun n => _
    simp
  | prec _ _ pf pg =>
    refine' (pf.prec pg).of_eq_tot fun n => _
    simp only [unpaired, PFun.coe_val, bind_eq_bind]
    induction n.unpair.2 with
    | zero => 

Proof state:
case prec.zero
f f✝ g✝ : ℕ → ℕ
a✝¹ : Nat.Primrec f✝
a✝ : Nat.Primrec g✝
pf : Partrec ↑f✝
pg : Partrec ↑g✝
n : ℕ
⊢ Nat.rec (f✝ (unpair n).1) (fun y IH => g✝ (Nat.pair (unpair n).1 (Nat.pair y IH))) Nat.zero ∈
    Nat.rec (Part.some (f✝ (unpair n).1))
      (fun y IH => Part.bind IH fun i => Part.some (g✝ (Nat.pair (unpair n).1 (Nat.pair y i)))) Nat.zero

Next tactic:
simp
theorem of_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) : Partrec f := by
  induction hf with
  | zero => exact zero
  | succ => exact succ
  | left => exact left
  | right => exact right
  | pair _ _ pf pg =>
    refine' (pf.pair pg).of_eq_tot fun n => _
    simp [Seq.seq]
  | comp _ _ pf pg =>
    refine' (pf.comp pg).of_eq_tot fun n => _
    simp
  | prec _ _ pf pg =>
    refine' (pf.prec pg).of_eq_tot fun n => _
    simp only [unpaired, PFun.coe_val, bind_eq_bind]
    induction n.unpair.2 with
    | zero => simp
    

Proof state:
case prec.succ
f f✝ g✝ : ℕ → ℕ
a✝¹ : Nat.Primrec f✝
a✝ : Nat.Primrec g✝
pf : Partrec ↑f✝
pg : Partrec ↑g✝
n m : ℕ
IH :
  Nat.rec (f✝ (unpair n).1) (fun y IH => g✝ (Nat.pair (unpair n).1 (Nat.pair y IH))) m ∈
    Nat.rec (Part.some (f✝ (unpair n).1))
      (fun y IH => Part.bind IH fun i => Part.some (g✝ (Nat.pair (unpair n).1 (Nat.pair y i)))) m
⊢ Nat.rec (f✝ (unpair n).1) (fun y IH => g✝ (Nat.pair (unpair n).1 (Nat.pair y IH))) (Nat.succ m) ∈
    Nat.rec (Part.some (f✝ (unpair n).1))
      (fun y IH => Part.bind IH fun i => Part.some (g✝ (Nat.pair (unpair n).1 (Nat.pair y i)))) (Nat.succ m)

Next tactic:
| succ m IH =>
      simp only [mem_bind_iff, mem_some_iff]
      exact ⟨_, IH, rfl⟩
theorem of_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) : Partrec f := by
  induction hf with
  | zero => exact zero
  | succ => exact succ
  | left => exact left
  | right => exact right
  | pair _ _ pf pg =>
    refine' (pf.pair pg).of_eq_tot fun n => _
    simp [Seq.seq]
  | comp _ _ pf pg =>
    refine' (pf.comp pg).of_eq_tot fun n => _
    simp
  | prec _ _ pf pg =>
    refine' (pf.prec pg).of_eq_tot fun n => _
    simp only [unpaired, PFun.coe_val, bind_eq_bind]
    induction n.unpair.2 with
    | zero => simp
    | succ m IH =>
      

Proof state:
case prec.succ
f f✝ g✝ : ℕ → ℕ
a✝¹ : Nat.Primrec f✝
a✝ : Nat.Primrec g✝
pf : Partrec ↑f✝
pg : Partrec ↑g✝
n m : ℕ
IH :
  Nat.rec (f✝ (unpair n).1) (fun y IH => g✝ (Nat.pair (unpair n).1 (Nat.pair y IH))) m ∈
    Nat.rec (Part.some (f✝ (unpair n).1))
      (fun y IH => Part.bind IH fun i => Part.some (g✝ (Nat.pair (unpair n).1 (Nat.pair y i)))) m
⊢ Nat.rec (f✝ (unpair n).1) (fun y IH => g✝ (Nat.pair (unpair n).1 (Nat.pair y IH))) (Nat.succ m) ∈
    Nat.rec (Part.some (f✝ (unpair n).1))
      (fun y IH => Part.bind IH fun i => Part.some (g✝ (Nat.pair (unpair n).1 (Nat.pair y i)))) (Nat.succ m)

Next tactic:
simp only [mem_bind_iff, mem_some_iff]
theorem of_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) : Partrec f := by
  induction hf with
  | zero => exact zero
  | succ => exact succ
  | left => exact left
  | right => exact right
  | pair _ _ pf pg =>
    refine' (pf.pair pg).of_eq_tot fun n => _
    simp [Seq.seq]
  | comp _ _ pf pg =>
    refine' (pf.comp pg).of_eq_tot fun n => _
    simp
  | prec _ _ pf pg =>
    refine' (pf.prec pg).of_eq_tot fun n => _
    simp only [unpaired, PFun.coe_val, bind_eq_bind]
    induction n.unpair.2 with
    | zero => simp
    | succ m IH =>
      simp only [mem_bind_iff, mem_some_iff]
      

Proof state:
case prec.succ
f f✝ g✝ : ℕ → ℕ
a✝¹ : Nat.Primrec f✝
a✝ : Nat.Primrec g✝
pf : Partrec ↑f✝
pg : Partrec ↑g✝
n m : ℕ
IH :
  Nat.rec (f✝ (unpair n).1) (fun y IH => g✝ (Nat.pair (unpair n).1 (Nat.pair y IH))) m ∈
    Nat.rec (Part.some (f✝ (unpair n).1))
      (fun y IH => Part.bind IH fun i => Part.some (g✝ (Nat.pair (unpair n).1 (Nat.pair y i)))) m
⊢ ∃
    a ∈
      Nat.rec (Part.some (f✝ (unpair n).1))
        (fun y IH => Part.bind IH fun i => Part.some (g✝ (Nat.pair (unpair n).1 (Nat.pair y i)))) m,
    g✝
        (Nat.pair (unpair n).1
          (Nat.pair m (Nat.rec (f✝ (unpair n).1) (fun y IH => g✝ (Nat.pair (unpair n).1 (Nat.pair y IH))) m))) =
      g✝ (Nat.pair (unpair n).1 (Nat.pair m a))

Next tactic:
exact ⟨_, IH, rfl⟩
theorem none : Partrec fun _ => none :=
  (of_primrec (Nat.Primrec.const 1)).rfind.of_eq fun n =>
    eq_none_iff.2 fun a ⟨h, _⟩ => by 

Proof state:
n a : ℕ
x✝ : a ∈ Nat.rfind fun n_1 => (fun m => decide (m = 0)) <$> (↑fun x => 1) (Nat.pair n n_1)
h : (Nat.rfind fun n_1 => (fun m => decide (m = 0)) <$> (↑fun x => 1) (Nat.pair n n_1)).Dom
h✝ : Part.get (Nat.rfind fun n_1 => (fun m => decide (m = 0)) <$> (↑fun x => 1) (Nat.pair n n_1)) h = a
⊢ False

Next tactic:
simp at h
theorem prec' {f g h} (hf : Partrec f) (hg : Partrec g) (hh : Partrec h) :
    Partrec fun a => (f a).bind fun n => n.rec (g a)
      fun y IH => do {let i ← IH; h (Nat.pair a (Nat.pair y i))} :=
  ((prec hg hh).comp (pair Partrec.some hf)).of_eq fun a =>
    ext fun s => by 

Proof state:
f g h : ℕ →. ℕ
hf : Partrec f
hg : Partrec g
hh : Partrec h
a s : ℕ
⊢ (s ∈
      (Seq.seq (Nat.pair <$> Part.some a) fun x => f a) >>=
        unpaired fun a n =>
          Nat.rec (g a)
            (fun y IH => do
              let i ← IH
              h (Nat.pair a (Nat.pair y i)))
            n) ↔
    s ∈
      Part.bind (f a) fun n =>
        Nat.rec (g a)
          (fun y IH => do
            let i ← IH
            h (Nat.pair a (Nat.pair y i)))
          n

Next tactic:
simp [Seq.seq]
theorem ppred : Partrec fun n => ppred n :=
  have : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1 :=
    (Primrec.ite
      (@PrimrecRel.comp _ _ _ _ _ _ _ _ _ _
        Primrec.eq Primrec.fst (_root_.Primrec.succ.comp Primrec.snd))
      (_root_.Primrec.const 0) (_root_.Primrec.const 1)).to₂
  (of_primrec (Primrec₂.unpaired'.2 this)).rfind.of_eq fun n => by
    

Proof state:
this : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1
n : ℕ
⊢ (Nat.rfind fun n_1 =>
      (fun m => decide (m = 0)) <$> ↑(unpaired fun n m => if n = Nat.succ m then 0 else 1) (Nat.pair n n_1)) =
    ↑(Nat.ppred n)

Next tactic:
cases n
theorem ppred : Partrec fun n => ppred n :=
  have : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1 :=
    (Primrec.ite
      (@PrimrecRel.comp _ _ _ _ _ _ _ _ _ _
        Primrec.eq Primrec.fst (_root_.Primrec.succ.comp Primrec.snd))
      (_root_.Primrec.const 0) (_root_.Primrec.const 1)).to₂
  (of_primrec (Primrec₂.unpaired'.2 this)).rfind.of_eq fun n => by
    cases n <;> 

Proof state:
case zero
this : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1
⊢ (Nat.rfind fun n =>
      (fun m => decide (m = 0)) <$> ↑(unpaired fun n m => if n = Nat.succ m then 0 else 1) (Nat.pair Nat.zero n)) =
    ↑(Nat.ppred Nat.zero)

Next tactic:
simp
theorem ppred : Partrec fun n => ppred n :=
  have : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1 :=
    (Primrec.ite
      (@PrimrecRel.comp _ _ _ _ _ _ _ _ _ _
        Primrec.eq Primrec.fst (_root_.Primrec.succ.comp Primrec.snd))
      (_root_.Primrec.const 0) (_root_.Primrec.const 1)).to₂
  (of_primrec (Primrec₂.unpaired'.2 this)).rfind.of_eq fun n => by
    cases n <;> 

Proof state:
case succ
this : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1
n✝ : ℕ
⊢ (Nat.rfind fun n =>
      (fun m => decide (m = 0)) <$> ↑(unpaired fun n m => if n = Nat.succ m then 0 else 1) (Nat.pair (Nat.succ n✝) n)) =
    ↑(Nat.ppred (Nat.succ n✝))

Next tactic:
simp
theorem ppred : Partrec fun n => ppred n :=
  have : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1 :=
    (Primrec.ite
      (@PrimrecRel.comp _ _ _ _ _ _ _ _ _ _
        Primrec.eq Primrec.fst (_root_.Primrec.succ.comp Primrec.snd))
      (_root_.Primrec.const 0) (_root_.Primrec.const 1)).to₂
  (of_primrec (Primrec₂.unpaired'.2 this)).rfind.of_eq fun n => by
    cases n <;> simp
    · 

Proof state:
case zero
this : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1
⊢ (Nat.rfind fun n => Part.some false) = Part.none

Next tactic:
exact
        eq_none_iff.2 fun a ⟨⟨m, h, _⟩, _⟩ => by
          simp [show 0 ≠ m.succ by intro h; injection h] at h
theorem ppred : Partrec fun n => ppred n :=
  have : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1 :=
    (Primrec.ite
      (@PrimrecRel.comp _ _ _ _ _ _ _ _ _ _
        Primrec.eq Primrec.fst (_root_.Primrec.succ.comp Primrec.snd))
      (_root_.Primrec.const 0) (_root_.Primrec.const 1)).to₂
  (of_primrec (Primrec₂.unpaired'.2 this)).rfind.of_eq fun n => by
    cases n <;> simp
    · exact
        eq_none_iff.2 fun a ⟨⟨m, h, _⟩, _⟩ => by
          

Proof state:
this : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1
a : ℕ
x✝ : a ∈ Nat.rfind fun n => Part.some false
m : ℕ
h : true ∈ (fun n => Part.some false) m
right✝ : ∀ k < m, ((fun n => Part.some false) k).Dom
h✝ :
  Part.get (Nat.rfind fun n => Part.some false)
      (_ : ∃ n, true ∈ (fun n => Part.some false) n ∧ ∀ k < n, ((fun n => Part.some false) k).Dom) =
    a
⊢ False

Next tactic:
simp [show 0 ≠ m.succ by intro h; injection h] at h
theorem ppred : Partrec fun n => ppred n :=
  have : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1 :=
    (Primrec.ite
      (@PrimrecRel.comp _ _ _ _ _ _ _ _ _ _
        Primrec.eq Primrec.fst (_root_.Primrec.succ.comp Primrec.snd))
      (_root_.Primrec.const 0) (_root_.Primrec.const 1)).to₂
  (of_primrec (Primrec₂.unpaired'.2 this)).rfind.of_eq fun n => by
    cases n <;> simp
    · exact
        eq_none_iff.2 fun a ⟨⟨m, h, _⟩, _⟩ => by
          simp [show 0 ≠ m.succ by 

Proof state:
this : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1
a : ℕ
x✝ : a ∈ Nat.rfind fun n => Part.some false
m : ℕ
h : true ∈ (fun n => Part.some false) m
right✝ : ∀ k < m, ((fun n => Part.some false) k).Dom
h✝ :
  Part.get (Nat.rfind fun n => Part.some false)
      (_ : ∃ n, true ∈ (fun n => Part.some false) n ∧ ∀ k < n, ((fun n => Part.some false) k).Dom) =
    a
⊢ 0 ≠ Nat.succ m

Next tactic:
intro h
theorem ppred : Partrec fun n => ppred n :=
  have : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1 :=
    (Primrec.ite
      (@PrimrecRel.comp _ _ _ _ _ _ _ _ _ _
        Primrec.eq Primrec.fst (_root_.Primrec.succ.comp Primrec.snd))
      (_root_.Primrec.const 0) (_root_.Primrec.const 1)).to₂
  (of_primrec (Primrec₂.unpaired'.2 this)).rfind.of_eq fun n => by
    cases n <;> simp
    · exact
        eq_none_iff.2 fun a ⟨⟨m, h, _⟩, _⟩ => by
          simp [show 0 ≠ m.succ by intro h; 

Proof state:
this : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1
a : ℕ
x✝ : a ∈ Nat.rfind fun n => Part.some false
m : ℕ
h✝¹ : true ∈ (fun n => Part.some false) m
right✝ : ∀ k < m, ((fun n => Part.some false) k).Dom
h✝ :
  Part.get (Nat.rfind fun n => Part.some false)
      (_ : ∃ n, true ∈ (fun n => Part.some false) n ∧ ∀ k < n, ((fun n => Part.some false) k).Dom) =
    a
h : 0 = Nat.succ m
⊢ False

Next tactic:
injection h
theorem ppred : Partrec fun n => ppred n :=
  have : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1 :=
    (Primrec.ite
      (@PrimrecRel.comp _ _ _ _ _ _ _ _ _ _
        Primrec.eq Primrec.fst (_root_.Primrec.succ.comp Primrec.snd))
      (_root_.Primrec.const 0) (_root_.Primrec.const 1)).to₂
  (of_primrec (Primrec₂.unpaired'.2 this)).rfind.of_eq fun n => by
    cases n <;> simp
    · exact
        eq_none_iff.2 fun a ⟨⟨m, h, _⟩, _⟩ => by
          simp [show 0 ≠ m.succ by intro h; injection h] at h
    · 

Proof state:
case succ
this : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1
n✝ : ℕ
⊢ (Nat.rfind fun n => Part.some (decide (n✝ = n))) = Part.some n✝

Next tactic:
refine' eq_some_iff.2 _
theorem ppred : Partrec fun n => ppred n :=
  have : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1 :=
    (Primrec.ite
      (@PrimrecRel.comp _ _ _ _ _ _ _ _ _ _
        Primrec.eq Primrec.fst (_root_.Primrec.succ.comp Primrec.snd))
      (_root_.Primrec.const 0) (_root_.Primrec.const 1)).to₂
  (of_primrec (Primrec₂.unpaired'.2 this)).rfind.of_eq fun n => by
    cases n <;> simp
    · exact
        eq_none_iff.2 fun a ⟨⟨m, h, _⟩, _⟩ => by
          simp [show 0 ≠ m.succ by intro h; injection h] at h
    · refine' eq_some_iff.2 _
      

Proof state:
case succ
this : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1
n✝ : ℕ
⊢ n✝ ∈ Nat.rfind fun n => Part.some (decide (n✝ = n))

Next tactic:
simp only [mem_rfind, not_true, IsEmpty.forall_iff, decide_True, mem_some_iff,
        false_eq_decide_iff, true_and]
theorem ppred : Partrec fun n => ppred n :=
  have : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1 :=
    (Primrec.ite
      (@PrimrecRel.comp _ _ _ _ _ _ _ _ _ _
        Primrec.eq Primrec.fst (_root_.Primrec.succ.comp Primrec.snd))
      (_root_.Primrec.const 0) (_root_.Primrec.const 1)).to₂
  (of_primrec (Primrec₂.unpaired'.2 this)).rfind.of_eq fun n => by
    cases n <;> simp
    · exact
        eq_none_iff.2 fun a ⟨⟨m, h, _⟩, _⟩ => by
          simp [show 0 ≠ m.succ by intro h; injection h] at h
    · refine' eq_some_iff.2 _
      simp only [mem_rfind, not_true, IsEmpty.forall_iff, decide_True, mem_some_iff,
        false_eq_decide_iff, true_and]
      

Proof state:
case succ
this : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1
n✝ : ℕ
⊢ ∀ {m : ℕ}, m < n✝ → ¬n✝ = m

Next tactic:
intro m h
theorem ppred : Partrec fun n => ppred n :=
  have : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1 :=
    (Primrec.ite
      (@PrimrecRel.comp _ _ _ _ _ _ _ _ _ _
        Primrec.eq Primrec.fst (_root_.Primrec.succ.comp Primrec.snd))
      (_root_.Primrec.const 0) (_root_.Primrec.const 1)).to₂
  (of_primrec (Primrec₂.unpaired'.2 this)).rfind.of_eq fun n => by
    cases n <;> simp
    · exact
        eq_none_iff.2 fun a ⟨⟨m, h, _⟩, _⟩ => by
          simp [show 0 ≠ m.succ by intro h; injection h] at h
    · refine' eq_some_iff.2 _
      simp only [mem_rfind, not_true, IsEmpty.forall_iff, decide_True, mem_some_iff,
        false_eq_decide_iff, true_and]
      intro m h
      

Proof state:
case succ
this : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1
n✝ m : ℕ
h : m < n✝
⊢ ¬n✝ = m

Next tactic:
simp [ne_of_gt h]
theorem Primrec.to_comp {α σ} [Primcodable α] [Primcodable σ] {f : α → σ} (hf : Primrec f) :
    Computable f :=
  (Nat.Partrec.ppred.comp (Nat.Partrec.of_primrec hf)).of_eq fun n => by
    

Proof state:
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
f : α → σ
hf : Primrec f
n : ℕ
⊢ (do
      let n ← (↑fun n => encode (Option.map f (decode n))) n
      ↑(Nat.ppred n)) =
    Part.bind ↑(decode n) fun a => map encode (↑f a)

Next tactic:
simp
theorem Primrec.to_comp {α σ} [Primcodable α] [Primcodable σ] {f : α → σ} (hf : Primrec f) :
    Computable f :=
  (Nat.Partrec.ppred.comp (Nat.Partrec.of_primrec hf)).of_eq fun n => by
    simp; 

Proof state:
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
f : α → σ
hf : Primrec f
n : ℕ
⊢ ↑(Nat.ppred (encode (Option.map f (decode n)))) = Part.bind ↑(decode n) fun a => Part.some (encode (f a))

Next tactic:
cases decode (α := α) n
theorem Primrec.to_comp {α σ} [Primcodable α] [Primcodable σ] {f : α → σ} (hf : Primrec f) :
    Computable f :=
  (Nat.Partrec.ppred.comp (Nat.Partrec.of_primrec hf)).of_eq fun n => by
    simp; cases decode (α := α) n <;> 

Proof state:
case none
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
f : α → σ
hf : Primrec f
n : ℕ
⊢ ↑(Nat.ppred (encode (Option.map f Option.none))) = Part.bind ↑Option.none fun a => Part.some (encode (f a))

Next tactic:
simp
theorem Primrec.to_comp {α σ} [Primcodable α] [Primcodable σ] {f : α → σ} (hf : Primrec f) :
    Computable f :=
  (Nat.Partrec.ppred.comp (Nat.Partrec.of_primrec hf)).of_eq fun n => by
    simp; cases decode (α := α) n <;> 

Proof state:
case some
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
f : α → σ
hf : Primrec f
n : ℕ
val✝ : α
⊢ ↑(Nat.ppred (encode (Option.map f (Option.some val✝)))) =
    Part.bind ↑(Option.some val✝) fun a => Part.some (encode (f a))

Next tactic:
simp
theorem ofOption {f : α → Option β} (hf : Computable f) : Partrec fun a => (f a : Part β) :=
  (Nat.Partrec.ppred.comp hf).of_eq fun n => by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → Option β
hf : Computable f
n : ℕ
⊢ (do
      let n ← Part.bind ↑(decode n) fun a => map encode (↑f a)
      ↑(Nat.ppred n)) =
    Part.bind ↑(decode n) fun a => map encode ((fun a => ↑(f a)) a)

Next tactic:
cases' decode (α := α) n with a
theorem ofOption {f : α → Option β} (hf : Computable f) : Partrec fun a => (f a : Part β) :=
  (Nat.Partrec.ppred.comp hf).of_eq fun n => by
    cases' decode (α := α) n with a <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → Option β
hf : Computable f
n : ℕ
⊢ (do
      let n ← Part.bind ↑Option.none fun a => map encode (↑f a)
      ↑(Nat.ppred n)) =
    Part.bind ↑Option.none fun a => map encode ((fun a => ↑(f a)) a)

Next tactic:
simp
theorem ofOption {f : α → Option β} (hf : Computable f) : Partrec fun a => (f a : Part β) :=
  (Nat.Partrec.ppred.comp hf).of_eq fun n => by
    cases' decode (α := α) n with a <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → Option β
hf : Computable f
n : ℕ
a : α
⊢ (do
      let n ← Part.bind ↑(Option.some a) fun a => map encode (↑f a)
      ↑(Nat.ppred n)) =
    Part.bind ↑(Option.some a) fun a => map encode ((fun a => ↑(f a)) a)

Next tactic:
simp
theorem ofOption {f : α → Option β} (hf : Computable f) : Partrec fun a => (f a : Part β) :=
  (Nat.Partrec.ppred.comp hf).of_eq fun n => by
    cases' decode (α := α) n with a <;> simp
    

Proof state:
case some
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → Option β
hf : Computable f
n : ℕ
a : α
⊢ ↑(Nat.ppred (encode (f a))) = map encode ↑(f a)

Next tactic:
cases' f a with b
theorem ofOption {f : α → Option β} (hf : Computable f) : Partrec fun a => (f a : Part β) :=
  (Nat.Partrec.ppred.comp hf).of_eq fun n => by
    cases' decode (α := α) n with a <;> simp
    cases' f a with b <;> 

Proof state:
case some.none
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → Option β
hf : Computable f
n : ℕ
a : α
⊢ ↑(Nat.ppred (encode Option.none)) = map encode ↑Option.none

Next tactic:
simp
theorem ofOption {f : α → Option β} (hf : Computable f) : Partrec fun a => (f a : Part β) :=
  (Nat.Partrec.ppred.comp hf).of_eq fun n => by
    cases' decode (α := α) n with a <;> simp
    cases' f a with b <;> 

Proof state:
case some.some
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → Option β
hf : Computable f
n : ℕ
a : α
b : β
⊢ ↑(Nat.ppred (encode (Option.some b))) = map encode ↑(Option.some b)

Next tactic:
simp
nonrec theorem pair {f : α → β} {g : α → γ} (hf : Computable f) (hg : Computable g) :
    Computable fun a => (f a, g a) :=
  (hf.pair hg).of_eq fun n => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β
g : α → γ
hf : Computable f
hg : Computable g
n : ℕ
⊢ (Seq.seq (Nat.pair <$> Part.bind ↑(decode n) fun a => map encode (↑f a)) fun x =>
      Part.bind ↑(decode n) fun a => map encode (↑g a)) =
    Part.bind ↑(decode n) fun a => map encode ((↑fun a => (f a, g a)) a)

Next tactic:
cases decode (α := α) n
nonrec theorem pair {f : α → β} {g : α → γ} (hf : Computable f) (hg : Computable g) :
    Computable fun a => (f a, g a) :=
  (hf.pair hg).of_eq fun n => by cases decode (α := α) n <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β
g : α → γ
hf : Computable f
hg : Computable g
n : ℕ
⊢ (Seq.seq (Nat.pair <$> Part.bind ↑Option.none fun a => map encode (↑f a)) fun x =>
      Part.bind ↑Option.none fun a => map encode (↑g a)) =
    Part.bind ↑Option.none fun a => map encode ((↑fun a => (f a, g a)) a)

Next tactic:
simp [Seq.seq]
nonrec theorem pair {f : α → β} {g : α → γ} (hf : Computable f) (hg : Computable g) :
    Computable fun a => (f a, g a) :=
  (hf.pair hg).of_eq fun n => by cases decode (α := α) n <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β
g : α → γ
hf : Computable f
hg : Computable g
n : ℕ
val✝ : α
⊢ (Seq.seq (Nat.pair <$> Part.bind ↑(Option.some val✝) fun a => map encode (↑f a)) fun x =>
      Part.bind ↑(Option.some val✝) fun a => map encode (↑g a)) =
    Part.bind ↑(Option.some val✝) fun a => map encode ((↑fun a => (f a, g a)) a)

Next tactic:
simp [Seq.seq]
theorem none : Partrec fun _ : α => @Part.none σ :=
  Nat.Partrec.none.of_eq fun n => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
n : ℕ
⊢ Part.none = Part.bind ↑(decode n) fun a => map encode ((fun x => Part.none) a)

Next tactic:
cases decode (α := α) n
theorem none : Partrec fun _ : α => @Part.none σ :=
  Nat.Partrec.none.of_eq fun n => by cases decode (α := α) n <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
n : ℕ
⊢ Part.none = Part.bind ↑Option.none fun a => map encode ((fun x => Part.none) a)

Next tactic:
simp
theorem none : Partrec fun _ : α => @Part.none σ :=
  Nat.Partrec.none.of_eq fun n => by cases decode (α := α) n <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
n : ℕ
val✝ : α
⊢ Part.none = Part.bind ↑(Option.some val✝) fun a => map encode ((fun x => Part.none) a)

Next tactic:
simp
protected theorem bind {f : α →. β} {g : α → β →. σ} (hf : Partrec f) (hg : Partrec₂ g) :
    Partrec fun a => (f a).bind (g a) :=
  (hg.comp (Nat.Partrec.some.pair hf)).of_eq fun n => by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α →. β
g : α → β →. σ
hf : Partrec f
hg : Partrec₂ g
n : ℕ
⊢ (do
      let n ← Seq.seq (Nat.pair <$> Part.some n) fun x => Part.bind ↑(decode n) fun a => map encode (f a)
      Part.bind ↑(decode n) fun a => map encode ((fun p => g p.1 p.2) a)) =
    Part.bind ↑(decode n) fun a => map encode ((fun a => Part.bind (f a) (g a)) a)

Next tactic:
simp [Seq.seq]
protected theorem bind {f : α →. β} {g : α → β →. σ} (hf : Partrec f) (hg : Partrec₂ g) :
    Partrec fun a => (f a).bind (g a) :=
  (hg.comp (Nat.Partrec.some.pair hf)).of_eq fun n => by
    simp [Seq.seq]; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α →. β
g : α → β →. σ
hf : Partrec f
hg : Partrec₂ g
n : ℕ
⊢ (Part.bind (Part.bind ↑(decode n) fun y => map (Nat.pair n) (map encode (f y))) fun n =>
      Part.bind ↑(Option.bind (decode (Nat.unpair n).1) fun a => Option.map (Prod.mk a) (decode (Nat.unpair n).2))
        fun a => map encode (g a.1 a.2)) =
    Part.bind ↑(decode n) fun a => Part.bind (f a) fun y => map encode (g a y)

Next tactic:
cases' e : decode (α := α) n with a