@@ -80,8 +80,8 @@ section Arithmetic
8080
8181/-- Monus (truncated subtraction) is URM-computable.
8282 sub(x, 0) = x, sub(x, y+1) = pred(sub(x, y)) -/
83- theorem sub_computable : URMComputable 2 (fun xy => Part.some (xy 0 - xy 1 )) := by
84- sorry
83+ theorem sub_computable : URMComputable 2 (fun xy => Part.some (xy 0 - xy 1 )) :=
84+ monus_computable
8585
8686-- mul_computable is now provided by Urm.Arithmetic
8787
@@ -1167,9 +1167,111 @@ theorem URMComputable1.prec {f g : ℕ →. ℕ}
11671167 (hf : URMComputable1 f) (hg : URMComputable1 g) :
11681168 URMComputable1 (Nat.unpaired fun a n =>
11691169 n.rec (f a) fun y IH => do let i ← IH; g (Nat.pair a (Nat.pair y i))) := by
1170- -- Adapt: f_base(x) = f(x 0), g_step(x,k,acc) = g(pair(x 0, pair(k, acc)))
1171- -- Then compose PrFunction with unpair using unpairLeft_computable, unpairRight_computable
1172- sorry
1170+ unfold URMComputable1 at *
1171+
1172+ -- Step 1: Build nested pair: (Fin 3 → ℕ) → Part ℕ computing pair(x0, pair(x1, x2))
1173+
1174+ -- Inner pair: projects (xka 1, xka 2) then pairs them
1175+ let innerPairGs : Fin 2 → (Fin 3 → ℕ) → Part ℕ := fun i xka =>
1176+ if i.val = 0 then Part.some (xka 1 ) else Part.some (xka 2 )
1177+ have h_innerPairGs : ∀ i, URMComputable 3 (innerPairGs i) := fun i => by
1178+ fin_cases i <;> simp only [innerPairGs, ↓reduceIte,
1179+ Nat.one_ne_zero] <;> exact URMComputable.proj_computable _ _
1180+ have h_innerPair := URMComputable.comp_general (m := 2 ) (n := 3 ) pair_computable h_innerPairGs
1181+
1182+ -- Prove the composition equals pair(xka 1, xka 2)
1183+ have h_innerPair_eq : compFunction 2 3 (fun xy => Part.some (Nat.pair (xy 0 ) (xy 1 ))) innerPairGs
1184+ = fun xka => Part.some (Nat.pair (xka 1 ) (xka 2 )) := by
1185+ funext xka
1186+ simp only [compFunction, Part.sequence, innerPairGs, Fin.val_zero, ↓reduceIte, Part.bind_some,
1187+ Part.map_some, Fin.cons_zero, Fin.cons_one, Fin.val_succ, Nat.add_one_ne_zero]
1188+
1189+ -- Outer pair: projects (xka 0, innerPair) then pairs them
1190+ let outerPairGs : Fin 2 → (Fin 3 → ℕ) → Part ℕ := fun i xka =>
1191+ if i.val = 0 then Part.some (xka 0 )
1192+ else Part.some (Nat.pair (xka 1 ) (xka 2 ))
1193+ have h_outerPairGs : ∀ i, URMComputable 3 (outerPairGs i) := fun i => by
1194+ fin_cases i
1195+ · simp only [outerPairGs, ↓reduceIte]
1196+ exact URMComputable.proj_computable _ _
1197+ · simp only [outerPairGs, Nat.one_ne_zero, ↓reduceIte]
1198+ rw [← h_innerPair_eq]
1199+ exact h_innerPair.toComputable
1200+ have h_nestedPair := URMComputable.comp_general (m := 2 ) (n := 3 ) pair_computable h_outerPairGs
1201+
1202+ -- Prove the composition equals pair(xka 0, pair(xka 1, xka 2))
1203+ have h_nestedPair_eq : compFunction 2 3 (fun xy => Part.some (Nat.pair (xy 0 ) (xy 1 ))) outerPairGs
1204+ = fun xka => Part.some (Nat.pair (xka 0 ) (Nat.pair (xka 1 ) (xka 2 ))) := by
1205+ funext xka
1206+ simp only [compFunction, Part.sequence, outerPairGs, Fin.val_zero, ↓reduceIte, Part.bind_some,
1207+ Part.map_some, Fin.cons_zero, Fin.cons_one, Fin.val_succ, Nat.add_one_ne_zero]
1208+
1209+ -- Step 2: Build g_step = g ∘ nestedPair
1210+ let nestedPairGs : Fin 1 → (Fin 3 → ℕ) → Part ℕ := fun _ xka =>
1211+ Part.some (Nat.pair (xka 0 ) (Nat.pair (xka 1 ) (xka 2 )))
1212+ have h_nestedPairGs : ∀ i, URMComputable 3 (nestedPairGs i) := fun _ => by
1213+ simp only [nestedPairGs]
1214+ rw [← h_nestedPair_eq]
1215+ exact h_nestedPair.toComputable
1216+ have h_gstep := URMComputable.comp_general (m := 1 ) (n := 3 ) hg h_nestedPairGs
1217+
1218+ -- Prove g_step computes g(pair(xka 0, pair(xka 1, xka 2)))
1219+ have h_gstep_eq : compFunction 1 3 (fun x => g (x 0 )) nestedPairGs
1220+ = fun xka => g (Nat.pair (xka 0 ) (Nat.pair (xka 1 ) (xka 2 ))) := by
1221+ funext xka
1222+ simp only [compFunction, Part.sequence, nestedPairGs, Part.bind_some, Part.map_some,
1223+ Fin.cons_zero]
1224+
1225+ -- Step 3: Apply primRec
1226+ let g_step : (Fin 3 → ℕ) → Part ℕ := fun xka => g (Nat.pair (xka 0 ) (Nat.pair (xka 1 ) (xka 2 )))
1227+ have h_gstep_computable : URMComputable 3 g_step := by
1228+ simp only [g_step]
1229+ rw [← h_gstep_eq]
1230+ exact h_gstep.toComputable
1231+
1232+ have h_primRec := URMComputable.primRec (n := 1 ) hf h_gstep_computable
1233+
1234+ -- Step 4: Compose with unpair to get URMComputable 1
1235+ let unpairGs : Fin 2 → (Fin 1 → ℕ) → Part ℕ := fun i x =>
1236+ if i.val = 0 then Part.some (x 0 ).unpair.1 else Part.some (x 0 ).unpair.2
1237+ have h_unpairGs : ∀ i, URMComputable 1 (unpairGs i) := fun i => by
1238+ fin_cases i
1239+ · simp only [unpairGs, ↓reduceIte]; exact unpairLeft_computable
1240+ · simp only [unpairGs, Nat.one_ne_zero, ↓reduceIte]; exact unpairRight_computable
1241+ have h_final := URMComputable.comp_general (m := 2 ) (n := 1 ) h_primRec h_unpairGs
1242+
1243+ -- Step 5: Prove semantic equivalence
1244+ convert h_final.toComputable using 1
1245+ funext x
1246+ -- Simplify the compFunction on RHS
1247+ simp only [Nat.unpaired, compFunction, Part.sequence, unpairGs, Fin.val_zero, ↓reduceIte,
1248+ Part.bind_some, Part.map_some, Fin.val_succ, Nat.add_one_ne_zero]
1249+ -- Now RHS is: PrFunction ... (Fin.cons (unpair (x 0)).1 (Fin.cons (unpair (x 0)).2 Fin.elim0))
1250+
1251+ -- Generalize for induction
1252+ set a := (x 0 ).unpair.1
1253+ set n := (x 0 ).unpair.2
1254+
1255+ -- Key lemma: PrFunction unfolds as Pr
1256+ simp only [PrFunction, Pr]
1257+
1258+ -- Helper: compute initInputs and lastInput on Fin.cons a (Fin.cons m Fin.elim0)
1259+ have h_init : ∀ m, initInputs (Fin.cons a (Fin.cons m Fin.elim0)) = fun _ : Fin 1 => a := by
1260+ intro m; funext i; fin_cases i; simp [initInputs, Fin.castSucc_zero, Fin.cons_zero]
1261+ have h_last : ∀ m, lastInput (Fin.cons a (Fin.cons m Fin.elim0)) = m := by
1262+ intro m; simp [lastInput, Fin.cons_one, Fin.cons_zero]
1263+
1264+ simp only [h_init, h_last]
1265+
1266+ -- Prove by induction on n
1267+ induction n with
1268+ | zero =>
1269+ -- Both sides reduce to: f a = f ((fun _ => a) 0)
1270+ simp only [Nat.rec_zero]
1271+ | succ n ih =>
1272+ -- Both sides reduce to: (n.rec ...).bind (fun acc => g (pair a (pair n acc)))
1273+ -- The Fin.snoc expressions are definitionally equal: snoc (snoc _ k) acc i = [ a,k,acc ] [i ]
1274+ rfl
11731275
11741276/-- Minimization preserves URMComputable1.
11751277
0 commit comments