src/HOL/Divides.thy
changeset 66815 93c6632ddf44
parent 66814 a24cde9588bb
child 66816 212a3334e7da
equal deleted inserted replaced
66814:a24cde9588bb 66815:93c6632ddf44
     4 *)
     4 *)
     5 
     5 
     6 section \<open>More on quotient and remainder\<close>
     6 section \<open>More on quotient and remainder\<close>
     7 
     7 
     8 theory Divides
     8 theory Divides
     9 imports Parity
     9 imports Parity Nat_Transfer
    10 begin
    10 begin
    11 
    11 
    12 subsection \<open>Numeral division with a pragmatic type class\<close>
    12 subsection \<open>Numeral division with a pragmatic type class\<close>
    13 
    13 
    14 text \<open>
    14 text \<open>
    17   to its positive segments.  This is its primary motivation, and it
    17   to its positive segments.  This is its primary motivation, and it
    18   could surely be formulated using a more fine-grained, more algebraic
    18   could surely be formulated using a more fine-grained, more algebraic
    19   and less technical class hierarchy.
    19   and less technical class hierarchy.
    20 \<close>
    20 \<close>
    21 
    21 
    22 class unique_euclidean_semiring_numeral = unique_euclidean_semiring + linordered_semidom +
    22 class unique_euclidean_semiring_numeral = semiring_parity + linordered_semidom +
    23   assumes div_less: "0 \<le> a \<Longrightarrow> a < b \<Longrightarrow> a div b = 0"
    23   assumes div_less: "0 \<le> a \<Longrightarrow> a < b \<Longrightarrow> a div b = 0"
    24     and mod_less: " 0 \<le> a \<Longrightarrow> a < b \<Longrightarrow> a mod b = a"
    24     and mod_less: " 0 \<le> a \<Longrightarrow> a < b \<Longrightarrow> a mod b = a"
    25     and div_positive: "0 < b \<Longrightarrow> b \<le> a \<Longrightarrow> a div b > 0"
    25     and div_positive: "0 < b \<Longrightarrow> b \<le> a \<Longrightarrow> a div b > 0"
    26     and mod_less_eq_dividend: "0 \<le> a \<Longrightarrow> a mod b \<le> a"
    26     and mod_less_eq_dividend: "0 \<le> a \<Longrightarrow> a mod b \<le> a"
    27     and pos_mod_bound: "0 < b \<Longrightarrow> a mod b < b"
    27     and pos_mod_bound: "0 < b \<Longrightarrow> a mod b < b"
    38     \<comment> \<open>These are conceptually definitions but force generated code
    38     \<comment> \<open>These are conceptually definitions but force generated code
    39     to be monomorphic wrt. particular instances of this class which
    39     to be monomorphic wrt. particular instances of this class which
    40     yields a significant speedup.\<close>
    40     yields a significant speedup.\<close>
    41 begin
    41 begin
    42 
    42 
    43 subclass unique_euclidean_semiring_parity
       
    44 proof
       
    45   fix a
       
    46   show "a mod 2 = 0 \<or> a mod 2 = 1"
       
    47   proof (rule ccontr)
       
    48     assume "\<not> (a mod 2 = 0 \<or> a mod 2 = 1)"
       
    49     then have "a mod 2 \<noteq> 0" and "a mod 2 \<noteq> 1" by simp_all
       
    50     have "0 < 2" by simp
       
    51     with pos_mod_bound pos_mod_sign have "0 \<le> a mod 2" "a mod 2 < 2" by simp_all
       
    52     with \<open>a mod 2 \<noteq> 0\<close> have "0 < a mod 2" by simp
       
    53     with discrete have "1 \<le> a mod 2" by simp
       
    54     with \<open>a mod 2 \<noteq> 1\<close> have "1 < a mod 2" by simp
       
    55     with discrete have "2 \<le> a mod 2" by simp
       
    56     with \<open>a mod 2 < 2\<close> show False by simp
       
    57   qed
       
    58 next
       
    59   show "1 mod 2 = 1"
       
    60     by (rule mod_less) simp_all
       
    61 next
       
    62   show "0 \<noteq> 2"
       
    63     by simp
       
    64 qed
       
    65 
       
    66 lemma divmod_digit_1:
    43 lemma divmod_digit_1:
    67   assumes "0 \<le> a" "0 < b" and "b \<le> a mod (2 * b)"
    44   assumes "0 \<le> a" "0 < b" and "b \<le> a mod (2 * b)"
    68   shows "2 * (a div (2 * b)) + 1 = a div b" (is "?P")
    45   shows "2 * (a div (2 * b)) + 1 = a div b" (is "?P")
    69     and "a mod (2 * b) - b = a mod b" (is "?Q")
    46     and "a mod (2 * b) - b = a mod b" (is "?Q")
    70 proof -
    47 proof -
    72     by (auto intro: trans)
    49     by (auto intro: trans)
    73   with \<open>0 < b\<close> have "0 < a div b" by (auto intro: div_positive)
    50   with \<open>0 < b\<close> have "0 < a div b" by (auto intro: div_positive)
    74   then have [simp]: "1 \<le> a div b" by (simp add: discrete)
    51   then have [simp]: "1 \<le> a div b" by (simp add: discrete)
    75   with \<open>0 < b\<close> have mod_less: "a mod b < b" by (simp add: pos_mod_bound)
    52   with \<open>0 < b\<close> have mod_less: "a mod b < b" by (simp add: pos_mod_bound)
    76   define w where "w = a div b mod 2"
    53   define w where "w = a div b mod 2"
    77   with parity have w_exhaust: "w = 0 \<or> w = 1" by auto
    54   then have w_exhaust: "w = 0 \<or> w = 1" by auto
    78   have mod_w: "a mod (2 * b) = a mod b + b * w"
    55   have mod_w: "a mod (2 * b) = a mod b + b * w"
    79     by (simp add: w_def mod_mult2_eq ac_simps)
    56     by (simp add: w_def mod_mult2_eq ac_simps)
    80   from assms w_exhaust have "w = 1"
    57   from assms w_exhaust have "w = 1"
    81     by (auto simp add: mod_w) (insert mod_less, auto)
    58     by (auto simp add: mod_w) (insert mod_less, auto)
    82   with mod_w have mod: "a mod (2 * b) = a mod b + b" by simp
    59   with mod_w have mod: "a mod (2 * b) = a mod b + b" by simp
    91   assumes "0 < b" and "a mod (2 * b) < b"
    68   assumes "0 < b" and "a mod (2 * b) < b"
    92   shows "2 * (a div (2 * b)) = a div b" (is "?P")
    69   shows "2 * (a div (2 * b)) = a div b" (is "?P")
    93     and "a mod (2 * b) = a mod b" (is "?Q")
    70     and "a mod (2 * b) = a mod b" (is "?Q")
    94 proof -
    71 proof -
    95   define w where "w = a div b mod 2"
    72   define w where "w = a div b mod 2"
    96   with parity have w_exhaust: "w = 0 \<or> w = 1" by auto
    73   then have w_exhaust: "w = 0 \<or> w = 1" by auto
    97   have mod_w: "a mod (2 * b) = a mod b + b * w"
    74   have mod_w: "a mod (2 * b) = a mod b + b * w"
    98     by (simp add: w_def mod_mult2_eq ac_simps)
    75     by (simp add: w_def mod_mult2_eq ac_simps)
    99   moreover have "b \<le> a mod b + b"
    76   moreover have "b \<le> a mod b + b"
   100   proof -
    77   proof -
   101     from \<open>0 < b\<close> pos_mod_sign have "0 \<le> a mod b" by blast
    78     from \<open>0 < b\<close> pos_mod_sign have "0 \<le> a mod b" by blast
   316 
   293 
   317 end
   294 end
   318 
   295 
   319 declare divmod_algorithm_code [where ?'a = nat, code]
   296 declare divmod_algorithm_code [where ?'a = nat, code]
   320 
   297 
   321 lemma odd_Suc_minus_one [simp]: "odd n \<Longrightarrow> Suc (n - Suc 0) = n"
       
   322   by (auto elim: oddE)
       
   323 
       
   324 lemma even_Suc_div_two [simp]:
       
   325   "even n \<Longrightarrow> Suc n div 2 = n div 2"
       
   326   using even_succ_div_two [of n] by simp
       
   327 
       
   328 lemma odd_Suc_div_two [simp]:
       
   329   "odd n \<Longrightarrow> Suc n div 2 = Suc (n div 2)"
       
   330   using odd_succ_div_two [of n] by simp
       
   331 
       
   332 lemma odd_two_times_div_two_nat [simp]:
       
   333   assumes "odd n"
       
   334   shows "2 * (n div 2) = n - (1 :: nat)"
       
   335 proof -
       
   336   from assms have "2 * (n div 2) + 1 = n"
       
   337     by (rule odd_two_times_div_two_succ)
       
   338   then have "Suc (2 * (n div 2)) - 1 = n - 1"
       
   339     by simp
       
   340   then show ?thesis
       
   341     by simp
       
   342 qed
       
   343 
       
   344 lemma parity_induct [case_names zero even odd]:
       
   345   assumes zero: "P 0"
       
   346   assumes even: "\<And>n. P n \<Longrightarrow> P (2 * n)"
       
   347   assumes odd: "\<And>n. P n \<Longrightarrow> P (Suc (2 * n))"
       
   348   shows "P n"
       
   349 proof (induct n rule: less_induct)
       
   350   case (less n)
       
   351   show "P n"
       
   352   proof (cases "n = 0")
       
   353     case True with zero show ?thesis by simp
       
   354   next
       
   355     case False
       
   356     with less have hyp: "P (n div 2)" by simp
       
   357     show ?thesis
       
   358     proof (cases "even n")
       
   359       case True
       
   360       with hyp even [of "n div 2"] show ?thesis
       
   361         by simp
       
   362     next
       
   363       case False
       
   364       with hyp odd [of "n div 2"] show ?thesis
       
   365         by simp
       
   366     qed
       
   367   qed
       
   368 qed
       
   369 
       
   370 lemma mod_2_not_eq_zero_eq_one_nat:
       
   371   fixes n :: nat
       
   372   shows "n mod 2 \<noteq> 0 \<longleftrightarrow> n mod 2 = 1"
       
   373   by (fact not_mod_2_eq_0_eq_1)
       
   374 
       
   375 lemma Suc_0_div_numeral [simp]:
   298 lemma Suc_0_div_numeral [simp]:
   376   fixes k l :: num
   299   fixes k l :: num
   377   shows "Suc 0 div numeral k = fst (divmod Num.One k)"
   300   shows "Suc 0 div numeral k = fst (divmod Num.One k)"
   378   by (simp_all add: fst_divmod)
   301   by (simp_all add: fst_divmod)
   379 
   302 
   705 apply (rule_tac q = "-1" in mod_int_unique)
   628 apply (rule_tac q = "-1" in mod_int_unique)
   706 apply (auto simp add: eucl_rel_int_iff)
   629 apply (auto simp add: eucl_rel_int_iff)
   707 done
   630 done
   708 
   631 
   709 text\<open>There is no \<open>mod_neg_pos_trivial\<close>.\<close>
   632 text\<open>There is no \<open>mod_neg_pos_trivial\<close>.\<close>
       
   633 
       
   634 instance int :: ring_parity
       
   635 proof
       
   636   fix k l :: int
       
   637   show "k mod 2 = 1" if "\<not> 2 dvd k"
       
   638   proof (rule order_antisym)
       
   639     have "0 \<le> k mod 2" and "k mod 2 < 2"
       
   640       by auto
       
   641     moreover have "k mod 2 \<noteq> 0"
       
   642       using that by (simp add: dvd_eq_mod_eq_0)
       
   643     ultimately have "0 < k mod 2"
       
   644       by (simp only: less_le) simp
       
   645     then show "1 \<le> k mod 2"
       
   646       by simp
       
   647     from \<open>k mod 2 < 2\<close> show "k mod 2 \<le> 1"
       
   648       by (simp only: less_le) simp
       
   649   qed
       
   650 qed (simp_all add: dvd_eq_mod_eq_0 divide_int_def)
       
   651 
       
   652 lemma even_diff_iff [simp]:
       
   653   "even (k - l) \<longleftrightarrow> even (k + l)" for k l :: int
       
   654   using dvd_add_times_triv_right_iff [of 2 "k - l" l] by (simp add: mult_2_right)
       
   655 
       
   656 lemma even_abs_add_iff [simp]:
       
   657   "even (\<bar>k\<bar> + l) \<longleftrightarrow> even (k + l)" for k l :: int
       
   658   by (cases "k \<ge> 0") (simp_all add: ac_simps)
       
   659 
       
   660 lemma even_add_abs_iff [simp]:
       
   661   "even (k + \<bar>l\<bar>) \<longleftrightarrow> even (k + l)" for k l :: int
       
   662   using even_abs_add_iff [of l k] by (simp add: ac_simps)
       
   663 
       
   664 lemma even_nat_iff: "0 \<le> k \<Longrightarrow> even (nat k) \<longleftrightarrow> even k"
       
   665   by (simp add: even_of_nat [of "nat k", where ?'a = int, symmetric])
   710 
   666 
   711 
   667 
   712 subsubsection \<open>Laws for div and mod with Unary Minus\<close>
   668 subsubsection \<open>Laws for div and mod with Unary Minus\<close>
   713 
   669 
   714 lemma zminus1_lemma:
   670 lemma zminus1_lemma:
  1493   from div_mult_mod_eq obtain q where "q * d + m mod d = m" by blast
  1449   from div_mult_mod_eq obtain q where "q * d + m mod d = m" by blast
  1494   with assms have "m = r + q * d" by simp
  1450   with assms have "m = r + q * d" by simp
  1495   then show ?thesis ..
  1451   then show ?thesis ..
  1496 qed
  1452 qed
  1497 
  1453 
       
  1454 lemmas even_times_iff = even_mult_iff -- \<open>FIXME duplicate\<close>
       
  1455 
       
  1456 lemma mod_2_not_eq_zero_eq_one_nat:
       
  1457   fixes n :: nat
       
  1458   shows "n mod 2 \<noteq> 0 \<longleftrightarrow> n mod 2 = 1"
       
  1459   by (fact not_mod_2_eq_0_eq_1)
       
  1460 
       
  1461 lemma even_int_iff [simp]: "even (int n) \<longleftrightarrow> even n"
       
  1462   by (fact even_of_nat)
       
  1463 
       
  1464 text \<open>Tool setup\<close>
       
  1465 
       
  1466 declare transfer_morphism_int_nat [transfer add return: even_int_iff]
       
  1467 
  1498 end
  1468 end