thys/Recs.thy
changeset 20 e04123f4bacc
parent 15 e3ecf558aef2
equal deleted inserted replaced
19:087d82632852 20:e04123f4bacc
   220 
   220 
   221 
   221 
   222 section {* Arithmetic Functions *}
   222 section {* Arithmetic Functions *}
   223 
   223 
   224 text {*
   224 text {*
   225   @{text "constn n"} is the recursive function which computes 
   225   @{text "constn n"} is the recursive function which generates
   226   natural number @{text "n"}.
   226   the natural number @{text "n"}. *}
   227 *}
   227 
   228 fun constn :: "nat \<Rightarrow> recf"
   228 fun constn :: "nat \<Rightarrow> recf"
   229   where
   229   where
   230   "constn 0 = Z"  |
   230   "constn 0 = Z"  |
   231   "constn (Suc n) = CN S [constn n]"
   231   "constn (Suc n) = CN S [constn n]"
   232 
   232 
   252   "rec_pred = CN (PR Z (Id 3 0)) [Id 1 0, Id 1 0]"
   252   "rec_pred = CN (PR Z (Id 3 0)) [Id 1 0, Id 1 0]"
   253 
   253 
   254 definition 
   254 definition 
   255   "rec_minus = rec_swap (PR (Id 1 0) (CN rec_pred [Id 3 1]))"
   255   "rec_minus = rec_swap (PR (Id 1 0) (CN rec_pred [Id 3 1]))"
   256 
   256 
       
   257 
   257 lemma constn_lemma [simp]: 
   258 lemma constn_lemma [simp]: 
   258   "rec_eval (constn n) xs = n"
   259   "rec_eval (constn n) xs = n"
   259 by (induct n) (simp_all)
   260 by (induct n) (simp_all)
   260 
   261 
   261 lemma swap_lemma [simp]:
   262 lemma swap_lemma [simp]:
   281 lemma fact_lemma [simp]: 
   282 lemma fact_lemma [simp]: 
   282   "rec_eval rec_fact [x] = fact x"
   283   "rec_eval rec_fact [x] = fact x"
   283 by (simp add: rec_fact_def)
   284 by (simp add: rec_fact_def)
   284 
   285 
   285 lemma pred_lemma [simp]: 
   286 lemma pred_lemma [simp]: 
   286   "rec_eval rec_pred [x] =  x - 1"
   287   "rec_eval rec_pred [x] = x - 1"
   287 by (induct x) (simp_all add: rec_pred_def)
   288 by (induct x) (simp_all add: rec_pred_def)
   288 
   289 
   289 lemma minus_lemma [simp]: 
   290 lemma minus_lemma [simp]: 
   290   "rec_eval rec_minus [x, y] = x - y"
   291   "rec_eval rec_minus [x, y] = x - y"
   291 by (induct y) (simp_all add: rec_minus_def)
   292 by (induct y) (simp_all add: rec_minus_def)
   292 
   293 
   293 
   294 
   294 section {* Logical functions *}
   295 section {* Logical Functions *}
   295 
   296 
   296 text {* 
   297 text {* 
   297   The @{text "sign"} function returns 1 when the input argument 
   298   The @{text "sign"} function returns 1 when the input argument 
   298   is greater than @{text "0"}. *}
   299   is greater than @{text "0"}. *}
   299 
   300 
   319   "rec_disj = CN rec_sign [rec_add]"
   320   "rec_disj = CN rec_sign [rec_add]"
   320 
   321 
   321 definition 
   322 definition 
   322   "rec_imp = CN rec_disj [CN rec_not [Id 2 0], Id 2 1]"
   323   "rec_imp = CN rec_disj [CN rec_not [Id 2 0], Id 2 1]"
   323 
   324 
   324 text {* @{term "rec_ifz [z, x, y]"} returns x if z is zero,
   325 text {* @{term "rec_ifz [z, x, y]"} returns @{text x} if @{text z} is zero, and
   325   y otherwise;  @{term "rec_if [z, x, y]"} returns x if z is *not*
   326   @{text y} otherwise;  @{term "rec_if [z, x, y]"} returns @{text x} if @{text z} 
   326   zero, y otherwise *}
   327   is *not* zero, and @{text y} otherwise. *}
   327 
   328 
   328 definition 
   329 definition 
   329   "rec_ifz = PR (Id 2 0) (Id 4 3)"
   330   "rec_ifz = PR (Id 2 0) (Id 4 3)"
   330 
   331 
   331 definition 
   332 definition 
   366 
   367 
   367 lemma if_lemma [simp]:
   368 lemma if_lemma [simp]:
   368   "rec_eval rec_if [z, x, y] = (if 0 < z then x else y)" 
   369   "rec_eval rec_if [z, x, y] = (if 0 < z then x else y)" 
   369 by (simp add: rec_if_def)
   370 by (simp add: rec_if_def)
   370 
   371 
   371 section {* Less and Le Relations *}
   372 
       
   373 section {* The Less and Less-Equal Relations *}
   372 
   374 
   373 text {*
   375 text {*
   374   @{text "rec_less"} compares two arguments and returns @{text "1"} if
   376   @{text "rec_less"} compares two arguments and returns @{text "1"} if
   375   the first is less than the second; otherwise returns @{text "0"}. *}
   377   the first is less than the second; otherwise it returns @{text "0"}. *}
   376 
   378 
   377 definition 
   379 definition 
   378   "rec_less = CN rec_sign [rec_swap rec_minus]"
   380   "rec_less = CN rec_sign [rec_swap rec_minus]"
   379 
   381 
   380 definition 
   382 definition 
   383 lemma less_lemma [simp]: 
   385 lemma less_lemma [simp]: 
   384   "rec_eval rec_less [x, y] = (if x < y then 1 else 0)"
   386   "rec_eval rec_less [x, y] = (if x < y then 1 else 0)"
   385 by (simp add: rec_less_def)
   387 by (simp add: rec_less_def)
   386 
   388 
   387 lemma le_lemma [simp]: 
   389 lemma le_lemma [simp]: 
   388   "rec_eval rec_le [x, y] = (if (x \<le> y) then 1 else 0)"
   390   "rec_eval rec_le [x, y] = (if x \<le> y then 1 else 0)"
   389 by(simp add: rec_le_def)
   391 by (simp add: rec_le_def)
   390 
   392 
   391 
   393 
   392 section {* Summation and Product Functions *}
   394 section {* Summation and Product Functions *}
   393 
   395 
   394 definition 
   396 definition 
   433 by (induct x) (simp_all add: rec_accum3_def)
   435 by (induct x) (simp_all add: rec_accum3_def)
   434 
   436 
   435 
   437 
   436 section {* Bounded Quantifiers *}
   438 section {* Bounded Quantifiers *}
   437 
   439 
       
   440 text {* Instead of defining quantifiers taking an aritrary 
       
   441   list of arguments, we define the simpler quantifiers taking
       
   442   one, two and three extra arguments besides the argument
       
   443   that is quantified over. *}
       
   444 
   438 definition
   445 definition
   439   "rec_all1 f = CN rec_sign [rec_accum1 f]"
   446   "rec_all1 f = CN rec_sign [rec_accum1 f]"
   440 
   447 
   441 definition
   448 definition
   442   "rec_all2 f = CN rec_sign [rec_accum2 f]"
   449   "rec_all2 f = CN rec_sign [rec_accum2 f]"
   482 by (simp add: rec_all3_def)
   489 by (simp add: rec_all3_def)
   483 
   490 
   484 lemma all1_less_lemma [simp]:
   491 lemma all1_less_lemma [simp]:
   485   "rec_eval (rec_all1_less f) [x, y] = (if (\<forall>z < x. 0 < rec_eval f [z, y]) then 1 else 0)"
   492   "rec_eval (rec_all1_less f) [x, y] = (if (\<forall>z < x. 0 < rec_eval f [z, y]) then 1 else 0)"
   486 apply(auto simp add: Let_def rec_all1_less_def)
   493 apply(auto simp add: Let_def rec_all1_less_def)
   487 apply (metis nat_less_le)+
   494 apply(metis nat_less_le)+
   488 done
   495 done
   489 
   496 
   490 lemma all2_less_lemma [simp]:
   497 lemma all2_less_lemma [simp]:
   491   "rec_eval (rec_all2_less f) [x, y1, y2] = (if (\<forall>z < x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"
   498   "rec_eval (rec_all2_less f) [x, y1, y2] = (if (\<forall>z < x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"
   492 apply(auto simp add: Let_def rec_all2_less_def)
   499 apply(auto simp add: Let_def rec_all2_less_def)
   493 apply(metis nat_less_le)+
   500 apply(metis nat_less_le)+
   494 done
   501 done
   495 
   502 
   496 section {* Quotients *}
   503 
   497 
   504 section {* Natural Number Division *}
   498 definition
   505 
   499   "rec_quo = (let lhs = CN S [Id 3 0] in
   506 definition
       
   507   "rec_div = (let lhs = CN S [Id 3 0] in
   500               let rhs = CN rec_mult [Id 3 2, CN S [Id 3 1]] in
   508               let rhs = CN rec_mult [Id 3 2, CN S [Id 3 1]] in
   501               let cond = CN rec_eq [lhs, rhs] in
   509               let cond = CN rec_eq [lhs, rhs] in
   502               let if_stmt = CN rec_if [cond, CN S [Id 3 1], Id 3 1]
   510               let if_stmt = CN rec_if [cond, CN S [Id 3 1], Id 3 1]
   503               in PR Z if_stmt)"
   511               in PR Z if_stmt)"
   504 
   512 
   505 fun Quo where
   513 fun Div where
   506   "Quo x 0 = 0"
   514   "Div x 0 = 0"
   507 | "Quo x (Suc y) = (if (Suc y = x * (Suc (Quo x y))) then Suc (Quo x y) else Quo x y)"
   515 | "Div x (Suc y) = (if (Suc y = x * (Suc (Div x y))) then Suc (Div x y) else Div x y)"
   508 
   516 
   509 lemma Quo0:
   517 lemma Div0:
   510   shows "Quo 0 y = 0"
   518   shows "Div 0 y = 0"
   511 by (induct y) (auto)
   519 by (induct y) (auto)
   512 
   520 
   513 lemma Quo1:
   521 lemma Div1:
   514   "x * (Quo x y) \<le> y"
   522   "x * (Div x y) \<le> y"
   515 by (induct y) (simp_all)
   523 by (induct y) (simp_all)
   516 
   524 
   517 lemma Quo2: 
   525 lemma Div2: 
   518   "b * (Quo b a) + a mod b = a"
   526   "x * (Div x y) + y mod x = y"
   519 by (induct a) (auto simp add: mod_Suc)
   527 by (induct y) (auto simp add: mod_Suc)
   520 
   528 
   521 lemma Quo3:
   529 lemma Div3:
   522   "n * (Quo n m) = m - m mod n"
   530   "x * (Div x y) = y - y mod x"
   523 using Quo2[of n m] by (auto)
   531 using Div2[of x y] by (auto)
   524 
   532 
   525 lemma Quo4:
   533 lemma Div4:
   526   assumes h: "0 < x"
   534   assumes h: "0 < x"
   527   shows "y < x + x * Quo x y"
   535   shows "y < x + x * Div x y"
   528 proof -
   536 proof -
   529   have "x - (y mod x) > 0" using mod_less_divisor assms by auto
   537   have "x - (y mod x) > 0" using mod_less_divisor assms by auto
   530   then have "y < y + (x - (y mod x))" by simp
   538   then have "y < y + (x - (y mod x))" by simp
   531   then have "y < x + (y - (y mod x))" by simp
   539   then have "y < x + (y - (y mod x))" by simp
   532   then show "y < x + x * (Quo x y)" by (simp add: Quo3) 
   540   then show "y < x + x * (Div x y)" by (simp add: Div3) 
   533 qed
   541 qed
   534 
   542 
   535 lemma Quo_div: 
   543 lemma Div_div: 
   536   shows "Quo x y = y div x"
   544   shows "Div x y = y div x"
   537 apply(case_tac "x = 0")
   545 apply(case_tac "x = 0")
   538 apply(simp add: Quo0)
   546 apply(simp add: Div0)
   539 apply(subst split_div_lemma[symmetric])
   547 apply(subst split_div_lemma[symmetric])
   540 apply(auto intro: Quo1 Quo4)
   548 apply(auto intro: Div1 Div4)
   541 done
   549 done
   542 
   550 
   543 lemma Quo_rec_quo:
   551 lemma Div_rec_div:
   544   shows "rec_eval rec_quo [y, x] = Quo x y"
   552   shows "rec_eval rec_div [y, x] = Div x y"
   545 by (induct y) (simp_all add: rec_quo_def)
   553 by (induct y) (simp_all add: rec_div_def)
   546 
   554 
   547 lemma quo_lemma [simp]:
   555 lemma div_lemma [simp]:
   548   shows "rec_eval rec_quo [y, x] = y div x"
   556   shows "rec_eval rec_div [y, x] = y div x"
   549 by (simp add: Quo_div Quo_rec_quo)
   557 by (simp add: Div_div Div_rec_div)
   550 
   558 
   551 
   559 
   552 section {* Iteration *}
   560 section {* Iteration *}
   553 
   561 
   554 definition
   562 definition
   567 by (induct n) (simp_all add: rec_iter_def)
   575 by (induct n) (simp_all add: rec_iter_def)
   568 
   576 
   569 
   577 
   570 section {* Bounded Maximisation *}
   578 section {* Bounded Maximisation *}
   571 
   579 
       
   580 text {* Computes the greatest number below a bound @{text n}
       
   581   such that a predicate holds. If such a maximum does not exist,
       
   582   then @{text 0} is returned. *}
   572 
   583 
   573 fun BMax_rec where
   584 fun BMax_rec where
   574   "BMax_rec R 0 = 0"
   585   "BMax_rec R 0 = 0"
   575 | "BMax_rec R (Suc n) = (if R (Suc n) then (Suc n) else BMax_rec R n)"
   586 | "BMax_rec R (Suc n) = (if R (Suc n) then (Suc n) else BMax_rec R n)"
   576 
   587 
   592 apply(auto intro: Max_eqI Max_eqI[symmetric])
   603 apply(auto intro: Max_eqI Max_eqI[symmetric])
   593 apply(simp add: le_Suc_eq)
   604 apply(simp add: le_Suc_eq)
   594 by metis
   605 by metis
   595 
   606 
   596 lemma BMax_rec_eq3:
   607 lemma BMax_rec_eq3:
   597   "BMax_rec R x = Max (Set.filter (\<lambda>z. R z) {..x} \<union> {0})"
   608   "BMax_rec R x = Max (Set.filter R {..x} \<union> {0})"
   598 by (simp add: BMax_rec_eq2 Set.filter_def)
   609 by (simp add: BMax_rec_eq2 Set.filter_def)
   599 
   610 
   600 definition 
   611 definition 
   601   "rec_max1 f = PR Z (CN rec_ifz [CN f [CN S [Id 3 0], Id 3 2], CN S [Id 3 0], Id 3 1])"
   612   "rec_max1 f = PR Z (CN rec_ifz [CN f [CN S [Id 3 0], Id 3 2], CN S [Id 3 0], Id 3 1])"
   602  
   613  
   610 lemma max2_lemma [simp]:
   621 lemma max2_lemma [simp]:
   611   "rec_eval (rec_max2 f) [x, y1, y2] = BMax_rec (\<lambda>u. rec_eval f [u, y1, y2] = 0) x"
   622   "rec_eval (rec_max2 f) [x, y1, y2] = BMax_rec (\<lambda>u. rec_eval f [u, y1, y2] = 0) x"
   612 by (induct x) (simp_all add: rec_max2_def)
   623 by (induct x) (simp_all add: rec_max2_def)
   613 
   624 
   614 
   625 
   615 section {* Encodings using Cantor's pairing function *}
   626 section {* Encodings using Cantor's Pairing Function *}
   616 
   627 
   617 text {*
   628 text {* We use Cantor's pairing function from the theory 
   618   We use Cantor's pairing function from Nat_Bijection.
   629   Nat_Bijection. However, we need to prove that the formulation 
   619   However, we need to prove that the formulation of the
   630   of the decoding function there is recursive. For this we first 
   620   decoding function there is recursive. For this we first 
       
   621   prove that we can extract the maximal triangle number 
   631   prove that we can extract the maximal triangle number 
   622   using @{term prod_decode}.
   632   using @{term prod_decode}.
   623 *}
   633 *}
   624 
   634 
   625 abbreviation Max_triangle_aux where
   635 abbreviation Max_triangle_aux where
   697 apply(simp)
   707 apply(simp)
   698 done
   708 done
   699 
   709 
   700 
   710 
   701 definition 
   711 definition 
   702   "rec_triangle = CN rec_quo [CN rec_mult [Id 1 0, S], constn 2]"
   712   "rec_triangle = CN rec_div [CN rec_mult [Id 1 0, S], constn 2]"
   703 
   713 
   704 definition
   714 definition
   705   "rec_max_triangle = 
   715   "rec_max_triangle = 
   706        (let cond = CN rec_not [CN rec_le [CN rec_triangle [Id 2 0], Id 2 1]] in
   716        (let cond = CN rec_not [CN rec_le [CN rec_triangle [Id 2 0], Id 2 1]] in
   707         CN (rec_max1 cond) [Id 1 0, Id 1 0])"
   717         CN (rec_max1 cond) [Id 1 0, Id 1 0])"
   714 lemma max_triangle_lemma [simp]:
   724 lemma max_triangle_lemma [simp]:
   715   "rec_eval rec_max_triangle [x] = Max_triangle x"
   725   "rec_eval rec_max_triangle [x] = Max_triangle x"
   716 by (simp add: Max_triangle_greatest rec_max_triangle_def Let_def BMax_rec_eq1) 
   726 by (simp add: Max_triangle_greatest rec_max_triangle_def Let_def BMax_rec_eq1) 
   717 
   727 
   718 
   728 
   719 text {* Encodings for Products *}
   729 text {* Encodings for Pairs of Natural Numbers *}
   720 
   730 
   721 definition
   731 definition
   722   "rec_penc = CN rec_add [CN rec_triangle [CN rec_add [Id 2 0, Id 2 1]], Id 2 0]"
   732   "rec_penc = CN rec_add [CN rec_triangle [CN rec_add [Id 2 0, Id 2 1]], Id 2 0]"
   723 
   733 
   724 definition 
   734 definition 
   738 lemma penc_lemma [simp]:
   748 lemma penc_lemma [simp]:
   739   "rec_eval rec_penc [m, n] = penc m n"
   749   "rec_eval rec_penc [m, n] = penc m n"
   740 by (simp add: rec_penc_def prod_encode_def)
   750 by (simp add: rec_penc_def prod_encode_def)
   741 
   751 
   742 
   752 
   743 text {* Encodings of Lists *}
   753 text {* Encodings of Lists of Natural Numbers *}
   744 
   754 
   745 fun 
   755 fun 
   746   lenc :: "nat list \<Rightarrow> nat" 
   756   lenc :: "nat list \<Rightarrow> nat" 
   747 where
   757 where
   748   "lenc [] = 0"
   758   "lenc [] = 0"
   770 
   780 
   771 lemma lenc_length_le:
   781 lemma lenc_length_le:
   772   "length xs \<le> lenc xs"  
   782   "length xs \<le> lenc xs"  
   773 by (induct xs) (simp_all add: prod_encode_def)
   783 by (induct xs) (simp_all add: prod_encode_def)
   774 
   784 
   775 
   785 text {* The membership predicate for an encoded list. *}
   776 text {* Membership for the List Encoding *}
       
   777 
   786 
   778 fun within :: "nat \<Rightarrow> nat \<Rightarrow> bool" where
   787 fun within :: "nat \<Rightarrow> nat \<Rightarrow> bool" where
   779   "within z 0 = (0 < z)"
   788   "within z 0 = (0 < z)"
   780 | "within z (Suc n) = within (pdec2 z) n"
   789 | "within z (Suc n) = within (pdec2 z) n"
   781     
   790     
   793 apply(simp_all add: prod_encode_def)
   802 apply(simp_all add: prod_encode_def)
   794 apply(case_tac xs)
   803 apply(case_tac xs)
   795 apply(simp_all)
   804 apply(simp_all)
   796 done
   805 done
   797 
   806 
   798 text {* Length of Encoded Lists *}
   807 text {* The length of an encoded list. *}
   799 
   808 
   800 lemma enclen_length [simp]:
   809 lemma enclen_length [simp]:
   801   "enclen (lenc xs) = length xs"
   810   "enclen (lenc xs) = length xs"
   802 unfolding enclen_def
   811 unfolding enclen_def
   803 apply(simp add: BMax_rec_eq1)
   812 apply(simp add: BMax_rec_eq1)