wenzelm@14770: (* Title: HOL/OrderedGroup.thy wenzelm@29269: Author: Gertrud Bauer, Steven Obua, Lawrence C Paulson, Markus Wenzel, Jeremy Avigad obua@14738: *) obua@14738: obua@14738: header {* Ordered Groups *} obua@14738: nipkow@15131: theory OrderedGroup haftmann@22452: imports Lattices wenzelm@19798: uses "~~/src/Provers/Arith/abel_cancel.ML" nipkow@15131: begin obua@14738: obua@14738: text {* obua@14738: The theory of partially ordered groups is taken from the books: obua@14738: \begin{itemize} obua@14738: \item \emph{Lattice Theory} by Garret Birkhoff, American Mathematical Society 1979 obua@14738: \item \emph{Partially Ordered Algebraic Systems}, Pergamon Press 1963 obua@14738: \end{itemize} obua@14738: Most of the used notions can also be looked up in obua@14738: \begin{itemize} wenzelm@14770: \item \url{http://www.mathworld.com} by Eric Weisstein et. al. obua@14738: \item \emph{Algebra I} by van der Waerden, Springer. obua@14738: \end{itemize} obua@14738: *} obua@14738: nipkow@29667: ML{* nipkow@29667: structure AlgebraSimps = nipkow@29667: NamedThmsFun(val name = "algebra_simps" nipkow@29667: val description = "algebra simplification rules"); nipkow@29667: *} nipkow@29667: nipkow@29667: setup AlgebraSimps.setup nipkow@29667: nipkow@29667: text{* The rewrites accumulated in @{text algebra_simps} deal with the nipkow@29667: classical algebraic structures of groups, rings and family. They simplify nipkow@29667: terms by multiplying everything out (in case of a ring) and bringing sums and nipkow@29667: products into a canonical form (by ordered rewriting). As a result it decides nipkow@29667: group and ring equalities but also helps with inequalities. nipkow@29667: nipkow@29667: Of course it also works for fields, but it knows nothing about multiplicative nipkow@29667: inverses or division. This is catered for by @{text field_simps}. *} nipkow@29667: nipkow@23085: subsection {* Semigroups and Monoids *} obua@14738: haftmann@22390: class semigroup_add = plus + nipkow@29667: assumes add_assoc[algebra_simps]: "(a + b) + c = a + (b + c)" haftmann@22390: haftmann@22390: class ab_semigroup_add = semigroup_add + nipkow@29667: assumes add_commute[algebra_simps]: "a + b = b + a" haftmann@25062: begin obua@14738: nipkow@29667: lemma add_left_commute[algebra_simps]: "a + (b + c) = b + (a + c)" nipkow@29667: by (rule mk_left_commute [of "plus", OF add_assoc add_commute]) haftmann@25062: haftmann@25062: theorems add_ac = add_assoc add_commute add_left_commute haftmann@25062: haftmann@25062: end obua@14738: obua@14738: theorems add_ac = add_assoc add_commute add_left_commute obua@14738: haftmann@22390: class semigroup_mult = times + nipkow@29667: assumes mult_assoc[algebra_simps]: "(a * b) * c = a * (b * c)" obua@14738: haftmann@22390: class ab_semigroup_mult = semigroup_mult + nipkow@29667: assumes mult_commute[algebra_simps]: "a * b = b * a" haftmann@23181: begin obua@14738: nipkow@29667: lemma mult_left_commute[algebra_simps]: "a * (b * c) = b * (a * c)" nipkow@29667: by (rule mk_left_commute [of "times", OF mult_assoc mult_commute]) haftmann@25062: haftmann@25062: theorems mult_ac = mult_assoc mult_commute mult_left_commute haftmann@23181: haftmann@23181: end obua@14738: obua@14738: theorems mult_ac = mult_assoc mult_commute mult_left_commute obua@14738: haftmann@26015: class ab_semigroup_idem_mult = ab_semigroup_mult + nipkow@29667: assumes mult_idem[simp]: "x * x = x" haftmann@26015: begin haftmann@26015: nipkow@29667: lemma mult_left_idem[simp]: "x * (x * y) = x * y" haftmann@26015: unfolding mult_assoc [symmetric, of x] mult_idem .. haftmann@26015: haftmann@26015: end haftmann@26015: nipkow@23085: class monoid_add = zero + semigroup_add + haftmann@25062: assumes add_0_left [simp]: "0 + a = a" haftmann@25062: and add_0_right [simp]: "a + 0 = a" nipkow@23085: haftmann@26071: lemma zero_reorient: "0 = x \ x = 0" nipkow@29667: by (rule eq_commute) haftmann@26071: haftmann@22390: class comm_monoid_add = zero + ab_semigroup_add + haftmann@25062: assumes add_0: "0 + a = a" haftmann@25062: begin nipkow@23085: haftmann@25062: subclass monoid_add haftmann@28823: proof qed (insert add_0, simp_all add: add_commute) haftmann@25062: haftmann@25062: end obua@14738: haftmann@22390: class monoid_mult = one + semigroup_mult + haftmann@25062: assumes mult_1_left [simp]: "1 * a = a" haftmann@25062: assumes mult_1_right [simp]: "a * 1 = a" obua@14738: haftmann@26071: lemma one_reorient: "1 = x \ x = 1" nipkow@29667: by (rule eq_commute) haftmann@26071: haftmann@22390: class comm_monoid_mult = one + ab_semigroup_mult + haftmann@25062: assumes mult_1: "1 * a = a" haftmann@25062: begin obua@14738: haftmann@25062: subclass monoid_mult haftmann@28823: proof qed (insert mult_1, simp_all add: mult_commute) haftmann@25062: haftmann@25062: end obua@14738: haftmann@22390: class cancel_semigroup_add = semigroup_add + haftmann@25062: assumes add_left_imp_eq: "a + b = a + c \ b = c" haftmann@25062: assumes add_right_imp_eq: "b + a = c + a \ b = c" huffman@27474: begin huffman@27474: huffman@27474: lemma add_left_cancel [simp]: huffman@27474: "a + b = a + c \ b = c" nipkow@29667: by (blast dest: add_left_imp_eq) huffman@27474: huffman@27474: lemma add_right_cancel [simp]: huffman@27474: "b + a = c + a \ b = c" nipkow@29667: by (blast dest: add_right_imp_eq) huffman@27474: huffman@27474: end obua@14738: haftmann@22390: class cancel_ab_semigroup_add = ab_semigroup_add + haftmann@25062: assumes add_imp_eq: "a + b = a + c \ b = c" haftmann@25267: begin obua@14738: haftmann@25267: subclass cancel_semigroup_add haftmann@28823: proof haftmann@22390: fix a b c :: 'a haftmann@22390: assume "a + b = a + c" haftmann@22390: then show "b = c" by (rule add_imp_eq) haftmann@22390: next obua@14738: fix a b c :: 'a obua@14738: assume "b + a = c + a" haftmann@22390: then have "a + b = a + c" by (simp only: add_commute) haftmann@22390: then show "b = c" by (rule add_imp_eq) obua@14738: qed obua@14738: haftmann@25267: end haftmann@25267: nipkow@23085: subsection {* Groups *} nipkow@23085: haftmann@25762: class group_add = minus + uminus + monoid_add + haftmann@25062: assumes left_minus [simp]: "- a + a = 0" haftmann@25062: assumes diff_minus: "a - b = a + (- b)" haftmann@25062: begin nipkow@23085: haftmann@25062: lemma minus_add_cancel: "- a + (a + b) = b" nipkow@29667: by (simp add: add_assoc[symmetric]) obua@14738: haftmann@25062: lemma minus_zero [simp]: "- 0 = 0" obua@14738: proof - haftmann@25062: have "- 0 = - 0 + (0 + 0)" by (simp only: add_0_right) haftmann@25062: also have "\ = 0" by (rule minus_add_cancel) obua@14738: finally show ?thesis . obua@14738: qed obua@14738: haftmann@25062: lemma minus_minus [simp]: "- (- a) = a" nipkow@23085: proof - haftmann@25062: have "- (- a) = - (- a) + (- a + a)" by simp haftmann@25062: also have "\ = a" by (rule minus_add_cancel) nipkow@23085: finally show ?thesis . nipkow@23085: qed obua@14738: haftmann@25062: lemma right_minus [simp]: "a + - a = 0" obua@14738: proof - haftmann@25062: have "a + - a = - (- a) + - a" by simp haftmann@25062: also have "\ = 0" by (rule left_minus) obua@14738: finally show ?thesis . obua@14738: qed obua@14738: haftmann@25062: lemma right_minus_eq: "a - b = 0 \ a = b" obua@14738: proof nipkow@23085: assume "a - b = 0" nipkow@23085: have "a = (a - b) + b" by (simp add:diff_minus add_assoc) nipkow@23085: also have "\ = b" using `a - b = 0` by simp nipkow@23085: finally show "a = b" . obua@14738: next nipkow@23085: assume "a = b" thus "a - b = 0" by (simp add: diff_minus) obua@14738: qed obua@14738: haftmann@25062: lemma equals_zero_I: nipkow@29667: assumes "a + b = 0" shows "- a = b" nipkow@23085: proof - haftmann@25062: have "- a = - a + (a + b)" using assms by simp haftmann@25062: also have "\ = b" by (simp add: add_assoc[symmetric]) nipkow@23085: finally show ?thesis . nipkow@23085: qed obua@14738: haftmann@25062: lemma diff_self [simp]: "a - a = 0" nipkow@29667: by (simp add: diff_minus) obua@14738: haftmann@25062: lemma diff_0 [simp]: "0 - a = - a" nipkow@29667: by (simp add: diff_minus) obua@14738: haftmann@25062: lemma diff_0_right [simp]: "a - 0 = a" nipkow@29667: by (simp add: diff_minus) obua@14738: haftmann@25062: lemma diff_minus_eq_add [simp]: "a - - b = a + b" nipkow@29667: by (simp add: diff_minus) obua@14738: haftmann@25062: lemma neg_equal_iff_equal [simp]: haftmann@25062: "- a = - b \ a = b" obua@14738: proof obua@14738: assume "- a = - b" nipkow@29667: hence "- (- a) = - (- b)" by simp haftmann@25062: thus "a = b" by simp obua@14738: next haftmann@25062: assume "a = b" haftmann@25062: thus "- a = - b" by simp obua@14738: qed obua@14738: haftmann@25062: lemma neg_equal_0_iff_equal [simp]: haftmann@25062: "- a = 0 \ a = 0" nipkow@29667: by (subst neg_equal_iff_equal [symmetric], simp) obua@14738: haftmann@25062: lemma neg_0_equal_iff_equal [simp]: haftmann@25062: "0 = - a \ 0 = a" nipkow@29667: by (subst neg_equal_iff_equal [symmetric], simp) obua@14738: obua@14738: text{*The next two equations can make the simplifier loop!*} obua@14738: haftmann@25062: lemma equation_minus_iff: haftmann@25062: "a = - b \ b = - a" obua@14738: proof - haftmann@25062: have "- (- a) = - b \ - a = b" by (rule neg_equal_iff_equal) haftmann@25062: thus ?thesis by (simp add: eq_commute) haftmann@25062: qed haftmann@25062: haftmann@25062: lemma minus_equation_iff: haftmann@25062: "- a = b \ - b = a" haftmann@25062: proof - haftmann@25062: have "- a = - (- b) \ a = -b" by (rule neg_equal_iff_equal) obua@14738: thus ?thesis by (simp add: eq_commute) obua@14738: qed obua@14738: huffman@28130: lemma diff_add_cancel: "a - b + b = a" nipkow@29667: by (simp add: diff_minus add_assoc) huffman@28130: huffman@28130: lemma add_diff_cancel: "a + b - b = a" nipkow@29667: by (simp add: diff_minus add_assoc) nipkow@29667: nipkow@29667: declare diff_minus[symmetric, algebra_simps] huffman@28130: haftmann@25062: end haftmann@25062: haftmann@25762: class ab_group_add = minus + uminus + comm_monoid_add + haftmann@25062: assumes ab_left_minus: "- a + a = 0" haftmann@25062: assumes ab_diff_minus: "a - b = a + (- b)" haftmann@25267: begin haftmann@25062: haftmann@25267: subclass group_add haftmann@28823: proof qed (simp_all add: ab_left_minus ab_diff_minus) haftmann@25062: haftmann@25267: subclass cancel_ab_semigroup_add haftmann@28823: proof haftmann@25062: fix a b c :: 'a haftmann@25062: assume "a + b = a + c" haftmann@25062: then have "- a + a + b = - a + a + c" haftmann@25062: unfolding add_assoc by simp haftmann@25062: then show "b = c" by simp haftmann@25062: qed haftmann@25062: nipkow@29667: lemma uminus_add_conv_diff[algebra_simps]: haftmann@25062: "- a + b = b - a" nipkow@29667: by (simp add:diff_minus add_commute) haftmann@25062: haftmann@25062: lemma minus_add_distrib [simp]: haftmann@25062: "- (a + b) = - a + - b" nipkow@29667: by (rule equals_zero_I) (simp add: add_ac) haftmann@25062: haftmann@25062: lemma minus_diff_eq [simp]: haftmann@25062: "- (a - b) = b - a" nipkow@29667: by (simp add: diff_minus add_commute) haftmann@25077: nipkow@29667: lemma add_diff_eq[algebra_simps]: "a + (b - c) = (a + b) - c" nipkow@29667: by (simp add: diff_minus add_ac) haftmann@25077: nipkow@29667: lemma diff_add_eq[algebra_simps]: "(a - b) + c = (a + c) - b" nipkow@29667: by (simp add: diff_minus add_ac) haftmann@25077: nipkow@29667: lemma diff_eq_eq[algebra_simps]: "a - b = c \ a = c + b" nipkow@29667: by (auto simp add: diff_minus add_assoc) haftmann@25077: nipkow@29667: lemma eq_diff_eq[algebra_simps]: "a = c - b \ a + b = c" nipkow@29667: by (auto simp add: diff_minus add_assoc) haftmann@25077: nipkow@29667: lemma diff_diff_eq[algebra_simps]: "(a - b) - c = a - (b + c)" nipkow@29667: by (simp add: diff_minus add_ac) haftmann@25077: nipkow@29667: lemma diff_diff_eq2[algebra_simps]: "a - (b - c) = (a + c) - b" nipkow@29667: by (simp add: diff_minus add_ac) haftmann@25077: haftmann@25077: lemma eq_iff_diff_eq_0: "a = b \ a - b = 0" nipkow@29667: by (simp add: algebra_simps) haftmann@25077: haftmann@25062: end obua@14738: obua@14738: subsection {* (Partially) Ordered Groups *} obua@14738: haftmann@22390: class pordered_ab_semigroup_add = order + ab_semigroup_add + haftmann@25062: assumes add_left_mono: "a \ b \ c + a \ c + b" haftmann@25062: begin haftmann@24380: haftmann@25062: lemma add_right_mono: haftmann@25062: "a \ b \ a + c \ b + c" nipkow@29667: by (simp add: add_commute [of _ c] add_left_mono) obua@14738: obua@14738: text {* non-strict, in both arguments *} obua@14738: lemma add_mono: haftmann@25062: "a \ b \ c \ d \ a + c \ b + d" obua@14738: apply (erule add_right_mono [THEN order_trans]) obua@14738: apply (simp add: add_commute add_left_mono) obua@14738: done obua@14738: haftmann@25062: end haftmann@25062: haftmann@25062: class pordered_cancel_ab_semigroup_add = haftmann@25062: pordered_ab_semigroup_add + cancel_ab_semigroup_add haftmann@25062: begin haftmann@25062: obua@14738: lemma add_strict_left_mono: haftmann@25062: "a < b \ c + a < c + b" nipkow@29667: by (auto simp add: less_le add_left_mono) obua@14738: obua@14738: lemma add_strict_right_mono: haftmann@25062: "a < b \ a + c < b + c" nipkow@29667: by (simp add: add_commute [of _ c] add_strict_left_mono) obua@14738: obua@14738: text{*Strict monotonicity in both arguments*} haftmann@25062: lemma add_strict_mono: haftmann@25062: "a < b \ c < d \ a + c < b + d" haftmann@25062: apply (erule add_strict_right_mono [THEN less_trans]) obua@14738: apply (erule add_strict_left_mono) obua@14738: done obua@14738: obua@14738: lemma add_less_le_mono: haftmann@25062: "a < b \ c \ d \ a + c < b + d" haftmann@25062: apply (erule add_strict_right_mono [THEN less_le_trans]) haftmann@25062: apply (erule add_left_mono) obua@14738: done obua@14738: obua@14738: lemma add_le_less_mono: haftmann@25062: "a \ b \ c < d \ a + c < b + d" haftmann@25062: apply (erule add_right_mono [THEN le_less_trans]) obua@14738: apply (erule add_strict_left_mono) obua@14738: done obua@14738: haftmann@25062: end haftmann@25062: haftmann@25062: class pordered_ab_semigroup_add_imp_le = haftmann@25062: pordered_cancel_ab_semigroup_add + haftmann@25062: assumes add_le_imp_le_left: "c + a \ c + b \ a \ b" haftmann@25062: begin haftmann@25062: obua@14738: lemma add_less_imp_less_left: nipkow@29667: assumes less: "c + a < c + b" shows "a < b" obua@14738: proof - obua@14738: from less have le: "c + a <= c + b" by (simp add: order_le_less) obua@14738: have "a <= b" obua@14738: apply (insert le) obua@14738: apply (drule add_le_imp_le_left) obua@14738: by (insert le, drule add_le_imp_le_left, assumption) obua@14738: moreover have "a \ b" obua@14738: proof (rule ccontr) obua@14738: assume "~(a \ b)" obua@14738: then have "a = b" by simp obua@14738: then have "c + a = c + b" by simp obua@14738: with less show "False"by simp obua@14738: qed obua@14738: ultimately show "a < b" by (simp add: order_le_less) obua@14738: qed obua@14738: obua@14738: lemma add_less_imp_less_right: haftmann@25062: "a + c < b + c \ a < b" obua@14738: apply (rule add_less_imp_less_left [of c]) obua@14738: apply (simp add: add_commute) obua@14738: done obua@14738: obua@14738: lemma add_less_cancel_left [simp]: haftmann@25062: "c + a < c + b \ a < b" nipkow@29667: by (blast intro: add_less_imp_less_left add_strict_left_mono) obua@14738: obua@14738: lemma add_less_cancel_right [simp]: haftmann@25062: "a + c < b + c \ a < b" nipkow@29667: by (blast intro: add_less_imp_less_right add_strict_right_mono) obua@14738: obua@14738: lemma add_le_cancel_left [simp]: haftmann@25062: "c + a \ c + b \ a \ b" nipkow@29667: by (auto, drule add_le_imp_le_left, simp_all add: add_left_mono) obua@14738: obua@14738: lemma add_le_cancel_right [simp]: haftmann@25062: "a + c \ b + c \ a \ b" nipkow@29667: by (simp add: add_commute [of a c] add_commute [of b c]) obua@14738: obua@14738: lemma add_le_imp_le_right: haftmann@25062: "a + c \ b + c \ a \ b" nipkow@29667: by simp haftmann@25062: haftmann@25077: lemma max_add_distrib_left: haftmann@25077: "max x y + z = max (x + z) (y + z)" haftmann@25077: unfolding max_def by auto haftmann@25077: haftmann@25077: lemma min_add_distrib_left: haftmann@25077: "min x y + z = min (x + z) (y + z)" haftmann@25077: unfolding min_def by auto haftmann@25077: haftmann@25062: end haftmann@25062: haftmann@25303: subsection {* Support for reasoning about signs *} haftmann@25303: haftmann@25303: class pordered_comm_monoid_add = haftmann@25303: pordered_cancel_ab_semigroup_add + comm_monoid_add haftmann@25303: begin haftmann@25303: haftmann@25303: lemma add_pos_nonneg: nipkow@29667: assumes "0 < a" and "0 \ b" shows "0 < a + b" haftmann@25303: proof - haftmann@25303: have "0 + 0 < a + b" haftmann@25303: using assms by (rule add_less_le_mono) haftmann@25303: then show ?thesis by simp haftmann@25303: qed haftmann@25303: haftmann@25303: lemma add_pos_pos: nipkow@29667: assumes "0 < a" and "0 < b" shows "0 < a + b" nipkow@29667: by (rule add_pos_nonneg) (insert assms, auto) haftmann@25303: haftmann@25303: lemma add_nonneg_pos: nipkow@29667: assumes "0 \ a" and "0 < b" shows "0 < a + b" haftmann@25303: proof - haftmann@25303: have "0 + 0 < a + b" haftmann@25303: using assms by (rule add_le_less_mono) haftmann@25303: then show ?thesis by simp haftmann@25303: qed haftmann@25303: haftmann@25303: lemma add_nonneg_nonneg: nipkow@29667: assumes "0 \ a" and "0 \ b" shows "0 \ a + b" haftmann@25303: proof - haftmann@25303: have "0 + 0 \ a + b" haftmann@25303: using assms by (rule add_mono) haftmann@25303: then show ?thesis by simp haftmann@25303: qed haftmann@25303: haftmann@25303: lemma add_neg_nonpos: nipkow@29667: assumes "a < 0" and "b \ 0" shows "a + b < 0" haftmann@25303: proof - haftmann@25303: have "a + b < 0 + 0" haftmann@25303: using assms by (rule add_less_le_mono) haftmann@25303: then show ?thesis by simp haftmann@25303: qed haftmann@25303: haftmann@25303: lemma add_neg_neg: nipkow@29667: assumes "a < 0" and "b < 0" shows "a + b < 0" nipkow@29667: by (rule add_neg_nonpos) (insert assms, auto) haftmann@25303: haftmann@25303: lemma add_nonpos_neg: nipkow@29667: assumes "a \ 0" and "b < 0" shows "a + b < 0" haftmann@25303: proof - haftmann@25303: have "a + b < 0 + 0" haftmann@25303: using assms by (rule add_le_less_mono) haftmann@25303: then show ?thesis by simp haftmann@25303: qed haftmann@25303: haftmann@25303: lemma add_nonpos_nonpos: nipkow@29667: assumes "a \ 0" and "b \ 0" shows "a + b \ 0" haftmann@25303: proof - haftmann@25303: have "a + b \ 0 + 0" haftmann@25303: using assms by (rule add_mono) haftmann@25303: then show ?thesis by simp haftmann@25303: qed haftmann@25303: haftmann@25303: end haftmann@25303: haftmann@25062: class pordered_ab_group_add = haftmann@25062: ab_group_add + pordered_ab_semigroup_add haftmann@25062: begin haftmann@25062: huffman@27516: subclass pordered_cancel_ab_semigroup_add .. haftmann@25062: haftmann@25062: subclass pordered_ab_semigroup_add_imp_le haftmann@28823: proof haftmann@25062: fix a b c :: 'a haftmann@25062: assume "c + a \ c + b" haftmann@25062: hence "(-c) + (c + a) \ (-c) + (c + b)" by (rule add_left_mono) haftmann@25062: hence "((-c) + c) + a \ ((-c) + c) + b" by (simp only: add_assoc) haftmann@25062: thus "a \ b" by simp haftmann@25062: qed haftmann@25062: huffman@27516: subclass pordered_comm_monoid_add .. haftmann@25303: haftmann@25077: lemma max_diff_distrib_left: haftmann@25077: shows "max x y - z = max (x - z) (y - z)" nipkow@29667: by (simp add: diff_minus, rule max_add_distrib_left) haftmann@25077: haftmann@25077: lemma min_diff_distrib_left: haftmann@25077: shows "min x y - z = min (x - z) (y - z)" nipkow@29667: by (simp add: diff_minus, rule min_add_distrib_left) haftmann@25077: haftmann@25077: lemma le_imp_neg_le: nipkow@29667: assumes "a \ b" shows "-b \ -a" haftmann@25077: proof - nipkow@29667: have "-a+a \ -a+b" using `a \ b` by (rule add_left_mono) nipkow@29667: hence "0 \ -a+b" by simp nipkow@29667: hence "0 + (-b) \ (-a + b) + (-b)" by (rule add_right_mono) nipkow@29667: thus ?thesis by (simp add: add_assoc) haftmann@25077: qed haftmann@25077: haftmann@25077: lemma neg_le_iff_le [simp]: "- b \ - a \ a \ b" haftmann@25077: proof haftmann@25077: assume "- b \ - a" nipkow@29667: hence "- (- a) \ - (- b)" by (rule le_imp_neg_le) haftmann@25077: thus "a\b" by simp haftmann@25077: next haftmann@25077: assume "a\b" haftmann@25077: thus "-b \ -a" by (rule le_imp_neg_le) haftmann@25077: qed haftmann@25077: haftmann@25077: lemma neg_le_0_iff_le [simp]: "- a \ 0 \ 0 \ a" nipkow@29667: by (subst neg_le_iff_le [symmetric], simp) haftmann@25077: haftmann@25077: lemma neg_0_le_iff_le [simp]: "0 \ - a \ a \ 0" nipkow@29667: by (subst neg_le_iff_le [symmetric], simp) haftmann@25077: haftmann@25077: lemma neg_less_iff_less [simp]: "- b < - a \ a < b" nipkow@29667: by (force simp add: less_le) haftmann@25077: haftmann@25077: lemma neg_less_0_iff_less [simp]: "- a < 0 \ 0 < a" nipkow@29667: by (subst neg_less_iff_less [symmetric], simp) haftmann@25077: haftmann@25077: lemma neg_0_less_iff_less [simp]: "0 < - a \ a < 0" nipkow@29667: by (subst neg_less_iff_less [symmetric], simp) haftmann@25077: haftmann@25077: text{*The next several equations can make the simplifier loop!*} haftmann@25077: haftmann@25077: lemma less_minus_iff: "a < - b \ b < - a" haftmann@25077: proof - haftmann@25077: have "(- (-a) < - b) = (b < - a)" by (rule neg_less_iff_less) haftmann@25077: thus ?thesis by simp haftmann@25077: qed haftmann@25077: haftmann@25077: lemma minus_less_iff: "- a < b \ - b < a" haftmann@25077: proof - haftmann@25077: have "(- a < - (-b)) = (- b < a)" by (rule neg_less_iff_less) haftmann@25077: thus ?thesis by simp haftmann@25077: qed haftmann@25077: haftmann@25077: lemma le_minus_iff: "a \ - b \ b \ - a" haftmann@25077: proof - haftmann@25077: have mm: "!! a (b::'a). (-(-a)) < -b \ -(-b) < -a" by (simp only: minus_less_iff) haftmann@25077: have "(- (- a) <= -b) = (b <= - a)" haftmann@25077: apply (auto simp only: le_less) haftmann@25077: apply (drule mm) haftmann@25077: apply (simp_all) haftmann@25077: apply (drule mm[simplified], assumption) haftmann@25077: done haftmann@25077: then show ?thesis by simp haftmann@25077: qed haftmann@25077: haftmann@25077: lemma minus_le_iff: "- a \ b \ - b \ a" nipkow@29667: by (auto simp add: le_less minus_less_iff) haftmann@25077: haftmann@25077: lemma less_iff_diff_less_0: "a < b \ a - b < 0" haftmann@25077: proof - haftmann@25077: have "(a < b) = (a + (- b) < b + (-b))" haftmann@25077: by (simp only: add_less_cancel_right) haftmann@25077: also have "... = (a - b < 0)" by (simp add: diff_minus) haftmann@25077: finally show ?thesis . haftmann@25077: qed haftmann@25077: nipkow@29667: lemma diff_less_eq[algebra_simps]: "a - b < c \ a < c + b" haftmann@25077: apply (subst less_iff_diff_less_0 [of a]) haftmann@25077: apply (rule less_iff_diff_less_0 [of _ c, THEN ssubst]) haftmann@25077: apply (simp add: diff_minus add_ac) haftmann@25077: done haftmann@25077: nipkow@29667: lemma less_diff_eq[algebra_simps]: "a < c - b \ a + b < c" haftmann@25077: apply (subst less_iff_diff_less_0 [of "plus a b"]) haftmann@25077: apply (subst less_iff_diff_less_0 [of a]) haftmann@25077: apply (simp add: diff_minus add_ac) haftmann@25077: done haftmann@25077: nipkow@29667: lemma diff_le_eq[algebra_simps]: "a - b \ c \ a \ c + b" nipkow@29667: by (auto simp add: le_less diff_less_eq diff_add_cancel add_diff_cancel) haftmann@25077: nipkow@29667: lemma le_diff_eq[algebra_simps]: "a \ c - b \ a + b \ c" nipkow@29667: by (auto simp add: le_less less_diff_eq diff_add_cancel add_diff_cancel) haftmann@25077: haftmann@25077: lemma le_iff_diff_le_0: "a \ b \ a - b \ 0" nipkow@29667: by (simp add: algebra_simps) haftmann@25077: nipkow@29667: text{*Legacy - use @{text algebra_simps} *} nipkow@29667: lemmas group_simps = algebra_simps haftmann@25230: haftmann@25077: end haftmann@25077: nipkow@29667: text{*Legacy - use @{text algebra_simps} *} nipkow@29667: lemmas group_simps = algebra_simps haftmann@25230: haftmann@25062: class ordered_ab_semigroup_add = haftmann@25062: linorder + pordered_ab_semigroup_add haftmann@25062: haftmann@25062: class ordered_cancel_ab_semigroup_add = haftmann@25062: linorder + pordered_cancel_ab_semigroup_add haftmann@25267: begin haftmann@25062: huffman@27516: subclass ordered_ab_semigroup_add .. haftmann@25062: haftmann@25267: subclass pordered_ab_semigroup_add_imp_le haftmann@28823: proof haftmann@25062: fix a b c :: 'a haftmann@25062: assume le: "c + a <= c + b" haftmann@25062: show "a <= b" haftmann@25062: proof (rule ccontr) haftmann@25062: assume w: "~ a \ b" haftmann@25062: hence "b <= a" by (simp add: linorder_not_le) haftmann@25062: hence le2: "c + b <= c + a" by (rule add_left_mono) haftmann@25062: have "a = b" haftmann@25062: apply (insert le) haftmann@25062: apply (insert le2) haftmann@25062: apply (drule antisym, simp_all) haftmann@25062: done haftmann@25062: with w show False haftmann@25062: by (simp add: linorder_not_le [symmetric]) haftmann@25062: qed haftmann@25062: qed haftmann@25062: haftmann@25267: end haftmann@25267: haftmann@25230: class ordered_ab_group_add = haftmann@25230: linorder + pordered_ab_group_add haftmann@25267: begin haftmann@25230: huffman@27516: subclass ordered_cancel_ab_semigroup_add .. haftmann@25230: haftmann@25303: lemma neg_less_eq_nonneg: haftmann@25303: "- a \ a \ 0 \ a" haftmann@25303: proof haftmann@25303: assume A: "- a \ a" show "0 \ a" haftmann@25303: proof (rule classical) haftmann@25303: assume "\ 0 \ a" haftmann@25303: then have "a < 0" by auto haftmann@25303: with A have "- a < 0" by (rule le_less_trans) haftmann@25303: then show ?thesis by auto haftmann@25303: qed haftmann@25303: next haftmann@25303: assume A: "0 \ a" show "- a \ a" haftmann@25303: proof (rule order_trans) haftmann@25303: show "- a \ 0" using A by (simp add: minus_le_iff) haftmann@25303: next haftmann@25303: show "0 \ a" using A . haftmann@25303: qed haftmann@25303: qed haftmann@25303: haftmann@25303: lemma less_eq_neg_nonpos: haftmann@25303: "a \ - a \ a \ 0" haftmann@25303: proof haftmann@25303: assume A: "a \ - a" show "a \ 0" haftmann@25303: proof (rule classical) haftmann@25303: assume "\ a \ 0" haftmann@25303: then have "0 < a" by auto haftmann@25303: then have "0 < - a" using A by (rule less_le_trans) haftmann@25303: then show ?thesis by auto haftmann@25303: qed haftmann@25303: next haftmann@25303: assume A: "a \ 0" show "a \ - a" haftmann@25303: proof (rule order_trans) haftmann@25303: show "0 \ - a" using A by (simp add: minus_le_iff) haftmann@25303: next haftmann@25303: show "a \ 0" using A . haftmann@25303: qed haftmann@25303: qed haftmann@25303: haftmann@25303: lemma equal_neg_zero: haftmann@25303: "a = - a \ a = 0" haftmann@25303: proof haftmann@25303: assume "a = 0" then show "a = - a" by simp haftmann@25303: next haftmann@25303: assume A: "a = - a" show "a = 0" haftmann@25303: proof (cases "0 \ a") haftmann@25303: case True with A have "0 \ - a" by auto haftmann@25303: with le_minus_iff have "a \ 0" by simp haftmann@25303: with True show ?thesis by (auto intro: order_trans) haftmann@25303: next haftmann@25303: case False then have B: "a \ 0" by auto haftmann@25303: with A have "- a \ 0" by auto haftmann@25303: with B show ?thesis by (auto intro: order_trans) haftmann@25303: qed haftmann@25303: qed haftmann@25303: haftmann@25303: lemma neg_equal_zero: haftmann@25303: "- a = a \ a = 0" haftmann@25303: unfolding equal_neg_zero [symmetric] by auto haftmann@25303: haftmann@25267: end haftmann@25267: haftmann@25077: -- {* FIXME localize the following *} obua@14738: paulson@15234: lemma add_increasing: paulson@15234: fixes c :: "'a::{pordered_ab_semigroup_add_imp_le, comm_monoid_add}" paulson@15234: shows "[|0\a; b\c|] ==> b \ a + c" obua@14738: by (insert add_mono [of 0 a b c], simp) obua@14738: nipkow@15539: lemma add_increasing2: nipkow@15539: fixes c :: "'a::{pordered_ab_semigroup_add_imp_le, comm_monoid_add}" nipkow@15539: shows "[|0\c; b\a|] ==> b \ a + c" nipkow@15539: by (simp add:add_increasing add_commute[of a]) nipkow@15539: paulson@15234: lemma add_strict_increasing: paulson@15234: fixes c :: "'a::{pordered_ab_semigroup_add_imp_le, comm_monoid_add}" paulson@15234: shows "[|0c|] ==> b < a + c" paulson@15234: by (insert add_less_le_mono [of 0 a b c], simp) paulson@15234: paulson@15234: lemma add_strict_increasing2: paulson@15234: fixes c :: "'a::{pordered_ab_semigroup_add_imp_le, comm_monoid_add}" paulson@15234: shows "[|0\a; b b < a + c" paulson@15234: by (insert add_le_less_mono [of 0 a b c], simp) paulson@15234: obua@14738: haftmann@25303: class pordered_ab_group_add_abs = pordered_ab_group_add + abs + haftmann@25303: assumes abs_ge_zero [simp]: "\a\ \ 0" haftmann@25303: and abs_ge_self: "a \ \a\" haftmann@25303: and abs_leI: "a \ b \ - a \ b \ \a\ \ b" haftmann@25303: and abs_minus_cancel [simp]: "\-a\ = \a\" haftmann@25303: and abs_triangle_ineq: "\a + b\ \ \a\ + \b\" haftmann@25303: begin haftmann@25303: haftmann@25307: lemma abs_minus_le_zero: "- \a\ \ 0" haftmann@25307: unfolding neg_le_0_iff_le by simp haftmann@25307: haftmann@25307: lemma abs_of_nonneg [simp]: nipkow@29667: assumes nonneg: "0 \ a" shows "\a\ = a" haftmann@25307: proof (rule antisym) haftmann@25307: from nonneg le_imp_neg_le have "- a \ 0" by simp haftmann@25307: from this nonneg have "- a \ a" by (rule order_trans) haftmann@25307: then show "\a\ \ a" by (auto intro: abs_leI) haftmann@25307: qed (rule abs_ge_self) haftmann@25307: haftmann@25307: lemma abs_idempotent [simp]: "\\a\\ = \a\" nipkow@29667: by (rule antisym) nipkow@29667: (auto intro!: abs_ge_self abs_leI order_trans [of "uminus (abs a)" zero "abs a"]) haftmann@25307: haftmann@25307: lemma abs_eq_0 [simp]: "\a\ = 0 \ a = 0" haftmann@25307: proof - haftmann@25307: have "\a\ = 0 \ a = 0" haftmann@25307: proof (rule antisym) haftmann@25307: assume zero: "\a\ = 0" haftmann@25307: with abs_ge_self show "a \ 0" by auto haftmann@25307: from zero have "\-a\ = 0" by simp haftmann@25307: with abs_ge_self [of "uminus a"] have "- a \ 0" by auto haftmann@25307: with neg_le_0_iff_le show "0 \ a" by auto haftmann@25307: qed haftmann@25307: then show ?thesis by auto haftmann@25307: qed haftmann@25307: haftmann@25303: lemma abs_zero [simp]: "\0\ = 0" nipkow@29667: by simp avigad@16775: haftmann@25303: lemma abs_0_eq [simp, noatp]: "0 = \a\ \ a = 0" haftmann@25303: proof - haftmann@25303: have "0 = \a\ \ \a\ = 0" by (simp only: eq_ac) haftmann@25303: thus ?thesis by simp haftmann@25303: qed haftmann@25303: haftmann@25303: lemma abs_le_zero_iff [simp]: "\a\ \ 0 \ a = 0" haftmann@25303: proof haftmann@25303: assume "\a\ \ 0" haftmann@25303: then have "\a\ = 0" by (rule antisym) simp haftmann@25303: thus "a = 0" by simp haftmann@25303: next haftmann@25303: assume "a = 0" haftmann@25303: thus "\a\ \ 0" by simp haftmann@25303: qed haftmann@25303: haftmann@25303: lemma zero_less_abs_iff [simp]: "0 < \a\ \ a \ 0" nipkow@29667: by (simp add: less_le) haftmann@25303: haftmann@25303: lemma abs_not_less_zero [simp]: "\ \a\ < 0" haftmann@25303: proof - haftmann@25303: have a: "\x y. x \ y \ \ y < x" by auto haftmann@25303: show ?thesis by (simp add: a) haftmann@25303: qed avigad@16775: haftmann@25303: lemma abs_ge_minus_self: "- a \ \a\" haftmann@25303: proof - haftmann@25303: have "- a \ \-a\" by (rule abs_ge_self) haftmann@25303: then show ?thesis by simp haftmann@25303: qed haftmann@25303: haftmann@25303: lemma abs_minus_commute: haftmann@25303: "\a - b\ = \b - a\" haftmann@25303: proof - haftmann@25303: have "\a - b\ = \- (a - b)\" by (simp only: abs_minus_cancel) haftmann@25303: also have "... = \b - a\" by simp haftmann@25303: finally show ?thesis . haftmann@25303: qed haftmann@25303: haftmann@25303: lemma abs_of_pos: "0 < a \ \a\ = a" nipkow@29667: by (rule abs_of_nonneg, rule less_imp_le) avigad@16775: haftmann@25303: lemma abs_of_nonpos [simp]: nipkow@29667: assumes "a \ 0" shows "\a\ = - a" haftmann@25303: proof - haftmann@25303: let ?b = "- a" haftmann@25303: have "- ?b \ 0 \ \- ?b\ = - (- ?b)" haftmann@25303: unfolding abs_minus_cancel [of "?b"] haftmann@25303: unfolding neg_le_0_iff_le [of "?b"] haftmann@25303: unfolding minus_minus by (erule abs_of_nonneg) haftmann@25303: then show ?thesis using assms by auto haftmann@25303: qed haftmann@25303: haftmann@25303: lemma abs_of_neg: "a < 0 \ \a\ = - a" nipkow@29667: by (rule abs_of_nonpos, rule less_imp_le) haftmann@25303: haftmann@25303: lemma abs_le_D1: "\a\ \ b \ a \ b" nipkow@29667: by (insert abs_ge_self, blast intro: order_trans) haftmann@25303: haftmann@25303: lemma abs_le_D2: "\a\ \ b \ - a \ b" nipkow@29667: by (insert abs_le_D1 [of "uminus a"], simp) haftmann@25303: haftmann@25303: lemma abs_le_iff: "\a\ \ b \ a \ b \ - a \ b" nipkow@29667: by (blast intro: abs_leI dest: abs_le_D1 abs_le_D2) haftmann@25303: haftmann@25303: lemma abs_triangle_ineq2: "\a\ - \b\ \ \a - b\" nipkow@29667: apply (simp add: algebra_simps) nipkow@29667: apply (subgoal_tac "abs a = abs (plus b (minus a b))") haftmann@25303: apply (erule ssubst) haftmann@25303: apply (rule abs_triangle_ineq) nipkow@29667: apply (rule arg_cong[of _ _ abs]) nipkow@29667: apply (simp add: algebra_simps) avigad@16775: done avigad@16775: haftmann@25303: lemma abs_triangle_ineq3: "\\a\ - \b\\ \ \a - b\" haftmann@25303: apply (subst abs_le_iff) haftmann@25303: apply auto haftmann@25303: apply (rule abs_triangle_ineq2) haftmann@25303: apply (subst abs_minus_commute) haftmann@25303: apply (rule abs_triangle_ineq2) avigad@16775: done avigad@16775: haftmann@25303: lemma abs_triangle_ineq4: "\a - b\ \ \a\ + \b\" haftmann@25303: proof - nipkow@29667: have "abs(a - b) = abs(a + - b)" by (subst diff_minus, rule refl) nipkow@29667: also have "... <= abs a + abs (- b)" by (rule abs_triangle_ineq) nipkow@29667: finally show ?thesis by simp haftmann@25303: qed avigad@16775: haftmann@25303: lemma abs_diff_triangle_ineq: "\a + b - (c + d)\ \ \a - c\ + \b - d\" haftmann@25303: proof - haftmann@25303: have "\a + b - (c+d)\ = \(a-c) + (b-d)\" by (simp add: diff_minus add_ac) haftmann@25303: also have "... \ \a-c\ + \b-d\" by (rule abs_triangle_ineq) haftmann@25303: finally show ?thesis . haftmann@25303: qed avigad@16775: haftmann@25303: lemma abs_add_abs [simp]: haftmann@25303: "\\a\ + \b\\ = \a\ + \b\" (is "?L = ?R") haftmann@25303: proof (rule antisym) haftmann@25303: show "?L \ ?R" by(rule abs_ge_self) haftmann@25303: next haftmann@25303: have "?L \ \\a\\ + \\b\\" by(rule abs_triangle_ineq) haftmann@25303: also have "\ = ?R" by simp haftmann@25303: finally show "?L \ ?R" . haftmann@25303: qed haftmann@25303: haftmann@25303: end obua@14738: haftmann@22452: obua@14738: subsection {* Lattice Ordered (Abelian) Groups *} obua@14738: haftmann@25303: class lordered_ab_group_add_meet = pordered_ab_group_add + lower_semilattice haftmann@25090: begin obua@14738: haftmann@25090: lemma add_inf_distrib_left: haftmann@25090: "a + inf b c = inf (a + b) (a + c)" haftmann@25090: apply (rule antisym) haftmann@22422: apply (simp_all add: le_infI) haftmann@25090: apply (rule add_le_imp_le_left [of "uminus a"]) haftmann@25090: apply (simp only: add_assoc [symmetric], simp) nipkow@21312: apply rule nipkow@21312: apply (rule add_le_imp_le_left[of "a"], simp only: add_assoc[symmetric], simp)+ obua@14738: done obua@14738: haftmann@25090: lemma add_inf_distrib_right: haftmann@25090: "inf a b + c = inf (a + c) (b + c)" haftmann@25090: proof - haftmann@25090: have "c + inf a b = inf (c+a) (c+b)" by (simp add: add_inf_distrib_left) haftmann@25090: thus ?thesis by (simp add: add_commute) haftmann@25090: qed haftmann@25090: haftmann@25090: end haftmann@25090: haftmann@25303: class lordered_ab_group_add_join = pordered_ab_group_add + upper_semilattice haftmann@25090: begin haftmann@25090: haftmann@25090: lemma add_sup_distrib_left: haftmann@25090: "a + sup b c = sup (a + b) (a + c)" haftmann@25090: apply (rule antisym) haftmann@25090: apply (rule add_le_imp_le_left [of "uminus a"]) obua@14738: apply (simp only: add_assoc[symmetric], simp) nipkow@21312: apply rule nipkow@21312: apply (rule add_le_imp_le_left [of "a"], simp only: add_assoc[symmetric], simp)+ haftmann@22422: apply (rule le_supI) nipkow@21312: apply (simp_all) obua@14738: done obua@14738: haftmann@25090: lemma add_sup_distrib_right: haftmann@25090: "sup a b + c = sup (a+c) (b+c)" obua@14738: proof - haftmann@22452: have "c + sup a b = sup (c+a) (c+b)" by (simp add: add_sup_distrib_left) obua@14738: thus ?thesis by (simp add: add_commute) obua@14738: qed obua@14738: haftmann@25090: end haftmann@25090: haftmann@25303: class lordered_ab_group_add = pordered_ab_group_add + lattice haftmann@25090: begin haftmann@25090: huffman@27516: subclass lordered_ab_group_add_meet .. huffman@27516: subclass lordered_ab_group_add_join .. haftmann@25090: haftmann@22422: lemmas add_sup_inf_distribs = add_inf_distrib_right add_inf_distrib_left add_sup_distrib_right add_sup_distrib_left obua@14738: haftmann@25090: lemma inf_eq_neg_sup: "inf a b = - sup (-a) (-b)" haftmann@22452: proof (rule inf_unique) haftmann@22452: fix a b :: 'a haftmann@25090: show "- sup (-a) (-b) \ a" haftmann@25090: by (rule add_le_imp_le_right [of _ "sup (uminus a) (uminus b)"]) haftmann@25090: (simp, simp add: add_sup_distrib_left) haftmann@22452: next haftmann@22452: fix a b :: 'a haftmann@25090: show "- sup (-a) (-b) \ b" haftmann@25090: by (rule add_le_imp_le_right [of _ "sup (uminus a) (uminus b)"]) haftmann@25090: (simp, simp add: add_sup_distrib_left) haftmann@22452: next haftmann@22452: fix a b c :: 'a haftmann@22452: assume "a \ b" "a \ c" haftmann@22452: then show "a \ - sup (-b) (-c)" by (subst neg_le_iff_le [symmetric]) haftmann@22452: (simp add: le_supI) haftmann@22452: qed haftmann@22452: haftmann@25090: lemma sup_eq_neg_inf: "sup a b = - inf (-a) (-b)" haftmann@22452: proof (rule sup_unique) haftmann@22452: fix a b :: 'a haftmann@25090: show "a \ - inf (-a) (-b)" haftmann@25090: by (rule add_le_imp_le_right [of _ "inf (uminus a) (uminus b)"]) haftmann@25090: (simp, simp add: add_inf_distrib_left) haftmann@22452: next haftmann@22452: fix a b :: 'a haftmann@25090: show "b \ - inf (-a) (-b)" haftmann@25090: by (rule add_le_imp_le_right [of _ "inf (uminus a) (uminus b)"]) haftmann@25090: (simp, simp add: add_inf_distrib_left) haftmann@22452: next haftmann@22452: fix a b c :: 'a haftmann@22452: assume "a \ c" "b \ c" haftmann@22452: then show "- inf (-a) (-b) \ c" by (subst neg_le_iff_le [symmetric]) haftmann@22452: (simp add: le_infI) haftmann@22452: qed obua@14738: haftmann@25230: lemma neg_inf_eq_sup: "- inf a b = sup (-a) (-b)" nipkow@29667: by (simp add: inf_eq_neg_sup) haftmann@25230: haftmann@25230: lemma neg_sup_eq_inf: "- sup a b = inf (-a) (-b)" nipkow@29667: by (simp add: sup_eq_neg_inf) haftmann@25230: haftmann@25090: lemma add_eq_inf_sup: "a + b = sup a b + inf a b" obua@14738: proof - haftmann@22422: have "0 = - inf 0 (a-b) + inf (a-b) 0" by (simp add: inf_commute) haftmann@22422: hence "0 = sup 0 (b-a) + inf (a-b) 0" by (simp add: inf_eq_neg_sup) haftmann@22422: hence "0 = (-a + sup a b) + (inf a b + (-b))" nipkow@29667: by (simp add: add_sup_distrib_left add_inf_distrib_right) nipkow@29667: (simp add: algebra_simps) nipkow@29667: thus ?thesis by (simp add: algebra_simps) obua@14738: qed obua@14738: obua@14738: subsection {* Positive Part, Negative Part, Absolute Value *} obua@14738: haftmann@22422: definition haftmann@25090: nprt :: "'a \ 'a" where haftmann@22422: "nprt x = inf x 0" haftmann@22422: haftmann@22422: definition haftmann@25090: pprt :: "'a \ 'a" where haftmann@22422: "pprt x = sup x 0" obua@14738: haftmann@25230: lemma pprt_neg: "pprt (- x) = - nprt x" haftmann@25230: proof - haftmann@25230: have "sup (- x) 0 = sup (- x) (- 0)" unfolding minus_zero .. haftmann@25230: also have "\ = - inf x 0" unfolding neg_inf_eq_sup .. haftmann@25230: finally have "sup (- x) 0 = - inf x 0" . haftmann@25230: then show ?thesis unfolding pprt_def nprt_def . haftmann@25230: qed haftmann@25230: haftmann@25230: lemma nprt_neg: "nprt (- x) = - pprt x" haftmann@25230: proof - haftmann@25230: from pprt_neg have "pprt (- (- x)) = - nprt (- x)" . haftmann@25230: then have "pprt x = - nprt (- x)" by simp haftmann@25230: then show ?thesis by simp haftmann@25230: qed haftmann@25230: obua@14738: lemma prts: "a = pprt a + nprt a" nipkow@29667: by (simp add: pprt_def nprt_def add_eq_inf_sup[symmetric]) obua@14738: obua@14738: lemma zero_le_pprt[simp]: "0 \ pprt a" nipkow@29667: by (simp add: pprt_def) obua@14738: obua@14738: lemma nprt_le_zero[simp]: "nprt a \ 0" nipkow@29667: by (simp add: nprt_def) obua@14738: haftmann@25090: lemma le_eq_neg: "a \ - b \ a + b \ 0" (is "?l = ?r") obua@14738: proof - obua@14738: have a: "?l \ ?r" obua@14738: apply (auto) haftmann@25090: apply (rule add_le_imp_le_right[of _ "uminus b" _]) obua@14738: apply (simp add: add_assoc) obua@14738: done obua@14738: have b: "?r \ ?l" obua@14738: apply (auto) obua@14738: apply (rule add_le_imp_le_right[of _ "b" _]) obua@14738: apply (simp) obua@14738: done obua@14738: from a b show ?thesis by blast obua@14738: qed obua@14738: obua@15580: lemma pprt_0[simp]: "pprt 0 = 0" by (simp add: pprt_def) obua@15580: lemma nprt_0[simp]: "nprt 0 = 0" by (simp add: nprt_def) obua@15580: haftmann@25090: lemma pprt_eq_id [simp, noatp]: "0 \ x \ pprt x = x" nipkow@29667: by (simp add: pprt_def le_iff_sup sup_ACI) obua@15580: haftmann@25090: lemma nprt_eq_id [simp, noatp]: "x \ 0 \ nprt x = x" nipkow@29667: by (simp add: nprt_def le_iff_inf inf_ACI) obua@15580: haftmann@25090: lemma pprt_eq_0 [simp, noatp]: "x \ 0 \ pprt x = 0" nipkow@29667: by (simp add: pprt_def le_iff_sup sup_ACI) obua@15580: haftmann@25090: lemma nprt_eq_0 [simp, noatp]: "0 \ x \ nprt x = 0" nipkow@29667: by (simp add: nprt_def le_iff_inf inf_ACI) obua@15580: haftmann@25090: lemma sup_0_imp_0: "sup a (- a) = 0 \ a = 0" obua@14738: proof - obua@14738: { obua@14738: fix a::'a haftmann@22422: assume hyp: "sup a (-a) = 0" haftmann@22422: hence "sup a (-a) + a = a" by (simp) haftmann@22422: hence "sup (a+a) 0 = a" by (simp add: add_sup_distrib_right) haftmann@22422: hence "sup (a+a) 0 <= a" by (simp) haftmann@22422: hence "0 <= a" by (blast intro: order_trans inf_sup_ord) obua@14738: } obua@14738: note p = this haftmann@22422: assume hyp:"sup a (-a) = 0" haftmann@22422: hence hyp2:"sup (-a) (-(-a)) = 0" by (simp add: sup_commute) obua@14738: from p[OF hyp] p[OF hyp2] show "a = 0" by simp obua@14738: qed obua@14738: haftmann@25090: lemma inf_0_imp_0: "inf a (-a) = 0 \ a = 0" haftmann@22422: apply (simp add: inf_eq_neg_sup) haftmann@22422: apply (simp add: sup_commute) haftmann@22422: apply (erule sup_0_imp_0) paulson@15481: done obua@14738: haftmann@25090: lemma inf_0_eq_0 [simp, noatp]: "inf a (- a) = 0 \ a = 0" nipkow@29667: by (rule, erule inf_0_imp_0) simp obua@14738: haftmann@25090: lemma sup_0_eq_0 [simp, noatp]: "sup a (- a) = 0 \ a = 0" nipkow@29667: by (rule, erule sup_0_imp_0) simp obua@14738: haftmann@25090: lemma zero_le_double_add_iff_zero_le_single_add [simp]: haftmann@25090: "0 \ a + a \ 0 \ a" obua@14738: proof obua@14738: assume "0 <= a + a" haftmann@22422: hence a:"inf (a+a) 0 = 0" by (simp add: le_iff_inf inf_commute) haftmann@25090: have "(inf a 0)+(inf a 0) = inf (inf (a+a) 0) a" (is "?l=_") haftmann@25090: by (simp add: add_sup_inf_distribs inf_ACI) haftmann@22422: hence "?l = 0 + inf a 0" by (simp add: a, simp add: inf_commute) haftmann@22422: hence "inf a 0 = 0" by (simp only: add_right_cancel) haftmann@22422: then show "0 <= a" by (simp add: le_iff_inf inf_commute) obua@14738: next obua@14738: assume a: "0 <= a" obua@14738: show "0 <= a + a" by (simp add: add_mono[OF a a, simplified]) obua@14738: qed obua@14738: haftmann@25090: lemma double_zero: "a + a = 0 \ a = 0" haftmann@25090: proof haftmann@25090: assume assm: "a + a = 0" haftmann@25090: then have "a + a + - a = - a" by simp haftmann@25090: then have "a + (a + - a) = - a" by (simp only: add_assoc) haftmann@25090: then have a: "- a = a" by simp (*FIXME tune proof*) haftmann@25102: show "a = 0" apply (rule antisym) haftmann@25090: apply (unfold neg_le_iff_le [symmetric, of a]) haftmann@25090: unfolding a apply simp haftmann@25090: unfolding zero_le_double_add_iff_zero_le_single_add [symmetric, of a] haftmann@25090: unfolding assm unfolding le_less apply simp_all done haftmann@25090: next haftmann@25090: assume "a = 0" then show "a + a = 0" by simp haftmann@25090: qed haftmann@25090: haftmann@25090: lemma zero_less_double_add_iff_zero_less_single_add: haftmann@25090: "0 < a + a \ 0 < a" haftmann@25090: proof (cases "a = 0") haftmann@25090: case True then show ?thesis by auto haftmann@25090: next haftmann@25090: case False then show ?thesis (*FIXME tune proof*) haftmann@25090: unfolding less_le apply simp apply rule haftmann@25090: apply clarify haftmann@25090: apply rule haftmann@25090: apply assumption haftmann@25090: apply (rule notI) haftmann@25090: unfolding double_zero [symmetric, of a] apply simp haftmann@25090: done haftmann@25090: qed haftmann@25090: haftmann@25090: lemma double_add_le_zero_iff_single_add_le_zero [simp]: haftmann@25090: "a + a \ 0 \ a \ 0" obua@14738: proof - haftmann@25090: have "a + a \ 0 \ 0 \ - (a + a)" by (subst le_minus_iff, simp) haftmann@25090: moreover have "\ \ a \ 0" by (simp add: zero_le_double_add_iff_zero_le_single_add) obua@14738: ultimately show ?thesis by blast obua@14738: qed obua@14738: haftmann@25090: lemma double_add_less_zero_iff_single_less_zero [simp]: haftmann@25090: "a + a < 0 \ a < 0" haftmann@25090: proof - haftmann@25090: have "a + a < 0 \ 0 < - (a + a)" by (subst less_minus_iff, simp) haftmann@25090: moreover have "\ \ a < 0" by (simp add: zero_less_double_add_iff_zero_less_single_add) haftmann@25090: ultimately show ?thesis by blast obua@14738: qed obua@14738: haftmann@25230: declare neg_inf_eq_sup [simp] neg_sup_eq_inf [simp] haftmann@25230: haftmann@25230: lemma le_minus_self_iff: "a \ - a \ a \ 0" haftmann@25230: proof - haftmann@25230: from add_le_cancel_left [of "uminus a" "plus a a" zero] haftmann@25230: have "(a <= -a) = (a+a <= 0)" haftmann@25230: by (simp add: add_assoc[symmetric]) haftmann@25230: thus ?thesis by simp haftmann@25230: qed haftmann@25230: haftmann@25230: lemma minus_le_self_iff: "- a \ a \ 0 \ a" haftmann@25230: proof - haftmann@25230: from add_le_cancel_left [of "uminus a" zero "plus a a"] haftmann@25230: have "(-a <= a) = (0 <= a+a)" haftmann@25230: by (simp add: add_assoc[symmetric]) haftmann@25230: thus ?thesis by simp haftmann@25230: qed haftmann@25230: haftmann@25230: lemma zero_le_iff_zero_nprt: "0 \ a \ nprt a = 0" nipkow@29667: by (simp add: le_iff_inf nprt_def inf_commute) haftmann@25230: haftmann@25230: lemma le_zero_iff_zero_pprt: "a \ 0 \ pprt a = 0" nipkow@29667: by (simp add: le_iff_sup pprt_def sup_commute) haftmann@25230: haftmann@25230: lemma le_zero_iff_pprt_id: "0 \ a \ pprt a = a" nipkow@29667: by (simp add: le_iff_sup pprt_def sup_commute) haftmann@25230: haftmann@25230: lemma zero_le_iff_nprt_id: "a \ 0 \ nprt a = a" nipkow@29667: by (simp add: le_iff_inf nprt_def inf_commute) haftmann@25230: haftmann@25230: lemma pprt_mono [simp, noatp]: "a \ b \ pprt a \ pprt b" nipkow@29667: by (simp add: le_iff_sup pprt_def sup_ACI sup_assoc [symmetric, of a]) haftmann@25230: haftmann@25230: lemma nprt_mono [simp, noatp]: "a \ b \ nprt a \ nprt b" nipkow@29667: by (simp add: le_iff_inf nprt_def inf_ACI inf_assoc [symmetric, of a]) haftmann@25230: haftmann@25090: end haftmann@25090: haftmann@25090: lemmas add_sup_inf_distribs = add_inf_distrib_right add_inf_distrib_left add_sup_distrib_right add_sup_distrib_left haftmann@25090: haftmann@25230: haftmann@25303: class lordered_ab_group_add_abs = lordered_ab_group_add + abs + haftmann@25230: assumes abs_lattice: "\a\ = sup a (- a)" haftmann@25230: begin haftmann@25230: haftmann@25230: lemma abs_prts: "\a\ = pprt a - nprt a" haftmann@25230: proof - haftmann@25230: have "0 \ \a\" haftmann@25230: proof - haftmann@25230: have a: "a \ \a\" and b: "- a \ \a\" by (auto simp add: abs_lattice) haftmann@25230: show ?thesis by (rule add_mono [OF a b, simplified]) haftmann@25230: qed haftmann@25230: then have "0 \ sup a (- a)" unfolding abs_lattice . haftmann@25230: then have "sup (sup a (- a)) 0 = sup a (- a)" by (rule sup_absorb1) haftmann@25230: then show ?thesis haftmann@25230: by (simp add: add_sup_inf_distribs sup_ACI haftmann@25230: pprt_def nprt_def diff_minus abs_lattice) haftmann@25230: qed haftmann@25230: haftmann@25230: subclass pordered_ab_group_add_abs haftmann@25230: proof - haftmann@25230: have abs_ge_zero [simp]: "\a. 0 \ \a\" haftmann@25230: proof - haftmann@25230: fix a b haftmann@25230: have a: "a \ \a\" and b: "- a \ \a\" by (auto simp add: abs_lattice) haftmann@25230: show "0 \ \a\" by (rule add_mono [OF a b, simplified]) haftmann@25230: qed haftmann@25230: have abs_leI: "\a b. a \ b \ - a \ b \ \a\ \ b" haftmann@25230: by (simp add: abs_lattice le_supI) haftmann@25230: show ?thesis haftmann@28823: proof haftmann@25230: fix a haftmann@25230: show "0 \ \a\" by simp haftmann@25230: next haftmann@25230: fix a nipkow@29667: show "a \ \a\" by (auto simp add: abs_lattice) haftmann@25230: next haftmann@25230: fix a nipkow@29667: show "\-a\ = \a\" by (simp add: abs_lattice sup_commute) haftmann@25230: next haftmann@25230: fix a b haftmann@25230: show "a \ b \ - a \ b \ \a\ \ b" by (erule abs_leI) haftmann@25230: next haftmann@25230: fix a b haftmann@25230: show "\a + b\ \ \a\ + \b\" haftmann@25230: proof - haftmann@25230: have g:"abs a + abs b = sup (a+b) (sup (-a-b) (sup (-a+b) (a + (-b))))" (is "_=sup ?m ?n") haftmann@25230: by (simp add: abs_lattice add_sup_inf_distribs sup_ACI diff_minus) haftmann@25230: have a:"a+b <= sup ?m ?n" by (simp) haftmann@25230: have b:"-a-b <= ?n" by (simp) haftmann@25230: have c:"?n <= sup ?m ?n" by (simp) haftmann@25230: from b c have d: "-a-b <= sup ?m ?n" by(rule order_trans) haftmann@25230: have e:"-a-b = -(a+b)" by (simp add: diff_minus) nipkow@29667: from a d e have "abs(a+b) <= sup ?m ?n" by (drule_tac abs_leI, auto) haftmann@25230: with g[symmetric] show ?thesis by simp haftmann@25230: qed haftmann@25230: qed auto haftmann@25230: qed haftmann@25230: haftmann@25230: end haftmann@25230: haftmann@25090: lemma sup_eq_if: haftmann@25303: fixes a :: "'a\{lordered_ab_group_add, linorder}" haftmann@25090: shows "sup a (- a) = (if a < 0 then - a else a)" haftmann@25090: proof - haftmann@25090: note add_le_cancel_right [of a a "- a", symmetric, simplified] haftmann@25090: moreover note add_le_cancel_right [of "-a" a a, symmetric, simplified] haftmann@25090: then show ?thesis by (auto simp: sup_max max_def) haftmann@25090: qed haftmann@25090: haftmann@25090: lemma abs_if_lattice: haftmann@25303: fixes a :: "'a\{lordered_ab_group_add_abs, linorder}" haftmann@25090: shows "\a\ = (if a < 0 then - a else a)" nipkow@29667: by auto haftmann@25090: haftmann@25090: obua@14754: text {* Needed for abelian cancellation simprocs: *} obua@14754: obua@14754: lemma add_cancel_21: "((x::'a::ab_group_add) + (y + z) = y + u) = (x + z = u)" obua@14754: apply (subst add_left_commute) obua@14754: apply (subst add_left_cancel) obua@14754: apply simp obua@14754: done obua@14754: obua@14754: lemma add_cancel_end: "(x + (y + z) = y) = (x = - (z::'a::ab_group_add))" obua@14754: apply (subst add_cancel_21[of _ _ _ 0, simplified]) obua@14754: apply (simp add: add_right_cancel[symmetric, of "x" "-z" "z", simplified]) obua@14754: done obua@14754: obua@14754: lemma less_eqI: "(x::'a::pordered_ab_group_add) - y = x' - y' \ (x < y) = (x' < y')" obua@14754: by (simp add: less_iff_diff_less_0[of x y] less_iff_diff_less_0[of x' y']) obua@14754: obua@14754: lemma le_eqI: "(x::'a::pordered_ab_group_add) - y = x' - y' \ (y <= x) = (y' <= x')" obua@14754: apply (simp add: le_iff_diff_le_0[of y x] le_iff_diff_le_0[of y' x']) obua@14754: apply (simp add: neg_le_iff_le[symmetric, of "y-x" 0] neg_le_iff_le[symmetric, of "y'-x'" 0]) obua@14754: done obua@14754: obua@14754: lemma eq_eqI: "(x::'a::ab_group_add) - y = x' - y' \ (x = y) = (x' = y')" obua@14754: by (simp add: eq_iff_diff_eq_0[of x y] eq_iff_diff_eq_0[of x' y']) obua@14754: obua@14754: lemma diff_def: "(x::'a::ab_group_add) - y == x + (-y)" obua@14754: by (simp add: diff_minus) obua@14754: obua@14754: lemma add_minus_cancel: "(a::'a::ab_group_add) + (-a + b) = b" obua@14754: by (simp add: add_assoc[symmetric]) obua@14754: haftmann@25090: lemma le_add_right_mono: obua@15178: assumes obua@15178: "a <= b + (c::'a::pordered_ab_group_add)" obua@15178: "c <= d" obua@15178: shows "a <= b + d" obua@15178: apply (rule_tac order_trans[where y = "b+c"]) obua@15178: apply (simp_all add: prems) obua@15178: done obua@15178: obua@15178: lemma estimate_by_abs: haftmann@25303: "a + b <= (c::'a::lordered_ab_group_add_abs) \ a <= c + abs b" obua@15178: proof - nipkow@23477: assume "a+b <= c" nipkow@29667: hence 2: "a <= c+(-b)" by (simp add: algebra_simps) obua@15178: have 3: "(-b) <= abs b" by (rule abs_ge_minus_self) obua@15178: show ?thesis by (rule le_add_right_mono[OF 2 3]) obua@15178: qed obua@15178: haftmann@25090: subsection {* Tools setup *} haftmann@25090: haftmann@25077: lemma add_mono_thms_ordered_semiring [noatp]: haftmann@25077: fixes i j k :: "'a\pordered_ab_semigroup_add" haftmann@25077: shows "i \ j \ k \ l \ i + k \ j + l" haftmann@25077: and "i = j \ k \ l \ i + k \ j + l" haftmann@25077: and "i \ j \ k = l \ i + k \ j + l" haftmann@25077: and "i = j \ k = l \ i + k = j + l" haftmann@25077: by (rule add_mono, clarify+)+ haftmann@25077: haftmann@25077: lemma add_mono_thms_ordered_field [noatp]: haftmann@25077: fixes i j k :: "'a\pordered_cancel_ab_semigroup_add" haftmann@25077: shows "i < j \ k = l \ i + k < j + l" haftmann@25077: and "i = j \ k < l \ i + k < j + l" haftmann@25077: and "i < j \ k \ l \ i + k < j + l" haftmann@25077: and "i \ j \ k < l \ i + k < j + l" haftmann@25077: and "i < j \ k < l \ i + k < j + l" haftmann@25077: by (auto intro: add_strict_right_mono add_strict_left_mono haftmann@25077: add_less_le_mono add_le_less_mono add_strict_mono) haftmann@25077: paulson@17085: text{*Simplification of @{term "x-y < 0"}, etc.*} haftmann@24380: lemmas diff_less_0_iff_less [simp] = less_iff_diff_less_0 [symmetric] haftmann@24380: lemmas diff_eq_0_iff_eq [simp, noatp] = eq_iff_diff_eq_0 [symmetric] haftmann@24380: lemmas diff_le_0_iff_le [simp] = le_iff_diff_le_0 [symmetric] paulson@17085: haftmann@22482: ML {* wenzelm@27250: structure ab_group_add_cancel = Abel_Cancel wenzelm@27250: ( haftmann@22482: haftmann@22482: (* term order for abelian groups *) haftmann@22482: haftmann@22482: fun agrp_ord (Const (a, _)) = find_index (fn a' => a = a') haftmann@22997: [@{const_name HOL.zero}, @{const_name HOL.plus}, haftmann@22997: @{const_name HOL.uminus}, @{const_name HOL.minus}] haftmann@22482: | agrp_ord _ = ~1; haftmann@22482: wenzelm@29269: fun termless_agrp (a, b) = (TermOrd.term_lpo agrp_ord (a, b) = LESS); haftmann@22482: haftmann@22482: local haftmann@22482: val ac1 = mk_meta_eq @{thm add_assoc}; haftmann@22482: val ac2 = mk_meta_eq @{thm add_commute}; haftmann@22482: val ac3 = mk_meta_eq @{thm add_left_commute}; haftmann@22997: fun solve_add_ac thy _ (_ $ (Const (@{const_name HOL.plus},_) $ _ $ _) $ _) = haftmann@22482: SOME ac1 haftmann@22997: | solve_add_ac thy _ (_ $ x $ (Const (@{const_name HOL.plus},_) $ y $ z)) = haftmann@22482: if termless_agrp (y, x) then SOME ac3 else NONE haftmann@22482: | solve_add_ac thy _ (_ $ x $ y) = haftmann@22482: if termless_agrp (y, x) then SOME ac2 else NONE haftmann@22482: | solve_add_ac thy _ _ = NONE haftmann@22482: in wenzelm@28262: val add_ac_proc = Simplifier.simproc (the_context ()) haftmann@22482: "add_ac_proc" ["x + y::'a::ab_semigroup_add"] solve_add_ac; haftmann@22482: end; haftmann@22482: wenzelm@27250: val eq_reflection = @{thm eq_reflection}; wenzelm@27250: wenzelm@27250: val T = @{typ "'a::ab_group_add"}; wenzelm@27250: haftmann@22482: val cancel_ss = HOL_basic_ss settermless termless_agrp haftmann@22482: addsimprocs [add_ac_proc] addsimps nipkow@23085: [@{thm add_0_left}, @{thm add_0_right}, @{thm diff_def}, haftmann@22482: @{thm minus_add_distrib}, @{thm minus_minus}, @{thm minus_zero}, haftmann@22482: @{thm right_minus}, @{thm left_minus}, @{thm add_minus_cancel}, haftmann@22482: @{thm minus_add_cancel}]; wenzelm@27250: wenzelm@27250: val sum_pats = [@{cterm "x + y::'a::ab_group_add"}, @{cterm "x - y::'a::ab_group_add"}]; haftmann@22482: haftmann@22548: val eqI_rules = [@{thm less_eqI}, @{thm le_eqI}, @{thm eq_eqI}]; haftmann@22482: haftmann@22482: val dest_eqI = haftmann@22482: fst o HOLogic.dest_bin "op =" HOLogic.boolT o HOLogic.dest_Trueprop o concl_of; haftmann@22482: wenzelm@27250: ); haftmann@22482: *} haftmann@22482: wenzelm@26480: ML {* haftmann@22482: Addsimprocs [ab_group_add_cancel.sum_conv, ab_group_add_cancel.rel_conv]; haftmann@22482: *} paulson@17085: obua@14738: end