haftmann@35050: (* Title: HOL/Groups.thy wenzelm@29269: Author: Gertrud Bauer, Steven Obua, Lawrence C Paulson, Markus Wenzel, Jeremy Avigad obua@14738: *) obua@14738: haftmann@35050: header {* Groups, also combined with orderings *} obua@14738: haftmann@35050: theory Groups haftmann@35092: imports Orderings haftmann@35267: uses ("~~/src/Provers/Arith/abel_cancel.ML") nipkow@15131: begin obua@14738: haftmann@35301: subsection {* Fact collections *} haftmann@35301: haftmann@35301: ML {* haftmann@36343: structure Ac_Simps = Named_Thms( haftmann@36343: val name = "ac_simps" haftmann@36343: val description = "associativity and commutativity simplification rules" haftmann@36343: ) haftmann@36343: *} haftmann@36343: haftmann@36343: setup Ac_Simps.setup haftmann@36343: haftmann@36348: text{* The rewrites accumulated in @{text algebra_simps} deal with the haftmann@36348: classical algebraic structures of groups, rings and family. They simplify haftmann@36348: terms by multiplying everything out (in case of a ring) and bringing sums and haftmann@36348: products into a canonical form (by ordered rewriting). As a result it decides haftmann@36348: group and ring equalities but also helps with inequalities. haftmann@36348: haftmann@36348: Of course it also works for fields, but it knows nothing about multiplicative haftmann@36348: inverses or division. This is catered for by @{text field_simps}. *} haftmann@36348: haftmann@36343: ML {* haftmann@35301: structure Algebra_Simps = Named_Thms( haftmann@35301: val name = "algebra_simps" haftmann@35301: val description = "algebra simplification rules" haftmann@35301: ) haftmann@35301: *} haftmann@35301: haftmann@35301: setup Algebra_Simps.setup haftmann@35301: haftmann@36348: text{* Lemmas @{text field_simps} multiply with denominators in (in)equations haftmann@36348: if they can be proved to be non-zero (for equations) or positive/negative haftmann@36348: (for inequations). Can be too aggressive and is therefore separate from the haftmann@36348: more benign @{text algebra_simps}. *} haftmann@35301: haftmann@36348: ML {* haftmann@36348: structure Field_Simps = Named_Thms( haftmann@36348: val name = "field_simps" haftmann@36348: val description = "algebra simplification rules for fields" haftmann@36348: ) haftmann@36348: *} haftmann@36348: haftmann@36348: setup Field_Simps.setup haftmann@35301: haftmann@35301: haftmann@35301: subsection {* Abstract structures *} haftmann@35301: haftmann@35301: text {* haftmann@35301: These locales provide basic structures for interpretation into haftmann@35301: bigger structures; extensions require careful thinking, otherwise haftmann@35301: undesired effects may occur due to interpretation. haftmann@35301: *} haftmann@35301: haftmann@35301: locale semigroup = haftmann@35301: fixes f :: "'a \ 'a \ 'a" (infixl "*" 70) haftmann@35301: assumes assoc [ac_simps]: "a * b * c = a * (b * c)" haftmann@35301: haftmann@35301: locale abel_semigroup = semigroup + haftmann@35301: assumes commute [ac_simps]: "a * b = b * a" haftmann@35301: begin haftmann@35301: haftmann@35301: lemma left_commute [ac_simps]: haftmann@35301: "b * (a * c) = a * (b * c)" haftmann@35301: proof - haftmann@35301: have "(b * a) * c = (a * b) * c" haftmann@35301: by (simp only: commute) haftmann@35301: then show ?thesis haftmann@35301: by (simp only: assoc) haftmann@35301: qed haftmann@35301: haftmann@35301: end haftmann@35301: haftmann@35720: locale monoid = semigroup + haftmann@35723: fixes z :: 'a ("1") haftmann@35723: assumes left_neutral [simp]: "1 * a = a" haftmann@35723: assumes right_neutral [simp]: "a * 1 = a" haftmann@35720: haftmann@35720: locale comm_monoid = abel_semigroup + haftmann@35723: fixes z :: 'a ("1") haftmann@35723: assumes comm_neutral: "a * 1 = a" haftmann@35720: haftmann@35720: sublocale comm_monoid < monoid proof haftmann@35720: qed (simp_all add: commute comm_neutral) haftmann@35720: haftmann@35301: haftmann@35267: subsection {* Generic operations *} haftmann@35267: haftmann@35267: class zero = haftmann@35267: fixes zero :: 'a ("0") haftmann@35267: haftmann@35267: class one = haftmann@35267: fixes one :: 'a ("1") haftmann@35267: wenzelm@36176: hide_const (open) zero one haftmann@35267: haftmann@35267: syntax haftmann@35267: "_index1" :: index ("\<^sub>1") haftmann@35267: translations haftmann@35267: (index) "\<^sub>1" => (index) "\<^bsub>\\<^esub>" haftmann@35267: haftmann@35267: lemma Let_0 [simp]: "Let 0 f = f 0" haftmann@35267: unfolding Let_def .. haftmann@35267: haftmann@35267: lemma Let_1 [simp]: "Let 1 f = f 1" haftmann@35267: unfolding Let_def .. haftmann@35267: haftmann@35267: setup {* haftmann@35267: Reorient_Proc.add haftmann@35267: (fn Const(@{const_name Groups.zero}, _) => true haftmann@35267: | Const(@{const_name Groups.one}, _) => true haftmann@35267: | _ => false) haftmann@35267: *} haftmann@35267: haftmann@35267: simproc_setup reorient_zero ("0 = x") = Reorient_Proc.proc haftmann@35267: simproc_setup reorient_one ("1 = x") = Reorient_Proc.proc haftmann@35267: haftmann@35267: typed_print_translation {* haftmann@35267: let haftmann@35267: fun tr' c = (c, fn show_sorts => fn T => fn ts => haftmann@35267: if (not o null) ts orelse T = dummyT haftmann@35267: orelse not (! show_types) andalso can Term.dest_Type T haftmann@35267: then raise Match haftmann@35267: else Syntax.const Syntax.constrainC $ Syntax.const c $ Syntax.term_of_typ show_sorts T); haftmann@35267: in map tr' [@{const_syntax Groups.one}, @{const_syntax Groups.zero}] end; haftmann@35267: *} -- {* show types that are presumably too general *} haftmann@35267: haftmann@35267: class plus = haftmann@35267: fixes plus :: "'a \ 'a \ 'a" (infixl "+" 65) haftmann@35267: haftmann@35267: class minus = haftmann@35267: fixes minus :: "'a \ 'a \ 'a" (infixl "-" 65) haftmann@35267: haftmann@35267: class uminus = haftmann@35267: fixes uminus :: "'a \ 'a" ("- _" [81] 80) haftmann@35267: haftmann@35267: class times = haftmann@35267: fixes times :: "'a \ 'a \ 'a" (infixl "*" 70) haftmann@35267: haftmann@35267: use "~~/src/Provers/Arith/abel_cancel.ML" haftmann@35267: haftmann@35092: nipkow@23085: subsection {* Semigroups and Monoids *} obua@14738: haftmann@22390: class semigroup_add = plus + haftmann@36348: assumes add_assoc [algebra_simps, field_simps]: "(a + b) + c = a + (b + c)" haftmann@34973: haftmann@35723: sublocale semigroup_add < add!: semigroup plus proof haftmann@34973: qed (fact add_assoc) haftmann@22390: haftmann@22390: class ab_semigroup_add = semigroup_add + haftmann@36348: assumes add_commute [algebra_simps, field_simps]: "a + b = b + a" haftmann@34973: haftmann@35723: sublocale ab_semigroup_add < add!: abel_semigroup plus proof haftmann@34973: qed (fact add_commute) haftmann@34973: haftmann@34973: context ab_semigroup_add haftmann@25062: begin obua@14738: haftmann@36348: lemmas add_left_commute [algebra_simps, field_simps] = add.left_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 + haftmann@36348: assumes mult_assoc [algebra_simps, field_simps]: "(a * b) * c = a * (b * c)" haftmann@34973: haftmann@35723: sublocale semigroup_mult < mult!: semigroup times proof haftmann@34973: qed (fact mult_assoc) obua@14738: haftmann@22390: class ab_semigroup_mult = semigroup_mult + haftmann@36348: assumes mult_commute [algebra_simps, field_simps]: "a * b = b * a" haftmann@34973: haftmann@35723: sublocale ab_semigroup_mult < mult!: abel_semigroup times proof haftmann@34973: qed (fact mult_commute) haftmann@34973: haftmann@34973: context ab_semigroup_mult haftmann@23181: begin obua@14738: haftmann@36348: lemmas mult_left_commute [algebra_simps, field_simps] = mult.left_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: nipkow@23085: class monoid_add = zero + semigroup_add + haftmann@35720: assumes add_0_left: "0 + a = a" haftmann@35720: and add_0_right: "a + 0 = a" haftmann@35720: haftmann@35723: sublocale monoid_add < add!: monoid plus 0 proof haftmann@35720: qed (fact add_0_left add_0_right)+ 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" nipkow@23085: haftmann@35723: sublocale comm_monoid_add < add!: comm_monoid plus 0 proof haftmann@35720: qed (insert add_0, simp add: ac_simps) haftmann@25062: haftmann@35720: subclass (in comm_monoid_add) monoid_add proof haftmann@35723: qed (fact add.left_neutral add.right_neutral)+ obua@14738: haftmann@22390: class monoid_mult = one + semigroup_mult + haftmann@35720: assumes mult_1_left: "1 * a = a" haftmann@35720: and mult_1_right: "a * 1 = a" haftmann@35720: haftmann@35723: sublocale monoid_mult < mult!: monoid times 1 proof haftmann@35720: qed (fact mult_1_left mult_1_right)+ 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" obua@14738: haftmann@35723: sublocale comm_monoid_mult < mult!: comm_monoid times 1 proof haftmann@35720: qed (insert mult_1, simp add: ac_simps) haftmann@25062: haftmann@35720: subclass (in comm_monoid_mult) monoid_mult proof haftmann@35723: qed (fact mult.left_neutral mult.right_neutral)+ 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: huffman@29904: class cancel_comm_monoid_add = cancel_ab_semigroup_add + comm_monoid_add huffman@29904: huffman@29904: 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: huffman@34147: lemma minus_unique: huffman@34147: assumes "a + b = 0" shows "- a = b" huffman@34147: proof - huffman@34147: have "- a = - a + (a + b)" using assms by simp huffman@34147: also have "\ = b" by (simp add: add_assoc [symmetric]) huffman@34147: finally show ?thesis . huffman@34147: qed huffman@34147: huffman@34147: lemmas equals_zero_I = minus_unique (* legacy name *) obua@14738: haftmann@25062: lemma minus_zero [simp]: "- 0 = 0" obua@14738: proof - huffman@34147: have "0 + 0 = 0" by (rule add_0_right) huffman@34147: thus "- 0 = 0" by (rule minus_unique) obua@14738: qed obua@14738: haftmann@25062: lemma minus_minus [simp]: "- (- a) = a" nipkow@23085: proof - huffman@34147: have "- a + a = 0" by (rule left_minus) huffman@34147: thus "- (- a) = a" by (rule minus_unique) 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: huffman@34147: lemma minus_add_cancel: "- a + (a + b) = b" huffman@34147: by (simp add: add_assoc [symmetric]) huffman@34147: huffman@34147: lemma add_minus_cancel: "a + (- a + b) = b" huffman@34147: by (simp add: add_assoc [symmetric]) huffman@34147: huffman@34147: lemma minus_add: "- (a + b) = - b + - a" huffman@34147: proof - huffman@34147: have "(a + b) + (- b + - a) = 0" huffman@34147: by (simp add: add_assoc add_minus_cancel) huffman@34147: thus "- (a + b) = - b + - a" huffman@34147: by (rule minus_unique) huffman@34147: qed huffman@34147: 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 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: haftmann@36348: declare diff_minus[symmetric, algebra_simps, field_simps] huffman@28130: huffman@29914: lemma eq_neg_iff_add_eq_0: "a = - b \ a + b = 0" huffman@29914: proof huffman@29914: assume "a = - b" then show "a + b = 0" by simp huffman@29914: next huffman@29914: assume "a + b = 0" huffman@29914: moreover have "a + (b + - b) = (a + b) + - b" huffman@29914: by (simp only: add_assoc) huffman@29914: ultimately show "a = - b" by simp huffman@29914: qed huffman@29914: 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: huffman@29904: subclass cancel_comm_monoid_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: haftmann@36348: lemma uminus_add_conv_diff[algebra_simps, field_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" huffman@34146: by (rule minus_unique) (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: haftmann@36348: lemma add_diff_eq[algebra_simps, field_simps]: "a + (b - c) = (a + b) - c" nipkow@29667: by (simp add: diff_minus add_ac) haftmann@25077: haftmann@36348: lemma diff_add_eq[algebra_simps, field_simps]: "(a - b) + c = (a + c) - b" nipkow@29667: by (simp add: diff_minus add_ac) haftmann@25077: haftmann@36348: lemma diff_eq_eq[algebra_simps, field_simps]: "a - b = c \ a = c + b" nipkow@29667: by (auto simp add: diff_minus add_assoc) haftmann@25077: haftmann@36348: lemma eq_diff_eq[algebra_simps, field_simps]: "a = c - b \ a + b = c" nipkow@29667: by (auto simp add: diff_minus add_assoc) haftmann@25077: haftmann@36348: lemma diff_diff_eq[algebra_simps, field_simps]: "(a - b) - c = a - (b + c)" nipkow@29667: by (simp add: diff_minus add_ac) haftmann@25077: haftmann@36348: lemma diff_diff_eq2[algebra_simps, field_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: huffman@35216: (* FIXME: duplicates right_minus_eq from class group_add *) huffman@35216: (* but only this one is declared as a simp rule. *) blanchet@35828: lemma diff_eq_0_iff_eq [simp, no_atp]: "a - b = 0 \ a = b" huffman@30629: by (simp add: algebra_simps) huffman@30629: haftmann@25062: end obua@14738: obua@14738: subsection {* (Partially) Ordered Groups *} obua@14738: haftmann@35301: text {* haftmann@35301: The theory of partially ordered groups is taken from the books: haftmann@35301: \begin{itemize} haftmann@35301: \item \emph{Lattice Theory} by Garret Birkhoff, American Mathematical Society 1979 haftmann@35301: \item \emph{Partially Ordered Algebraic Systems}, Pergamon Press 1963 haftmann@35301: \end{itemize} haftmann@35301: Most of the used notions can also be looked up in haftmann@35301: \begin{itemize} haftmann@35301: \item \url{http://www.mathworld.com} by Eric Weisstein et. al. haftmann@35301: \item \emph{Algebra I} by van der Waerden, Springer. haftmann@35301: \end{itemize} haftmann@35301: *} haftmann@35301: haftmann@35028: class ordered_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@35028: class ordered_cancel_ab_semigroup_add = haftmann@35028: ordered_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@35028: class ordered_ab_semigroup_add_imp_le = haftmann@35028: ordered_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@35028: class ordered_comm_monoid_add = haftmann@35028: ordered_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: huffman@30691: 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: huffman@30691: lemmas add_sign_intros = huffman@30691: add_pos_nonneg add_pos_pos add_nonneg_pos add_nonneg_nonneg huffman@30691: add_neg_nonpos add_neg_neg add_nonpos_neg add_nonpos_nonpos huffman@30691: huffman@29886: lemma add_nonneg_eq_0_iff: huffman@29886: assumes x: "0 \ x" and y: "0 \ y" huffman@29886: shows "x + y = 0 \ x = 0 \ y = 0" huffman@29886: proof (intro iffI conjI) huffman@29886: have "x = x + 0" by simp huffman@29886: also have "x + 0 \ x + y" using y by (rule add_left_mono) huffman@29886: also assume "x + y = 0" huffman@29886: also have "0 \ x" using x . huffman@29886: finally show "x = 0" . huffman@29886: next huffman@29886: have "y = 0 + y" by simp huffman@29886: also have "0 + y \ x + y" using x by (rule add_right_mono) huffman@29886: also assume "x + y = 0" huffman@29886: also have "0 \ y" using y . huffman@29886: finally show "y = 0" . huffman@29886: next huffman@29886: assume "x = 0 \ y = 0" huffman@29886: then show "x + y = 0" by simp huffman@29886: qed huffman@29886: haftmann@25303: end haftmann@25303: haftmann@35028: class ordered_ab_group_add = haftmann@35028: ab_group_add + ordered_ab_semigroup_add haftmann@25062: begin haftmann@25062: haftmann@35028: subclass ordered_cancel_ab_semigroup_add .. haftmann@25062: haftmann@35028: subclass ordered_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: haftmann@35028: subclass ordered_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: haftmann@36348: lemma diff_less_eq[algebra_simps, field_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: haftmann@36348: lemma less_diff_eq[algebra_simps, field_simps]: "a < c - b \ a + b < c" haftmann@36302: apply (subst less_iff_diff_less_0 [of "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: haftmann@36348: lemma diff_le_eq[algebra_simps, field_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: haftmann@36348: lemma le_diff_eq[algebra_simps, field_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: haftmann@25077: end haftmann@25077: haftmann@35028: class linordered_ab_semigroup_add = haftmann@35028: linorder + ordered_ab_semigroup_add haftmann@25062: haftmann@35028: class linordered_cancel_ab_semigroup_add = haftmann@35028: linorder + ordered_cancel_ab_semigroup_add haftmann@25267: begin haftmann@25062: haftmann@35028: subclass linordered_ab_semigroup_add .. haftmann@25062: haftmann@35028: subclass ordered_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@35028: class linordered_ab_group_add = linorder + ordered_ab_group_add haftmann@25267: begin haftmann@25230: haftmann@35028: subclass linordered_cancel_ab_semigroup_add .. haftmann@25230: haftmann@35036: lemma neg_less_eq_nonneg [simp]: 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@35036: haftmann@35036: lemma neg_less_nonneg [simp]: haftmann@35036: "- a < a \ 0 < a" haftmann@35036: proof haftmann@35036: assume A: "- a < a" show "0 < a" haftmann@35036: proof (rule classical) haftmann@35036: assume "\ 0 < a" haftmann@35036: then have "a \ 0" by auto haftmann@35036: with A have "- a < 0" by (rule less_le_trans) haftmann@35036: then show ?thesis by auto haftmann@35036: qed haftmann@35036: next haftmann@35036: assume A: "0 < a" show "- a < a" haftmann@35036: proof (rule less_trans) haftmann@35036: show "- a < 0" using A by (simp add: minus_le_iff) haftmann@35036: next haftmann@35036: show "0 < a" using A . haftmann@35036: qed haftmann@35036: qed haftmann@35036: haftmann@35036: lemma less_eq_neg_nonpos [simp]: 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@35036: lemma equal_neg_zero [simp]: 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@35036: lemma neg_equal_zero [simp]: haftmann@25303: "- a = a \ a = 0" haftmann@35036: by (auto dest: sym) haftmann@35036: haftmann@35036: lemma double_zero [simp]: haftmann@35036: "a + a = 0 \ a = 0" haftmann@35036: proof haftmann@35036: assume assm: "a + a = 0" haftmann@35036: then have a: "- a = a" by (rule minus_unique) huffman@35216: then show "a = 0" by (simp only: neg_equal_zero) haftmann@35036: qed simp haftmann@35036: haftmann@35036: lemma double_zero_sym [simp]: haftmann@35036: "0 = a + a \ a = 0" haftmann@35036: by (rule, drule sym) simp_all haftmann@35036: haftmann@35036: lemma zero_less_double_add_iff_zero_less_single_add [simp]: haftmann@35036: "0 < a + a \ 0 < a" haftmann@35036: proof haftmann@35036: assume "0 < a + a" haftmann@35036: then have "0 - a < a" by (simp only: diff_less_eq) haftmann@35036: then have "- a < a" by simp huffman@35216: then show "0 < a" by (simp only: neg_less_nonneg) haftmann@35036: next haftmann@35036: assume "0 < a" haftmann@35036: with this have "0 + 0 < a + a" haftmann@35036: by (rule add_strict_mono) haftmann@35036: then show "0 < a + a" by simp haftmann@35036: qed haftmann@35036: haftmann@35036: lemma zero_le_double_add_iff_zero_le_single_add [simp]: haftmann@35036: "0 \ a + a \ 0 \ a" haftmann@35036: by (auto simp add: le_less) haftmann@35036: haftmann@35036: lemma double_add_less_zero_iff_single_add_less_zero [simp]: haftmann@35036: "a + a < 0 \ a < 0" haftmann@35036: proof - haftmann@35036: have "\ a + a < 0 \ \ a < 0" haftmann@35036: by (simp add: not_less) haftmann@35036: then show ?thesis by simp haftmann@35036: qed haftmann@35036: haftmann@35036: lemma double_add_le_zero_iff_single_add_le_zero [simp]: haftmann@35036: "a + a \ 0 \ a \ 0" haftmann@35036: proof - haftmann@35036: have "\ a + a \ 0 \ \ a \ 0" haftmann@35036: by (simp add: not_le) haftmann@35036: then show ?thesis by simp haftmann@35036: qed haftmann@35036: haftmann@35036: lemma le_minus_self_iff: haftmann@35036: "a \ - a \ a \ 0" haftmann@35036: proof - haftmann@35036: from add_le_cancel_left [of "- a" "a + a" 0] haftmann@35036: have "a \ - a \ a + a \ 0" haftmann@35036: by (simp add: add_assoc [symmetric]) haftmann@35036: thus ?thesis by simp haftmann@35036: qed haftmann@35036: haftmann@35036: lemma minus_le_self_iff: haftmann@35036: "- a \ a \ 0 \ a" haftmann@35036: proof - haftmann@35036: from add_le_cancel_left [of "- a" 0 "a + a"] haftmann@35036: have "- a \ a \ 0 \ a + a" haftmann@35036: by (simp add: add_assoc [symmetric]) haftmann@35036: thus ?thesis by simp haftmann@35036: qed haftmann@35036: haftmann@35036: lemma minus_max_eq_min: haftmann@35036: "- max x y = min (-x) (-y)" haftmann@35036: by (auto simp add: max_def min_def) haftmann@35036: haftmann@35036: lemma minus_min_eq_max: haftmann@35036: "- min x y = max (-x) (-y)" haftmann@35036: by (auto simp add: max_def min_def) haftmann@25303: haftmann@25267: end haftmann@25267: haftmann@36302: context ordered_comm_monoid_add haftmann@36302: begin obua@14738: paulson@15234: lemma add_increasing: haftmann@36302: "0 \ a \ b \ c \ b \ a + c" haftmann@36302: by (insert add_mono [of 0 a b c], simp) obua@14738: nipkow@15539: lemma add_increasing2: haftmann@36302: "0 \ c \ b \ a \ b \ a + c" haftmann@36302: by (simp add: add_increasing add_commute [of a]) nipkow@15539: paulson@15234: lemma add_strict_increasing: haftmann@36302: "0 < a \ b \ c \ b < a + c" haftmann@36302: by (insert add_less_le_mono [of 0 a b c], simp) paulson@15234: paulson@15234: lemma add_strict_increasing2: haftmann@36302: "0 \ a \ b < c \ b < a + c" haftmann@36302: by (insert add_le_less_mono [of 0 a b c], simp) haftmann@36302: haftmann@36302: end paulson@15234: haftmann@35092: class abs = haftmann@35092: fixes abs :: "'a \ 'a" haftmann@35092: begin haftmann@35092: haftmann@35092: notation (xsymbols) haftmann@35092: abs ("\_\") haftmann@35092: haftmann@35092: notation (HTML output) haftmann@35092: abs ("\_\") haftmann@35092: haftmann@35092: end haftmann@35092: haftmann@35092: class sgn = haftmann@35092: fixes sgn :: "'a \ 'a" haftmann@35092: haftmann@35092: class abs_if = minus + uminus + ord + zero + abs + haftmann@35092: assumes abs_if: "\a\ = (if a < 0 then - a else a)" haftmann@35092: haftmann@35092: class sgn_if = minus + uminus + zero + one + ord + sgn + haftmann@35092: assumes sgn_if: "sgn x = (if x = 0 then 0 else if 0 < x then 1 else - 1)" haftmann@35092: begin haftmann@35092: haftmann@35092: lemma sgn0 [simp]: "sgn 0 = 0" haftmann@35092: by (simp add:sgn_if) haftmann@35092: haftmann@35092: end obua@14738: haftmann@35028: class ordered_ab_group_add_abs = ordered_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) haftmann@36302: (auto intro!: abs_ge_self abs_leI order_trans [of "- \a\" 0 "\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@36302: with abs_ge_self [of "- 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: blanchet@35828: lemma abs_0_eq [simp, no_atp]: "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" haftmann@36302: by (insert abs_le_D1 [of "- 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\" haftmann@36302: proof - haftmann@36302: have "\a\ = \b + (a - b)\" haftmann@36302: by (simp add: algebra_simps add_diff_cancel) haftmann@36302: then have "\a\ \ \b\ + \a - b\" haftmann@36302: by (simp add: abs_triangle_ineq) haftmann@36302: then show ?thesis haftmann@36302: by (simp add: algebra_simps) haftmann@36302: qed haftmann@36302: haftmann@36302: lemma abs_triangle_ineq2_sym: "\a\ - \b\ \ \b - a\" haftmann@36302: by (simp only: abs_minus_commute [of b] abs_triangle_ineq2) avigad@16775: haftmann@25303: lemma abs_triangle_ineq3: "\\a\ - \b\\ \ \a - b\" haftmann@36302: by (simp add: abs_le_iff abs_triangle_ineq2 abs_triangle_ineq2_sym) avigad@16775: haftmann@25303: lemma abs_triangle_ineq4: "\a - b\ \ \a\ + \b\" haftmann@25303: proof - haftmann@36302: have "\a - b\ = \a + - b\" by (subst diff_minus, rule refl) haftmann@36302: also have "... \ \a\ + \- 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: 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: haftmann@35028: lemma less_eqI: "(x::'a::ordered_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: haftmann@35028: lemma le_eqI: "(x::'a::ordered_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')" huffman@30629: by (simp only: 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: haftmann@25090: lemma le_add_right_mono: obua@15178: assumes haftmann@35028: "a <= b + (c::'a::ordered_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: haftmann@25090: subsection {* Tools setup *} haftmann@25090: blanchet@35828: lemma add_mono_thms_linordered_semiring [no_atp]: haftmann@35028: fixes i j k :: "'a\ordered_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: blanchet@35828: lemma add_mono_thms_linordered_field [no_atp]: haftmann@35028: fixes i j k :: "'a\ordered_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.*} blanchet@35828: lemmas diff_less_0_iff_less [simp, no_atp] = less_iff_diff_less_0 [symmetric] blanchet@35828: lemmas diff_le_0_iff_le [simp, no_atp] = 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@35267: [@{const_name Groups.zero}, @{const_name Groups.plus}, haftmann@35267: @{const_name Groups.uminus}, @{const_name Groups.minus}] haftmann@22482: | agrp_ord _ = ~1; haftmann@22482: wenzelm@35408: fun termless_agrp (a, b) = (Term_Ord.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@35267: fun solve_add_ac thy _ (_ $ (Const (@{const_name Groups.plus},_) $ _ $ _) $ _) = haftmann@22482: SOME ac1 haftmann@35267: | solve_add_ac thy _ (_ $ x $ (Const (@{const_name Groups.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@32010: val add_ac_proc = Simplifier.simproc @{theory} 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 = wenzelm@35364: fst o HOLogic.dest_bin @{const_name "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: haftmann@33364: code_modulename SML haftmann@35050: Groups Arith haftmann@33364: haftmann@33364: code_modulename OCaml haftmann@35050: Groups Arith haftmann@33364: haftmann@33364: code_modulename Haskell haftmann@35050: Groups Arith haftmann@33364: obua@14738: end