l3lab/ntp-mathlib huggingface dataset:
theorem rfindOpt {n} {f : Vector ℕ (n + 1) → ℕ} (hf : @Partrec' (n + 1) f) :
    @Partrec' n fun v => Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v)) :=
  ((rfind <|
        (of_prim (Primrec.nat_sub.comp (_root_.Primrec.const 1) Primrec.vector_head)).comp₁
          (fun n => Part.some (1 - n)) hf).bind
    ((prim Nat.Primrec'.pred).comp₁ Nat.pred hf)).of_eq
    fun v =>
    Part.ext fun b => by
      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]
      refine'
        exists_congr fun a => (and_congr (iff_of_eq _) Iff.rfl).trans (and_congr_right fun h => _)
      · congr
        funext n
        cases f (n ::ᵥ v) <;> 

Proof state:
case refine'_1.e_a.e_p.h.succ
n✝¹ : ℕ
f : Vector ℕ (n✝¹ + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n✝¹
b a n n✝ : ℕ
⊢ Part.some (decide (1 ≤ succ n✝)) = ↑(some (Option.isSome (ofNat (Option ℕ) (succ n✝))))

Next tactic:
simp [Nat.succ_le_succ]
theorem rfindOpt {n} {f : Vector ℕ (n + 1) → ℕ} (hf : @Partrec' (n + 1) f) :
    @Partrec' n fun v => Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v)) :=
  ((rfind <|
        (of_prim (Primrec.nat_sub.comp (_root_.Primrec.const 1) Primrec.vector_head)).comp₁
          (fun n => Part.some (1 - n)) hf).bind
    ((prim Nat.Primrec'.pred).comp₁ Nat.pred hf)).of_eq
    fun v =>
    Part.ext fun b => by
      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]
      refine'
        exists_congr fun a => (and_congr (iff_of_eq _) Iff.rfl).trans (and_congr_right fun h => _)
      · congr
        funext n
        cases f (n ::ᵥ v) <;> simp [Nat.succ_le_succ] <;> 

Proof state:
case refine'_1.e_a.e_p.h.zero
n✝ : ℕ
f : Vector ℕ (n✝ + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n✝
b a n : ℕ
⊢ false = Option.isSome (ofNat (Option ℕ) 0)

Next tactic:
rfl
theorem rfindOpt {n} {f : Vector ℕ (n + 1) → ℕ} (hf : @Partrec' (n + 1) f) :
    @Partrec' n fun v => Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v)) :=
  ((rfind <|
        (of_prim (Primrec.nat_sub.comp (_root_.Primrec.const 1) Primrec.vector_head)).comp₁
          (fun n => Part.some (1 - n)) hf).bind
    ((prim Nat.Primrec'.pred).comp₁ Nat.pred hf)).of_eq
    fun v =>
    Part.ext fun b => by
      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]
      refine'
        exists_congr fun a => (and_congr (iff_of_eq _) Iff.rfl).trans (and_congr_right fun h => _)
      · congr
        funext n
        cases f (n ::ᵥ v) <;> simp [Nat.succ_le_succ] <;> 

Proof state:
case refine'_1.e_a.e_p.h.succ
n✝¹ : ℕ
f : Vector ℕ (n✝¹ + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n✝¹
b a n n✝ : ℕ
⊢ true = Option.isSome (ofNat (Option ℕ) (succ n✝))

Next tactic:
rfl
theorem rfindOpt {n} {f : Vector ℕ (n + 1) → ℕ} (hf : @Partrec' (n + 1) f) :
    @Partrec' n fun v => Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v)) :=
  ((rfind <|
        (of_prim (Primrec.nat_sub.comp (_root_.Primrec.const 1) Primrec.vector_head)).comp₁
          (fun n => Part.some (1 - n)) hf).bind
    ((prim Nat.Primrec'.pred).comp₁ Nat.pred hf)).of_eq
    fun v =>
    Part.ext fun b => by
      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]
      refine'
        exists_congr fun a => (and_congr (iff_of_eq _) Iff.rfl).trans (and_congr_right fun h => _)
      · congr
        funext n
        cases f (n ::ᵥ v) <;> simp [Nat.succ_le_succ] <;> rfl
      · 

Proof state:
case refine'_2
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
⊢ b = pred (f (a ::ᵥ v)) ↔ ofNat (Option ℕ) (f (a ::ᵥ v)) = some b

Next tactic:
have := Nat.rfind_spec h
theorem rfindOpt {n} {f : Vector ℕ (n + 1) → ℕ} (hf : @Partrec' (n + 1) f) :
    @Partrec' n fun v => Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v)) :=
  ((rfind <|
        (of_prim (Primrec.nat_sub.comp (_root_.Primrec.const 1) Primrec.vector_head)).comp₁
          (fun n => Part.some (1 - n)) hf).bind
    ((prim Nat.Primrec'.pred).comp₁ Nat.pred hf)).of_eq
    fun v =>
    Part.ext fun b => by
      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]
      refine'
        exists_congr fun a => (and_congr (iff_of_eq _) Iff.rfl).trans (and_congr_right fun h => _)
      · congr
        funext n
        cases f (n ::ᵥ v) <;> simp [Nat.succ_le_succ] <;> rfl
      · have := Nat.rfind_spec h
        

Proof state:
case refine'_2
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
this : true ∈ ↑(some (Option.isSome (ofNat (Option ℕ) (f (a ::ᵥ v)))))
⊢ b = pred (f (a ::ᵥ v)) ↔ ofNat (Option ℕ) (f (a ::ᵥ v)) = some b

Next tactic:
simp only [Part.coe_some, Part.mem_some_iff] at this
theorem rfindOpt {n} {f : Vector ℕ (n + 1) → ℕ} (hf : @Partrec' (n + 1) f) :
    @Partrec' n fun v => Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v)) :=
  ((rfind <|
        (of_prim (Primrec.nat_sub.comp (_root_.Primrec.const 1) Primrec.vector_head)).comp₁
          (fun n => Part.some (1 - n)) hf).bind
    ((prim Nat.Primrec'.pred).comp₁ Nat.pred hf)).of_eq
    fun v =>
    Part.ext fun b => by
      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]
      refine'
        exists_congr fun a => (and_congr (iff_of_eq _) Iff.rfl).trans (and_congr_right fun h => _)
      · congr
        funext n
        cases f (n ::ᵥ v) <;> simp [Nat.succ_le_succ] <;> rfl
      · have := Nat.rfind_spec h
        simp only [Part.coe_some, Part.mem_some_iff] at this
        

Proof state:
case refine'_2
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
this : true = Option.isSome (ofNat (Option ℕ) (f (a ::ᵥ v)))
⊢ b = pred (f (a ::ᵥ v)) ↔ ofNat (Option ℕ) (f (a ::ᵥ v)) = some b

Next tactic:
revert this
theorem rfindOpt {n} {f : Vector ℕ (n + 1) → ℕ} (hf : @Partrec' (n + 1) f) :
    @Partrec' n fun v => Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v)) :=
  ((rfind <|
        (of_prim (Primrec.nat_sub.comp (_root_.Primrec.const 1) Primrec.vector_head)).comp₁
          (fun n => Part.some (1 - n)) hf).bind
    ((prim Nat.Primrec'.pred).comp₁ Nat.pred hf)).of_eq
    fun v =>
    Part.ext fun b => by
      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]
      refine'
        exists_congr fun a => (and_congr (iff_of_eq _) Iff.rfl).trans (and_congr_right fun h => _)
      · congr
        funext n
        cases f (n ::ᵥ v) <;> simp [Nat.succ_le_succ] <;> rfl
      · have := Nat.rfind_spec h
        simp only [Part.coe_some, Part.mem_some_iff] at this
        revert this; 

Proof state:
case refine'_2
n : ℕ
f : Vector ℕ (n + 1) → ℕ
hf : Partrec' ↑f
v : Vector ℕ n
b a : ℕ
h : a ∈ Nat.rfind fun n_1 => ↑(some (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
⊢ true = Option.isSome (ofNat (Option ℕ) (f (a ::ᵥ v))) →
    (b = pred (f (a ::ᵥ v)) ↔ ofNat (Option ℕ) (f (a ::ᵥ v)) = some b)

Next tactic:
cases' f (a ::ᵥ v) with c
theorem rfindOpt {n} {f : Vector ℕ (n + 1) → ℕ} (hf : @Partrec' (n + 1) f) :
    @Partrec' n fun v => Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v)) :=
  ((rfind <|
        (of_prim (Primrec.nat_sub.comp (_root_.Primrec.const 1) Primrec.vector_head)).comp₁
          (fun n => Part.some (1 - n)) hf).bind
    ((prim Nat.Primrec'.pred).comp₁ Nat.pred hf)).of_eq
    fun v =>
    Part.ext fun b => by
      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]
      refine'
        exists_congr fun a => (and_congr (iff_of_eq _) Iff.rfl).trans (and_congr_right fun h => _)
      · congr
        funext n
        cases f (n ::ᵥ v) <;> simp [Nat.succ_le_succ] <;> rfl
      · have := Nat.rfind_spec h
        simp only [Part.coe_some, Part.mem_some_iff] at this
        revert this; cases' f (a ::ᵥ v) with c <;> 

Proof state:
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 (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
⊢ true = Option.isSome (ofNat (Option ℕ) zero) → (b = pred zero ↔ ofNat (Option ℕ) zero = some b)

Next tactic:
intro this
theorem rfindOpt {n} {f : Vector ℕ (n + 1) → ℕ} (hf : @Partrec' (n + 1) f) :
    @Partrec' n fun v => Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v)) :=
  ((rfind <|
        (of_prim (Primrec.nat_sub.comp (_root_.Primrec.const 1) Primrec.vector_head)).comp₁
          (fun n => Part.some (1 - n)) hf).bind
    ((prim Nat.Primrec'.pred).comp₁ Nat.pred hf)).of_eq
    fun v =>
    Part.ext fun b => by
      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]
      refine'
        exists_congr fun a => (and_congr (iff_of_eq _) Iff.rfl).trans (and_congr_right fun h => _)
      · congr
        funext n
        cases f (n ::ᵥ v) <;> simp [Nat.succ_le_succ] <;> rfl
      · have := Nat.rfind_spec h
        simp only [Part.coe_some, Part.mem_some_iff] at this
        revert this; cases' f (a ::ᵥ v) with c <;> 

Proof state:
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 (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
c : ℕ
⊢ true = Option.isSome (ofNat (Option ℕ) (succ c)) → (b = pred (succ c) ↔ ofNat (Option ℕ) (succ c) = some b)

Next tactic:
intro this
theorem rfindOpt {n} {f : Vector ℕ (n + 1) → ℕ} (hf : @Partrec' (n + 1) f) :
    @Partrec' n fun v => Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v)) :=
  ((rfind <|
        (of_prim (Primrec.nat_sub.comp (_root_.Primrec.const 1) Primrec.vector_head)).comp₁
          (fun n => Part.some (1 - n)) hf).bind
    ((prim Nat.Primrec'.pred).comp₁ Nat.pred hf)).of_eq
    fun v =>
    Part.ext fun b => by
      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]
      refine'
        exists_congr fun a => (and_congr (iff_of_eq _) Iff.rfl).trans (and_congr_right fun h => _)
      · congr
        funext n
        cases f (n ::ᵥ v) <;> simp [Nat.succ_le_succ] <;> rfl
      · have := Nat.rfind_spec h
        simp only [Part.coe_some, Part.mem_some_iff] at this
        revert this; cases' f (a ::ᵥ v) with c <;> intro this
        · 

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

Next tactic:
cases this
theorem rfindOpt {n} {f : Vector ℕ (n + 1) → ℕ} (hf : @Partrec' (n + 1) f) :
    @Partrec' n fun v => Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v)) :=
  ((rfind <|
        (of_prim (Primrec.nat_sub.comp (_root_.Primrec.const 1) Primrec.vector_head)).comp₁
          (fun n => Part.some (1 - n)) hf).bind
    ((prim Nat.Primrec'.pred).comp₁ Nat.pred hf)).of_eq
    fun v =>
    Part.ext fun b => by
      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]
      refine'
        exists_congr fun a => (and_congr (iff_of_eq _) Iff.rfl).trans (and_congr_right fun h => _)
      · congr
        funext n
        cases f (n ::ᵥ v) <;> simp [Nat.succ_le_succ] <;> rfl
      · have := Nat.rfind_spec h
        simp only [Part.coe_some, Part.mem_some_iff] at this
        revert this; cases' f (a ::ᵥ v) with c <;> intro this
        · cases this
        

Proof state:
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 (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
c : ℕ
this : true = Option.isSome (ofNat (Option ℕ) (succ c))
⊢ b = pred (succ c) ↔ ofNat (Option ℕ) (succ c) = some b

Next tactic:
rw [← Option.some_inj, eq_comm]
theorem rfindOpt {n} {f : Vector ℕ (n + 1) → ℕ} (hf : @Partrec' (n + 1) f) :
    @Partrec' n fun v => Nat.rfindOpt fun a => ofNat (Option ℕ) (f (a ::ᵥ v)) :=
  ((rfind <|
        (of_prim (Primrec.nat_sub.comp (_root_.Primrec.const 1) Primrec.vector_head)).comp₁
          (fun n => Part.some (1 - n)) hf).bind
    ((prim Nat.Primrec'.pred).comp₁ Nat.pred hf)).of_eq
    fun v =>
    Part.ext fun b => by
      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]
      refine'
        exists_congr fun a => (and_congr (iff_of_eq _) Iff.rfl).trans (and_congr_right fun h => _)
      · congr
        funext n
        cases f (n ::ᵥ v) <;> simp [Nat.succ_le_succ] <;> rfl
      · have := Nat.rfind_spec h
        simp only [Part.coe_some, Part.mem_some_iff] at this
        revert this; cases' f (a ::ᵥ v) with c <;> intro this
        · cases this
        rw [← Option.some_inj, eq_comm]
        

Proof state:
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 (Option.isSome (ofNat (Option ℕ) (f (n_1 ::ᵥ v)))))
c : ℕ
this : true = Option.isSome (ofNat (Option ℕ) (succ c))
⊢ some (pred (succ c)) = some b ↔ ofNat (Option ℕ) (succ c) = some b

Next tactic:
rfl
theorem of_part : ∀ {n f}, _root_.Partrec f → @Partrec' n f :=
  @(suffices ∀ f, Nat.Partrec f → @Partrec' 1 fun v => f v.head from fun {n f} hf => by
      let g := fun n₁ =>
        (Part.ofOption (decode (α := Vector ℕ n) n₁)).bind (fun a => Part.map encode (f a))
      exact
        (comp₁ g (this g hf) (prim Nat.Primrec'.encode)).of_eq fun i => by
          dsimp only; simp [encodek, Part.map_id']
    fun f hf => by
    

Proof state:
f : ℕ →. ℕ
hf : Partrec f
⊢ Partrec' fun v => f (Vector.head v)

Next tactic:
obtain ⟨c, rfl⟩ := exists_code.1 hf
theorem of_part : ∀ {n f}, _root_.Partrec f → @Partrec' n f :=
  @(suffices ∀ f, Nat.Partrec f → @Partrec' 1 fun v => f v.head from fun {n f} hf => by
      let g := fun n₁ =>
        (Part.ofOption (decode (α := Vector ℕ n) n₁)).bind (fun a => Part.map encode (f a))
      exact
        (comp₁ g (this g hf) (prim Nat.Primrec'.encode)).of_eq fun i => by
          dsimp only; simp [encodek, Part.map_id']
    fun f hf => by
    obtain ⟨c, rfl⟩ := exists_code.1 hf
    

Proof state:
case intro
c : Code
hf : Partrec (eval c)
⊢ Partrec' fun v => eval c (Vector.head v)

Next tactic:
simpa [eval_eq_rfindOpt] using
      rfindOpt <|
        of_prim <|
          Primrec.encode_iff.2 <|
            evaln_prim.comp <|
              (Primrec.vector_head.pair (_root_.Primrec.const c)).pair <|
                Primrec.vector_head.comp Primrec.vector_tail
theorem of_part : ∀ {n f}, _root_.Partrec f → @Partrec' n f :=
  @(suffices ∀ f, Nat.Partrec f → @Partrec' 1 fun v => f v.head from fun {n f} hf => by
      

Proof state:
this : ∀ (f : ℕ →. ℕ), Partrec f → Partrec' fun v => f (Vector.head v)
n : ℕ
f : Vector ℕ n →. ℕ
hf : _root_.Partrec f
⊢ Partrec' f

Next tactic:
let g := fun n₁ =>
        (Part.ofOption (decode (α := Vector ℕ n) n₁)).bind (fun a => Part.map encode (f a))
theorem of_part : ∀ {n f}, _root_.Partrec f → @Partrec' n f :=
  @(suffices ∀ f, Nat.Partrec f → @Partrec' 1 fun v => f v.head from fun {n f} hf => by
      let g := fun n₁ =>
        (Part.ofOption (decode (α := Vector ℕ n) n₁)).bind (fun a => Part.map encode (f a))
      

Proof state:
this : ∀ (f : ℕ →. ℕ), Partrec f → Partrec' fun v => f (Vector.head v)
n : ℕ
f : Vector ℕ n →. ℕ
hf : _root_.Partrec f
g : ℕ → Part ℕ := fun n₁ => Part.bind ↑(decode n₁) fun a => Part.map encode (f a)
⊢ Partrec' f

Next tactic:
exact
        (comp₁ g (this g hf) (prim Nat.Primrec'.encode)).of_eq fun i => by
          dsimp only; simp [encodek, Part.map_id']
theorem of_part : ∀ {n f}, _root_.Partrec f → @Partrec' n f :=
  @(suffices ∀ f, Nat.Partrec f → @Partrec' 1 fun v => f v.head from fun {n f} hf => by
      let g := fun n₁ =>
        (Part.ofOption (decode (α := Vector ℕ n) n₁)).bind (fun a => Part.map encode (f a))
      exact
        (comp₁ g (this g hf) (prim Nat.Primrec'.encode)).of_eq fun i => by
          

Proof state:
this : ∀ (f : ℕ →. ℕ), Partrec f → Partrec' fun v => f (Vector.head v)
n : ℕ
f : Vector ℕ n →. ℕ
hf : _root_.Partrec f
g : ℕ → Part ℕ := fun n₁ => Part.bind ↑(decode n₁) fun a => Part.map encode (f a)
i : Vector ℕ n
⊢ g (encode i) = f i

Next tactic:
dsimp only
theorem of_part : ∀ {n f}, _root_.Partrec f → @Partrec' n f :=
  @(suffices ∀ f, Nat.Partrec f → @Partrec' 1 fun v => f v.head from fun {n f} hf => by
      let g := fun n₁ =>
        (Part.ofOption (decode (α := Vector ℕ n) n₁)).bind (fun a => Part.map encode (f a))
      exact
        (comp₁ g (this g hf) (prim Nat.Primrec'.encode)).of_eq fun i => by
          dsimp only; 

Proof state:
this : ∀ (f : ℕ →. ℕ), Partrec f → Partrec' fun v => f (Vector.head v)
n : ℕ
f : Vector ℕ n →. ℕ
hf : _root_.Partrec f
g : ℕ → Part ℕ := fun n₁ => Part.bind ↑(decode n₁) fun a => Part.map encode (f a)
i : Vector ℕ n
⊢ (Part.bind ↑(decode (encode i)) fun a => Part.map encode (f a)) = f i

Next tactic:
simp [encodek, Part.map_id']
theorem part_iff₁ {f : ℕ →. ℕ} : (@Partrec' 1 fun v => f v.head) ↔ _root_.Partrec f :=
  part_iff.trans
    ⟨fun h =>
      (h.comp <| (Primrec.vector_ofFn fun _ => _root_.Primrec.id).to_comp).of_eq fun v => by
        

Proof state:
f : ℕ →. ℕ
h : _root_.Partrec fun v => f (Vector.head v)
v : ℕ
⊢ f (Vector.head (ofFn fun i => id v)) = f v

Next tactic:
simp only [id.def, head_ofFn]
theorem part_iff₂ {f : ℕ → ℕ →. ℕ} : (@Partrec' 2 fun v => f v.head v.tail.head) ↔ Partrec₂ f :=
  part_iff.trans
    ⟨fun h =>
      (h.comp <| vector_cons.comp fst <| vector_cons.comp snd (const nil)).of_eq fun v => by
        

Proof state:
f : ℕ → ℕ →. ℕ
h : _root_.Partrec fun v => f (Vector.head v) (Vector.head (Vector.tail v))
v : ℕ × ℕ
⊢ f (Vector.head (v.1 ::ᵥ v.2 ::ᵥ nil)) (Vector.head (Vector.tail (v.1 ::ᵥ v.2 ::ᵥ nil))) = f v.1 v.2

Next tactic:
simp only [head_cons, tail_cons]
theorem vec_iff {m n f} : @Vec m n f ↔ Computable f :=
  ⟨fun h => by 

Proof state:
m n : ℕ
f : Vector ℕ m → Vector ℕ n
h : Vec f
⊢ Computable f

Next tactic:
simpa only [ofFn_get] using vector_ofFn fun i => to_part (h i)
theorem zero : FinMeasAdditive μ (0 : Set α → β) := fun s t _ _ _ _ _ => by 

Proof state:
α : Type u_1
E : Type u_2
F : Type u_3
F' : Type u_4
G : Type u_5
𝕜 : Type u_6
p : ℝ≥0∞
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace ℝ E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace ℝ F
inst✝³ : NormedAddCommGroup F'
inst✝² : NormedSpace ℝ F'
inst✝¹ : NormedAddCommGroup G
m : MeasurableSpace α
μ : Measure α
β : Type u_7
inst✝ : AddCommMonoid β
T T' : Set α → β
s t : Set α
x✝⁴ : MeasurableSet s
x✝³ : MeasurableSet t
x✝² : ↑↑μ s ≠ ⊤
x✝¹ : ↑↑μ t ≠ ⊤
x✝ : s ∩ t = ∅
⊢ OfNat.ofNat 0 (s ∪ t) = OfNat.ofNat 0 s + OfNat.ofNat 0 t

Next tactic:
simp
theorem add (hT : FinMeasAdditive μ T) (hT' : FinMeasAdditive μ T') :
    FinMeasAdditive μ (T + T') := by
  

Proof state:
α : Type u_1
E : Type u_2
F : Type u_3
F' : Type u_4
G : Type u_5
𝕜 : Type u_6
p : ℝ≥0∞
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace ℝ E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace ℝ F
inst✝³ : NormedAddCommGroup F'
inst✝² : NormedSpace ℝ F'
inst✝¹ : NormedAddCommGroup G
m : MeasurableSpace α
μ : Measure α
β : Type u_7
inst✝ : AddCommMonoid β
T T' : Set α → β
hT : FinMeasAdditive μ T
hT' : FinMeasAdditive μ T'
⊢ FinMeasAdditive μ (T + T')

Next tactic:
intro s t hs ht hμs hμt hst
theorem add (hT : FinMeasAdditive μ T) (hT' : FinMeasAdditive μ T') :
    FinMeasAdditive μ (T + T') := by
  intro s t hs ht hμs hμt hst
  

Proof state:
α : Type u_1
E : Type u_2
F : Type u_3
F' : Type u_4
G : Type u_5
𝕜 : Type u_6
p : ℝ≥0∞
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace ℝ E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace ℝ F
inst✝³ : NormedAddCommGroup F'
inst✝² : NormedSpace ℝ F'
inst✝¹ : NormedAddCommGroup G
m : MeasurableSpace α
μ : Measure α
β : Type u_7
inst✝ : AddCommMonoid β
T T' : Set α → β
hT : FinMeasAdditive μ T
hT' : FinMeasAdditive μ T'
s t : Set α
hs : MeasurableSet s
ht : MeasurableSet t
hμs : ↑↑μ s ≠ ⊤
hμt : ↑↑μ t ≠ ⊤
hst : s ∩ t = ∅
⊢ (T + T') (s ∪ t) = (T + T') s + (T + T') t

Next tactic:
simp only [hT s t hs ht hμs hμt hst, hT' s t hs ht hμs hμt hst, Pi.add_apply]
theorem add (hT : FinMeasAdditive μ T) (hT' : FinMeasAdditive μ T') :
    FinMeasAdditive μ (T + T') := by
  intro s t hs ht hμs hμt hst
  simp only [hT s t hs ht hμs hμt hst, hT' s t hs ht hμs hμt hst, Pi.add_apply]
  

Proof state:
α : Type u_1
E : Type u_2
F : Type u_3
F' : Type u_4
G : Type u_5
𝕜 : Type u_6
p : ℝ≥0∞
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace ℝ E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace ℝ F
inst✝³ : NormedAddCommGroup F'
inst✝² : NormedSpace ℝ F'
inst✝¹ : NormedAddCommGroup G
m : MeasurableSpace α
μ : Measure α
β : Type u_7
inst✝ : AddCommMonoid β
T T' : Set α → β
hT : FinMeasAdditive μ T
hT' : FinMeasAdditive μ T'
s t : Set α
hs : MeasurableSet s
ht : MeasurableSet t
hμs : ↑↑μ s ≠ ⊤
hμt : ↑↑μ t ≠ ⊤
hst : s ∩ t = ∅
⊢ T s + T t + (T' s + T' t) = T s + T' s + (T t + T' t)

Next tactic:
abel
theorem smul [Monoid 𝕜] [DistribMulAction 𝕜 β] (hT : FinMeasAdditive μ T) (c : 𝕜) :
    FinMeasAdditive μ fun s => c • T s := fun s t hs ht hμs hμt hst => by
  

Proof state:
α : Type u_1
E : Type u_2
F : Type u_3
F' : Type u_4
G : Type u_5
𝕜 : Type u_6
p : ℝ≥0∞
inst✝⁹ : NormedAddCommGroup E
inst✝⁸ : NormedSpace ℝ E
inst✝⁷ : NormedAddCommGroup F
inst✝⁶ : NormedSpace ℝ F
inst✝⁵ : NormedAddCommGroup F'
inst✝⁴ : NormedSpace ℝ F'
inst✝³ : NormedAddCommGroup G
m : MeasurableSpace α
μ : Measure α
β : Type u_7
inst✝² : AddCommMonoid β
T T' : Set α → β
inst✝¹ : Monoid 𝕜
inst✝ : DistribMulAction 𝕜 β
hT : FinMeasAdditive μ T
c : 𝕜
s t : Set α
hs : MeasurableSet s
ht : MeasurableSet t
hμs : ↑↑μ s ≠ ⊤
hμt : ↑↑μ t ≠ ⊤
hst : s ∩ t = ∅
⊢ (fun s => c • T s) (s ∪ t) = (fun s => c • T s) s + (fun s => c • T s) t

Next tactic:
simp [hT s t hs ht hμs hμt hst]
theorem of_smul_measure (c : ℝ≥0∞) (hc_ne_top : c ≠ ∞) (hT : FinMeasAdditive (c • μ) T) :
    FinMeasAdditive μ T := by
  

Proof state:
α : Type u_1
E : Type u_2
F : Type u_3
F' : Type u_4
G : Type u_5
𝕜 : Type u_6
p : ℝ≥0∞
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace ℝ E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace ℝ F
inst✝³ : NormedAddCommGroup F'
inst✝² : NormedSpace ℝ F'
inst✝¹ : NormedAddCommGroup G
m : MeasurableSpace α
μ : Measure α
β : Type u_7
inst✝ : AddCommMonoid β
T T' : Set α → β
c : ℝ≥0∞
hc_ne_top : c ≠ ⊤
hT : FinMeasAdditive (c • μ) T
⊢ FinMeasAdditive μ T

Next tactic:
refine' of_eq_top_imp_eq_top (fun s _ hμs => _) hT
theorem of_smul_measure (c : ℝ≥0∞) (hc_ne_top : c ≠ ∞) (hT : FinMeasAdditive (c • μ) T) :
    FinMeasAdditive μ T := by
  refine' of_eq_top_imp_eq_top (fun s _ hμs => _) hT
  

Proof state:
α : Type u_1
E : Type u_2
F : Type u_3
F' : Type u_4
G : Type u_5
𝕜 : Type u_6
p : ℝ≥0∞
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace ℝ E
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace ℝ F
inst✝³ : NormedAddCommGroup F'
inst✝² : NormedSpace ℝ F'
inst✝¹ : NormedAddCommGroup G
m : MeasurableSpace α
μ : Measure α
β : Type u_7
inst✝ : AddCommMonoid β
T T' : Set α → β
c : ℝ≥0∞
hc_ne_top : c ≠ ⊤
hT : FinMeasAdditive (c • μ) T
s : Set α
x✝ : MeasurableSet s
hμs : ↑↑(c • μ) s = ⊤
⊢ ↑↑μ s = ⊤

Next tactic:
rw [Measure.smul_apply, smul_eq_mul, ENNReal.mul_eq_top] at hμs