thys2/Recs.thy
changeset 266 b1b47d28c295
parent 265 fa3c214559b0
child 269 fa40fd8abb54
equal deleted inserted replaced
265:fa3c214559b0 266:b1b47d28c295
   176 | "arity (Id m n) = m"
   176 | "arity (Id m n) = m"
   177 | "arity (Cn n f gs) = n"
   177 | "arity (Cn n f gs) = n"
   178 | "arity (Pr n f g) = Suc n"
   178 | "arity (Pr n f g) = Suc n"
   179 | "arity (Mn n f) = n"
   179 | "arity (Mn n f) = n"
   180 
   180 
       
   181 text {* Abbreviations for calculating the arity of the constructors *}
       
   182 
   181 abbreviation
   183 abbreviation
   182   "CN f gs \<equiv> Cn (arity (hd gs)) f gs"
   184   "CN f gs \<equiv> Cn (arity (hd gs)) f gs"
   183 
   185 
   184 abbreviation
   186 abbreviation
   185   "PR f g \<equiv> Pr (arity f) f g"
   187   "PR f g \<equiv> Pr (arity f) f g"
   186 
   188 
   187 abbreviation
   189 abbreviation
   188   "MN f \<equiv> Mn (arity f - 1) f"
   190   "MN f \<equiv> Mn (arity f - 1) f"
       
   191 
       
   192 text {* the evaluation function and termination relation *}
   189 
   193 
   190 fun rec_eval :: "recf \<Rightarrow> nat list \<Rightarrow> nat"
   194 fun rec_eval :: "recf \<Rightarrow> nat list \<Rightarrow> nat"
   191   where
   195   where
   192   "rec_eval Z xs = 0" 
   196   "rec_eval Z xs = 0" 
   193 | "rec_eval S xs = Suc (xs ! 0)" 
   197 | "rec_eval S xs = Suc (xs ! 0)" 
   213 | termi_mn: "\<lbrakk>length xs = n; terminates f (r # xs); 
   217 | termi_mn: "\<lbrakk>length xs = n; terminates f (r # xs); 
   214               rec_eval f (r # xs) = 0;
   218               rec_eval f (r # xs) = 0;
   215               \<forall> i < r. terminates f (i # xs) \<and> rec_eval f (i # xs) > 0\<rbrakk> \<Longrightarrow> terminates (Mn n f) xs"
   219               \<forall> i < r. terminates f (i # xs) \<and> rec_eval f (i # xs) > 0\<rbrakk> \<Longrightarrow> terminates (Mn n f) xs"
   216 
   220 
   217 
   221 
   218 section {* Recursive Function Definitions *}
   222 section {* Arithmetic Functions *}
   219 
   223 
   220 text {*
   224 text {*
   221   @{text "constn n"} is the recursive function which computes 
   225   @{text "constn n"} is the recursive function which computes 
   222   natural number @{text "n"}.
   226   natural number @{text "n"}.
   223 *}
   227 *}
   245   "rec_pred = CN (PR Z (Id 3 0)) [Id 1 0, Id 1 0]"
   249   "rec_pred = CN (PR Z (Id 3 0)) [Id 1 0, Id 1 0]"
   246 
   250 
   247 definition 
   251 definition 
   248   "rec_minus = rec_swap (PR (Id 1 0) (CN rec_pred [Id 3 1]))"
   252   "rec_minus = rec_swap (PR (Id 1 0) (CN rec_pred [Id 3 1]))"
   249 
   253 
       
   254 lemma constn_lemma [simp]: 
       
   255   "rec_eval (constn n) xs = n"
       
   256 by (induct n) (simp_all)
       
   257 
       
   258 lemma swap_lemma [simp]:
       
   259   "rec_eval (rec_swap f) [x, y] = rec_eval f [y, x]"
       
   260 by (simp add: rec_swap_def)
       
   261 
       
   262 lemma add_lemma [simp]: 
       
   263   "rec_eval rec_add [x, y] =  x + y"
       
   264 by (induct x) (simp_all add: rec_add_def)
       
   265 
       
   266 lemma mult_lemma [simp]: 
       
   267   "rec_eval rec_mult [x, y] = x * y"
       
   268 by (induct x) (simp_all add: rec_mult_def)
       
   269 
       
   270 lemma power_lemma [simp]: 
       
   271   "rec_eval rec_power [x, y] = x ^ y"
       
   272 by (induct y) (simp_all add: rec_power_def)
       
   273 
       
   274 lemma fact_lemma [simp]: 
       
   275   "rec_eval rec_fact [x] = fact x"
       
   276 by (induct x) (simp_all add: rec_fact_def)
       
   277 
       
   278 lemma pred_lemma [simp]: 
       
   279   "rec_eval rec_pred [x] =  x - 1"
       
   280 by (induct x) (simp_all add: rec_pred_def)
       
   281 
       
   282 lemma minus_lemma [simp]: 
       
   283   "rec_eval rec_minus [x, y] = x - y"
       
   284 by (induct y) (simp_all add: rec_minus_def)
       
   285 
       
   286 
       
   287 section {* Logical functions *}
   250 
   288 
   251 text {* 
   289 text {* 
   252   The @{text "sign"} function returns 1 when the input argument 
   290   The @{text "sign"} function returns 1 when the input argument 
   253   is greater than @{text "0"}. *}
   291   is greater than @{text "0"}. *}
   254 
   292 
   284   "rec_ifz = PR (Id 2 0) (Id 4 3)"
   322   "rec_ifz = PR (Id 2 0) (Id 4 3)"
   285 
   323 
   286 definition 
   324 definition 
   287   "rec_if = CN rec_ifz [CN rec_not [Id 3 0], Id 3 1, Id 3 2]"
   325   "rec_if = CN rec_ifz [CN rec_not [Id 3 0], Id 3 1, Id 3 2]"
   288 
   326 
       
   327 
       
   328 lemma sign_lemma [simp]: 
       
   329   "rec_eval rec_sign [x] = (if x = 0 then 0 else 1)"
       
   330 by (simp add: rec_sign_def)
       
   331 
       
   332 lemma not_lemma [simp]: 
       
   333   "rec_eval rec_not [x] = (if x = 0 then 1 else 0)"
       
   334 by (simp add: rec_not_def)
       
   335 
       
   336 lemma eq_lemma [simp]: 
       
   337   "rec_eval rec_eq [x, y] = (if x = y then 1 else 0)"
       
   338 by (simp add: rec_eq_def)
       
   339 
       
   340 lemma noteq_lemma [simp]: 
       
   341   "rec_eval rec_noteq [x, y] = (if x \<noteq> y then 1 else 0)"
       
   342 by (simp add: rec_noteq_def)
       
   343 
       
   344 lemma conj_lemma [simp]: 
       
   345   "rec_eval rec_conj [x, y] = (if x = 0 \<or> y = 0 then 0 else 1)"
       
   346 by (simp add: rec_conj_def)
       
   347 
       
   348 lemma disj_lemma [simp]: 
       
   349   "rec_eval rec_disj [x, y] = (if x = 0 \<and> y = 0 then 0 else 1)"
       
   350 by (simp add: rec_disj_def)
       
   351 
       
   352 lemma imp_lemma [simp]: 
       
   353   "rec_eval rec_imp [x, y] = (if 0 < x \<and> y = 0 then 0 else 1)"
       
   354 by (simp add: rec_imp_def)
       
   355 
       
   356 lemma ifz_lemma [simp]:
       
   357   "rec_eval rec_ifz [z, x, y] = (if z = 0 then x else y)" 
       
   358 by (case_tac z) (simp_all add: rec_ifz_def)
       
   359 
       
   360 lemma if_lemma [simp]:
       
   361   "rec_eval rec_if [z, x, y] = (if 0 < z then x else y)" 
       
   362 by (simp add: rec_if_def)
       
   363 
       
   364 section {* Less and Le Relations *}
       
   365 
   289 text {*
   366 text {*
   290   @{text "rec_less"} compares two arguments and returns @{text "1"} if
   367   @{text "rec_less"} compares two arguments and returns @{text "1"} if
   291   the first is less than the second; otherwise returns @{text "0"}. *}
   368   the first is less than the second; otherwise returns @{text "0"}. *}
   292 
   369 
   293 definition 
   370 definition 
   294   "rec_less = CN rec_sign [rec_swap rec_minus]"
   371   "rec_less = CN rec_sign [rec_swap rec_minus]"
   295 
   372 
   296 definition 
   373 definition 
   297   "rec_le = CN rec_disj [rec_less, rec_eq]"
   374   "rec_le = CN rec_disj [rec_less, rec_eq]"
   298 
   375 
   299 text {* Sigma and Accum for function with one and two arguments *}
   376 lemma less_lemma [simp]: 
       
   377   "rec_eval rec_less [x, y] = (if x < y then 1 else 0)"
       
   378 by (simp add: rec_less_def)
       
   379 
       
   380 lemma le_lemma [simp]: 
       
   381   "rec_eval rec_le [x, y] = (if (x \<le> y) then 1 else 0)"
       
   382 by(simp add: rec_le_def)
       
   383 
       
   384 
       
   385 section {* Summation and Product Functions *}
   300 
   386 
   301 definition 
   387 definition 
   302   "rec_sigma1 f = PR (CN f [Z, Id 1 0]) (CN rec_add [Id 3 1, CN f [S, Id 3 2]])"
   388   "rec_sigma1 f = PR (CN f [Z, Id 1 0]) (CN rec_add [Id 3 1, CN f [S, Id 3 2]])"
   303 
   389 
   304 definition 
   390 definition 
   313 definition 
   399 definition 
   314   "rec_accum3 f = PR (CN f [Z, Id 3 0, Id 3 1, Id 3 2]) 
   400   "rec_accum3 f = PR (CN f [Z, Id 3 0, Id 3 1, Id 3 2]) 
   315                      (CN rec_mult [Id 5 1, CN f [S, Id 5 2, Id 5 3, Id 5 4]])"
   401                      (CN rec_mult [Id 5 1, CN f [S, Id 5 2, Id 5 3, Id 5 4]])"
   316 
   402 
   317 
   403 
   318 text {* Bounded quantifiers for one and two arguments *}
   404 lemma sigma1_lemma [simp]: 
       
   405   shows "rec_eval (rec_sigma1 f) [x, y] = (\<Sum> z \<le> x. (rec_eval f)  [z, y])"
       
   406 by (induct x) (simp_all add: rec_sigma1_def)
       
   407 
       
   408 lemma sigma2_lemma [simp]: 
       
   409   shows "rec_eval (rec_sigma2 f) [x, y1, y2] = (\<Sum> z \<le> x. (rec_eval f)  [z, y1, y2])"
       
   410 by (induct x) (simp_all add: rec_sigma2_def)
       
   411 
       
   412 lemma accum1_lemma [simp]: 
       
   413   shows "rec_eval (rec_accum1 f) [x, y] = (\<Prod> z \<le> x. (rec_eval f)  [z, y])"
       
   414 by (induct x) (simp_all add: rec_accum1_def)
       
   415 
       
   416 lemma accum2_lemma [simp]: 
       
   417   shows "rec_eval (rec_accum2 f) [x, y1, y2] = (\<Prod> z \<le> x. (rec_eval f)  [z, y1, y2])"
       
   418 by (induct x) (simp_all add: rec_accum2_def)
       
   419 
       
   420 lemma accum3_lemma [simp]: 
       
   421   shows "rec_eval (rec_accum3 f) [x, y1, y2, y3] = (\<Prod> z \<le> x. (rec_eval f)  [z, y1, y2, y3])"
       
   422 by (induct x) (simp_all add: rec_accum3_def)
       
   423 
       
   424 
       
   425 section {* Bounded Quantifiers *}
   319 
   426 
   320 definition
   427 definition
   321   "rec_all1 f = CN rec_sign [rec_accum1 f]"
   428   "rec_all1 f = CN rec_sign [rec_accum1 f]"
   322 
   429 
   323 definition
   430 definition
   329 definition
   436 definition
   330   "rec_all1_less f = (let f' = CN rec_disj [CN rec_eq [Id 3 0, Id 3 1], CN f [Id 3 0, Id 3 2]] 
   437   "rec_all1_less f = (let f' = CN rec_disj [CN rec_eq [Id 3 0, Id 3 1], CN f [Id 3 0, Id 3 2]] 
   331                       in CN (rec_all2 f') [Id 2 0, Id 2 0, Id 2 1])"
   438                       in CN (rec_all2 f') [Id 2 0, Id 2 0, Id 2 1])"
   332 
   439 
   333 definition
   440 definition
   334   "rec_all2_less f = (let f' = CN rec_disj [CN rec_eq [Id 4 0, Id 4 1], CN f [Id 4 0, Id 4 2, Id 4 3]] 
   441   "rec_all2_less f = (let cond1 = CN rec_eq [Id 4 0, Id 4 1] in 
   335                       in CN (rec_all3 f') [Id 3 0, Id 3 0, Id 3 1, Id 3 2])"
   442                       let cond2 = CN f [Id 4 0, Id 4 2, Id 4 3] in 
       
   443                       CN (rec_all3 (CN rec_disj [cond1, cond2])) [Id 3 0, Id 3 0, Id 3 1, Id 3 2])"
   336 
   444 
   337 definition
   445 definition
   338   "rec_ex1 f = CN rec_sign [rec_sigma1 f]"
   446   "rec_ex1 f = CN rec_sign [rec_sigma1 f]"
   339 
   447 
   340 definition
   448 definition
   341   "rec_ex2 f = CN rec_sign [rec_sigma2 f]"
   449   "rec_ex2 f = CN rec_sign [rec_sigma2 f]"
   342 
   450 
   343 text {* Dvd, Quotient, Modulo *}
   451 
   344 
   452 lemma ex1_lemma [simp]:
   345 (* FIXME: probably all not needed *)
   453  "rec_eval (rec_ex1 f) [x, y] = (if (\<exists>z \<le> x. 0 < rec_eval f [z, y]) then 1 else 0)"
   346 definition 
   454 by (simp add: rec_ex1_def)
   347   "rec_dvd = 
   455 
   348      rec_swap (CN (rec_ex2 (CN rec_eq [Id 3 2, CN rec_mult [Id 3 1, Id 3 0]])) [Id 2 0, Id 2 1, Id 2 0])"  
   456 lemma ex2_lemma [simp]:
       
   457  "rec_eval (rec_ex2 f) [x, y1, y2] = (if (\<exists>z \<le> x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"
       
   458 by (simp add: rec_ex2_def)
       
   459 
       
   460 lemma all1_lemma [simp]:
       
   461  "rec_eval (rec_all1 f) [x, y] = (if (\<forall>z \<le> x. 0 < rec_eval f [z, y]) then 1 else 0)"
       
   462 by (simp add: rec_all1_def)
       
   463 
       
   464 lemma all2_lemma [simp]:
       
   465  "rec_eval (rec_all2 f) [x, y1, y2] = (if (\<forall>z \<le> x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"
       
   466 by (simp add: rec_all2_def)
       
   467 
       
   468 lemma all3_lemma [simp]:
       
   469  "rec_eval (rec_all3 f) [x, y1, y2, y3] = (if (\<forall>z \<le> x. 0 < rec_eval f [z, y1, y2, y3]) then 1 else 0)"
       
   470 by (simp add: rec_all3_def)
       
   471 
       
   472 lemma all1_less_lemma [simp]:
       
   473   "rec_eval (rec_all1_less f) [x, y] = (if (\<forall>z < x. 0 < rec_eval f [z, y]) then 1 else 0)"
       
   474 apply(auto simp add: Let_def rec_all1_less_def)
       
   475 apply (metis nat_less_le)+
       
   476 done
       
   477 
       
   478 lemma all2_less_lemma [simp]:
       
   479   "rec_eval (rec_all2_less f) [x, y1, y2] = (if (\<forall>z < x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"
       
   480 apply(auto simp add: Let_def rec_all2_less_def)
       
   481 apply(metis nat_less_le)+
       
   482 done
       
   483 
       
   484 section {* Quotients *}
   349 
   485 
   350 definition
   486 definition
   351   "rec_quo = (let lhs = CN S [Id 3 0] in
   487   "rec_quo = (let lhs = CN S [Id 3 0] in
   352               let rhs = CN rec_mult [Id 3 2, CN S [Id 3 1]] in
   488               let rhs = CN rec_mult [Id 3 2, CN S [Id 3 1]] in
   353               let cond = CN rec_eq [lhs, rhs] in
   489               let cond = CN rec_eq [lhs, rhs] in
   354               let if_stmt = CN rec_if [cond, CN S [Id 3 1], Id 3 1]
   490               let if_stmt = CN rec_if [cond, CN S [Id 3 1], Id 3 1]
   355               in PR Z if_stmt)"
   491               in PR Z if_stmt)"
   356 
   492 
   357 definition
       
   358   "rec_mod = CN rec_minus [Id 2 0, CN rec_mult [Id 2 1, rec_quo]]"
       
   359 
       
   360 text {* Iteration *}
       
   361 
       
   362 definition
       
   363    "rec_iter f = PR (Id 2 0) (CN f [Id 3 1])"
       
   364 
       
   365 fun Iter where
       
   366   "Iter f 0 = id"
       
   367 | "Iter f (Suc n) = f \<circ> (Iter f n)"
       
   368 
       
   369 lemma Iter_comm:
       
   370   "(Iter f n) (f x) = f ((Iter f n) x)"
       
   371 by (induct n) (simp_all)
       
   372 
       
   373 lemma iter_lemma [simp]:
       
   374   "rec_eval (rec_iter f) [n, x] =  Iter (\<lambda>x. rec_eval f [x]) n x"
       
   375 by (induct n) (simp_all add: rec_iter_def)
       
   376 
       
   377 section {* Correctness of Recursive Functions *}
       
   378 
       
   379 lemma constn_lemma [simp]: 
       
   380   "rec_eval (constn n) xs = n"
       
   381 by (induct n) (simp_all)
       
   382 
       
   383 lemma swap_lemma [simp]:
       
   384   "rec_eval (rec_swap f) [x, y] = rec_eval f [y, x]"
       
   385 by (simp add: rec_swap_def)
       
   386 
       
   387 lemma add_lemma [simp]: 
       
   388   "rec_eval rec_add [x, y] =  x + y"
       
   389 by (induct x) (simp_all add: rec_add_def)
       
   390 
       
   391 lemma mult_lemma [simp]: 
       
   392   "rec_eval rec_mult [x, y] = x * y"
       
   393 by (induct x) (simp_all add: rec_mult_def)
       
   394 
       
   395 lemma power_lemma [simp]: 
       
   396   "rec_eval rec_power [x, y] = x ^ y"
       
   397 by (induct y) (simp_all add: rec_power_def)
       
   398 
       
   399 lemma fact_lemma [simp]: 
       
   400   "rec_eval rec_fact [x] = fact x"
       
   401 by (induct x) (simp_all add: rec_fact_def)
       
   402 
       
   403 lemma pred_lemma [simp]: 
       
   404   "rec_eval rec_pred [x] =  x - 1"
       
   405 by (induct x) (simp_all add: rec_pred_def)
       
   406 
       
   407 lemma minus_lemma [simp]: 
       
   408   "rec_eval rec_minus [x, y] = x - y"
       
   409 by (induct y) (simp_all add: rec_minus_def)
       
   410 
       
   411 lemma sign_lemma [simp]: 
       
   412   "rec_eval rec_sign [x] = (if x = 0 then 0 else 1)"
       
   413 by (simp add: rec_sign_def)
       
   414 
       
   415 lemma not_lemma [simp]: 
       
   416   "rec_eval rec_not [x] = (if x = 0 then 1 else 0)"
       
   417 by (simp add: rec_not_def)
       
   418 
       
   419 lemma eq_lemma [simp]: 
       
   420   "rec_eval rec_eq [x, y] = (if x = y then 1 else 0)"
       
   421 by (simp add: rec_eq_def)
       
   422 
       
   423 lemma noteq_lemma [simp]: 
       
   424   "rec_eval rec_noteq [x, y] = (if x \<noteq> y then 1 else 0)"
       
   425 by (simp add: rec_noteq_def)
       
   426 
       
   427 lemma conj_lemma [simp]: 
       
   428   "rec_eval rec_conj [x, y] = (if x = 0 \<or> y = 0 then 0 else 1)"
       
   429 by (simp add: rec_conj_def)
       
   430 
       
   431 lemma disj_lemma [simp]: 
       
   432   "rec_eval rec_disj [x, y] = (if x = 0 \<and> y = 0 then 0 else 1)"
       
   433 by (simp add: rec_disj_def)
       
   434 
       
   435 lemma imp_lemma [simp]: 
       
   436   "rec_eval rec_imp [x, y] = (if 0 < x \<and> y = 0 then 0 else 1)"
       
   437 by (simp add: rec_imp_def)
       
   438 
       
   439 lemma less_lemma [simp]: 
       
   440   "rec_eval rec_less [x, y] = (if x < y then 1 else 0)"
       
   441 by (simp add: rec_less_def)
       
   442 
       
   443 lemma le_lemma [simp]: 
       
   444   "rec_eval rec_le [x, y] = (if (x \<le> y) then 1 else 0)"
       
   445 by(simp add: rec_le_def)
       
   446 
       
   447 lemma ifz_lemma [simp]:
       
   448   "rec_eval rec_ifz [z, x, y] = (if z = 0 then x else y)" 
       
   449 by (case_tac z) (simp_all add: rec_ifz_def)
       
   450 
       
   451 lemma if_lemma [simp]:
       
   452   "rec_eval rec_if [z, x, y] = (if 0 < z then x else y)" 
       
   453 by (simp add: rec_if_def)
       
   454 
       
   455 lemma sigma1_lemma [simp]: 
       
   456   shows "rec_eval (rec_sigma1 f) [x, y] = (\<Sum> z \<le> x. (rec_eval f)  [z, y])"
       
   457 by (induct x) (simp_all add: rec_sigma1_def)
       
   458 
       
   459 lemma sigma2_lemma [simp]: 
       
   460   shows "rec_eval (rec_sigma2 f) [x, y1, y2] = (\<Sum> z \<le> x. (rec_eval f)  [z, y1, y2])"
       
   461 by (induct x) (simp_all add: rec_sigma2_def)
       
   462 
       
   463 lemma accum1_lemma [simp]: 
       
   464   shows "rec_eval (rec_accum1 f) [x, y] = (\<Prod> z \<le> x. (rec_eval f)  [z, y])"
       
   465 by (induct x) (simp_all add: rec_accum1_def)
       
   466 
       
   467 lemma accum2_lemma [simp]: 
       
   468   shows "rec_eval (rec_accum2 f) [x, y1, y2] = (\<Prod> z \<le> x. (rec_eval f)  [z, y1, y2])"
       
   469 by (induct x) (simp_all add: rec_accum2_def)
       
   470 
       
   471 lemma accum3_lemma [simp]: 
       
   472   shows "rec_eval (rec_accum3 f) [x, y1, y2, y3] = (\<Prod> z \<le> x. (rec_eval f)  [z, y1, y2, y3])"
       
   473 by (induct x) (simp_all add: rec_accum3_def)
       
   474 
       
   475 lemma ex1_lemma [simp]:
       
   476  "rec_eval (rec_ex1 f) [x, y] = (if (\<exists>z \<le> x. 0 < rec_eval f [z, y]) then 1 else 0)"
       
   477 by (simp add: rec_ex1_def)
       
   478 
       
   479 lemma ex2_lemma [simp]:
       
   480  "rec_eval (rec_ex2 f) [x, y1, y2] = (if (\<exists>z \<le> x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"
       
   481 by (simp add: rec_ex2_def)
       
   482 
       
   483 lemma all1_lemma [simp]:
       
   484  "rec_eval (rec_all1 f) [x, y] = (if (\<forall>z \<le> x. 0 < rec_eval f [z, y]) then 1 else 0)"
       
   485 by (simp add: rec_all1_def)
       
   486 
       
   487 lemma all2_lemma [simp]:
       
   488  "rec_eval (rec_all2 f) [x, y1, y2] = (if (\<forall>z \<le> x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"
       
   489 by (simp add: rec_all2_def)
       
   490 
       
   491 lemma all3_lemma [simp]:
       
   492  "rec_eval (rec_all3 f) [x, y1, y2, y3] = (if (\<forall>z \<le> x. 0 < rec_eval f [z, y1, y2, y3]) then 1 else 0)"
       
   493 by (simp add: rec_all3_def)
       
   494 
       
   495 lemma all1_less_lemma [simp]:
       
   496   "rec_eval (rec_all1_less f) [x, y] = (if (\<forall>z < x. 0 < rec_eval f [z, y]) then 1 else 0)"
       
   497 apply(auto simp add: Let_def rec_all1_less_def)
       
   498 apply (metis nat_less_le)+
       
   499 done
       
   500 
       
   501 lemma all2_less_lemma [simp]:
       
   502   "rec_eval (rec_all2_less f) [x, y1, y2] = (if (\<forall>z < x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"
       
   503 apply(auto simp add: Let_def rec_all2_less_def)
       
   504 apply(metis nat_less_le)+
       
   505 done
       
   506 
       
   507 
       
   508 lemma dvd_alt_def:
       
   509   fixes x y k:: nat
       
   510   shows "(x dvd y) = (\<exists> k \<le> y. y = x * k)"
       
   511 apply(auto simp add: dvd_def)
       
   512 apply(case_tac x)
       
   513 apply(auto)
       
   514 done
       
   515 
       
   516 lemma dvd_lemma [simp]:
       
   517   "rec_eval rec_dvd [x, y] = (if x dvd y then 1 else 0)"
       
   518 unfolding dvd_alt_def
       
   519 by (auto simp add: rec_dvd_def)
       
   520 
       
   521 fun Quo where
   493 fun Quo where
   522   "Quo x 0 = 0"
   494   "Quo x 0 = 0"
   523 | "Quo x (Suc y) = (if (Suc y = x * (Suc (Quo x y))) then Suc (Quo x y) else Quo x y)"
   495 | "Quo x (Suc y) = (if (Suc y = x * (Suc (Quo x y))) then Suc (Quo x y) else Quo x y)"
   524 
   496 
   525 lemma Quo0:
   497 lemma Quo0:
   526   shows "Quo 0 y = 0"
   498   shows "Quo 0 y = 0"
   527 apply(induct y)
   499 by (induct y) (auto)
   528 apply(auto)
       
   529 done
       
   530 
   500 
   531 lemma Quo1:
   501 lemma Quo1:
   532   "x * (Quo x y) \<le> y"
   502   "x * (Quo x y) \<le> y"
   533 by (induct y) (simp_all)
   503 by (induct y) (simp_all)
   534 
   504 
   564 
   534 
   565 lemma quo_lemma [simp]:
   535 lemma quo_lemma [simp]:
   566   shows "rec_eval rec_quo [y, x] = y div x"
   536   shows "rec_eval rec_quo [y, x] = y div x"
   567 by (simp add: Quo_div Quo_rec_quo)
   537 by (simp add: Quo_div Quo_rec_quo)
   568 
   538 
   569 lemma rem_lemma [simp]:
   539 
   570   shows "rec_eval rec_mod [y, x] = y mod x"
   540 section {* Iteration *}
   571 by (simp add: rec_mod_def mod_div_equality' nat_mult_commute)
   541 
       
   542 definition
       
   543    "rec_iter f = PR (Id 2 0) (CN f [Id 3 1])"
       
   544 
       
   545 fun Iter where
       
   546   "Iter f 0 = id"
       
   547 | "Iter f (Suc n) = f \<circ> (Iter f n)"
       
   548 
       
   549 lemma Iter_comm:
       
   550   "(Iter f n) (f x) = f ((Iter f n) x)"
       
   551 by (induct n) (simp_all)
       
   552 
       
   553 lemma iter_lemma [simp]:
       
   554   "rec_eval (rec_iter f) [n, x] =  Iter (\<lambda>x. rec_eval f [x]) n x"
       
   555 by (induct n) (simp_all add: rec_iter_def)
   572 
   556 
   573 
   557 
   574 section {* Bounded Maximisation *}
   558 section {* Bounded Maximisation *}
   575 
   559 
   576 fun BMax_rec where
   560 fun BMax_rec where
   577   "BMax_rec R 0 = 0"
   561   "BMax_rec R 0 = 0"
   578 | "BMax_rec R (Suc n) = (if R (Suc n) then (Suc n) else BMax_rec R n)"
   562 | "BMax_rec R (Suc n) = (if R (Suc n) then (Suc n) else BMax_rec R n)"
   579 
   563 
   580 definition BMax_set :: "(nat \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> nat"
   564 definition 
   581   where "BMax_set R x = Max ({z. z \<le> x \<and> R z} \<union> {0})"
   565   BMax_set :: "(nat \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> nat"
       
   566 where 
       
   567   "BMax_set R x = Max ({z. z \<le> x \<and> R z} \<union> {0})"
   582 
   568 
   583 lemma BMax_rec_eq1:
   569 lemma BMax_rec_eq1:
   584  "BMax_rec R x = (GREATEST z. (R z \<and> z \<le> x) \<or> z = 0)"
   570  "BMax_rec R x = (GREATEST z. (R z \<and> z \<le> x) \<or> z = 0)"
   585 apply(induct x)
   571 apply(induct x)
   586 apply(auto intro: Greatest_equality Greatest_equality[symmetric])
   572 apply(auto intro: Greatest_equality Greatest_equality[symmetric])
   609   "rec_max2 f = PR (constn 0) (CN rec_ifz [CN f [CN S [Id 4 0], Id 4 2, Id 4 3], CN S [Id 4 0], Id 4 1])"
   595   "rec_max2 f = PR (constn 0) (CN rec_ifz [CN f [CN S [Id 4 0], Id 4 2, Id 4 3], CN S [Id 4 0], Id 4 1])"
   610  
   596  
   611 lemma max2_lemma [simp]:
   597 lemma max2_lemma [simp]:
   612   "rec_eval (rec_max2 f) [x, y1, y2] = BMax_rec (\<lambda>u. rec_eval f [u, y1, y2] = 0) x"
   598   "rec_eval (rec_max2 f) [x, y1, y2] = BMax_rec (\<lambda>u. rec_eval f [u, y1, y2] = 0) x"
   613 by (induct x) (simp_all add: rec_max2_def)
   599 by (induct x) (simp_all add: rec_max2_def)
       
   600 
   614 
   601 
   615 section {* Encodings using Cantor's pairing function *}
   602 section {* Encodings using Cantor's pairing function *}
   616 
   603 
   617 text {*
   604 text {*
   618   We use Cantor's pairing function from Nat_Bijection.
   605   We use Cantor's pairing function from Nat_Bijection.
   695 apply(simp only: w_aux)
   682 apply(simp only: w_aux)
   696 apply(rule y_aux)
   683 apply(rule y_aux)
   697 apply(simp)
   684 apply(simp)
   698 done
   685 done
   699 
   686 
       
   687 
   700 definition 
   688 definition 
   701   "rec_triangle = CN rec_quo [CN rec_mult [Id 1 0, S], constn 2]"
   689   "rec_triangle = CN rec_quo [CN rec_mult [Id 1 0, S], constn 2]"
       
   690 
       
   691 definition
       
   692   "rec_max_triangle = 
       
   693        (let cond = CN rec_not [CN rec_le [CN rec_triangle [Id 2 0], Id 2 1]] in
       
   694         CN (rec_max1 cond) [Id 1 0, Id 1 0])"
       
   695 
   702 
   696 
   703 lemma triangle_lemma [simp]:
   697 lemma triangle_lemma [simp]:
   704   "rec_eval rec_triangle [x] = triangle x"
   698   "rec_eval rec_triangle [x] = triangle x"
   705 by (simp add: rec_triangle_def triangle_def)
   699 by (simp add: rec_triangle_def triangle_def)
   706  
   700  
   707 definition
       
   708   "rec_max_triangle = 
       
   709        (let cond = CN rec_not [CN rec_le [CN rec_triangle [Id 2 0], Id 2 1]] in
       
   710         CN (rec_max1 cond) [Id 1 0, Id 1 0])"
       
   711 
       
   712 lemma max_triangle_lemma [simp]:
   701 lemma max_triangle_lemma [simp]:
   713   "rec_eval rec_max_triangle [x] = Max_triangle x"
   702   "rec_eval rec_max_triangle [x] = Max_triangle x"
   714 by (simp add: Max_triangle_greatest rec_max_triangle_def Let_def BMax_rec_eq1) 
   703 by (simp add: Max_triangle_greatest rec_max_triangle_def Let_def BMax_rec_eq1) 
   715 
   704 
       
   705 
       
   706 text {* Encodings for Products *}
       
   707 
   716 definition
   708 definition
   717   "rec_penc = CN rec_add [CN rec_triangle [CN rec_add [Id 2 0, Id 2 1]], Id 2 0]"
   709   "rec_penc = CN rec_add [CN rec_triangle [CN rec_add [Id 2 0, Id 2 1]], Id 2 0]"
   718 
   710 
   719 definition 
   711 definition 
   720   "rec_pdec1 = CN rec_minus [Id 1 0, CN rec_triangle [CN rec_max_triangle [Id 1 0]]]" 
   712   "rec_pdec1 = CN rec_minus [Id 1 0, CN rec_triangle [CN rec_max_triangle [Id 1 0]]]" 
   732 
   724 
   733 lemma penc_lemma [simp]:
   725 lemma penc_lemma [simp]:
   734   "rec_eval rec_penc [m, n] = penc m n"
   726   "rec_eval rec_penc [m, n] = penc m n"
   735 by (simp add: rec_penc_def prod_encode_def)
   727 by (simp add: rec_penc_def prod_encode_def)
   736 
   728 
   737 text {* encoding and decoding of lists of natural numbers *}
   729 
       
   730 text {* Encodings of Lists *}
   738 
   731 
   739 fun 
   732 fun 
   740   lenc :: "nat list \<Rightarrow> nat" 
   733   lenc :: "nat list \<Rightarrow> nat" 
   741 where
   734 where
   742   "lenc [] = 0"
   735   "lenc [] = 0"
   760 lemma list_encode_inverse: 
   753 lemma list_encode_inverse: 
   761   "ldec (lenc xs) n = (if n < length xs then xs ! n else 0)"
   754   "ldec (lenc xs) n = (if n < length xs then xs ! n else 0)"
   762 by (induct xs arbitrary: n rule: lenc.induct) 
   755 by (induct xs arbitrary: n rule: lenc.induct) 
   763    (auto simp add: ldec_zero nth_Cons split: nat.splits)
   756    (auto simp add: ldec_zero nth_Cons split: nat.splits)
   764 
   757 
   765 
       
   766 lemma lenc_length_le:
   758 lemma lenc_length_le:
   767   "length xs \<le> lenc xs"  
   759   "length xs \<le> lenc xs"  
   768 by (induct xs) (simp_all add: prod_encode_def)
   760 by (induct xs) (simp_all add: prod_encode_def)
       
   761 
       
   762 
       
   763 text {* Membership for the List Encoding *}
   769 
   764 
   770 fun within :: "nat \<Rightarrow> nat \<Rightarrow> bool" where
   765 fun within :: "nat \<Rightarrow> nat \<Rightarrow> bool" where
   771   "within z 0 = (0 < z)"
   766   "within z 0 = (0 < z)"
   772 | "within z (Suc n) = within (pdec2 z) n"
   767 | "within z (Suc n) = within (pdec2 z) n"
   773     
   768     
   785 apply(simp_all add: prod_encode_def)
   780 apply(simp_all add: prod_encode_def)
   786 apply(case_tac xs)
   781 apply(case_tac xs)
   787 apply(simp_all)
   782 apply(simp_all)
   788 done
   783 done
   789 
   784 
       
   785 text {* Length of Encoded Lists *}
       
   786 
   790 lemma enclen_length [simp]:
   787 lemma enclen_length [simp]:
   791   "enclen (lenc xs) = length xs"
   788   "enclen (lenc xs) = length xs"
   792 unfolding enclen_def
   789 unfolding enclen_def
   793 apply(simp add: BMax_rec_eq1)
   790 apply(simp add: BMax_rec_eq1)
   794 apply(rule Greatest_equality)
   791 apply(rule Greatest_equality)
   801 
   798 
   802 lemma enclen_zero [simp]:
   799 lemma enclen_zero [simp]:
   803   "enclen 0 = 0"
   800   "enclen 0 = 0"
   804 by (simp add: enclen_def)
   801 by (simp add: enclen_def)
   805 
   802 
       
   803 
       
   804 text {* Recursive De3finitions for List Encodings *}
       
   805 
   806 fun 
   806 fun 
   807   rec_lenc :: "recf list \<Rightarrow> recf" 
   807   rec_lenc :: "recf list \<Rightarrow> recf" 
   808 where
   808 where
   809   "rec_lenc [] = Z"
   809   "rec_lenc [] = Z"
   810 | "rec_lenc (f # fs) = CN rec_penc [CN S [f], rec_lenc fs]"
   810 | "rec_lenc (f # fs) = CN rec_penc [CN S [f], rec_lenc fs]"
   817 
   817 
   818 definition
   818 definition
   819   "rec_enclen = CN (rec_max1 (CN rec_not [CN rec_within [Id 2 1, CN rec_pred [Id 2 0]]])) [Id 1 0, Id 1 0]"
   819   "rec_enclen = CN (rec_max1 (CN rec_not [CN rec_within [Id 2 1, CN rec_pred [Id 2 0]]])) [Id 1 0, Id 1 0]"
   820 
   820 
   821 lemma ldec_iter:
   821 lemma ldec_iter:
   822   "ldec z n = pdec1 ((Iter pdec2 n) z) - 1"
   822   "ldec z n = pdec1 (Iter pdec2 n z) - 1"
   823 by (induct n arbitrary: z) (simp | subst Iter_comm)+
   823 by (induct n arbitrary: z) (simp | subst Iter_comm)+
   824 
   824 
   825 lemma within_iter:
   825 lemma within_iter:
   826   "within z n = (0 < (Iter pdec2 n) z)"
   826   "within z n = (0 < Iter pdec2 n z)"
   827 by (induct n arbitrary: z) (simp | subst Iter_comm)+
   827 by (induct n arbitrary: z) (simp | subst Iter_comm)+
   828 
   828 
   829 lemma lenc_lemma [simp]:
   829 lemma lenc_lemma [simp]:
   830   "rec_eval (rec_lenc fs) xs = lenc (map (\<lambda>f. rec_eval f xs) fs)"
   830   "rec_eval (rec_lenc fs) xs = lenc (map (\<lambda>f. rec_eval f xs) fs)"
   831 by (induct fs) (simp_all)
   831 by (induct fs) (simp_all)