diff -r fc19de122712 -r 8a48e18f081e src/HOL/Divides.thy --- a/src/HOL/Divides.thy Fri Sep 30 21:03:58 2022 +0200 +++ b/src/HOL/Divides.thy Sat Oct 01 07:56:53 2022 +0000 @@ -1,25 +1,32 @@ (* Title: HOL/Divides.thy *) -section \Lemmas of doubtful value\ +section \Misc lemmas on division, to be sorted out finally\ theory Divides imports Parity begin class unique_euclidean_semiring_numeral = unique_euclidean_semiring_with_nat + linordered_semidom + - assumes div_less: "0 \ a \ a < b \ a div b = 0" - and mod_less: " 0 \ a \ a < b \ a mod b = a" - and div_positive: "0 < b \ b \ a \ a div b > 0" - and mod_less_eq_dividend: "0 \ a \ a mod b \ a" - and pos_mod_bound: "0 < b \ a mod b < b" - and pos_mod_sign: "0 < b \ 0 \ a mod b" - and mod_mult2_eq: "0 \ c \ a mod (b * c) = b * (a div b mod c) + a mod b" - and div_mult2_eq: "0 \ c \ a div (b * c) = a div b div c" - assumes discrete: "a < b \ a + 1 \ b" + assumes div_less [no_atp]: "0 \ a \ a < b \ a div b = 0" + and mod_less [no_atp]: " 0 \ a \ a < b \ a mod b = a" + and div_positive [no_atp]: "0 < b \ b \ a \ a div b > 0" + and mod_less_eq_dividend [no_atp]: "0 \ a \ a mod b \ a" + and pos_mod_bound [no_atp]: "0 < b \ a mod b < b" + and pos_mod_sign [no_atp]: "0 < b \ 0 \ a mod b" + and mod_mult2_eq [no_atp]: "0 \ c \ a mod (b * c) = b * (a div b mod c) + a mod b" + and div_mult2_eq [no_atp]: "0 \ c \ a div (b * c) = a div b div c" + assumes discrete [no_atp]: "a < b \ a + 1 \ b" + +hide_fact (open) div_less mod_less mod_less_eq_dividend mod_mult2_eq div_mult2_eq + +context unique_euclidean_semiring_numeral begin -lemma divmod_digit_1: +context +begin + +lemma divmod_digit_1 [no_atp]: assumes "0 \ a" "0 < b" and "b \ a mod (2 * b)" shows "2 * (a div (2 * b)) + 1 = a div b" (is "?P") and "a mod (2 * b) - b = a mod b" (is "?Q") @@ -43,7 +50,7 @@ by (simp_all add: div mod add_implies_diff [symmetric]) qed -lemma divmod_digit_0: +lemma divmod_digit_0 [no_atp]: assumes "0 < b" and "a mod (2 * b) < b" shows "2 * (a div (2 * b)) = a div b" (is "?P") and "a mod (2 * b) = a mod b" (is "?Q") @@ -68,7 +75,7 @@ by (simp_all add: div mod) qed -lemma mod_double_modulus: +lemma mod_double_modulus: \\This is actually useful and should be transferred to a suitable type class\ assumes "m > 0" "x \ 0" shows "x mod (2 * m) = x mod m \ x mod (2 * m) = x mod m + m" proof (cases "x mod (2 * m) < m") @@ -85,7 +92,7 @@ end -hide_fact (open) div_less mod_less mod_less_eq_dividend mod_mult2_eq div_mult2_eq +end instance nat :: unique_euclidean_semiring_numeral by standard @@ -95,29 +102,29 @@ by standard (auto intro: zmod_le_nonneg_dividend simp add: pos_imp_zdiv_pos_iff zmod_zmult2_eq zdiv_zmult2_eq) -lemma div_geq: "m div n = Suc ((m - n) div n)" if "0 < n" and " \ m < n" for m n :: nat - by (rule le_div_geq) (use that in \simp_all add: not_less\) - -lemma mod_geq: "m mod n = (m - n) mod n" if "\ m < n" for m n :: nat - by (rule le_mod_geq) (use that in \simp add: not_less\) - -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 -lemma div_positive_int: +lemma div_geq [no_atp]: "m div n = Suc ((m - n) div n)" if "0 < n" and " \ m < n" for m n :: nat + by (rule le_div_geq) (use that in \simp_all add: not_less\) + +lemma mod_geq [no_atp]: "m mod n = (m - n) mod n" if "\ m < n" for m n :: nat + by (rule le_mod_geq) (use that in \simp add: not_less\) + +lemma mod_eq_0D [no_atp]: "\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 [no_atp]: "0 < b \ 0 \ a mod b \ a mod b < b" for a b :: int + by simp + +lemma neg_mod_conj [no_atp]: "b < 0 \ a mod b \ 0 \ b < a mod b" for a b :: int + by simp + +lemma zmod_eq_0_iff [no_atp]: "m mod d = 0 \ (\q. m = d * q)" for m d :: int + by (auto simp add: mod_eq_0_iff_dvd) + +lemma div_positive_int [no_atp]: "k div l > 0" if "k \ l" and "l > 0" for k l :: int using that by (simp add: nonneg1_imp_zdiv_pos_iff)