src/ZF/IntDiv_ZF.thy
changeset 60770 240563fbf41d
parent 58871 c399ae4b836f
child 61395 4f8c2c4a0a8c
equal deleted inserted replaced
60769:cf7f3465eaf1 60770:240563fbf41d
    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)
  1284 apply auto
  1284 apply auto
  1285 done
  1285 done
  1286 
  1286 
  1287 
  1287 
  1288 
  1288 
  1289 subsection{* More algebraic laws for zdiv and zmod *}
  1289 subsection\<open>More algebraic laws for zdiv and zmod\<close>
  1290 
  1290 
  1291 (** proving (a*b) zdiv c = a $* (b zdiv c) $+ a * (b zmod c) **)
  1291 (** proving (a*b) zdiv c = a $* (b zdiv c) $+ a * (b zmod c) **)
  1292 
  1292 
  1293 lemma zmult1_lemma:
  1293 lemma zmult1_lemma:
  1294      "[| quorem(<b,c>, <q,r>);  c \<in> int;  c \<noteq> #0 |]
  1294      "[| quorem(<b,c>, <q,r>);  c \<in> int;  c \<noteq> #0 |]
  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)