src/HOL/Integ/IntDiv.thy
changeset 22802 92026479179e
parent 22744 5cbe966d67a2
child 22948 8752ca7f849a
equal deleted inserted replaced
22801:caffcb450ef4 22802:92026479179e
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     4     Copyright   1999  University of Cambridge
     4     Copyright   1999  University of Cambridge
     5 
     5 
     6 *)
     6 *)
     7 
     7 
     8 
       
     9 header{*The Division Operators div and mod; the Divides Relation dvd*}
     8 header{*The Division Operators div and mod; the Divides Relation dvd*}
    10 
     9 
    11 theory IntDiv
    10 theory IntDiv
    12 imports "../Divides" "../SetInterval" "../Recdef"
    11 imports IntArith "../Divides" "../FunDef"
    13 uses ("IntDiv_setup.ML")
    12 uses ("IntDiv_setup.ML")
    14 begin
    13 begin
    15 
    14 
    16 declare zless_nat_conj [simp]
    15 declare zless_nat_conj [simp]
    17 
    16 
    26     --{*for the division algorithm*}
    25     --{*for the division algorithm*}
    27     [code func]: "adjust b == %(q,r). if 0 \<le> r-b then (2*q + 1, r-b)
    26     [code func]: "adjust b == %(q,r). if 0 \<le> r-b then (2*q + 1, r-b)
    28                          else (2*q, r)"
    27                          else (2*q, r)"
    29 
    28 
    30 text{*algorithm for the case @{text "a\<ge>0, b>0"}*}
    29 text{*algorithm for the case @{text "a\<ge>0, b>0"}*}
    31 consts posDivAlg :: "int*int => int*int"
    30 function
    32 recdef posDivAlg "measure (%(a,b). nat(a - b + 1))"
    31   posDivAlg :: "int \<Rightarrow> int \<Rightarrow> int \<times> int"
    33     "posDivAlg (a,b) =
    32 where
    34        (if (a<b | b\<le>0) then (0,a)
    33   "posDivAlg a b =
    35         else adjust b (posDivAlg(a, 2*b)))"
    34      (if (a<b | b\<le>0) then (0,a)
       
    35         else adjust b (posDivAlg a (2*b)))"
       
    36 by auto
       
    37 termination by (relation "measure (%(a,b). nat(a - b + 1))") auto
    36 
    38 
    37 text{*algorithm for the case @{text "a<0, b>0"}*}
    39 text{*algorithm for the case @{text "a<0, b>0"}*}
    38 consts negDivAlg :: "int*int => int*int"
    40 function
    39 recdef negDivAlg "measure (%(a,b). nat(- a - b))"
    41   negDivAlg :: "int \<Rightarrow> int \<Rightarrow> int \<times> int"
    40     "negDivAlg (a,b) =
    42 where
    41        (if (0\<le>a+b | b\<le>0) then (-1,a+b)
    43   "negDivAlg a b  =
    42         else adjust b (negDivAlg(a, 2*b)))"
    44      (if (0\<le>a+b | b\<le>0) then (-1,a+b)
       
    45       else adjust b (negDivAlg a (2*b)))"
       
    46 by auto
       
    47 termination by (relation "measure (%(a,b). nat(- a - b))") auto
    43 
    48 
    44 text{*algorithm for the general case @{term "b\<noteq>0"}*}
    49 text{*algorithm for the general case @{term "b\<noteq>0"}*}
    45 constdefs
    50 constdefs
    46   negateSnd :: "int*int => int*int"
    51   negateSnd :: "int*int => int*int"
    47     [code func]: "negateSnd == %(q,r). (q,-r)"
    52     [code func]: "negateSnd == %(q,r). (q,-r)"
    48 
    53 
    49   divAlg :: "int*int => int*int"
    54 definition
       
    55   divAlg :: "int \<times> int \<Rightarrow> int \<times> int"
    50     --{*The full division algorithm considers all possible signs for a, b
    56     --{*The full division algorithm considers all possible signs for a, b
    51        including the special case @{text "a=0, b<0"} because 
    57        including the special case @{text "a=0, b<0"} because 
    52        @{term negDivAlg} requires @{term "a<0"}.*}
    58        @{term negDivAlg} requires @{term "a<0"}.*}
    53     [code func]: "divAlg ==
    59 where
    54        %(a,b). if 0\<le>a then
    60   "divAlg = (\<lambda>(a, b). (if 0\<le>a then
    55                   if 0\<le>b then posDivAlg (a,b)
    61                   if 0\<le>b then posDivAlg a b
    56                   else if a=0 then (0,0)
    62                   else if a=0 then (0, 0)
    57                        else negateSnd (negDivAlg (-a,-b))
    63                        else negateSnd (negDivAlg (-a) (-b))
    58                else 
    64                else 
    59                   if 0<b then negDivAlg (a,b)
    65                   if 0<b then negDivAlg a b
    60                   else         negateSnd (posDivAlg (-a,-b))"
    66                   else negateSnd (posDivAlg (-a) (-b))))"
    61 
    67 
    62 instance
    68 instance int :: Divides.div
    63   int :: "Divides.div" ..       --{*avoid clash with 'div' token*}
    69   div_def: "a div b == fst (divAlg (a, b))"
    64 
    70   mod_def: "a mod b == snd (divAlg (a, b))" ..
    65 text{*The operators are defined with reference to the algorithm, which is
       
    66 proved to satisfy the specification.*}
       
    67 defs
       
    68   div_def [code func]: "a div b == fst (divAlg (a,b))"
       
    69   mod_def [code func]: "a mod b == snd (divAlg (a,b))"
       
    70 
       
    71 
    71 
    72 text{*
    72 text{*
    73 Here is the division algorithm in ML:
    73 Here is the division algorithm in ML:
    74 
    74 
    75 \begin{verbatim}
    75 \begin{verbatim}
   153 declare posDivAlg.simps [simp del]
   153 declare posDivAlg.simps [simp del]
   154 
   154 
   155 text{*use with a simproc to avoid repeatedly proving the premise*}
   155 text{*use with a simproc to avoid repeatedly proving the premise*}
   156 lemma posDivAlg_eqn:
   156 lemma posDivAlg_eqn:
   157      "0 < b ==>  
   157      "0 < b ==>  
   158       posDivAlg (a,b) = (if a<b then (0,a) else adjust b (posDivAlg(a, 2*b)))"
   158       posDivAlg a b = (if a<b then (0,a) else adjust b (posDivAlg a (2*b)))"
   159 by (rule posDivAlg.simps [THEN trans], simp)
   159 by (rule posDivAlg.simps [THEN trans], simp)
   160 
   160 
   161 text{*Correctness of @{term posDivAlg}: it computes quotients correctly*}
   161 text{*Correctness of @{term posDivAlg}: it computes quotients correctly*}
   162 theorem posDivAlg_correct [rule_format]:
   162 theorem posDivAlg_correct:
   163      "0 \<le> a --> 0 < b --> quorem ((a, b), posDivAlg (a, b))"
   163   assumes "0 \<le> a" and "0 < b"
   164 apply (induct_tac a b rule: posDivAlg.induct, auto)
   164   shows "quorem ((a, b), posDivAlg a b)"
   165  apply (simp_all add: quorem_def)
   165 using prems apply (induct a b rule: posDivAlg.induct)
   166  (*base case: a<b*)
   166 apply auto
   167  apply (simp add: posDivAlg_eqn)
   167 apply (simp add: quorem_def)
   168 (*main argument*)
   168 apply (subst posDivAlg_eqn, simp add: right_distrib)
   169 apply (subst posDivAlg_eqn, simp_all)
   169 apply (case_tac "a < b")
       
   170 apply simp_all
   170 apply (erule splitE)
   171 apply (erule splitE)
   171 apply (auto simp add: right_distrib Let_def)
   172 apply (auto simp add: right_distrib Let_def)
   172 done
   173 done
   173 
   174 
   174 
   175 
   179 declare negDivAlg.simps [simp del]
   180 declare negDivAlg.simps [simp del]
   180 
   181 
   181 text{*use with a simproc to avoid repeatedly proving the premise*}
   182 text{*use with a simproc to avoid repeatedly proving the premise*}
   182 lemma negDivAlg_eqn:
   183 lemma negDivAlg_eqn:
   183      "0 < b ==>  
   184      "0 < b ==>  
   184       negDivAlg (a,b) =       
   185       negDivAlg a b =       
   185        (if 0\<le>a+b then (-1,a+b) else adjust b (negDivAlg(a, 2*b)))"
   186        (if 0\<le>a+b then (-1,a+b) else adjust b (negDivAlg a (2*b)))"
   186 by (rule negDivAlg.simps [THEN trans], simp)
   187 by (rule negDivAlg.simps [THEN trans], simp)
   187 
   188 
   188 (*Correctness of negDivAlg: it computes quotients correctly
   189 (*Correctness of negDivAlg: it computes quotients correctly
   189   It doesn't work if a=0 because the 0/b equals 0, not -1*)
   190   It doesn't work if a=0 because the 0/b equals 0, not -1*)
   190 lemma negDivAlg_correct [rule_format]:
   191 lemma negDivAlg_correct:
   191      "a < 0 --> 0 < b --> quorem ((a, b), negDivAlg (a, b))"
   192   assumes "a < 0" and "b > 0"
   192 apply (induct_tac a b rule: negDivAlg.induct, auto)
   193   shows "quorem ((a, b), negDivAlg a b)"
   193  apply (simp_all add: quorem_def)
   194 using prems apply (induct a b rule: negDivAlg.induct)
   194  (*base case: 0\<le>a+b*)
   195 apply (auto simp add: linorder_not_le)
   195  apply (simp add: negDivAlg_eqn)
   196 apply (simp add: quorem_def)
   196 (*main argument*)
       
   197 apply (subst negDivAlg_eqn, assumption)
   197 apply (subst negDivAlg_eqn, assumption)
       
   198 apply (case_tac "a + b < (0\<Colon>int)")
       
   199 apply simp_all
   198 apply (erule splitE)
   200 apply (erule splitE)
   199 apply (auto simp add: right_distrib Let_def)
   201 apply (auto simp add: right_distrib Let_def)
   200 done
   202 done
   201 
   203 
   202 
   204 
   204 
   206 
   205 (*the case a=0*)
   207 (*the case a=0*)
   206 lemma quorem_0: "b \<noteq> 0 ==> quorem ((0,b), (0,0))"
   208 lemma quorem_0: "b \<noteq> 0 ==> quorem ((0,b), (0,0))"
   207 by (auto simp add: quorem_def linorder_neq_iff)
   209 by (auto simp add: quorem_def linorder_neq_iff)
   208 
   210 
   209 lemma posDivAlg_0 [simp]: "posDivAlg (0, b) = (0, 0)"
   211 lemma posDivAlg_0 [simp]: "posDivAlg 0 b = (0, 0)"
   210 by (subst posDivAlg.simps, auto)
   212 by (subst posDivAlg.simps, auto)
   211 
   213 
   212 lemma negDivAlg_minus1 [simp]: "negDivAlg (-1, b) = (-1, b - 1)"
   214 lemma negDivAlg_minus1 [simp]: "negDivAlg -1 b = (-1, b - 1)"
   213 by (subst negDivAlg.simps, auto)
   215 by (subst negDivAlg.simps, auto)
   214 
   216 
   215 lemma negateSnd_eq [simp]: "negateSnd(q,r) = (q,-r)"
   217 lemma negateSnd_eq [simp]: "negateSnd(q,r) = (q,-r)"
   216 by (simp add: negateSnd_def)
   218 by (simp add: negateSnd_def)
   217 
   219 
   218 lemma quorem_neg: "quorem ((-a,-b), qr) ==> quorem ((a,b), negateSnd qr)"
   220 lemma quorem_neg: "quorem ((-a,-b), qr) ==> quorem ((a,b), negateSnd qr)"
   219 by (auto simp add: split_ifs quorem_def)
   221 by (auto simp add: split_ifs quorem_def)
   220 
   222 
   221 lemma divAlg_correct: "b \<noteq> 0 ==> quorem ((a,b), divAlg(a,b))"
   223 lemma divAlg_correct: "b \<noteq> 0 ==> quorem ((a,b), divAlg (a, b))"
   222 by (force simp add: linorder_neq_iff quorem_0 divAlg_def quorem_neg
   224 by (force simp add: linorder_neq_iff quorem_0 divAlg_def quorem_neg
   223                     posDivAlg_correct negDivAlg_correct)
   225                     posDivAlg_correct negDivAlg_correct)
   224 
   226 
   225 text{*Arbitrary definitions for division by zero.  Useful to simplify 
   227 text{*Arbitrary definitions for division by zero.  Useful to simplify 
   226     certain equations.*}
   228     certain equations.*}
   248 lemma pos_mod_conj : "(0::int) < b ==> 0 \<le> a mod b & a mod b < b"
   250 lemma pos_mod_conj : "(0::int) < b ==> 0 \<le> a mod b & a mod b < b"
   249 apply (cut_tac a = a and b = b in divAlg_correct)
   251 apply (cut_tac a = a and b = b in divAlg_correct)
   250 apply (auto simp add: quorem_def mod_def)
   252 apply (auto simp add: quorem_def mod_def)
   251 done
   253 done
   252 
   254 
   253 lemmas pos_mod_sign  = pos_mod_conj [THEN conjunct1, standard]
   255 lemmas pos_mod_sign  [simp] = pos_mod_conj [THEN conjunct1, standard]
   254    and pos_mod_bound = pos_mod_conj [THEN conjunct2, standard]
   256    and pos_mod_bound [simp] = pos_mod_conj [THEN conjunct2, standard]
   255 
       
   256 declare pos_mod_sign[simp] pos_mod_bound[simp]
       
   257 
   257 
   258 lemma neg_mod_conj : "b < (0::int) ==> a mod b \<le> 0 & b < a mod b"
   258 lemma neg_mod_conj : "b < (0::int) ==> a mod b \<le> 0 & b < a mod b"
   259 apply (cut_tac a = a and b = b in divAlg_correct)
   259 apply (cut_tac a = a and b = b in divAlg_correct)
   260 apply (auto simp add: quorem_def div_def mod_def)
   260 apply (auto simp add: quorem_def div_def mod_def)
   261 done
   261 done
   262 
   262 
   263 lemmas neg_mod_sign  = neg_mod_conj [THEN conjunct1, standard]
   263 lemmas neg_mod_sign  [simp] = neg_mod_conj [THEN conjunct1, standard]
   264    and neg_mod_bound = neg_mod_conj [THEN conjunct2, standard]
   264    and neg_mod_bound [simp] = neg_mod_conj [THEN conjunct2, standard]
   265 declare neg_mod_sign[simp] neg_mod_bound[simp]
       
   266 
   265 
   267 
   266 
   268 
   267 
   269 subsection{*General Properties of div and mod*}
   268 subsection{*General Properties of div and mod*}
   270 
   269 
   421 lemma zmod_minus1: "(0::int) < b ==> -1 mod b = b - 1"
   420 lemma zmod_minus1: "(0::int) < b ==> -1 mod b = b - 1"
   422 by (simp add: mod_def divAlg_def)
   421 by (simp add: mod_def divAlg_def)
   423 
   422 
   424 text{*a positive, b positive *}
   423 text{*a positive, b positive *}
   425 
   424 
   426 lemma div_pos_pos: "[| 0 < a;  0 \<le> b |] ==> a div b = fst (posDivAlg(a,b))"
   425 lemma div_pos_pos: "[| 0 < a;  0 \<le> b |] ==> a div b = fst (posDivAlg a b)"
   427 by (simp add: div_def divAlg_def)
   426 by (simp add: div_def divAlg_def)
   428 
   427 
   429 lemma mod_pos_pos: "[| 0 < a;  0 \<le> b |] ==> a mod b = snd (posDivAlg(a,b))"
   428 lemma mod_pos_pos: "[| 0 < a;  0 \<le> b |] ==> a mod b = snd (posDivAlg a b)"
   430 by (simp add: mod_def divAlg_def)
   429 by (simp add: mod_def divAlg_def)
   431 
   430 
   432 text{*a negative, b positive *}
   431 text{*a negative, b positive *}
   433 
   432 
   434 lemma div_neg_pos: "[| a < 0;  0 < b |] ==> a div b = fst (negDivAlg(a,b))"
   433 lemma div_neg_pos: "[| a < 0;  0 < b |] ==> a div b = fst (negDivAlg a b)"
   435 by (simp add: div_def divAlg_def)
   434 by (simp add: div_def divAlg_def)
   436 
   435 
   437 lemma mod_neg_pos: "[| a < 0;  0 < b |] ==> a mod b = snd (negDivAlg(a,b))"
   436 lemma mod_neg_pos: "[| a < 0;  0 < b |] ==> a mod b = snd (negDivAlg a b)"
   438 by (simp add: mod_def divAlg_def)
   437 by (simp add: mod_def divAlg_def)
   439 
   438 
   440 text{*a positive, b negative *}
   439 text{*a positive, b negative *}
   441 
   440 
   442 lemma div_pos_neg:
   441 lemma div_pos_neg:
   443      "[| 0 < a;  b < 0 |] ==> a div b = fst (negateSnd(negDivAlg(-a,-b)))"
   442      "[| 0 < a;  b < 0 |] ==> a div b = fst (negateSnd (negDivAlg (-a) (-b)))"
   444 by (simp add: div_def divAlg_def)
   443 by (simp add: div_def divAlg_def)
   445 
   444 
   446 lemma mod_pos_neg:
   445 lemma mod_pos_neg:
   447      "[| 0 < a;  b < 0 |] ==> a mod b = snd (negateSnd(negDivAlg(-a,-b)))"
   446      "[| 0 < a;  b < 0 |] ==> a mod b = snd (negateSnd (negDivAlg (-a) (-b)))"
   448 by (simp add: mod_def divAlg_def)
   447 by (simp add: mod_def divAlg_def)
   449 
   448 
   450 text{*a negative, b negative *}
   449 text{*a negative, b negative *}
   451 
   450 
   452 lemma div_neg_neg:
   451 lemma div_neg_neg:
   453      "[| a < 0;  b \<le> 0 |] ==> a div b = fst (negateSnd(posDivAlg(-a,-b)))"
   452      "[| a < 0;  b \<le> 0 |] ==> a div b = fst (negateSnd (posDivAlg (-a) (-b)))"
   454 by (simp add: div_def divAlg_def)
   453 by (simp add: div_def divAlg_def)
   455 
   454 
   456 lemma mod_neg_neg:
   455 lemma mod_neg_neg:
   457      "[| a < 0;  b \<le> 0 |] ==> a mod b = snd (negateSnd(posDivAlg(-a,-b)))"
   456      "[| a < 0;  b \<le> 0 |] ==> a mod b = snd (negateSnd (posDivAlg (-a) (-b)))"
   458 by (simp add: mod_def divAlg_def)
   457 by (simp add: mod_def divAlg_def)
   459 
   458 
   460 text {*Simplify expresions in which div and mod combine numerical constants*}
   459 text {*Simplify expresions in which div and mod combine numerical constants*}
   461 
   460 
   462 lemmas div_pos_pos_number_of =
   461 lemmas div_pos_pos_number_of [simp] =
   463     div_pos_pos [of "number_of v" "number_of w", standard]
   462     div_pos_pos [of "number_of v" "number_of w", standard]
   464 declare div_pos_pos_number_of [simp]
   463 
   465 
   464 lemmas div_neg_pos_number_of [simp] =
   466 lemmas div_neg_pos_number_of =
       
   467     div_neg_pos [of "number_of v" "number_of w", standard]
   465     div_neg_pos [of "number_of v" "number_of w", standard]
   468 declare div_neg_pos_number_of [simp]
   466 
   469 
   467 lemmas div_pos_neg_number_of [simp] =
   470 lemmas div_pos_neg_number_of =
       
   471     div_pos_neg [of "number_of v" "number_of w", standard]
   468     div_pos_neg [of "number_of v" "number_of w", standard]
   472 declare div_pos_neg_number_of [simp]
   469 
   473 
   470 lemmas div_neg_neg_number_of [simp] =
   474 lemmas div_neg_neg_number_of =
       
   475     div_neg_neg [of "number_of v" "number_of w", standard]
   471     div_neg_neg [of "number_of v" "number_of w", standard]
   476 declare div_neg_neg_number_of [simp]
   472 
   477 
   473 
   478 
   474 lemmas mod_pos_pos_number_of [simp] =
   479 lemmas mod_pos_pos_number_of =
       
   480     mod_pos_pos [of "number_of v" "number_of w", standard]
   475     mod_pos_pos [of "number_of v" "number_of w", standard]
   481 declare mod_pos_pos_number_of [simp]
   476 
   482 
   477 lemmas mod_neg_pos_number_of [simp] =
   483 lemmas mod_neg_pos_number_of =
       
   484     mod_neg_pos [of "number_of v" "number_of w", standard]
   478     mod_neg_pos [of "number_of v" "number_of w", standard]
   485 declare mod_neg_pos_number_of [simp]
   479 
   486 
   480 lemmas mod_pos_neg_number_of [simp] =
   487 lemmas mod_pos_neg_number_of =
       
   488     mod_pos_neg [of "number_of v" "number_of w", standard]
   481     mod_pos_neg [of "number_of v" "number_of w", standard]
   489 declare mod_pos_neg_number_of [simp]
   482 
   490 
   483 lemmas mod_neg_neg_number_of [simp] =
   491 lemmas mod_neg_neg_number_of =
       
   492     mod_neg_neg [of "number_of v" "number_of w", standard]
   484     mod_neg_neg [of "number_of v" "number_of w", standard]
   493 declare mod_neg_neg_number_of [simp]
   485 
   494 
   486 
   495 
   487 lemmas posDivAlg_eqn_number_of [simp] =
   496 lemmas posDivAlg_eqn_number_of =
       
   497     posDivAlg_eqn [of "number_of v" "number_of w", standard]
   488     posDivAlg_eqn [of "number_of v" "number_of w", standard]
   498 declare posDivAlg_eqn_number_of [simp]
   489 
   499 
   490 lemmas negDivAlg_eqn_number_of [simp] =
   500 lemmas negDivAlg_eqn_number_of =
       
   501     negDivAlg_eqn [of "number_of v" "number_of w", standard]
   491     negDivAlg_eqn [of "number_of v" "number_of w", standard]
   502 declare negDivAlg_eqn_number_of [simp]
       
   503 
       
   504 
   492 
   505 
   493 
   506 text{*Special-case simplification *}
   494 text{*Special-case simplification *}
   507 
   495 
   508 lemma zmod_1 [simp]: "a mod (1::int) = 0"
   496 lemma zmod_1 [simp]: "a mod (1::int) = 0"
   524 by (cut_tac a = a and b = "-1" in zmod_zdiv_equality, auto)
   512 by (cut_tac a = a and b = "-1" in zmod_zdiv_equality, auto)
   525 
   513 
   526 (** The last remaining special cases for constant arithmetic:
   514 (** The last remaining special cases for constant arithmetic:
   527     1 div z and 1 mod z **)
   515     1 div z and 1 mod z **)
   528 
   516 
   529 lemmas div_pos_pos_1_number_of =
   517 lemmas div_pos_pos_1_number_of [simp] =
   530     div_pos_pos [OF int_0_less_1, of "number_of w", standard]
   518     div_pos_pos [OF int_0_less_1, of "number_of w", standard]
   531 declare div_pos_pos_1_number_of [simp]
   519 
   532 
   520 lemmas div_pos_neg_1_number_of [simp] =
   533 lemmas div_pos_neg_1_number_of =
       
   534     div_pos_neg [OF int_0_less_1, of "number_of w", standard]
   521     div_pos_neg [OF int_0_less_1, of "number_of w", standard]
   535 declare div_pos_neg_1_number_of [simp]
   522 
   536 
   523 lemmas mod_pos_pos_1_number_of [simp] =
   537 lemmas mod_pos_pos_1_number_of =
       
   538     mod_pos_pos [OF int_0_less_1, of "number_of w", standard]
   524     mod_pos_pos [OF int_0_less_1, of "number_of w", standard]
   539 declare mod_pos_pos_1_number_of [simp]
   525 
   540 
   526 lemmas mod_pos_neg_1_number_of [simp] =
   541 lemmas mod_pos_neg_1_number_of =
       
   542     mod_pos_neg [OF int_0_less_1, of "number_of w", standard]
   527     mod_pos_neg [OF int_0_less_1, of "number_of w", standard]
   543 declare mod_pos_neg_1_number_of [simp]
   528 
   544 
   529 
   545 
   530 lemmas posDivAlg_eqn_1_number_of [simp] =
   546 lemmas posDivAlg_eqn_1_number_of =
       
   547     posDivAlg_eqn [of concl: 1 "number_of w", standard]
   531     posDivAlg_eqn [of concl: 1 "number_of w", standard]
   548 declare posDivAlg_eqn_1_number_of [simp]
   532 
   549 
   533 lemmas negDivAlg_eqn_1_number_of [simp] =
   550 lemmas negDivAlg_eqn_1_number_of =
       
   551     negDivAlg_eqn [of concl: 1 "number_of w", standard]
   534     negDivAlg_eqn [of concl: 1 "number_of w", standard]
   552 declare negDivAlg_eqn_1_number_of [simp]
       
   553 
   535 
   554 
   536 
   555 
   537 
   556 subsection{*Monotonicity in the First Argument (Dividend)*}
   538 subsection{*Monotonicity in the First Argument (Dividend)*}
   557 
   539 
   683 next
   665 next
   684   assume "EX q::int. m = d*q"
   666   assume "EX q::int. m = d*q"
   685   thus "m mod d = 0" by auto
   667   thus "m mod d = 0" by auto
   686 qed
   668 qed
   687 
   669 
   688 lemmas zmod_eq_0D = zmod_eq_0_iff [THEN iffD1]
   670 lemmas zmod_eq_0D [dest!] = zmod_eq_0_iff [THEN iffD1]
   689 declare zmod_eq_0D [dest!]
       
   690 
   671 
   691 text{*proving (a+b) div c = a div c + b div c + ((a mod c + b mod c) div c) *}
   672 text{*proving (a+b) div c = a div c + b div c + ((a mod c + b mod c) div c) *}
   692 
   673 
   693 lemma zadd1_lemma:
   674 lemma zadd1_lemma:
   694      "[| quorem((a,c),(aq,ar));  quorem((b,c),(bq,br));  c \<noteq> 0 |]  
   675      "[| quorem((a,c),(aq,ar));  quorem((b,c),(bq,br));  c \<noteq> 0 |]  
  1045 subsection {* The Divides Relation *}
  1026 subsection {* The Divides Relation *}
  1046 
  1027 
  1047 lemma zdvd_iff_zmod_eq_0: "(m dvd n) = (n mod m = (0::int))"
  1028 lemma zdvd_iff_zmod_eq_0: "(m dvd n) = (n mod m = (0::int))"
  1048 by(simp add:dvd_def zmod_eq_0_iff)
  1029 by(simp add:dvd_def zmod_eq_0_iff)
  1049 
  1030 
  1050 lemmas zdvd_iff_zmod_eq_0_number_of =
  1031 lemmas zdvd_iff_zmod_eq_0_number_of [simp] =
  1051   zdvd_iff_zmod_eq_0 [of "number_of x" "number_of y", standard]
  1032   zdvd_iff_zmod_eq_0 [of "number_of x" "number_of y", standard]
  1052 
       
  1053 declare zdvd_iff_zmod_eq_0_number_of [simp]
       
  1054 
  1033 
  1055 lemma zdvd_0_right [iff]: "(m::int) dvd 0"
  1034 lemma zdvd_0_right [iff]: "(m::int) dvd 0"
  1056 by (simp add: dvd_def)
  1035 by (simp add: dvd_def)
  1057 
  1036 
  1058 lemma zdvd_0_left [iff]: "(0 dvd (m::int)) = (m = 0)"
  1037 lemma zdvd_0_left [iff]: "(0 dvd (m::int)) = (m = 0)"
  1378  apply (erule ssubst)
  1357  apply (erule ssubst)
  1379  apply (simp only: power_add)
  1358  apply (simp only: power_add)
  1380  apply simp_all
  1359  apply simp_all
  1381 done
  1360 done
  1382 
  1361 
  1383 ML
  1362 text {* code serializer setup *}
  1384 {*
  1363 
  1385 val quorem_def = thm "quorem_def";
  1364 code_modulename SML
  1386 
  1365   IntDiv Integer
  1387 val unique_quotient = thm "unique_quotient";
  1366 
  1388 val unique_remainder = thm "unique_remainder";
  1367 code_modulename OCaml
  1389 val adjust_eq = thm "adjust_eq";
  1368   IntDiv Integer
  1390 val posDivAlg_eqn = thm "posDivAlg_eqn";
  1369 
  1391 val posDivAlg_correct = thm "posDivAlg_correct";
  1370 code_modulename Haskell
  1392 val negDivAlg_eqn = thm "negDivAlg_eqn";
  1371   IntDiv Divides
  1393 val negDivAlg_correct = thm "negDivAlg_correct";
       
  1394 val quorem_0 = thm "quorem_0";
       
  1395 val posDivAlg_0 = thm "posDivAlg_0";
       
  1396 val negDivAlg_minus1 = thm "negDivAlg_minus1";
       
  1397 val negateSnd_eq = thm "negateSnd_eq";
       
  1398 val quorem_neg = thm "quorem_neg";
       
  1399 val divAlg_correct = thm "divAlg_correct";
       
  1400 val DIVISION_BY_ZERO = thm "DIVISION_BY_ZERO";
       
  1401 val zmod_zdiv_equality = thm "zmod_zdiv_equality";
       
  1402 val pos_mod_conj = thm "pos_mod_conj";
       
  1403 val pos_mod_sign = thm "pos_mod_sign";
       
  1404 val neg_mod_conj = thm "neg_mod_conj";
       
  1405 val neg_mod_sign = thm "neg_mod_sign";
       
  1406 val quorem_div_mod = thm "quorem_div_mod";
       
  1407 val quorem_div = thm "quorem_div";
       
  1408 val quorem_mod = thm "quorem_mod";
       
  1409 val div_pos_pos_trivial = thm "div_pos_pos_trivial";
       
  1410 val div_neg_neg_trivial = thm "div_neg_neg_trivial";
       
  1411 val div_pos_neg_trivial = thm "div_pos_neg_trivial";
       
  1412 val mod_pos_pos_trivial = thm "mod_pos_pos_trivial";
       
  1413 val mod_neg_neg_trivial = thm "mod_neg_neg_trivial";
       
  1414 val mod_pos_neg_trivial = thm "mod_pos_neg_trivial";
       
  1415 val zdiv_zminus_zminus = thm "zdiv_zminus_zminus";
       
  1416 val zmod_zminus_zminus = thm "zmod_zminus_zminus";
       
  1417 val zdiv_zminus1_eq_if = thm "zdiv_zminus1_eq_if";
       
  1418 val zmod_zminus1_eq_if = thm "zmod_zminus1_eq_if";
       
  1419 val zdiv_zminus2 = thm "zdiv_zminus2";
       
  1420 val zmod_zminus2 = thm "zmod_zminus2";
       
  1421 val zdiv_zminus2_eq_if = thm "zdiv_zminus2_eq_if";
       
  1422 val zmod_zminus2_eq_if = thm "zmod_zminus2_eq_if";
       
  1423 val self_quotient = thm "self_quotient";
       
  1424 val self_remainder = thm "self_remainder";
       
  1425 val zdiv_self = thm "zdiv_self";
       
  1426 val zmod_self = thm "zmod_self";
       
  1427 val zdiv_zero = thm "zdiv_zero";
       
  1428 val div_eq_minus1 = thm "div_eq_minus1";
       
  1429 val zmod_zero = thm "zmod_zero";
       
  1430 val zdiv_minus1 = thm "zdiv_minus1";
       
  1431 val zmod_minus1 = thm "zmod_minus1";
       
  1432 val div_pos_pos = thm "div_pos_pos";
       
  1433 val mod_pos_pos = thm "mod_pos_pos";
       
  1434 val div_neg_pos = thm "div_neg_pos";
       
  1435 val mod_neg_pos = thm "mod_neg_pos";
       
  1436 val div_pos_neg = thm "div_pos_neg";
       
  1437 val mod_pos_neg = thm "mod_pos_neg";
       
  1438 val div_neg_neg = thm "div_neg_neg";
       
  1439 val mod_neg_neg = thm "mod_neg_neg";
       
  1440 val zmod_1 = thm "zmod_1";
       
  1441 val zdiv_1 = thm "zdiv_1";
       
  1442 val zmod_minus1_right = thm "zmod_minus1_right";
       
  1443 val zdiv_minus1_right = thm "zdiv_minus1_right";
       
  1444 val zdiv_mono1 = thm "zdiv_mono1";
       
  1445 val zdiv_mono1_neg = thm "zdiv_mono1_neg";
       
  1446 val zdiv_mono2 = thm "zdiv_mono2";
       
  1447 val zdiv_mono2_neg = thm "zdiv_mono2_neg";
       
  1448 val zdiv_zmult1_eq = thm "zdiv_zmult1_eq";
       
  1449 val zmod_zmult1_eq = thm "zmod_zmult1_eq";
       
  1450 val zmod_zmult1_eq' = thm "zmod_zmult1_eq'";
       
  1451 val zmod_zmult_distrib = thm "zmod_zmult_distrib";
       
  1452 val zdiv_zmult_self1 = thm "zdiv_zmult_self1";
       
  1453 val zdiv_zmult_self2 = thm "zdiv_zmult_self2";
       
  1454 val zmod_zmult_self1 = thm "zmod_zmult_self1";
       
  1455 val zmod_zmult_self2 = thm "zmod_zmult_self2";
       
  1456 val zmod_eq_0_iff = thm "zmod_eq_0_iff";
       
  1457 val zdiv_zadd1_eq = thm "zdiv_zadd1_eq";
       
  1458 val zmod_zadd1_eq = thm "zmod_zadd1_eq";
       
  1459 val mod_div_trivial = thm "mod_div_trivial";
       
  1460 val mod_mod_trivial = thm "mod_mod_trivial";
       
  1461 val zmod_zadd_left_eq = thm "zmod_zadd_left_eq";
       
  1462 val zmod_zadd_right_eq = thm "zmod_zadd_right_eq";
       
  1463 val zdiv_zadd_self1 = thm "zdiv_zadd_self1";
       
  1464 val zdiv_zadd_self2 = thm "zdiv_zadd_self2";
       
  1465 val zmod_zadd_self1 = thm "zmod_zadd_self1";
       
  1466 val zmod_zadd_self2 = thm "zmod_zadd_self2";
       
  1467 val zdiv_zmult2_eq = thm "zdiv_zmult2_eq";
       
  1468 val zmod_zmult2_eq = thm "zmod_zmult2_eq";
       
  1469 val zdiv_zmult_zmult1 = thm "zdiv_zmult_zmult1";
       
  1470 val zdiv_zmult_zmult2 = thm "zdiv_zmult_zmult2";
       
  1471 val zmod_zmult_zmult1 = thm "zmod_zmult_zmult1";
       
  1472 val zmod_zmult_zmult2 = thm "zmod_zmult_zmult2";
       
  1473 val pos_zdiv_mult_2 = thm "pos_zdiv_mult_2";
       
  1474 val neg_zdiv_mult_2 = thm "neg_zdiv_mult_2";
       
  1475 val zdiv_number_of_BIT = thm "zdiv_number_of_BIT";
       
  1476 val pos_zmod_mult_2 = thm "pos_zmod_mult_2";
       
  1477 val neg_zmod_mult_2 = thm "neg_zmod_mult_2";
       
  1478 val zmod_number_of_BIT = thm "zmod_number_of_BIT";
       
  1479 val div_neg_pos_less0 = thm "div_neg_pos_less0";
       
  1480 val div_nonneg_neg_le0 = thm "div_nonneg_neg_le0";
       
  1481 val pos_imp_zdiv_nonneg_iff = thm "pos_imp_zdiv_nonneg_iff";
       
  1482 val neg_imp_zdiv_nonneg_iff = thm "neg_imp_zdiv_nonneg_iff";
       
  1483 val pos_imp_zdiv_neg_iff = thm "pos_imp_zdiv_neg_iff";
       
  1484 val neg_imp_zdiv_neg_iff = thm "neg_imp_zdiv_neg_iff";
       
  1485 
       
  1486 val zpower_zmod = thm "zpower_zmod";
       
  1487 val zpower_zadd_distrib = thm "zpower_zadd_distrib";
       
  1488 val zpower_zpower = thm "zpower_zpower";
       
  1489 val zero_less_zpower_abs_iff = thm "zero_less_zpower_abs_iff";
       
  1490 val zero_le_zpower_abs = thm "zero_le_zpower_abs";
       
  1491 val zpower_int = thm "zpower_int";
       
  1492 *}
       
  1493 
  1372 
  1494 end
  1373 end