# HG changeset patch # User haftmann # Date 1547930417 0 # Node ID 753ae9e9773d61c72be9afc13154516347cb0a91 # Parent 2633e166136af84e1d8600e0887105ac83fd5233 algebraized more material from theory Divides diff -r 2633e166136a -r 753ae9e9773d src/HOL/Divides.thy --- a/src/HOL/Divides.thy Sat Jan 19 20:31:00 2019 +0100 +++ b/src/HOL/Divides.thy Sat Jan 19 20:40:17 2019 +0000 @@ -97,11 +97,11 @@ lemma zdiv_int: "int (a div b) = int a div int b" - by (simp add: divide_int_def sgn_1_pos) + by (simp add: divide_int_def) lemma zmod_int: "int (a mod b) = int a mod int b" - by (simp add: modulo_int_def sgn_1_pos) + by (simp add: modulo_int_def) lemma div_sgn_abs_cancel: fixes k l v :: int @@ -167,54 +167,40 @@ using assms by (simp only: divide_int_def [of k l], auto simp add: not_less zdiv_int) -text\Basic laws about division and remainder\ - -lemma pos_mod_conj: "(0::int) < b \ 0 \ a mod b \ a mod b < b" - using eucl_rel_int [of a b] - by (auto simp add: eucl_rel_int_iff prod_eq_iff) - -lemmas pos_mod_sign = pos_mod_conj [THEN conjunct1] - and pos_mod_bound = pos_mod_conj [THEN conjunct2] - -lemma neg_mod_conj: "b < (0::int) \ a mod b \ 0 \ b < a mod b" - using eucl_rel_int [of a b] - by (auto simp add: eucl_rel_int_iff prod_eq_iff) - -lemmas neg_mod_sign [simp] = neg_mod_conj [THEN conjunct1] - and neg_mod_bound [simp] = neg_mod_conj [THEN conjunct2] - subsubsection \General Properties of div and mod\ lemma div_pos_pos_trivial [simp]: "k div l = 0" if "k \ 0" and "k < l" for k l :: int - using that by (auto intro!: div_int_unique [of _ _ _ k] simp add: eucl_rel_int_iff) + using that by (simp add: unique_euclidean_semiring_class.div_eq_0_iff division_segment_int_def) + +lemma mod_pos_pos_trivial [simp]: + "k mod l = k" if "k \ 0" and "k < l" for k l :: int + using that by (simp add: mod_eq_self_iff_div_eq_0) lemma div_neg_neg_trivial [simp]: "k div l = 0" if "k \ 0" and "l < k" for k l :: int - using that by (auto intro!: div_int_unique [of _ _ _ k] simp add: eucl_rel_int_iff) - -lemma div_pos_neg_trivial: "[| (0::int) < a; a+b \ 0 |] ==> a div b = -1" -apply (rule div_int_unique) -apply (auto simp add: eucl_rel_int_iff) -done - -(*There is no div_neg_pos_trivial because 0 div b = 0 would supersede it*) - -lemma mod_pos_pos_trivial [simp]: - "k mod l = k" if "k \ 0" and "k < l" for k l :: int - using that by (auto intro!: mod_int_unique [of _ _ 0] simp add: eucl_rel_int_iff) + using that by (cases "k = 0") (simp, simp add: unique_euclidean_semiring_class.div_eq_0_iff division_segment_int_def) lemma mod_neg_neg_trivial [simp]: "k mod l = k" if "k \ 0" and "l < k" for k l :: int - using that by (auto intro!: mod_int_unique [of _ _ 0] simp add: eucl_rel_int_iff) + using that by (simp add: mod_eq_self_iff_div_eq_0) + +lemma div_pos_neg_trivial: + "k div l = - 1" if "0 < k" and "k + l \ 0" for k l :: int + apply (rule div_int_unique [of _ _ _ "k + l"]) + apply (use that in \auto simp add: eucl_rel_int_iff\) + done -lemma mod_pos_neg_trivial: "[| (0::int) < a; a+b \ 0 |] ==> a mod b = a+b" -apply (rule_tac q = "-1" in mod_int_unique) -apply (auto simp add: eucl_rel_int_iff) -done +lemma mod_pos_neg_trivial: + "k mod l = k + l" if "0 < k" and "k + l \ 0" for k l :: int + apply (rule mod_int_unique [of _ _ "- 1"]) + apply (use that in \auto simp add: eucl_rel_int_iff\) + done -text\There is no \mod_neg_pos_trivial\.\ +text \There is neither \div_neg_pos_trivial\ nor \mod_neg_pos_trivial\ + because \<^term>\0 div l = 0\ would supersede it.\ + subsubsection \Laws for div and mod with Unary Minus\ @@ -345,15 +331,6 @@ qed (use assms in auto) -subsubsection \More Algebraic Laws for div and mod\ - -lemma zmod_eq_0_iff: "(m mod d = 0) = (\q::int. m = d*q)" - by (simp add: dvd_eq_mod_eq_0 [symmetric] dvd_def) - -(* REVISIT: should this be generalized to all semiring_div types? *) -lemmas zmod_eq_0D [dest!] = zmod_eq_0_iff [THEN iffD1] - - subsubsection \Proving \<^term>\a div (b * c) = (a div b) div c\\ (*The condition c>0 seems necessary. Consider that 7 div ~6 = ~2 but @@ -697,7 +674,7 @@ proof (cases "l > 0") case False then show ?thesis - by (simp add: dvd_eq_mod_eq_0) (use neg_mod_conj [of l k] in \auto simp add: le_less not_less\) + by (simp add: dvd_eq_mod_eq_0) (use neg_mod_sign [of l k] in \auto simp add: le_less not_less\) qed auto text \Simplify expressions in which div and mod combine numerical constants\ @@ -1341,4 +1318,17 @@ lemma mod_eq_0D: "\q. m = d * q" if "m mod d = 0" for m d :: nat using that by (auto simp add: mod_eq_0_iff_dvd) +lemma pos_mod_conj: "0 < b \ 0 \ a mod b \ a mod b < b" for a b :: int + by simp + +lemma neg_mod_conj: "b < 0 \ a mod b \ 0 \ b < a mod b" for a b :: int + by simp + +lemma zmod_eq_0_iff: "m mod d = 0 \ (\q. m = d * q)" for m d :: int + by (auto simp add: mod_eq_0_iff_dvd) + +(* REVISIT: should this be generalized to all semiring_div types? *) +lemma zmod_eq_0D [dest!]: "\q. m = d * q" if "m mod d = 0" for m d :: int + using that by auto + end diff -r 2633e166136a -r 753ae9e9773d src/HOL/Euclidean_Division.thy --- a/src/HOL/Euclidean_Division.thy Sat Jan 19 20:31:00 2019 +0100 +++ b/src/HOL/Euclidean_Division.thy Sat Jan 19 20:40:17 2019 +0000 @@ -125,6 +125,18 @@ "a mod b = 0" if "is_unit b" using that by (simp add: mod_eq_0_iff_dvd unit_imp_dvd) +lemma mod_eq_self_iff_div_eq_0: + "a mod b = a \ a div b = 0" (is "?P \ ?Q") +proof + assume ?P + with div_mult_mod_eq [of a b] show ?Q + by auto +next + assume ?Q + with div_mult_mod_eq [of a b] show ?P + by simp +qed + lemma coprime_mod_left_iff [simp]: "coprime (a mod b) b \ coprime a b" if "b \ 0" by (rule; rule coprimeI) @@ -1646,11 +1658,28 @@ "k mod l < l" if "l > 0" for k l :: int proof - obtain m and s where "k = sgn s * int m" - by (blast intro: int_sgnE elim: that) + by (rule int_sgnE) moreover from that obtain n where "l = sgn 1 * int n" - by (cases l) auto + by (cases l) simp_all + moreover from this that have "n > 0" + by simp ultimately show ?thesis - using that by (simp only: modulo_int_unfold) + by (simp only: modulo_int_unfold) + (simp add: mod_greater_zero_iff_not_dvd) +qed + +lemma neg_mod_bound [simp]: + "l < k mod l" if "l < 0" for k l :: int +proof - + obtain m and s where "k = sgn s * int m" + by (rule int_sgnE) + moreover from that obtain q where "l = sgn (- 1) * int (Suc q)" + by (cases l) simp_all + moreover define n where "n = Suc q" + then have "Suc q = n" + by simp + ultimately show ?thesis + by (simp only: modulo_int_unfold) (simp add: mod_greater_zero_iff_not_dvd) qed @@ -1658,11 +1687,27 @@ "0 \ k mod l" if "l > 0" for k l :: int proof - obtain m and s where "k = sgn s * int m" - by (blast intro: int_sgnE elim: that) + by (rule int_sgnE) moreover from that obtain n where "l = sgn 1 * int n" by (cases l) auto + moreover from this that have "n > 0" + by simp ultimately show ?thesis - using that by (simp only: modulo_int_unfold) simp + by (simp only: modulo_int_unfold) simp +qed + +lemma neg_mod_sign [simp]: + "k mod l \ 0" if "l < 0" for k l :: int +proof - + obtain m and s where "k = sgn s * int m" + by (rule int_sgnE) + moreover from that obtain q where "l = sgn (- 1) * int (Suc q)" + by (cases l) simp_all + moreover define n where "n = Suc q" + then have "Suc q = n" + by simp + ultimately show ?thesis + by (simp only: modulo_int_unfold) simp qed