English
The function mapping a pair ((n, c), m) to evaln n c m is primitive recursive.
Русский
Функция, сопоставляющая пару ((n, c), m) значению evaln n c m, является примитивно вычислимой.
LaTeX
$$$\\mathrm{Primrec}\\;((\\lambda a,b,c.\\; \\mathrm{evaln}\\ a.1.1 a.1.2 a.2))$$$
Lean4
/-- The `Nat.Partrec.Code.evaln` function is primitive recursive. -/
theorem primrec_evaln : Primrec fun a : (ℕ × Code) × ℕ => evaln a.1.1 a.1.2 a.2 :=
have :
Primrec₂ fun (_ : Unit) (n : ℕ) =>
let a := ofNat (ℕ × Code) n
(List.range a.1).map (evaln a.1 a.2) :=
Primrec.nat_strong_rec _ (hG.comp Primrec.snd).to₂ fun _ p =>
by
simp only [G, prod_ofNat_val, ofNat_nat, List.length_map, List.length_range, Nat.pair_unpair, Option.some_inj]
refine List.map_congr_left fun n => ?_
have : List.range p = List.range (Nat.pair p.unpair.1 (encode (ofNat Code p.unpair.2))) := by simp
rw [this]
generalize p.unpair.1 = k
generalize ofNat Code p.unpair.2 = c
intro nk
rcases k with - | k'
· simp [evaln]
let k := k' + 1
simp only
simp only [List.mem_range, Nat.lt_succ_iff] at nk
have hg :
∀ {k' c' n},
Nat.pair k' (encode c') < Nat.pair k (encode c) →
lup
((List.range (Nat.pair k (encode c))).map fun n =>
(List.range n.unpair.1).map (evaln n.unpair.1 (ofNat Code n.unpair.2)))
(k', c') n =
evaln k' c' n :=
by
intro k₁ c₁ n₁ hl
simp [lup, List.getElem?_range hl, evaln_map, Bind.bind, Option.bind_map]
obtain - | - | - | - | ⟨cf, cg⟩ | ⟨cf, cg⟩ | ⟨cf, cg⟩ | cf := c <;>
simp [evaln, nk, Bind.bind, Functor.map, Seq.seq, pure]
· obtain ⟨lf, lg⟩ := encode_lt_pair cf cg
rw [hg (Nat.pair_lt_pair_right _ lf), hg (Nat.pair_lt_pair_right _ lg)]
cases evaln k cf n
· rfl
cases evaln k cg n <;> rfl
· obtain ⟨lf, lg⟩ := encode_lt_comp cf cg
rw [hg (Nat.pair_lt_pair_right _ lg)]
cases evaln k cg n
· rfl
simp [k, hg (Nat.pair_lt_pair_right _ lf)]
· obtain ⟨lf, lg⟩ := encode_lt_prec cf cg
rw [hg (Nat.pair_lt_pair_right _ lf)]
cases n.unpair.2
· rfl
simp only
rw [hg (Nat.pair_lt_pair_left _ k'.lt_succ_self)]
cases evaln k' _ _
· rfl
simp [k, hg (Nat.pair_lt_pair_right _ lg)]
· have lf := encode_lt_rfind' cf
rw [hg (Nat.pair_lt_pair_right _ lf)]
rcases evaln k cf n with - | x
· rfl
simp only [Option.bind_some]
cases x <;> simp
rw [hg (Nat.pair_lt_pair_left _ k'.lt_succ_self)]
(Primrec.option_bind
(Primrec.list_getElem?.comp (this.comp (_root_.Primrec.const ()) (Primrec.encode_iff.2 Primrec.fst))
Primrec.snd)
Primrec.snd.to₂).of_eq
fun ⟨⟨k, c⟩, n⟩ => by simp [evaln_map, Option.bind_map]