679 text {* Simproc for cancelling @{const div} and @{const mod} *} |
679 text {* Simproc for cancelling @{const div} and @{const mod} *} |
680 |
680 |
681 ML {* |
681 ML {* |
682 local |
682 local |
683 |
683 |
684 structure CancelDivMod = CancelDivModFun(struct |
684 structure CancelDivMod = CancelDivModFun |
685 |
685 ( |
686 val div_name = @{const_name div}; |
686 val div_name = @{const_name div}; |
687 val mod_name = @{const_name mod}; |
687 val mod_name = @{const_name mod}; |
688 val mk_binop = HOLogic.mk_binop; |
688 val mk_binop = HOLogic.mk_binop; |
689 val mk_sum = Nat_Arith.mk_sum; |
689 val mk_sum = Nat_Arith.mk_sum; |
690 val dest_sum = Nat_Arith.dest_sum; |
690 val dest_sum = Nat_Arith.dest_sum; |
691 |
691 |
692 val div_mod_eqs = map mk_meta_eq [@{thm div_mod_equality}, @{thm div_mod_equality2}]; |
692 val div_mod_eqs = map mk_meta_eq [@{thm div_mod_equality}, @{thm div_mod_equality2}]; |
693 |
693 |
694 val trans = trans; |
|
695 |
|
696 val prove_eq_sums = Arith_Data.prove_conv2 all_tac (Arith_Data.simp_all_tac |
694 val prove_eq_sums = Arith_Data.prove_conv2 all_tac (Arith_Data.simp_all_tac |
697 (@{thm add_0_left} :: @{thm add_0_right} :: @{thms add_ac})) |
695 (@{thm add_0_left} :: @{thm add_0_right} :: @{thms add_ac})) |
698 |
696 ) |
699 end) |
|
700 |
697 |
701 in |
698 in |
702 |
699 |
703 val cancel_div_mod_nat_proc = Simplifier.simproc_global @{theory} |
700 val cancel_div_mod_nat_proc = Simplifier.simproc_global @{theory} |
704 "cancel_div_mod" ["(m::nat) + n"] (K CancelDivMod.proc); |
701 "cancel_div_mod" ["(m::nat) + n"] (K CancelDivMod.proc); |
1350 |
1347 |
1351 text{*Correctness of @{term posDivAlg}: it computes quotients correctly*} |
1348 text{*Correctness of @{term posDivAlg}: it computes quotients correctly*} |
1352 theorem posDivAlg_correct: |
1349 theorem posDivAlg_correct: |
1353 assumes "0 \<le> a" and "0 < b" |
1350 assumes "0 \<le> a" and "0 < b" |
1354 shows "divmod_int_rel a b (posDivAlg a b)" |
1351 shows "divmod_int_rel a b (posDivAlg a b)" |
1355 using prems apply (induct a b rule: posDivAlg.induct) |
1352 using assms |
1356 apply auto |
1353 apply (induct a b rule: posDivAlg.induct) |
1357 apply (simp add: divmod_int_rel_def) |
1354 apply auto |
1358 apply (subst posDivAlg_eqn, simp add: right_distrib) |
1355 apply (simp add: divmod_int_rel_def) |
1359 apply (case_tac "a < b") |
1356 apply (subst posDivAlg_eqn, simp add: right_distrib) |
1360 apply simp_all |
1357 apply (case_tac "a < b") |
1361 apply (erule splitE) |
1358 apply simp_all |
1362 apply (auto simp add: right_distrib Let_def mult_ac mult_2_right) |
1359 apply (erule splitE) |
1363 done |
1360 apply (auto simp add: right_distrib Let_def mult_ac mult_2_right) |
|
1361 done |
1364 |
1362 |
1365 |
1363 |
1366 subsubsection{*Correctness of @{term negDivAlg}, the Algorithm for Negative Dividends*} |
1364 subsubsection{*Correctness of @{term negDivAlg}, the Algorithm for Negative Dividends*} |
1367 |
1365 |
1368 text{*And positive divisors*} |
1366 text{*And positive divisors*} |
1379 (*Correctness of negDivAlg: it computes quotients correctly |
1377 (*Correctness of negDivAlg: it computes quotients correctly |
1380 It doesn't work if a=0 because the 0/b equals 0, not -1*) |
1378 It doesn't work if a=0 because the 0/b equals 0, not -1*) |
1381 lemma negDivAlg_correct: |
1379 lemma negDivAlg_correct: |
1382 assumes "a < 0" and "b > 0" |
1380 assumes "a < 0" and "b > 0" |
1383 shows "divmod_int_rel a b (negDivAlg a b)" |
1381 shows "divmod_int_rel a b (negDivAlg a b)" |
1384 using prems apply (induct a b rule: negDivAlg.induct) |
1382 using assms |
1385 apply (auto simp add: linorder_not_le) |
1383 apply (induct a b rule: negDivAlg.induct) |
1386 apply (simp add: divmod_int_rel_def) |
1384 apply (auto simp add: linorder_not_le) |
1387 apply (subst negDivAlg_eqn, assumption) |
1385 apply (simp add: divmod_int_rel_def) |
1388 apply (case_tac "a + b < (0\<Colon>int)") |
1386 apply (subst negDivAlg_eqn, assumption) |
1389 apply simp_all |
1387 apply (case_tac "a + b < (0\<Colon>int)") |
1390 apply (erule splitE) |
1388 apply simp_all |
1391 apply (auto simp add: right_distrib Let_def mult_ac mult_2_right) |
1389 apply (erule splitE) |
1392 done |
1390 apply (auto simp add: right_distrib Let_def mult_ac mult_2_right) |
|
1391 done |
1393 |
1392 |
1394 |
1393 |
1395 subsubsection{*Existence Shown by Proving the Division Algorithm to be Correct*} |
1394 subsubsection{*Existence Shown by Proving the Division Algorithm to be Correct*} |
1396 |
1395 |
1397 (*the case a=0*) |
1396 (*the case a=0*) |
1438 text {* Tool setup *} |
1437 text {* Tool setup *} |
1439 |
1438 |
1440 ML {* |
1439 ML {* |
1441 local |
1440 local |
1442 |
1441 |
1443 structure CancelDivMod = CancelDivModFun(struct |
1442 structure CancelDivMod = CancelDivModFun |
1444 |
1443 ( |
1445 val div_name = @{const_name div}; |
1444 val div_name = @{const_name div}; |
1446 val mod_name = @{const_name mod}; |
1445 val mod_name = @{const_name mod}; |
1447 val mk_binop = HOLogic.mk_binop; |
1446 val mk_binop = HOLogic.mk_binop; |
1448 val mk_sum = Arith_Data.mk_sum HOLogic.intT; |
1447 val mk_sum = Arith_Data.mk_sum HOLogic.intT; |
1449 val dest_sum = Arith_Data.dest_sum; |
1448 val dest_sum = Arith_Data.dest_sum; |
1450 |
1449 |
1451 val div_mod_eqs = map mk_meta_eq [@{thm zdiv_zmod_equality}, @{thm zdiv_zmod_equality2}]; |
1450 val div_mod_eqs = map mk_meta_eq [@{thm zdiv_zmod_equality}, @{thm zdiv_zmod_equality2}]; |
1452 |
1451 |
1453 val trans = trans; |
|
1454 |
|
1455 val prove_eq_sums = Arith_Data.prove_conv2 all_tac (Arith_Data.simp_all_tac |
1452 val prove_eq_sums = Arith_Data.prove_conv2 all_tac (Arith_Data.simp_all_tac |
1456 (@{thm diff_minus} :: @{thms add_0s} @ @{thms add_ac})) |
1453 (@{thm diff_minus} :: @{thms add_0s} @ @{thms add_ac})) |
1457 |
1454 ) |
1458 end) |
|
1459 |
1455 |
1460 in |
1456 in |
1461 |
1457 |
1462 val cancel_div_mod_int_proc = Simplifier.simproc_global @{theory} |
1458 val cancel_div_mod_int_proc = Simplifier.simproc_global @{theory} |
1463 "cancel_zdiv_zmod" ["(k::int) + l"] (K CancelDivMod.proc); |
1459 "cancel_zdiv_zmod" ["(k::int) + l"] (K CancelDivMod.proc); |