25 else |
25 else |
26 if 0<b then negDivAlg (a,b) |
26 if 0<b then negDivAlg (a,b) |
27 else negateSnd (posDivAlg (~a,~b)); |
27 else negateSnd (posDivAlg (~a,~b)); |
28 *) |
28 *) |
29 |
29 |
30 section{*The Division Operators Div and Mod*} |
30 section\<open>The Division Operators Div and Mod\<close> |
31 |
31 |
32 theory IntDiv_ZF |
32 theory IntDiv_ZF |
33 imports Bin OrderArith |
33 imports Bin OrderArith |
34 begin |
34 begin |
35 |
35 |
347 lemma zmult_cancel1 [simp]: |
347 lemma zmult_cancel1 [simp]: |
348 "(k$*m = k$*n) \<longleftrightarrow> (intify(k) = #0 | intify(m) = intify(n))" |
348 "(k$*m = k$*n) \<longleftrightarrow> (intify(k) = #0 | intify(m) = intify(n))" |
349 by (simp add: zmult_commute [of k] zmult_cancel2) |
349 by (simp add: zmult_commute [of k] zmult_cancel2) |
350 |
350 |
351 |
351 |
352 subsection{* Uniqueness and monotonicity of quotients and remainders *} |
352 subsection\<open>Uniqueness and monotonicity of quotients and remainders\<close> |
353 |
353 |
354 lemma unique_quotient_lemma: |
354 lemma unique_quotient_lemma: |
355 "[| b$*q' $+ r' $<= b$*q $+ r; #0 $<= r'; #0 $< b; r $< b |] |
355 "[| b$*q' $+ r' $<= b$*q $+ r; #0 $<= r'; #0 $< b; r $< b |] |
356 ==> q' $<= q" |
356 ==> q' $<= q" |
357 apply (subgoal_tac "r' $+ b $* (q'$-q) $<= r") |
357 apply (subgoal_tac "r' $+ b $* (q'$-q) $<= r") |
398 prefer 2 apply (blast intro: unique_quotient) |
398 prefer 2 apply (blast intro: unique_quotient) |
399 apply (simp add: quorem_def) |
399 apply (simp add: quorem_def) |
400 done |
400 done |
401 |
401 |
402 |
402 |
403 subsection{*Correctness of posDivAlg, |
403 subsection\<open>Correctness of posDivAlg, |
404 the Division Algorithm for @{text "a\<ge>0"} and @{text "b>0"} *} |
404 the Division Algorithm for @{text "a\<ge>0"} and @{text "b>0"}\<close> |
405 |
405 |
406 lemma adjust_eq [simp]: |
406 lemma adjust_eq [simp]: |
407 "adjust(b, <q,r>) = (let diff = r$-b in |
407 "adjust(b, <q,r>) = (let diff = r$-b in |
408 if #0 $<= diff then <#2$*q $+ #1,diff> |
408 if #0 $<= diff then <#2$*q $+ #1,diff> |
409 else <#2$*q,r>)" |
409 else <#2$*q,r>)" |
464 then this rewrite can work for all constants!!*) |
464 then this rewrite can work for all constants!!*) |
465 lemma intify_eq_0_iff_zle: "intify(m) = #0 \<longleftrightarrow> (m $<= #0 & #0 $<= m)" |
465 lemma intify_eq_0_iff_zle: "intify(m) = #0 \<longleftrightarrow> (m $<= #0 & #0 $<= m)" |
466 by (simp add: int_eq_iff_zle) |
466 by (simp add: int_eq_iff_zle) |
467 |
467 |
468 |
468 |
469 subsection{* Some convenient biconditionals for products of signs *} |
469 subsection\<open>Some convenient biconditionals for products of signs\<close> |
470 |
470 |
471 lemma zmult_pos: "[| #0 $< i; #0 $< j |] ==> #0 $< i $* j" |
471 lemma zmult_pos: "[| #0 $< i; #0 $< j |] ==> #0 $< i $* j" |
472 by (drule zmult_zless_mono1, auto) |
472 by (drule zmult_zless_mono1, auto) |
473 |
473 |
474 lemma zmult_neg: "[| i $< #0; j $< #0 |] ==> #0 $< i $* j" |
474 lemma zmult_neg: "[| i $< #0; j $< #0 |] ==> #0 $< i $* j" |
544 "[| a \<in> int; b \<in> int |] |
544 "[| a \<in> int; b \<in> int |] |
545 ==> #0 $<= a \<longrightarrow> #0 $< b \<longrightarrow> quorem (<a,b>, posDivAlg(<a,b>))" |
545 ==> #0 $<= a \<longrightarrow> #0 $< b \<longrightarrow> quorem (<a,b>, posDivAlg(<a,b>))" |
546 apply (rule_tac u = "a" and v = "b" in posDivAlg_induct) |
546 apply (rule_tac u = "a" and v = "b" in posDivAlg_induct) |
547 apply auto |
547 apply auto |
548 apply (simp_all add: quorem_def) |
548 apply (simp_all add: quorem_def) |
549 txt{*base case: a<b*} |
549 txt\<open>base case: a<b\<close> |
550 apply (simp add: posDivAlg_eqn) |
550 apply (simp add: posDivAlg_eqn) |
551 apply (simp add: not_zless_iff_zle [THEN iff_sym]) |
551 apply (simp add: not_zless_iff_zle [THEN iff_sym]) |
552 apply (simp add: int_0_less_mult_iff) |
552 apply (simp add: int_0_less_mult_iff) |
553 txt{*main argument*} |
553 txt\<open>main argument\<close> |
554 apply (subst posDivAlg_eqn) |
554 apply (subst posDivAlg_eqn) |
555 apply (simp_all (no_asm_simp)) |
555 apply (simp_all (no_asm_simp)) |
556 apply (erule splitE) |
556 apply (erule splitE) |
557 apply (rule posDivAlg_type) |
557 apply (rule posDivAlg_type) |
558 apply (simp_all add: int_0_less_mult_iff) |
558 apply (simp_all add: int_0_less_mult_iff) |
559 apply (auto simp add: zadd_zmult_distrib2 Let_def) |
559 apply (auto simp add: zadd_zmult_distrib2 Let_def) |
560 txt{*now just linear arithmetic*} |
560 txt\<open>now just linear arithmetic\<close> |
561 apply (simp add: not_zle_iff_zless zdiff_zless_iff) |
561 apply (simp add: not_zle_iff_zless zdiff_zless_iff) |
562 done |
562 done |
563 |
563 |
564 |
564 |
565 subsection{*Correctness of negDivAlg, the division algorithm for a<0 and b>0*} |
565 subsection\<open>Correctness of negDivAlg, the division algorithm for a<0 and b>0\<close> |
566 |
566 |
567 lemma negDivAlg_termination: |
567 lemma negDivAlg_termination: |
568 "[| #0 $< b; a $+ b $< #0 |] |
568 "[| #0 $< b; a $+ b $< #0 |] |
569 ==> nat_of($- a $- #2 $* b) < nat_of($- a $- b)" |
569 ==> nat_of($- a $- #2 $* b) < nat_of($- a $- b)" |
570 apply (simp (no_asm) add: zless_nat_conj) |
570 apply (simp (no_asm) add: zless_nat_conj) |
640 "[| a \<in> int; b \<in> int |] |
640 "[| a \<in> int; b \<in> int |] |
641 ==> a $< #0 \<longrightarrow> #0 $< b \<longrightarrow> quorem (<a,b>, negDivAlg(<a,b>))" |
641 ==> a $< #0 \<longrightarrow> #0 $< b \<longrightarrow> quorem (<a,b>, negDivAlg(<a,b>))" |
642 apply (rule_tac u = "a" and v = "b" in negDivAlg_induct) |
642 apply (rule_tac u = "a" and v = "b" in negDivAlg_induct) |
643 apply auto |
643 apply auto |
644 apply (simp_all add: quorem_def) |
644 apply (simp_all add: quorem_def) |
645 txt{*base case: @{term "0$<=a$+b"}*} |
645 txt\<open>base case: @{term "0$<=a$+b"}\<close> |
646 apply (simp add: negDivAlg_eqn) |
646 apply (simp add: negDivAlg_eqn) |
647 apply (simp add: not_zless_iff_zle [THEN iff_sym]) |
647 apply (simp add: not_zless_iff_zle [THEN iff_sym]) |
648 apply (simp add: int_0_less_mult_iff) |
648 apply (simp add: int_0_less_mult_iff) |
649 txt{*main argument*} |
649 txt\<open>main argument\<close> |
650 apply (subst negDivAlg_eqn) |
650 apply (subst negDivAlg_eqn) |
651 apply (simp_all (no_asm_simp)) |
651 apply (simp_all (no_asm_simp)) |
652 apply (erule splitE) |
652 apply (erule splitE) |
653 apply (rule negDivAlg_type) |
653 apply (rule negDivAlg_type) |
654 apply (simp_all add: int_0_less_mult_iff) |
654 apply (simp_all add: int_0_less_mult_iff) |
655 apply (auto simp add: zadd_zmult_distrib2 Let_def) |
655 apply (auto simp add: zadd_zmult_distrib2 Let_def) |
656 txt{*now just linear arithmetic*} |
656 txt\<open>now just linear arithmetic\<close> |
657 apply (simp add: not_zle_iff_zless zdiff_zless_iff) |
657 apply (simp add: not_zle_iff_zless zdiff_zless_iff) |
658 done |
658 done |
659 |
659 |
660 |
660 |
661 subsection{* Existence shown by proving the division algorithm to be correct *} |
661 subsection\<open>Existence shown by proving the division algorithm to be correct\<close> |
662 |
662 |
663 (*the case a=0*) |
663 (*the case a=0*) |
664 lemma quorem_0: "[|b \<noteq> #0; b \<in> int|] ==> quorem (<#0,b>, <#0,#0>)" |
664 lemma quorem_0: "[|b \<noteq> #0; b \<in> int|] ==> quorem (<#0,b>, <#0,#0>)" |
665 by (force simp add: quorem_def neq_iff_zless) |
665 by (force simp add: quorem_def neq_iff_zless) |
666 |
666 |
700 lemma quorem_neg: |
700 lemma quorem_neg: |
701 "[|quorem (<$-a,$-b>, qr); a \<in> int; b \<in> int; qr \<in> int * int|] |
701 "[|quorem (<$-a,$-b>, qr); a \<in> int; b \<in> int; qr \<in> int * int|] |
702 ==> quorem (<a,b>, negateSnd(qr))" |
702 ==> quorem (<a,b>, negateSnd(qr))" |
703 apply clarify |
703 apply clarify |
704 apply (auto elim: zless_asym simp add: quorem_def zless_zminus) |
704 apply (auto elim: zless_asym simp add: quorem_def zless_zminus) |
705 txt{*linear arithmetic from here on*} |
705 txt\<open>linear arithmetic from here on\<close> |
706 apply (simp_all add: zminus_equation [of a] zminus_zless) |
706 apply (simp_all add: zminus_equation [of a] zminus_zless) |
707 apply (cut_tac [2] z = "b" and w = "#0" in zless_linear) |
707 apply (cut_tac [2] z = "b" and w = "#0" in zless_linear) |
708 apply (cut_tac [1] z = "b" and w = "#0" in zless_linear) |
708 apply (cut_tac [1] z = "b" and w = "#0" in zless_linear) |
709 apply auto |
709 apply auto |
710 apply (blast dest: zle_zless_trans)+ |
710 apply (blast dest: zle_zless_trans)+ |
714 "[|b \<noteq> #0; a \<in> int; b \<in> int|] ==> quorem (<a,b>, divAlg(<a,b>))" |
714 "[|b \<noteq> #0; a \<in> int; b \<in> int|] ==> quorem (<a,b>, divAlg(<a,b>))" |
715 apply (auto simp add: quorem_0 divAlg_def) |
715 apply (auto simp add: quorem_0 divAlg_def) |
716 apply (safe intro!: quorem_neg posDivAlg_correct negDivAlg_correct |
716 apply (safe intro!: quorem_neg posDivAlg_correct negDivAlg_correct |
717 posDivAlg_type negDivAlg_type) |
717 posDivAlg_type negDivAlg_type) |
718 apply (auto simp add: quorem_def neq_iff_zless) |
718 apply (auto simp add: quorem_def neq_iff_zless) |
719 txt{*linear arithmetic from here on*} |
719 txt\<open>linear arithmetic from here on\<close> |
720 apply (auto simp add: zle_def) |
720 apply (auto simp add: zle_def) |
721 done |
721 done |
722 |
722 |
723 lemma divAlg_type: "[|a \<in> int; b \<in> int|] ==> divAlg(<a,b>) \<in> int * int" |
723 lemma divAlg_type: "[|a \<in> int; b \<in> int|] ==> divAlg(<a,b>) \<in> int * int" |
724 apply (auto simp add: divAlg_def) |
724 apply (auto simp add: divAlg_def) |
943 apply (cut_tac a = "intify (a)" and b = "intify (b)" in zmod_zminus_zminus_raw) |
943 apply (cut_tac a = "intify (a)" and b = "intify (b)" in zmod_zminus_zminus_raw) |
944 apply auto |
944 apply auto |
945 done |
945 done |
946 |
946 |
947 |
947 |
948 subsection{* division of a number by itself *} |
948 subsection\<open>division of a number by itself\<close> |
949 |
949 |
950 lemma self_quotient_aux1: "[| #0 $< a; a = r $+ a$*q; r $< a |] ==> #1 $<= q" |
950 lemma self_quotient_aux1: "[| #0 $< a; a = r $+ a$*q; r $< a |] ==> #1 $<= q" |
951 apply (subgoal_tac "#0 $< a$*q") |
951 apply (subgoal_tac "#0 $< a$*q") |
952 apply (cut_tac w = "#0" and z = "q" in add1_zle_iff) |
952 apply (cut_tac w = "#0" and z = "q" in add1_zle_iff) |
953 apply (simp add: int_0_less_mult_iff) |
953 apply (simp add: int_0_less_mult_iff) |
1009 apply (cut_tac a = "intify (a)" in zmod_self_raw) |
1009 apply (cut_tac a = "intify (a)" in zmod_self_raw) |
1010 apply auto |
1010 apply auto |
1011 done |
1011 done |
1012 |
1012 |
1013 |
1013 |
1014 subsection{* Computation of division and remainder *} |
1014 subsection\<open>Computation of division and remainder\<close> |
1015 |
1015 |
1016 lemma zdiv_zero [simp]: "#0 zdiv b = #0" |
1016 lemma zdiv_zero [simp]: "#0 zdiv b = #0" |
1017 by (simp add: zdiv_def divAlg_def) |
1017 by (simp add: zdiv_def divAlg_def) |
1018 |
1018 |
1019 lemma zdiv_eq_minus1: "#0 $< b ==> #-1 zdiv b = #-1" |
1019 lemma zdiv_eq_minus1: "#0 $< b ==> #-1 zdiv b = #-1" |
1150 apply auto |
1150 apply auto |
1151 done |
1151 done |
1152 declare zdiv_minus1_right [simp] |
1152 declare zdiv_minus1_right [simp] |
1153 |
1153 |
1154 |
1154 |
1155 subsection{* Monotonicity in the first argument (divisor) *} |
1155 subsection\<open>Monotonicity in the first argument (divisor)\<close> |
1156 |
1156 |
1157 lemma zdiv_mono1: "[| a $<= a'; #0 $< b |] ==> a zdiv b $<= a' zdiv b" |
1157 lemma zdiv_mono1: "[| a $<= a'; #0 $< b |] ==> a zdiv b $<= a' zdiv b" |
1158 apply (cut_tac a = "a" and b = "b" in zmod_zdiv_equality) |
1158 apply (cut_tac a = "a" and b = "b" in zmod_zdiv_equality) |
1159 apply (cut_tac a = "a'" and b = "b" in zmod_zdiv_equality) |
1159 apply (cut_tac a = "a'" and b = "b" in zmod_zdiv_equality) |
1160 apply (rule unique_quotient_lemma) |
1160 apply (rule unique_quotient_lemma) |
1171 apply (erule subst) |
1171 apply (erule subst) |
1172 apply (simp_all (no_asm_simp) add: neg_mod_sign neg_mod_bound) |
1172 apply (simp_all (no_asm_simp) add: neg_mod_sign neg_mod_bound) |
1173 done |
1173 done |
1174 |
1174 |
1175 |
1175 |
1176 subsection{* Monotonicity in the second argument (dividend) *} |
1176 subsection\<open>Monotonicity in the second argument (dividend)\<close> |
1177 |
1177 |
1178 lemma q_pos_lemma: |
1178 lemma q_pos_lemma: |
1179 "[| #0 $<= b'$*q' $+ r'; r' $< b'; #0 $< b' |] ==> #0 $<= q'" |
1179 "[| #0 $<= b'$*q' $+ r'; r' $< b'; #0 $< b' |] ==> #0 $<= q'" |
1180 apply (subgoal_tac "#0 $< b'$* (q' $+ #1)") |
1180 apply (subgoal_tac "#0 $< b'$* (q' $+ #1)") |
1181 apply (simp add: int_0_less_mult_iff) |
1181 apply (simp add: int_0_less_mult_iff) |
1454 apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) |
1454 apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) |
1455 apply (simp (no_asm_simp) add: zmod_zadd1_eq) |
1455 apply (simp (no_asm_simp) add: zmod_zadd1_eq) |
1456 done |
1456 done |
1457 |
1457 |
1458 |
1458 |
1459 subsection{* proving a zdiv (b*c) = (a zdiv b) zdiv c *} |
1459 subsection\<open>proving a zdiv (b*c) = (a zdiv b) zdiv c\<close> |
1460 |
1460 |
1461 (*The condition c>0 seems necessary. Consider that 7 zdiv ~6 = ~2 but |
1461 (*The condition c>0 seems necessary. Consider that 7 zdiv ~6 = ~2 but |
1462 7 zdiv 2 zdiv ~3 = 3 zdiv ~3 = ~1. The subcase (a zdiv b) zmod c = 0 seems |
1462 7 zdiv 2 zdiv ~3 = 3 zdiv ~3 = ~1. The subcase (a zdiv b) zmod c = 0 seems |
1463 to cause particular problems.*) |
1463 to cause particular problems.*) |
1464 |
1464 |
1548 "#0 $< c ==> a zmod (b$*c) = b$*(a zdiv b zmod c) $+ a zmod b" |
1548 "#0 $< c ==> a zmod (b$*c) = b$*(a zdiv b zmod c) $+ a zmod b" |
1549 apply (cut_tac a = "intify (a)" and b = "intify (b)" in zmod_zmult2_eq_raw) |
1549 apply (cut_tac a = "intify (a)" and b = "intify (b)" in zmod_zmult2_eq_raw) |
1550 apply auto |
1550 apply auto |
1551 done |
1551 done |
1552 |
1552 |
1553 subsection{* Cancellation of common factors in "zdiv" *} |
1553 subsection\<open>Cancellation of common factors in "zdiv"\<close> |
1554 |
1554 |
1555 lemma zdiv_zmult_zmult1_aux1: |
1555 lemma zdiv_zmult_zmult1_aux1: |
1556 "[| #0 $< b; intify(c) \<noteq> #0 |] ==> (c$*a) zdiv (c$*b) = a zdiv b" |
1556 "[| #0 $< b; intify(c) \<noteq> #0 |] ==> (c$*a) zdiv (c$*b) = a zdiv b" |
1557 apply (subst zdiv_zmult2_eq) |
1557 apply (subst zdiv_zmult2_eq) |
1558 apply auto |
1558 apply auto |
1582 apply (drule zdiv_zmult_zmult1) |
1582 apply (drule zdiv_zmult_zmult1) |
1583 apply (auto simp add: zmult_commute) |
1583 apply (auto simp add: zmult_commute) |
1584 done |
1584 done |
1585 |
1585 |
1586 |
1586 |
1587 subsection{* Distribution of factors over "zmod" *} |
1587 subsection\<open>Distribution of factors over "zmod"\<close> |
1588 |
1588 |
1589 lemma zmod_zmult_zmult1_aux1: |
1589 lemma zmod_zmult_zmult1_aux1: |
1590 "[| #0 $< b; intify(c) \<noteq> #0 |] |
1590 "[| #0 $< b; intify(c) \<noteq> #0 |] |
1591 ==> (c$*a) zmod (c$*b) = c $* (a zmod b)" |
1591 ==> (c$*a) zmod (c$*b) = c $* (a zmod b)" |
1592 apply (subst zmod_zmult2_eq) |
1592 apply (subst zmod_zmult2_eq) |