l3lab/ntp-mathlib huggingface dataset:
theorem sqrt : @Primrec' 1 fun v => v.head.sqrt := by
  suffices H : ∀ n : ℕ, n.sqrt = n.rec 0 fun x y => if x.succ < y.succ * y.succ then y else y.succ
  · simp [H]
    have :=
      @prec' 1 _ _
        (fun v => by
          have x := v.head; have y := v.tail.head;
            exact if x.succ < y.succ * y.succ then y else y.succ)
        head (const 0) ?_
    · exact this
    

Proof state:
case refine_1
H : ∀ (n : ℕ), Nat.sqrt n = Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n
⊢ Primrec' fun v =>
    let_fun x := Vector.head v;
    let_fun y := Vector.head (Vector.tail v);
    if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y

Next tactic:
have x1 : @Primrec' 3 fun v => v.head.succ := succ.comp₁ _ head
theorem sqrt : @Primrec' 1 fun v => v.head.sqrt := by
  suffices H : ∀ n : ℕ, n.sqrt = n.rec 0 fun x y => if x.succ < y.succ * y.succ then y else y.succ
  · simp [H]
    have :=
      @prec' 1 _ _
        (fun v => by
          have x := v.head; have y := v.tail.head;
            exact if x.succ < y.succ * y.succ then y else y.succ)
        head (const 0) ?_
    · exact this
    have x1 : @Primrec' 3 fun v => v.head.succ := succ.comp₁ _ head
    

Proof state:
case refine_1
H : ∀ (n : ℕ), Nat.sqrt n = Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n
x1 : Primrec' fun v => Nat.succ (Vector.head v)
⊢ Primrec' fun v =>
    let_fun x := Vector.head v;
    let_fun y := Vector.head (Vector.tail v);
    if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y

Next tactic:
have y1 : @Primrec' 3 fun v => v.tail.head.succ := succ.comp₁ _ (tail head)
theorem sqrt : @Primrec' 1 fun v => v.head.sqrt := by
  suffices H : ∀ n : ℕ, n.sqrt = n.rec 0 fun x y => if x.succ < y.succ * y.succ then y else y.succ
  · simp [H]
    have :=
      @prec' 1 _ _
        (fun v => by
          have x := v.head; have y := v.tail.head;
            exact if x.succ < y.succ * y.succ then y else y.succ)
        head (const 0) ?_
    · exact this
    have x1 : @Primrec' 3 fun v => v.head.succ := succ.comp₁ _ head
    have y1 : @Primrec' 3 fun v => v.tail.head.succ := succ.comp₁ _ (tail head)
    

Proof state:
case refine_1
H : ∀ (n : ℕ), Nat.sqrt n = Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n
x1 : Primrec' fun v => Nat.succ (Vector.head v)
y1 : Primrec' fun v => Nat.succ (Vector.head (Vector.tail v))
⊢ Primrec' fun v =>
    let_fun x := Vector.head v;
    let_fun y := Vector.head (Vector.tail v);
    if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y

Next tactic:
exact if_lt x1 (mul.comp₂ _ y1 y1) (tail head) y1
theorem sqrt : @Primrec' 1 fun v => v.head.sqrt := by
  suffices H : ∀ n : ℕ, n.sqrt = n.rec 0 fun x y => if x.succ < y.succ * y.succ then y else y.succ
  · simp [H]
    have :=
      @prec' 1 _ _
        (fun v => by
          have x := v.head; have y := v.tail.head;
            exact if x.succ < y.succ * y.succ then y else y.succ)
        head (const 0) ?_
    · exact this
    have x1 : @Primrec' 3 fun v => v.head.succ := succ.comp₁ _ head
    have y1 : @Primrec' 3 fun v => v.tail.head.succ := succ.comp₁ _ (tail head)
    exact if_lt x1 (mul.comp₂ _ y1 y1) (tail head) y1
  

Proof state:
case H
⊢ ∀ (n : ℕ), Nat.sqrt n = Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n

Next tactic:
introv
theorem sqrt : @Primrec' 1 fun v => v.head.sqrt := by
  suffices H : ∀ n : ℕ, n.sqrt = n.rec 0 fun x y => if x.succ < y.succ * y.succ then y else y.succ
  · simp [H]
    have :=
      @prec' 1 _ _
        (fun v => by
          have x := v.head; have y := v.tail.head;
            exact if x.succ < y.succ * y.succ then y else y.succ)
        head (const 0) ?_
    · exact this
    have x1 : @Primrec' 3 fun v => v.head.succ := succ.comp₁ _ head
    have y1 : @Primrec' 3 fun v => v.tail.head.succ := succ.comp₁ _ (tail head)
    exact if_lt x1 (mul.comp₂ _ y1 y1) (tail head) y1
  introv; 

Proof state:
case H
n : ℕ
⊢ Nat.sqrt n = Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n

Next tactic:
symm
theorem sqrt : @Primrec' 1 fun v => v.head.sqrt := by
  suffices H : ∀ n : ℕ, n.sqrt = n.rec 0 fun x y => if x.succ < y.succ * y.succ then y else y.succ
  · simp [H]
    have :=
      @prec' 1 _ _
        (fun v => by
          have x := v.head; have y := v.tail.head;
            exact if x.succ < y.succ * y.succ then y else y.succ)
        head (const 0) ?_
    · exact this
    have x1 : @Primrec' 3 fun v => v.head.succ := succ.comp₁ _ head
    have y1 : @Primrec' 3 fun v => v.tail.head.succ := succ.comp₁ _ (tail head)
    exact if_lt x1 (mul.comp₂ _ y1 y1) (tail head) y1
  introv; symm
  

Proof state:
case H
n : ℕ
⊢ Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n = Nat.sqrt n

Next tactic:
induction' n with n IH
theorem sqrt : @Primrec' 1 fun v => v.head.sqrt := by
  suffices H : ∀ n : ℕ, n.sqrt = n.rec 0 fun x y => if x.succ < y.succ * y.succ then y else y.succ
  · simp [H]
    have :=
      @prec' 1 _ _
        (fun v => by
          have x := v.head; have y := v.tail.head;
            exact if x.succ < y.succ * y.succ then y else y.succ)
        head (const 0) ?_
    · exact this
    have x1 : @Primrec' 3 fun v => v.head.succ := succ.comp₁ _ head
    have y1 : @Primrec' 3 fun v => v.tail.head.succ := succ.comp₁ _ (tail head)
    exact if_lt x1 (mul.comp₂ _ y1 y1) (tail head) y1
  introv; symm
  induction' n with n IH; · 

Proof state:
case H.zero
⊢ Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) Nat.zero = Nat.sqrt Nat.zero

Next tactic:
simp
theorem sqrt : @Primrec' 1 fun v => v.head.sqrt := by
  suffices H : ∀ n : ℕ, n.sqrt = n.rec 0 fun x y => if x.succ < y.succ * y.succ then y else y.succ
  · simp [H]
    have :=
      @prec' 1 _ _
        (fun v => by
          have x := v.head; have y := v.tail.head;
            exact if x.succ < y.succ * y.succ then y else y.succ)
        head (const 0) ?_
    · exact this
    have x1 : @Primrec' 3 fun v => v.head.succ := succ.comp₁ _ head
    have y1 : @Primrec' 3 fun v => v.tail.head.succ := succ.comp₁ _ (tail head)
    exact if_lt x1 (mul.comp₂ _ y1 y1) (tail head) y1
  introv; symm
  induction' n with n IH; · simp
  

Proof state:
case H.succ
n : ℕ
IH : Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n = Nat.sqrt n
⊢ Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) (Nat.succ n) =
    Nat.sqrt (Nat.succ n)

Next tactic:
dsimp
theorem sqrt : @Primrec' 1 fun v => v.head.sqrt := by
  suffices H : ∀ n : ℕ, n.sqrt = n.rec 0 fun x y => if x.succ < y.succ * y.succ then y else y.succ
  · simp [H]
    have :=
      @prec' 1 _ _
        (fun v => by
          have x := v.head; have y := v.tail.head;
            exact if x.succ < y.succ * y.succ then y else y.succ)
        head (const 0) ?_
    · exact this
    have x1 : @Primrec' 3 fun v => v.head.succ := succ.comp₁ _ head
    have y1 : @Primrec' 3 fun v => v.tail.head.succ := succ.comp₁ _ (tail head)
    exact if_lt x1 (mul.comp₂ _ y1 y1) (tail head) y1
  introv; symm
  induction' n with n IH; · simp
  dsimp; 

Proof state:
case H.succ
n : ℕ
IH : Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n = Nat.sqrt n
⊢ (if
        Nat.succ n <
          Nat.succ (Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n) *
            Nat.succ (Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n) then
      Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n
    else Nat.succ (Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n)) =
    Nat.sqrt (Nat.succ n)

Next tactic:
rw [IH]
theorem sqrt : @Primrec' 1 fun v => v.head.sqrt := by
  suffices H : ∀ n : ℕ, n.sqrt = n.rec 0 fun x y => if x.succ < y.succ * y.succ then y else y.succ
  · simp [H]
    have :=
      @prec' 1 _ _
        (fun v => by
          have x := v.head; have y := v.tail.head;
            exact if x.succ < y.succ * y.succ then y else y.succ)
        head (const 0) ?_
    · exact this
    have x1 : @Primrec' 3 fun v => v.head.succ := succ.comp₁ _ head
    have y1 : @Primrec' 3 fun v => v.tail.head.succ := succ.comp₁ _ (tail head)
    exact if_lt x1 (mul.comp₂ _ y1 y1) (tail head) y1
  introv; symm
  induction' n with n IH; · simp
  dsimp; rw [IH]; 

Proof state:
case H.succ
n : ℕ
IH : Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n = Nat.sqrt n
⊢ (if Nat.succ n < Nat.succ (Nat.sqrt n) * Nat.succ (Nat.sqrt n) then Nat.sqrt n else Nat.succ (Nat.sqrt n)) =
    Nat.sqrt (Nat.succ n)

Next tactic:
split_ifs with h
theorem sqrt : @Primrec' 1 fun v => v.head.sqrt := by
  suffices H : ∀ n : ℕ, n.sqrt = n.rec 0 fun x y => if x.succ < y.succ * y.succ then y else y.succ
  · simp [H]
    have :=
      @prec' 1 _ _
        (fun v => by
          have x := v.head; have y := v.tail.head;
            exact if x.succ < y.succ * y.succ then y else y.succ)
        head (const 0) ?_
    · exact this
    have x1 : @Primrec' 3 fun v => v.head.succ := succ.comp₁ _ head
    have y1 : @Primrec' 3 fun v => v.tail.head.succ := succ.comp₁ _ (tail head)
    exact if_lt x1 (mul.comp₂ _ y1 y1) (tail head) y1
  introv; symm
  induction' n with n IH; · simp
  dsimp; rw [IH]; split_ifs with h
  · 

Proof state:
case pos
n : ℕ
IH : Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n = Nat.sqrt n
h : Nat.succ n < Nat.succ (Nat.sqrt n) * Nat.succ (Nat.sqrt n)
⊢ Nat.sqrt n = Nat.sqrt (Nat.succ n)

Next tactic:
exact le_antisymm (Nat.sqrt_le_sqrt (Nat.le_succ _)) (Nat.lt_succ_iff.1 <| Nat.sqrt_lt.2 h)
theorem sqrt : @Primrec' 1 fun v => v.head.sqrt := by
  suffices H : ∀ n : ℕ, n.sqrt = n.rec 0 fun x y => if x.succ < y.succ * y.succ then y else y.succ
  · simp [H]
    have :=
      @prec' 1 _ _
        (fun v => by
          have x := v.head; have y := v.tail.head;
            exact if x.succ < y.succ * y.succ then y else y.succ)
        head (const 0) ?_
    · exact this
    have x1 : @Primrec' 3 fun v => v.head.succ := succ.comp₁ _ head
    have y1 : @Primrec' 3 fun v => v.tail.head.succ := succ.comp₁ _ (tail head)
    exact if_lt x1 (mul.comp₂ _ y1 y1) (tail head) y1
  introv; symm
  induction' n with n IH; · simp
  dsimp; rw [IH]; split_ifs with h
  · exact le_antisymm (Nat.sqrt_le_sqrt (Nat.le_succ _)) (Nat.lt_succ_iff.1 <| Nat.sqrt_lt.2 h)
  · 

Proof state:
case neg
n : ℕ
IH : Nat.rec 0 (fun x y => if Nat.succ x < Nat.succ y * Nat.succ y then y else Nat.succ y) n = Nat.sqrt n
h : ¬Nat.succ n < Nat.succ (Nat.sqrt n) * Nat.succ (Nat.sqrt n)
⊢ Nat.succ (Nat.sqrt n) = Nat.sqrt (Nat.succ n)

Next tactic:
exact
      Nat.eq_sqrt.2 ⟨not_lt.1 h, Nat.sqrt_lt.1 <| Nat.lt_succ_iff.2 <| Nat.sqrt_succ_le_succ_sqrt _⟩
theorem unpair₁ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.1 := by
  

Proof state:
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
⊢ Primrec' fun v => (unpair (f v)).1

Next tactic:
have s := sqrt.comp₁ _ hf
theorem unpair₁ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.1 := by
  have s := sqrt.comp₁ _ hf
  

Proof state:
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
s : Primrec' fun v => Nat.sqrt (f v)
⊢ Primrec' fun v => (unpair (f v)).1

Next tactic:
have fss := sub.comp₂ _ hf (mul.comp₂ _ s s)
theorem unpair₁ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.1 := by
  have s := sqrt.comp₁ _ hf
  have fss := sub.comp₂ _ hf (mul.comp₂ _ s s)
  

Proof state:
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
s : Primrec' fun v => Nat.sqrt (f v)
fss : Primrec' fun v => f v - Nat.sqrt (f v) * Nat.sqrt (f v)
⊢ Primrec' fun v => (unpair (f v)).1

Next tactic:
refine' (if_lt fss s fss s).of_eq fun v => _
theorem unpair₁ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.1 := by
  have s := sqrt.comp₁ _ hf
  have fss := sub.comp₂ _ hf (mul.comp₂ _ s s)
  refine' (if_lt fss s fss s).of_eq fun v => _
  

Proof state:
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
s : Primrec' fun v => Nat.sqrt (f v)
fss : Primrec' fun v => f v - Nat.sqrt (f v) * Nat.sqrt (f v)
v : Vector ℕ n
⊢ (if f v - Nat.sqrt (f v) * Nat.sqrt (f v) < Nat.sqrt (f v) then f v - Nat.sqrt (f v) * Nat.sqrt (f v)
    else Nat.sqrt (f v)) =
    (unpair (f v)).1

Next tactic:
simp [Nat.unpair]
theorem unpair₁ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.1 := by
  have s := sqrt.comp₁ _ hf
  have fss := sub.comp₂ _ hf (mul.comp₂ _ s s)
  refine' (if_lt fss s fss s).of_eq fun v => _
  simp [Nat.unpair]; 

Proof state:
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
s : Primrec' fun v => Nat.sqrt (f v)
fss : Primrec' fun v => f v - Nat.sqrt (f v) * Nat.sqrt (f v)
v : Vector ℕ n
⊢ (if f v - Nat.sqrt (f v) * Nat.sqrt (f v) < Nat.sqrt (f v) then f v - Nat.sqrt (f v) * Nat.sqrt (f v)
    else Nat.sqrt (f v)) =
    (if f v - Nat.sqrt (f v) * Nat.sqrt (f v) < Nat.sqrt (f v) then
        (f v - Nat.sqrt (f v) * Nat.sqrt (f v), Nat.sqrt (f v))
      else (Nat.sqrt (f v), f v - Nat.sqrt (f v) * Nat.sqrt (f v) - Nat.sqrt (f v))).1

Next tactic:
split_ifs
theorem unpair₁ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.1 := by
  have s := sqrt.comp₁ _ hf
  have fss := sub.comp₂ _ hf (mul.comp₂ _ s s)
  refine' (if_lt fss s fss s).of_eq fun v => _
  simp [Nat.unpair]; split_ifs <;> 

Proof state:
case pos
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
s : Primrec' fun v => Nat.sqrt (f v)
fss : Primrec' fun v => f v - Nat.sqrt (f v) * Nat.sqrt (f v)
v : Vector ℕ n
h✝ : f v - Nat.sqrt (f v) * Nat.sqrt (f v) < Nat.sqrt (f v)
⊢ f v - Nat.sqrt (f v) * Nat.sqrt (f v) = (f v - Nat.sqrt (f v) * Nat.sqrt (f v), Nat.sqrt (f v)).1

Next tactic:
rfl
theorem unpair₁ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.1 := by
  have s := sqrt.comp₁ _ hf
  have fss := sub.comp₂ _ hf (mul.comp₂ _ s s)
  refine' (if_lt fss s fss s).of_eq fun v => _
  simp [Nat.unpair]; split_ifs <;> 

Proof state:
case neg
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
s : Primrec' fun v => Nat.sqrt (f v)
fss : Primrec' fun v => f v - Nat.sqrt (f v) * Nat.sqrt (f v)
v : Vector ℕ n
h✝ : ¬f v - Nat.sqrt (f v) * Nat.sqrt (f v) < Nat.sqrt (f v)
⊢ Nat.sqrt (f v) = (Nat.sqrt (f v), f v - Nat.sqrt (f v) * Nat.sqrt (f v) - Nat.sqrt (f v)).1

Next tactic:
rfl
theorem unpair₂ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.2 := by
  

Proof state:
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
⊢ Primrec' fun v => (unpair (f v)).2

Next tactic:
have s := sqrt.comp₁ _ hf
theorem unpair₂ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.2 := by
  have s := sqrt.comp₁ _ hf
  

Proof state:
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
s : Primrec' fun v => Nat.sqrt (f v)
⊢ Primrec' fun v => (unpair (f v)).2

Next tactic:
have fss := sub.comp₂ _ hf (mul.comp₂ _ s s)
theorem unpair₂ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.2 := by
  have s := sqrt.comp₁ _ hf
  have fss := sub.comp₂ _ hf (mul.comp₂ _ s s)
  

Proof state:
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
s : Primrec' fun v => Nat.sqrt (f v)
fss : Primrec' fun v => f v - Nat.sqrt (f v) * Nat.sqrt (f v)
⊢ Primrec' fun v => (unpair (f v)).2

Next tactic:
refine' (if_lt fss s s (sub.comp₂ _ fss s)).of_eq fun v => _
theorem unpair₂ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.2 := by
  have s := sqrt.comp₁ _ hf
  have fss := sub.comp₂ _ hf (mul.comp₂ _ s s)
  refine' (if_lt fss s s (sub.comp₂ _ fss s)).of_eq fun v => _
  

Proof state:
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
s : Primrec' fun v => Nat.sqrt (f v)
fss : Primrec' fun v => f v - Nat.sqrt (f v) * Nat.sqrt (f v)
v : Vector ℕ n
⊢ (if f v - Nat.sqrt (f v) * Nat.sqrt (f v) < Nat.sqrt (f v) then Nat.sqrt (f v)
    else f v - Nat.sqrt (f v) * Nat.sqrt (f v) - Nat.sqrt (f v)) =
    (unpair (f v)).2

Next tactic:
simp [Nat.unpair]
theorem unpair₂ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.2 := by
  have s := sqrt.comp₁ _ hf
  have fss := sub.comp₂ _ hf (mul.comp₂ _ s s)
  refine' (if_lt fss s s (sub.comp₂ _ fss s)).of_eq fun v => _
  simp [Nat.unpair]; 

Proof state:
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
s : Primrec' fun v => Nat.sqrt (f v)
fss : Primrec' fun v => f v - Nat.sqrt (f v) * Nat.sqrt (f v)
v : Vector ℕ n
⊢ (if f v - Nat.sqrt (f v) * Nat.sqrt (f v) < Nat.sqrt (f v) then Nat.sqrt (f v)
    else f v - Nat.sqrt (f v) * Nat.sqrt (f v) - Nat.sqrt (f v)) =
    (if f v - Nat.sqrt (f v) * Nat.sqrt (f v) < Nat.sqrt (f v) then
        (f v - Nat.sqrt (f v) * Nat.sqrt (f v), Nat.sqrt (f v))
      else (Nat.sqrt (f v), f v - Nat.sqrt (f v) * Nat.sqrt (f v) - Nat.sqrt (f v))).2

Next tactic:
split_ifs
theorem unpair₂ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.2 := by
  have s := sqrt.comp₁ _ hf
  have fss := sub.comp₂ _ hf (mul.comp₂ _ s s)
  refine' (if_lt fss s s (sub.comp₂ _ fss s)).of_eq fun v => _
  simp [Nat.unpair]; split_ifs <;> 

Proof state:
case pos
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
s : Primrec' fun v => Nat.sqrt (f v)
fss : Primrec' fun v => f v - Nat.sqrt (f v) * Nat.sqrt (f v)
v : Vector ℕ n
h✝ : f v - Nat.sqrt (f v) * Nat.sqrt (f v) < Nat.sqrt (f v)
⊢ Nat.sqrt (f v) = (f v - Nat.sqrt (f v) * Nat.sqrt (f v), Nat.sqrt (f v)).2

Next tactic:
rfl
theorem unpair₂ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.2 := by
  have s := sqrt.comp₁ _ hf
  have fss := sub.comp₂ _ hf (mul.comp₂ _ s s)
  refine' (if_lt fss s s (sub.comp₂ _ fss s)).of_eq fun v => _
  simp [Nat.unpair]; split_ifs <;> 

Proof state:
case neg
n : ℕ
f : Vector ℕ n → ℕ
hf : Primrec' f
s : Primrec' fun v => Nat.sqrt (f v)
fss : Primrec' fun v => f v - Nat.sqrt (f v) * Nat.sqrt (f v)
v : Vector ℕ n
h✝ : ¬f v - Nat.sqrt (f v) * Nat.sqrt (f v) < Nat.sqrt (f v)
⊢ f v - Nat.sqrt (f v) * Nat.sqrt (f v) - Nat.sqrt (f v) =
    (Nat.sqrt (f v), f v - Nat.sqrt (f v) * Nat.sqrt (f v) - Nat.sqrt (f v)).2

Next tactic:
rfl
theorem of_prim {n f} : Primrec f → @Primrec' n f :=
  suffices ∀ f, Nat.Primrec f → @Primrec' 1 fun v => f v.head from fun hf =>
    (pred.comp₁ _ <|
          (this _ hf).comp₁ (fun m => Encodable.encode <| (@decode (Vector ℕ n) _ m).map f)
            Primrec'.encode).of_eq
      fun i => by simp [encodek]
  fun f hf => by
  

Proof state:
n : ℕ
f✝ : Vector ℕ n → ℕ
f : ℕ → ℕ
hf : Nat.Primrec f
⊢ Primrec' fun v => f (Vector.head v)

Next tactic:
induction hf
theorem of_prim {n f} : Primrec f → @Primrec' n f :=
  suffices ∀ f, Nat.Primrec f → @Primrec' 1 fun v => f v.head from fun hf =>
    (pred.comp₁ _ <|
          (this _ hf).comp₁ (fun m => Encodable.encode <| (@decode (Vector ℕ n) _ m).map f)
            Primrec'.encode).of_eq
      fun i => by simp [encodek]
  fun f hf => by
  induction hf
  

Proof state:
case zero
n : ℕ
f✝ : Vector ℕ n → ℕ
f : ℕ → ℕ
⊢ Primrec' fun v => (fun x => 0) (Vector.head v)
case succ
n : ℕ
f✝ : Vector ℕ n → ℕ
f : ℕ → ℕ
⊢ Primrec' fun v => Nat.succ (Vector.head v)
case left
n : ℕ
f✝ : Vector ℕ n → ℕ
f : ℕ → ℕ
⊢ Primrec' fun v => (fun n => (unpair n).1) (Vector.head v)
case right
n : ℕ
f✝ : Vector ℕ n → ℕ
f : ℕ → ℕ
⊢ Primrec' fun v => (fun n => (unpair n).2) (Vector.head v)
case pair
n : ℕ
f✝¹ : Vector ℕ n → ℕ
f f✝ g✝ : ℕ → ℕ
a✝¹ : Nat.Primrec f✝
a✝ : Nat.Primrec g✝
a_ih✝¹ : Primrec' fun v => f✝ (Vector.head v)
a_ih✝ : Primrec' fun v => g✝ (Vector.head v)
⊢ Primrec' fun v => (fun n => pair (f✝ n) (g✝ n)) (Vector.head v)
case comp
n : ℕ
f✝¹ : Vector ℕ n → ℕ
f f✝ g✝ : ℕ → ℕ
a✝¹ : Nat.Primrec f✝
a✝ : Nat.Primrec g✝
a_ih✝¹ : Primrec' fun v => f✝ (Vector.head v)
a_ih✝ : Primrec' fun v => g✝ (Vector.head v)
⊢ Primrec' fun v => (fun n => f✝ (g✝ n)) (Vector.head v)
case prec
n : ℕ
f✝¹ : Vector ℕ n → ℕ
f f✝ g✝ : ℕ → ℕ
a✝¹ : Nat.Primrec f✝
a✝ : Nat.Primrec g✝
a_ih✝¹ : Primrec' fun v => f✝ (Vector.head v)
a_ih✝ : Primrec' fun v => g✝ (Vector.head v)
⊢ Primrec' fun v => unpaired (fun z n => Nat.rec (f✝ z) (fun y IH => g✝ (pair z (pair y IH))) n) (Vector.head v)

Next tactic:
case zero => exact const 0
theorem of_prim {n f} : Primrec f → @Primrec' n f :=
  suffices ∀ f, Nat.Primrec f → @Primrec' 1 fun v => f v.head from fun hf =>
    (pred.comp₁ _ <|
          (this _ hf).comp₁ (fun m => Encodable.encode <| (@decode (Vector ℕ n) _ m).map f)
            Primrec'.encode).of_eq
      fun i => by simp [encodek]
  fun f hf => by
  induction hf
  

Proof state:
n : ℕ
f✝ : Vector ℕ n → ℕ
f : ℕ → ℕ
⊢ Primrec' fun v => (fun x => 0) (Vector.head v)

Next tactic:
case zero => exact const 0
theorem of_prim {n f} : Primrec f → @Primrec' n f :=
  suffices ∀ f, Nat.Primrec f → @Primrec' 1 fun v => f v.head from fun hf =>
    (pred.comp₁ _ <|
          (this _ hf).comp₁ (fun m => Encodable.encode <| (@decode (Vector ℕ n) _ m).map f)
            Primrec'.encode).of_eq
      fun i => by simp [encodek]
  fun f hf => by
  induction hf
  case zero => 

Proof state:
n : ℕ
f✝ : Vector ℕ n → ℕ
f : ℕ → ℕ
⊢ Primrec' fun v => (fun x => 0) (Vector.head v)

Next tactic:
exact const 0
theorem of_prim {n f} : Primrec f → @Primrec' n f :=
  suffices ∀ f, Nat.Primrec f → @Primrec' 1 fun v => f v.head from fun hf =>
    (pred.comp₁ _ <|
          (this _ hf).comp₁ (fun m => Encodable.encode <| (@decode (Vector ℕ n) _ m).map f)
            Primrec'.encode).of_eq
      fun i => by simp [encodek]
  fun f hf => by
  induction hf
  case zero => exact const 0
  

Proof state:
case succ
n : ℕ
f✝ : Vector ℕ n → ℕ
f : ℕ → ℕ
⊢ Primrec' fun v => Nat.succ (Vector.head v)
case left
n : ℕ
f✝ : Vector ℕ n → ℕ
f : ℕ → ℕ
⊢ Primrec' fun v => (fun n => (unpair n).1) (Vector.head v)
case right
n : ℕ
f✝ : Vector ℕ n → ℕ
f : ℕ → ℕ
⊢ Primrec' fun v => (fun n => (unpair n).2) (Vector.head v)
case pair
n : ℕ
f✝¹ : Vector ℕ n → ℕ
f f✝ g✝ : ℕ → ℕ
a✝¹ : Nat.Primrec f✝
a✝ : Nat.Primrec g✝
a_ih✝¹ : Primrec' fun v => f✝ (Vector.head v)
a_ih✝ : Primrec' fun v => g✝ (Vector.head v)
⊢ Primrec' fun v => (fun n => pair (f✝ n) (g✝ n)) (Vector.head v)
case comp
n : ℕ
f✝¹ : Vector ℕ n → ℕ
f f✝ g✝ : ℕ → ℕ
a✝¹ : Nat.Primrec f✝
a✝ : Nat.Primrec g✝
a_ih✝¹ : Primrec' fun v => f✝ (Vector.head v)
a_ih✝ : Primrec' fun v => g✝ (Vector.head v)
⊢ Primrec' fun v => (fun n => f✝ (g✝ n)) (Vector.head v)
case prec
n : ℕ
f✝¹ : Vector ℕ n → ℕ
f f✝ g✝ : ℕ → ℕ
a✝¹ : Nat.Primrec f✝
a✝ : Nat.Primrec g✝
a_ih✝¹ : Primrec' fun v => f✝ (Vector.head v)
a_ih✝ : Primrec' fun v => g✝ (Vector.head v)
⊢ Primrec' fun v => unpaired (fun z n => Nat.rec (f✝ z) (fun y IH => g✝ (pair z (pair y IH))) n) (Vector.head v)

Next tactic:
case succ => exact succ
theorem of_prim {n f} : Primrec f → @Primrec' n f :=
  suffices ∀ f, Nat.Primrec f → @Primrec' 1 fun v => f v.head from fun hf =>
    (pred.comp₁ _ <|
          (this _ hf).comp₁ (fun m => Encodable.encode <| (@decode (Vector ℕ n) _ m).map f)
            Primrec'.encode).of_eq
      fun i => by simp [encodek]
  fun f hf => by
  induction hf
  case zero => exact const 0
  

Proof state:
n : ℕ
f✝ : Vector ℕ n → ℕ
f : ℕ → ℕ
⊢ Primrec' fun v => Nat.succ (Vector.head v)

Next tactic:
case succ => exact succ
theorem of_prim {n f} : Primrec f → @Primrec' n f :=
  suffices ∀ f, Nat.Primrec f → @Primrec' 1 fun v => f v.head from fun hf =>
    (pred.comp₁ _ <|
          (this _ hf).comp₁ (fun m => Encodable.encode <| (@decode (Vector ℕ n) _ m).map f)
            Primrec'.encode).of_eq
      fun i => by simp [encodek]
  fun f hf => by
  induction hf
  case zero => exact const 0
  case succ => 

Proof state:
n : ℕ
f✝ : Vector ℕ n → ℕ
f : ℕ → ℕ
⊢ Primrec' fun v => Nat.succ (Vector.head v)

Next tactic:
exact succ