# HG changeset patch # User haftmann # Date 1660888151 0 # Node ID 714fad33252e41c373ac486309cff7c8621dfcc4 # Parent 24b17460ee60109b43986d610b98d6324a82ec95 more thorough split rules for div and mod on numerals, tuned split rules setup diff -r 24b17460ee60 -r 714fad33252e src/HOL/Divides.thy --- a/src/HOL/Divides.thy Fri Aug 19 05:49:10 2022 +0000 +++ b/src/HOL/Divides.thy Fri Aug 19 05:49:11 2022 +0000 @@ -62,8 +62,10 @@ 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\, linarith_split] for k -declare split_zmod [of _ _ \numeral k\, linarith_split] for k +declare split_zdiv [of _ _ \numeral n\, linarith_split] for n +declare split_zdiv [of _ _ \- numeral n\, linarith_split] for n +declare split_zmod [of _ _ \numeral n\, linarith_split] for n +declare split_zmod [of _ _ \- numeral n\, linarith_split] for n lemma half_nonnegative_int_iff [simp]: \k div 2 \ 0 \ k \ 0\ for k :: int diff -r 24b17460ee60 -r 714fad33252e src/HOL/Euclidean_Division.thy --- a/src/HOL/Euclidean_Division.thy Fri Aug 19 05:49:10 2022 +0000 +++ b/src/HOL/Euclidean_Division.thy Fri Aug 19 05:49:11 2022 +0000 @@ -1480,6 +1480,9 @@ qed qed +declare split_div [of _ _ \numeral n\, linarith_split] for n +declare split_mod [of _ _ \numeral n\, linarith_split] for n + lemma funpow_mod_eq: \<^marker>\contributor \Lars Noschinski\\ \(f ^^ (m mod n)) x = (f ^^ m) x\ if \(f ^^ n) x = x\ proof - diff -r 24b17460ee60 -r 714fad33252e src/HOL/Fields.thy --- a/src/HOL/Fields.thy Fri Aug 19 05:49:10 2022 +0000 +++ b/src/HOL/Fields.thy Fri Aug 19 05:49:11 2022 +0000 @@ -13,32 +13,6 @@ imports Nat begin -context idom -begin - -lemma inj_mult_left [simp]: \inj ((*) a) \ a \ 0\ (is \?P \ ?Q\) -proof - assume ?P - show ?Q - proof - assume \a = 0\ - with \?P\ have "inj ((*) 0)" - by simp - moreover have "0 * 0 = 0 * 1" - by simp - ultimately have "0 = 1" - by (rule injD) - then show False - by simp - qed -next - assume ?Q then show ?P - by (auto intro: injI) -qed - -end - - subsection \Division rings\ text \ @@ -60,7 +34,7 @@ ML_file \~~/src/Provers/Arith/fast_lin_arith.ML\ ML_file \Tools/lin_arith.ML\ setup \Lin_Arith.global_setup\ -declaration \K ( +declaration \K ( Lin_Arith.init_arith_data #> Lin_Arith.add_discrete_type \<^type_name>\nat\ #> Lin_Arith.add_lessD @{thm Suc_leI} @@ -85,7 +59,7 @@ \<^text>\fast_nat_arith_simproc\ anyway. However, it seems cheaper to activate the solver all the time rather than add the additional check.\ -lemmas [linarith_split] = nat_diff_split split_min split_max +lemmas [linarith_split] = nat_diff_split split_min split_max abs_split text\Lemmas \divide_simps\ move division to the outside and eliminates them on (in)equalities.\ diff -r 24b17460ee60 -r 714fad33252e src/HOL/Int.thy --- a/src/HOL/Int.thy Fri Aug 19 05:49:10 2022 +0000 +++ b/src/HOL/Int.thy Fri Aug 19 05:49:11 2022 +0000 @@ -737,16 +737,6 @@ lemma zadd_int_left: "int m + (int n + z) = int (m + n) + z" by simp -text \ - This version is proved for all ordered rings, not just integers! - It is proved here because attribute \linarith_split\ is not available - in theory \Rings\. - But is it really better than just rewriting with \abs_if\? -\ -lemma abs_split [linarith_split, no_atp]: "P \a\ \ (0 \ a \ P a) \ (a < 0 \ P (- a))" - for a :: "'a::linordered_idom" - by (force dest: order_less_le_trans simp add: abs_if linorder_not_less) - lemma negD: assumes "x < 0" shows "\n. x = - (int (Suc n))" proof - diff -r 24b17460ee60 -r 714fad33252e src/HOL/Numeral_Simprocs.thy --- a/src/HOL/Numeral_Simprocs.thy Fri Aug 19 05:49:10 2022 +0000 +++ b/src/HOL/Numeral_Simprocs.thy Fri Aug 19 05:49:11 2022 +0000 @@ -20,9 +20,6 @@ numeral_One [symmetric] uminus_numeral_One [symmetric] Suc_eq_plus1 eq_numeral_iff_iszero not_iszero_Numeral1 -declare split_div [of _ _ "numeral k", linarith_split] for k -declare split_mod [of _ _ "numeral k", linarith_split] for k - text \For \combine_numerals\\ lemma left_add_mult_distrib: "i*u + (j*u + k) = (i+j)*u + (k::nat)" diff -r 24b17460ee60 -r 714fad33252e src/HOL/Rings.thy --- a/src/HOL/Rings.thy Fri Aug 19 05:49:10 2022 +0000 +++ b/src/HOL/Rings.thy Fri Aug 19 05:49:11 2022 +0000 @@ -560,6 +560,26 @@ then show "a * a = b * b" by auto qed +lemma inj_mult_left [simp]: \inj ((*) a) \ a \ 0\ (is \?P \ ?Q\) +proof + assume ?P + show ?Q + proof + assume \a = 0\ + with \?P\ have "inj ((*) 0)" + by simp + moreover have "0 * 0 = 0 * 1" + by simp + ultimately have "0 = 1" + by (rule injD) + then show False + by simp + qed +next + assume ?Q then show ?P + by (auto intro: injI) +qed + end class idom_abs_sgn = idom + abs + sgn + @@ -2651,6 +2671,12 @@ shows "x+y < 0 \ x<0 \ y<0" by (auto simp: not_less intro: le_less_trans [of _ "x+y"]) +text \ + Is this really better than just rewriting with \abs_if\? +\ +lemma abs_split [no_atp]: \P \a\ \ (0 \ a \ P a) \ (a < 0 \ P (- a))\ + by (force dest: order_less_le_trans simp add: abs_if linorder_not_less) + end text \Reasoning about inequalities with division\