src/HOL/Divides.thy
changeset 61799 4cf66f21b764
parent 61649 268d88ec9087
child 61944 5d06ecfdb472
equal deleted inserted replaced
61798:27f3c10b0b50 61799:4cf66f21b764
   218   then show ?thesis by (simp add: mod_div_equality)
   218   then show ?thesis by (simp add: mod_div_equality)
   219 qed
   219 qed
   220 
   220 
   221 text \<open>Addition respects modular equivalence.\<close>
   221 text \<open>Addition respects modular equivalence.\<close>
   222 
   222 
   223 lemma mod_add_left_eq: -- \<open>FIXME reorient\<close>
   223 lemma mod_add_left_eq: \<comment> \<open>FIXME reorient\<close>
   224   "(a + b) mod c = (a mod c + b) mod c"
   224   "(a + b) mod c = (a mod c + b) mod c"
   225 proof -
   225 proof -
   226   have "(a + b) mod c = (a div c * c + a mod c + b) mod c"
   226   have "(a + b) mod c = (a div c * c + a mod c + b) mod c"
   227     by (simp only: mod_div_equality)
   227     by (simp only: mod_div_equality)
   228   also have "\<dots> = (a mod c + b + a div c * c) mod c"
   228   also have "\<dots> = (a mod c + b + a div c * c) mod c"
   230   also have "\<dots> = (a mod c + b) mod c"
   230   also have "\<dots> = (a mod c + b) mod c"
   231     by (rule mod_mult_self1)
   231     by (rule mod_mult_self1)
   232   finally show ?thesis .
   232   finally show ?thesis .
   233 qed
   233 qed
   234 
   234 
   235 lemma mod_add_right_eq: -- \<open>FIXME reorient\<close>
   235 lemma mod_add_right_eq: \<comment> \<open>FIXME reorient\<close>
   236   "(a + b) mod c = (a + b mod c) mod c"
   236   "(a + b) mod c = (a + b mod c) mod c"
   237 proof -
   237 proof -
   238   have "(a + b) mod c = (a + (b div c * c + b mod c)) mod c"
   238   have "(a + b) mod c = (a + (b div c * c + b mod c)) mod c"
   239     by (simp only: mod_div_equality)
   239     by (simp only: mod_div_equality)
   240   also have "\<dots> = (a + b mod c + b div c * c) mod c"
   240   also have "\<dots> = (a + b mod c + b div c * c) mod c"
   242   also have "\<dots> = (a + b mod c) mod c"
   242   also have "\<dots> = (a + b mod c) mod c"
   243     by (rule mod_mult_self1)
   243     by (rule mod_mult_self1)
   244   finally show ?thesis .
   244   finally show ?thesis .
   245 qed
   245 qed
   246 
   246 
   247 lemma mod_add_eq: -- \<open>FIXME reorient\<close>
   247 lemma mod_add_eq: \<comment> \<open>FIXME reorient\<close>
   248   "(a + b) mod c = (a mod c + b mod c) mod c"
   248   "(a + b) mod c = (a mod c + b mod c) mod c"
   249 by (rule trans [OF mod_add_left_eq mod_add_right_eq])
   249 by (rule trans [OF mod_add_left_eq mod_add_right_eq])
   250 
   250 
   251 lemma mod_add_cong:
   251 lemma mod_add_cong:
   252   assumes "a mod c = a' mod c"
   252   assumes "a mod c = a' mod c"
   259     by (simp only: mod_add_eq [symmetric])
   259     by (simp only: mod_add_eq [symmetric])
   260 qed
   260 qed
   261 
   261 
   262 text \<open>Multiplication respects modular equivalence.\<close>
   262 text \<open>Multiplication respects modular equivalence.\<close>
   263 
   263 
   264 lemma mod_mult_left_eq: -- \<open>FIXME reorient\<close>
   264 lemma mod_mult_left_eq: \<comment> \<open>FIXME reorient\<close>
   265   "(a * b) mod c = ((a mod c) * b) mod c"
   265   "(a * b) mod c = ((a mod c) * b) mod c"
   266 proof -
   266 proof -
   267   have "(a * b) mod c = ((a div c * c + a mod c) * b) mod c"
   267   have "(a * b) mod c = ((a div c * c + a mod c) * b) mod c"
   268     by (simp only: mod_div_equality)
   268     by (simp only: mod_div_equality)
   269   also have "\<dots> = (a mod c * b + a div c * b * c) mod c"
   269   also have "\<dots> = (a mod c * b + a div c * b * c) mod c"
   271   also have "\<dots> = (a mod c * b) mod c"
   271   also have "\<dots> = (a mod c * b) mod c"
   272     by (rule mod_mult_self1)
   272     by (rule mod_mult_self1)
   273   finally show ?thesis .
   273   finally show ?thesis .
   274 qed
   274 qed
   275 
   275 
   276 lemma mod_mult_right_eq: -- \<open>FIXME reorient\<close>
   276 lemma mod_mult_right_eq: \<comment> \<open>FIXME reorient\<close>
   277   "(a * b) mod c = (a * (b mod c)) mod c"
   277   "(a * b) mod c = (a * (b mod c)) mod c"
   278 proof -
   278 proof -
   279   have "(a * b) mod c = (a * (b div c * c + b mod c)) mod c"
   279   have "(a * b) mod c = (a * (b div c * c + b mod c)) mod c"
   280     by (simp only: mod_div_equality)
   280     by (simp only: mod_div_equality)
   281   also have "\<dots> = (a * (b mod c) + a * (b div c) * c) mod c"
   281   also have "\<dots> = (a * (b mod c) + a * (b div c) * c) mod c"
   283   also have "\<dots> = (a * (b mod c)) mod c"
   283   also have "\<dots> = (a * (b mod c)) mod c"
   284     by (rule mod_mult_self1)
   284     by (rule mod_mult_self1)
   285   finally show ?thesis .
   285   finally show ?thesis .
   286 qed
   286 qed
   287 
   287 
   288 lemma mod_mult_eq: -- \<open>FIXME reorient\<close>
   288 lemma mod_mult_eq: \<comment> \<open>FIXME reorient\<close>
   289   "(a * b) mod c = ((a mod c) * (b mod c)) mod c"
   289   "(a * b) mod c = ((a mod c) * (b mod c)) mod c"
   290 by (rule trans [OF mod_mult_left_eq mod_mult_right_eq])
   290 by (rule trans [OF mod_mult_left_eq mod_mult_right_eq])
   291 
   291 
   292 lemma mod_mult_cong:
   292 lemma mod_mult_cong:
   293   assumes "a mod c = a' mod c"
   293   assumes "a mod c = a' mod c"
   571     and divmod_step :: "num \<Rightarrow> 'a \<times> 'a \<Rightarrow> 'a \<times> 'a"
   571     and divmod_step :: "num \<Rightarrow> 'a \<times> 'a \<Rightarrow> 'a \<times> 'a"
   572   assumes divmod_def: "divmod m n = (numeral m div numeral n, numeral m mod numeral n)"
   572   assumes divmod_def: "divmod m n = (numeral m div numeral n, numeral m mod numeral n)"
   573     and divmod_step_def: "divmod_step l qr = (let (q, r) = qr
   573     and divmod_step_def: "divmod_step l qr = (let (q, r) = qr
   574     in if r \<ge> numeral l then (2 * q + 1, r - numeral l)
   574     in if r \<ge> numeral l then (2 * q + 1, r - numeral l)
   575     else (2 * q, r))"
   575     else (2 * q, r))"
   576     -- \<open>These are conceptually definitions but force generated code
   576     \<comment> \<open>These are conceptually definitions but force generated code
   577     to be monomorphic wrt. particular instances of this class which
   577     to be monomorphic wrt. particular instances of this class which
   578     yields a significant speedup.\<close>
   578     yields a significant speedup.\<close>
   579 
   579 
   580 begin
   580 begin
   581 
   581 
   731   then have "divmod m n = divmod_step n (divmod m (Num.Bit0 n))"
   731   then have "divmod m n = divmod_step n (divmod m (Num.Bit0 n))"
   732     by (simp add: divmod_def)
   732     by (simp add: divmod_def)
   733   with False show ?thesis by simp
   733   with False show ?thesis by simp
   734 qed
   734 qed
   735 
   735 
   736 text \<open>The division rewrite proper -- first, trivial results involving @{text 1}\<close>
   736 text \<open>The division rewrite proper -- first, trivial results involving \<open>1\<close>\<close>
   737 
   737 
   738 lemma divmod_trivial [simp]:
   738 lemma divmod_trivial [simp]:
   739   "divmod Num.One Num.One = (numeral Num.One, 0)"
   739   "divmod Num.One Num.One = (numeral Num.One, 0)"
   740   "divmod (Num.Bit0 m) Num.One = (numeral (Num.Bit0 m), 0)"
   740   "divmod (Num.Bit0 m) Num.One = (numeral (Num.Bit0 m), 0)"
   741   "divmod (Num.Bit1 m) Num.One = (numeral (Num.Bit1 m), 0)"
   741   "divmod (Num.Bit1 m) Num.One = (numeral (Num.Bit1 m), 0)"
  1426   have "\<forall>k. 0<k \<longrightarrow> \<not> P (p-k)" (is "\<forall>k. ?A k")
  1426   have "\<forall>k. 0<k \<longrightarrow> \<not> P (p-k)" (is "\<forall>k. ?A k")
  1427   proof
  1427   proof
  1428     fix k
  1428     fix k
  1429     show "?A k"
  1429     show "?A k"
  1430     proof (induct k)
  1430     proof (induct k)
  1431       show "?A 0" by simp  -- "by contradiction"
  1431       show "?A 0" by simp  \<comment> "by contradiction"
  1432     next
  1432     next
  1433       fix n
  1433       fix n
  1434       assume ih: "?A n"
  1434       assume ih: "?A n"
  1435       show "?A (Suc n)"
  1435       show "?A (Suc n)"
  1436       proof (clarsimp)
  1436       proof (clarsimp)
  1636   by (simp_all add: snd_divmod)
  1636   by (simp_all add: snd_divmod)
  1637 
  1637 
  1638 
  1638 
  1639 subsection \<open>Division on @{typ int}\<close>
  1639 subsection \<open>Division on @{typ int}\<close>
  1640 
  1640 
  1641 definition divmod_int_rel :: "int \<Rightarrow> int \<Rightarrow> int \<times> int \<Rightarrow> bool" -- \<open>definition of quotient and remainder\<close>
  1641 definition divmod_int_rel :: "int \<Rightarrow> int \<Rightarrow> int \<times> int \<Rightarrow> bool" \<comment> \<open>definition of quotient and remainder\<close>
  1642   where "divmod_int_rel a b = (\<lambda>(q, r). a = b * q + r \<and>
  1642   where "divmod_int_rel a b = (\<lambda>(q, r). a = b * q + r \<and>
  1643     (if 0 < b then 0 \<le> r \<and> r < b else if b < 0 then b < r \<and> r \<le> 0 else q = 0))"
  1643     (if 0 < b then 0 \<le> r \<and> r < b else if b < 0 then b < r \<and> r \<le> 0 else q = 0))"
  1644 
  1644 
  1645 lemma unique_quotient_lemma:
  1645 lemma unique_quotient_lemma:
  1646   "b * q' + r' \<le> b * q + r \<Longrightarrow> 0 \<le> r' \<Longrightarrow> r' < b \<Longrightarrow> r < b \<Longrightarrow> q' \<le> (q::int)"
  1646   "b * q' + r' \<le> b * q + r \<Longrightarrow> 0 \<le> r' \<Longrightarrow> r' < b \<Longrightarrow> r < b \<Longrightarrow> q' \<le> (q::int)"
  1858 lemma mod_pos_neg_trivial: "[| (0::int) < a;  a+b \<le> 0 |] ==> a mod b = a+b"
  1858 lemma mod_pos_neg_trivial: "[| (0::int) < a;  a+b \<le> 0 |] ==> a mod b = a+b"
  1859 apply (rule_tac q = "-1" in mod_int_unique)
  1859 apply (rule_tac q = "-1" in mod_int_unique)
  1860 apply (auto simp add: divmod_int_rel_def)
  1860 apply (auto simp add: divmod_int_rel_def)
  1861 done
  1861 done
  1862 
  1862 
  1863 text\<open>There is no @{text mod_neg_pos_trivial}.\<close>
  1863 text\<open>There is no \<open>mod_neg_pos_trivial\<close>.\<close>
  1864 
  1864 
  1865 
  1865 
  1866 subsubsection \<open>Laws for div and mod with Unary Minus\<close>
  1866 subsubsection \<open>Laws for div and mod with Unary Minus\<close>
  1867 
  1867 
  1868 lemma zminus1_lemma:
  1868 lemma zminus1_lemma:
  2168   @{term "numeral k"}:\<close>
  2168   @{term "numeral k"}:\<close>
  2169 declare split_zdiv [of _ _ "numeral k", arith_split] for k
  2169 declare split_zdiv [of _ _ "numeral k", arith_split] for k
  2170 declare split_zmod [of _ _ "numeral k", arith_split] for k
  2170 declare split_zmod [of _ _ "numeral k", arith_split] for k
  2171 
  2171 
  2172 
  2172 
  2173 subsubsection \<open>Computing @{text "div"} and @{text "mod"} with shifting\<close>
  2173 subsubsection \<open>Computing \<open>div\<close> and \<open>mod\<close> with shifting\<close>
  2174 
  2174 
  2175 lemma pos_divmod_int_rel_mult_2:
  2175 lemma pos_divmod_int_rel_mult_2:
  2176   assumes "0 \<le> b"
  2176   assumes "0 \<le> b"
  2177   assumes "divmod_int_rel a b (q, r)"
  2177   assumes "divmod_int_rel a b (q, r)"
  2178   shows "divmod_int_rel (1 + 2*a) (2*b) (q, 1 + 2*r)"
  2178   shows "divmod_int_rel (1 + 2*a) (2*b) (q, 1 + 2*r)"
  2270 by (drule zdiv_mono1_neg, auto)
  2270 by (drule zdiv_mono1_neg, auto)
  2271 
  2271 
  2272 lemma div_nonpos_pos_le0: "[| (a::int) \<le> 0; b > 0 |] ==> a div b \<le> 0"
  2272 lemma div_nonpos_pos_le0: "[| (a::int) \<le> 0; b > 0 |] ==> a div b \<le> 0"
  2273 by (drule zdiv_mono1, auto)
  2273 by (drule zdiv_mono1, auto)
  2274 
  2274 
  2275 text\<open>Now for some equivalences of the form @{text"a div b >=< 0 \<longleftrightarrow> \<dots>"}
  2275 text\<open>Now for some equivalences of the form \<open>a div b >=< 0 \<longleftrightarrow> \<dots>\<close>
  2276 conditional upon the sign of @{text a} or @{text b}. There are many more.
  2276 conditional upon the sign of \<open>a\<close> or \<open>b\<close>. There are many more.
  2277 They should all be simp rules unless that causes too much search.\<close>
  2277 They should all be simp rules unless that causes too much search.\<close>
  2278 
  2278 
  2279 lemma pos_imp_zdiv_nonneg_iff: "(0::int) < b ==> (0 \<le> a div b) = (0 \<le> a)"
  2279 lemma pos_imp_zdiv_nonneg_iff: "(0::int) < b ==> (0 \<le> a div b) = (0 \<le> a)"
  2280 apply auto
  2280 apply auto
  2281 apply (drule_tac [2] zdiv_mono1)
  2281 apply (drule_tac [2] zdiv_mono1)
  2464   mod_mult_right_eq[symmetric]
  2464   mod_mult_right_eq[symmetric]
  2465   mod_mult_left_eq [symmetric]
  2465   mod_mult_left_eq [symmetric]
  2466   power_mod
  2466   power_mod
  2467   zminus_zmod zdiff_zmod_left zdiff_zmod_right
  2467   zminus_zmod zdiff_zmod_left zdiff_zmod_right
  2468 
  2468 
  2469 text \<open>Distributive laws for function @{text nat}.\<close>
  2469 text \<open>Distributive laws for function \<open>nat\<close>.\<close>
  2470 
  2470 
  2471 lemma nat_div_distrib: "0 \<le> x \<Longrightarrow> nat (x div y) = nat x div nat y"
  2471 lemma nat_div_distrib: "0 \<le> x \<Longrightarrow> nat (x div y) = nat x div nat y"
  2472 apply (rule linorder_cases [of y 0])
  2472 apply (rule linorder_cases [of y 0])
  2473 apply (simp add: div_nonneg_neg_le0)
  2473 apply (simp add: div_nonneg_neg_le0)
  2474 apply simp
  2474 apply simp