# HG changeset patch # User haftmann # Date 1660888147 0 # Node ID dc758531077b3f9111c01d4f6514b6d0998bb5a2 # Parent 647879691c1c3866d2639c786c32abd619d81b0e streamlined theorems diff -r 647879691c1c -r dc758531077b src/HOL/Divides.thy --- a/src/HOL/Divides.thy Fri Aug 19 05:49:06 2022 +0000 +++ b/src/HOL/Divides.thy Fri Aug 19 05:49:07 2022 +0000 @@ -11,39 +11,92 @@ subsection \More on division\ -subsubsection \Laws for div and mod with Unary Minus\ +subsubsection \Splitting Rules for div and mod\ + +text\The proofs of the two lemmas below are essentially identical\ + +lemma split_pos_lemma: + "0 + P(n div k :: int)(n mod k) = (\i j. 0\j \ j n = k*i + j \ P i j)" + by auto + +lemma split_neg_lemma: + "k<0 \ + P(n div k :: int)(n mod k) = (\i j. k j\0 \ n = k*i + j \ P i j)" + by auto -lemma zmod_zminus1_not_zero: - fixes k l :: int - shows "- k mod l \ 0 \ k mod l \ 0" - by (simp add: mod_eq_0_iff_dvd) - -lemma zmod_zminus2_not_zero: - fixes k l :: int - shows "k mod - l \ 0 \ k mod l \ 0" - by (simp add: mod_eq_0_iff_dvd) +lemma split_zdiv: + \P (n div k) \ + (k = 0 \ P 0) \ + (0 < k \ (\i j. 0 \ j \ j < k \ n = k * i + j \ P i)) \ + (k < 0 \ (\i j. k < j \ j \ 0 \ n = k * i + j \ P i))\ for n k :: int +proof (cases \k = 0\) + case True + then show ?thesis + by simp +next + case False + then have \k < 0 \ 0 < k\ + by auto + then show ?thesis + by (auto simp add: split_pos_lemma [of concl: "\x y. P x"] split_neg_lemma [of concl: "\x y. P x"]) +qed -lemma zdiv_zminus1_eq_if: - \(- a) div b = (if a mod b = 0 then - (a div b) else - (a div b) - 1)\ - if \b \ 0\ for a b :: int - using that sgn_not_eq_imp [of b \- a\] - by (cases \a = 0\) (auto simp add: div_eq_div_abs [of \- a\ b] div_eq_div_abs [of a b] sgn_eq_0_iff) +lemma split_zmod: + \P (n mod k) \ + (k = 0 \ P n) \ + (0 < k \ (\i j. 0 \ j \ j < k \ n = k * i + j \ P j)) \ + (k < 0 \ (\i j. k < j \ j \ 0 \ n = k * i + j \ P j))\ for n k :: int +proof (cases \k = 0\) + case True + then show ?thesis + by simp +next + case False + then have \k < 0 \ 0 < k\ + by auto + then show ?thesis + by (auto simp add: split_pos_lemma [of concl: "\x y. P y"] split_neg_lemma [of concl: "\x y. P y"]) +qed -lemma zdiv_zminus2_eq_if: - \a div (- b) = (if a mod b = 0 then - (a div b) else - (a div b) - 1)\ - if \b \ 0\ for a b :: int - using that by (auto simp add: zdiv_zminus1_eq_if div_minus_right) +text \Enable (lin)arith to deal with \<^const>\divide\ and \<^const>\modulo\ + when these are applied to some constant that is of the form + \<^term>\numeral k\:\ +declare split_zdiv [of _ _ \numeral k\, arith_split] for k +declare split_zmod [of _ _ \numeral k\, arith_split] for k + +lemma half_nonnegative_int_iff [simp]: + \k div 2 \ 0 \ k \ 0\ for k :: int + by auto -lemma zmod_zminus1_eq_if: - \(- a) mod b = (if a mod b = 0 then 0 else b - (a mod b))\ - for a b :: int - by (cases \b = 0\) - (auto simp flip: minus_div_mult_eq_mod simp add: zdiv_zminus1_eq_if algebra_simps) +lemma half_negative_int_iff [simp]: + \k div 2 < 0 \ k < 0\ for k :: int + by auto -lemma zmod_zminus2_eq_if: - \a mod (- b) = (if a mod b = 0 then 0 else (a mod b) - b)\ - for a b :: int - by (auto simp add: zmod_zminus1_eq_if mod_minus_right) +lemma zdiv_eq_0_iff: + "i div k = 0 \ k = 0 \ 0 \ i \ i < k \ i \ 0 \ k < i" (is "?L = ?R") + for i k :: int +proof + assume ?L + moreover have "?L \ ?R" + by (rule split_zdiv [THEN iffD2]) simp + ultimately show ?R + by blast +next + assume ?R then show ?L + by auto +qed + +lemma zmod_trivial_iff: + fixes i k :: int + shows "i mod k = i \ k = 0 \ 0 \ i \ i < k \ i \ 0 \ k < i" +proof - + have "i mod k = i \ i div k = 0" + using div_mult_mod_eq [of i k] by safe auto + with zdiv_eq_0_iff + show ?thesis + by simp +qed subsubsection \Monotonicity in the First Argument (Dividend)\ @@ -238,84 +291,6 @@ qed -subsubsection \Splitting Rules for div and mod\ - -text\The proofs of the two lemmas below are essentially identical\ - -lemma split_pos_lemma: - "0 - P(n div k :: int)(n mod k) = (\i j. 0\j \ j n = k*i + j \ P i j)" - by auto - -lemma split_neg_lemma: - "k<0 \ - P(n div k :: int)(n mod k) = (\i j. k j\0 \ n = k*i + j \ P i j)" - by auto - -lemma split_zdiv: - "P(n div k :: int) = - ((k = 0 \ P 0) \ - (0 (\i j. 0\j \ j n = k*i + j \ P i)) \ - (k<0 \ (\i j. k j\0 \ n = k*i + j \ P i)))" -proof (cases "k = 0") - case False - then show ?thesis - unfolding linorder_neq_iff - by (auto simp add: split_pos_lemma [of concl: "\x y. P x"] split_neg_lemma [of concl: "\x y. P x"]) -qed auto - -lemma split_zmod: - "P(n mod k :: int) = - ((k = 0 \ P n) \ - (0 (\i j. 0\j \ j n = k*i + j \ P j)) \ - (k<0 \ (\i j. k j\0 \ n = k*i + j \ P j)))" -proof (cases "k = 0") - case False - then show ?thesis - unfolding linorder_neq_iff - by (auto simp add: split_pos_lemma [of concl: "\x y. P y"] split_neg_lemma [of concl: "\x y. P y"]) -qed auto - -text \Enable (lin)arith to deal with \<^const>\divide\ and \<^const>\modulo\ - when these are applied to some constant that is of the form - \<^term>\numeral k\:\ -declare split_zdiv [of _ _ "numeral k", arith_split] for k -declare split_zmod [of _ _ "numeral k", arith_split] for k - -lemma half_nonnegative_int_iff [simp]: - \k div 2 \ 0 \ k \ 0\ for k :: int - by auto - -lemma half_negative_int_iff [simp]: - \k div 2 < 0 \ k < 0\ for k :: int - by auto - -lemma zdiv_eq_0_iff: - "i div k = 0 \ k = 0 \ 0 \ i \ i < k \ i \ 0 \ k < i" (is "?L = ?R") - for i k :: int -proof - assume ?L - moreover have "?L \ ?R" - by (rule split_zdiv [THEN iffD2]) simp - ultimately show ?R - by blast -next - assume ?R then show ?L - by auto -qed - -lemma zmod_trivial_iff: - fixes i k :: int - shows "i mod k = i \ k = 0 \ 0 \ i \ i < k \ i \ 0 \ k < i" -proof - - have "i mod k = i \ i div k = 0" - using div_mult_mod_eq [of i k] by safe auto - with zdiv_eq_0_iff - show ?thesis - by simp -qed - - subsubsection \Computing \div\ and \mod\ with shifting\ lemma pos_eucl_rel_int_mult_2: @@ -381,7 +356,6 @@ unfolding mult_2 [symmetric] add.commute [of _ 1] by (rule pos_zmod_mult_2, simp) - subsubsection \Quotients of Signs\ diff -r 647879691c1c -r dc758531077b src/HOL/Euclidean_Division.thy --- a/src/HOL/Euclidean_Division.thy Fri Aug 19 05:49:06 2022 +0000 +++ b/src/HOL/Euclidean_Division.thy Fri Aug 19 05:49:07 2022 +0000 @@ -2091,6 +2091,41 @@ because \<^term>\0 div l = 0\ would supersede it.\ +subsubsection \Laws for unary minus\ + +lemma zmod_zminus1_not_zero: + fixes k l :: int + shows "- k mod l \ 0 \ k mod l \ 0" + by (simp add: mod_eq_0_iff_dvd) + +lemma zmod_zminus2_not_zero: + fixes k l :: int + shows "k mod - l \ 0 \ k mod l \ 0" + by (simp add: mod_eq_0_iff_dvd) + +lemma zdiv_zminus1_eq_if: + \(- a) div b = (if a mod b = 0 then - (a div b) else - (a div b) - 1)\ + if \b \ 0\ for a b :: int + using that sgn_not_eq_imp [of b \- a\] + by (cases \a = 0\) (auto simp add: div_eq_div_abs [of \- a\ b] div_eq_div_abs [of a b] sgn_eq_0_iff) + +lemma zdiv_zminus2_eq_if: + \a div (- b) = (if a mod b = 0 then - (a div b) else - (a div b) - 1)\ + if \b \ 0\ for a b :: int + using that by (auto simp add: zdiv_zminus1_eq_if div_minus_right) + +lemma zmod_zminus1_eq_if: + \(- a) mod b = (if a mod b = 0 then 0 else b - (a mod b))\ + for a b :: int + by (cases \b = 0\) + (auto simp flip: minus_div_mult_eq_mod simp add: zdiv_zminus1_eq_if algebra_simps) + +lemma zmod_zminus2_eq_if: + \a mod (- b) = (if a mod b = 0 then 0 else (a mod b) - b)\ + for a b :: int + by (auto simp add: zmod_zminus1_eq_if mod_minus_right) + + subsubsection \Borders\ lemma pos_mod_bound [simp]: