# HG changeset patch # User haftmann # Date 1476809333 -7200 # Node ID fb5c74a587968612dcc23c71e74d34a1c917c7a2 # Parent 42f28160bad92d9e1ff94a4433543269c4e89db0 suitable logical type class for abs, sgn diff -r 42f28160bad9 -r fb5c74a58796 NEWS --- a/NEWS Tue Oct 18 17:29:28 2016 +0200 +++ b/NEWS Tue Oct 18 18:48:53 2016 +0200 @@ -281,6 +281,10 @@ mod_1 ~> mod_by_Suc_0 INCOMPATIBILITY. +* New type class "idom_abs_sgn" specifies algebraic properties +of sign and absolute value functions. Type class "sgn_if" has +disappeared. Slight INCOMPATIBILITY. + * Dedicated syntax LENGTH('a) for length of types. * New proof method "argo" using the built-in Argo solver based on SMT diff -r 42f28160bad9 -r fb5c74a58796 src/HOL/Complex.thy --- a/src/HOL/Complex.thy Tue Oct 18 17:29:28 2016 +0200 +++ b/src/HOL/Complex.thy Tue Oct 18 18:48:53 2016 +0200 @@ -381,6 +381,23 @@ by (simp add: complex_sgn_def divide_inverse) +subsection \Absolute value\ + +instantiation complex :: field_abs_sgn +begin + +definition abs_complex :: "complex \ complex" + where "abs_complex = of_real \ norm" + +instance + apply standard + apply (auto simp add: abs_complex_def complex_sgn_def norm_mult) + apply (auto simp add: scaleR_conv_of_real field_simps) + done + +end + + subsection \Completeness of the Complexes\ lemma bounded_linear_Re: "bounded_linear Re" diff -r 42f28160bad9 -r fb5c74a58796 src/HOL/Enum.thy --- a/src/HOL/Enum.thy Tue Oct 18 17:29:28 2016 +0200 +++ b/src/HOL/Enum.thy Tue Oct 18 18:48:53 2016 +0200 @@ -580,7 +580,7 @@ instantiation finite_1 :: "{linordered_ring_strict, linordered_comm_semiring_strict, ordered_comm_ring, ordered_cancel_comm_monoid_diff, comm_monoid_mult, ordered_ring_abs, - one, modulo, sgn_if, inverse}" + one, modulo, sgn, inverse}" begin definition [simp]: "Groups.zero = a\<^sub>1" definition [simp]: "Groups.one = a\<^sub>1" @@ -683,7 +683,7 @@ instance finite_2 :: complete_linorder .. -instantiation finite_2 :: "{field, abs_if, ring_div, sgn_if, semiring_div}" begin +instantiation finite_2 :: "{field, ring_div, idom_abs_sgn}" begin definition [simp]: "0 = a\<^sub>1" definition [simp]: "1 = a\<^sub>2" definition "x + y = (case (x, y) of (a\<^sub>1, a\<^sub>1) \ a\<^sub>1 | (a\<^sub>2, a\<^sub>2) \ a\<^sub>1 | _ \ a\<^sub>2)" @@ -806,7 +806,7 @@ instance finite_3 :: complete_linorder .. -instantiation finite_3 :: "{field, abs_if, ring_div, semiring_div, sgn_if}" begin +instantiation finite_3 :: "{field, ring_div, idom_abs_sgn}" begin definition [simp]: "0 = a\<^sub>1" definition [simp]: "1 = a\<^sub>2" definition @@ -819,9 +819,9 @@ definition "x * y = (case (x, y) of (a\<^sub>2, a\<^sub>2) \ a\<^sub>2 | (a\<^sub>3, a\<^sub>3) \ a\<^sub>2 | (a\<^sub>2, a\<^sub>3) \ a\<^sub>3 | (a\<^sub>3, a\<^sub>2) \ a\<^sub>3 | _ \ a\<^sub>1)" definition "inverse = (\x :: finite_3. x)" definition "x div y = x * inverse (y :: finite_3)" -definition "abs = (\x :: finite_3. x)" +definition "abs = (\x. case x of a\<^sub>3 \ a\<^sub>2 | _ \ x)" definition "x mod y = (case (x, y) of (a\<^sub>2, a\<^sub>1) \ a\<^sub>2 | (a\<^sub>3, a\<^sub>1) \ a\<^sub>3 | _ \ a\<^sub>1)" -definition "sgn = (\x. case x of a\<^sub>1 \ a\<^sub>1 | _ \ a\<^sub>2)" +definition "sgn = (\x :: finite_3. x)" instance by intro_classes (simp_all add: plus_finite_3_def uminus_finite_3_def minus_finite_3_def times_finite_3_def diff -r 42f28160bad9 -r fb5c74a58796 src/HOL/Fields.thy --- a/src/HOL/Fields.thy Tue Oct 18 17:29:28 2016 +0200 +++ b/src/HOL/Fields.thy Tue Oct 18 18:48:53 2016 +0200 @@ -513,6 +513,48 @@ subsection \Ordered fields\ +class field_abs_sgn = field + idom_abs_sgn +begin + +lemma sgn_inverse [simp]: + "sgn (inverse a) = inverse (sgn a)" +proof (cases "a = 0") + case True then show ?thesis by simp +next + case False + then have "a * inverse a = 1" + by simp + then have "sgn (a * inverse a) = sgn 1" + by simp + then have "sgn a * sgn (inverse a) = 1" + by (simp add: sgn_mult) + then have "inverse (sgn a) * (sgn a * sgn (inverse a)) = inverse (sgn a) * 1" + by simp + then have "(inverse (sgn a) * sgn a) * sgn (inverse a) = inverse (sgn a)" + by (simp add: ac_simps) + with False show ?thesis + by (simp add: sgn_eq_0_iff) +qed + +lemma abs_inverse [simp]: + "\inverse a\ = inverse \a\" +proof - + from sgn_mult_abs [of "inverse a"] sgn_mult_abs [of a] + have "inverse (sgn a) * \inverse a\ = inverse (sgn a * \a\)" + by simp + then show ?thesis by (auto simp add: sgn_eq_0_iff) +qed + +lemma sgn_divide [simp]: + "sgn (a / b) = sgn a / sgn b" + unfolding divide_inverse sgn_mult by simp + +lemma abs_divide [simp]: + "\a / b\ = \a\ / \b\" + unfolding divide_inverse abs_mult by simp + +end + class linordered_field = field + linordered_idom begin @@ -932,16 +974,15 @@ show "x < y \ \z>x. z < y" by (blast intro!: less_half_sum gt_half_sum) qed +subclass field_abs_sgn .. + lemma nonzero_abs_inverse: - "a \ 0 ==> \inverse a\ = inverse \a\" -apply (auto simp add: neq_iff abs_if nonzero_inverse_minus_eq - negative_imp_inverse_negative) -apply (blast intro: positive_imp_inverse_positive elim: less_asym) -done + "a \ 0 ==> \inverse a\ = inverse \a\" + by (rule abs_inverse) lemma nonzero_abs_divide: - "b \ 0 ==> \a / b\ = \a\ / \b\" - by (simp add: divide_inverse abs_mult nonzero_abs_inverse) + "b \ 0 ==> \a / b\ = \a\ / \b\" + by (rule abs_divide) lemma field_le_epsilon: assumes e: "\e. 0 < e \ x \ y + e" @@ -1147,19 +1188,6 @@ "(b/a = 1) = ((a \ 0 & a = b))" by (auto simp add: divide_eq_eq) -lemma abs_inverse [simp]: - "\inverse a\ = - inverse \a\" -apply (cases "a=0", simp) -apply (simp add: nonzero_abs_inverse) -done - -lemma abs_divide [simp]: - "\a / b\ = \a\ / \b\" -apply (cases "b=0", simp) -apply (simp add: nonzero_abs_divide) -done - lemma abs_div_pos: "0 < y ==> \x\ / y = \x / y\" apply (subst abs_divide) @@ -1174,7 +1202,7 @@ lemma inverse_sgn: "sgn (inverse a) = inverse (sgn a)" - by (simp add: sgn_if) + by (fact sgn_inverse) lemma field_le_mult_one_interval: assumes *: "\z. \ 0 < z ; z < 1 \ \ z * x \ y" diff -r 42f28160bad9 -r fb5c74a58796 src/HOL/Groups.thy --- a/src/HOL/Groups.thy Tue Oct 18 17:29:28 2016 +0200 +++ b/src/HOL/Groups.thy Tue Oct 18 18:48:53 2016 +0200 @@ -1148,18 +1148,6 @@ class sgn = fixes sgn :: "'a \ 'a" -class abs_if = minus + uminus + ord + zero + abs + - assumes abs_if: "\a\ = (if a < 0 then - a else a)" - -class sgn_if = minus + uminus + zero + one + ord + sgn + - assumes sgn_if: "sgn x = (if x = 0 then 0 else if 0 < x then 1 else - 1)" -begin - -lemma sgn0 [simp]: "sgn 0 = 0" - by (simp add:sgn_if) - -end - class ordered_ab_group_add_abs = ordered_ab_group_add + abs + assumes abs_ge_zero [simp]: "\a\ \ 0" and abs_ge_self: "a \ \a\" diff -r 42f28160bad9 -r fb5c74a58796 src/HOL/Library/Fraction_Field.thy --- a/src/HOL/Library/Fraction_Field.thy Tue Oct 18 17:29:28 2016 +0200 +++ b/src/HOL/Library/Fraction_Field.thy Tue Oct 18 18:48:53 2016 +0200 @@ -70,7 +70,7 @@ and "\a c. Fract 0 a = Fract 0 c" by(transfer; simp)+ -instantiation fract :: (idom) "{comm_ring_1,power}" +instantiation fract :: (idom) comm_ring_1 begin lift_definition zero_fract :: "'a fract" is "(0, 1)" by simp @@ -353,31 +353,20 @@ end -instantiation fract :: (linordered_idom) "{distrib_lattice,abs_if,sgn_if}" +instantiation fract :: (linordered_idom) linordered_field begin -definition abs_fract_def2: "\q\ = (if q < 0 then -q else (q::'a fract))" +definition abs_fract_def2: + "\q\ = (if q < 0 then -q else (q::'a fract))" definition sgn_fract_def: "sgn (q::'a fract) = (if q = 0 then 0 else if 0 < q then 1 else - 1)" theorem abs_fract [simp]: "\Fract a b\ = Fract \a\ \b\" -unfolding abs_fract_def2 not_le[symmetric] -by transfer(auto simp add: zero_less_mult_iff le_less) - -definition inf_fract_def: - "(inf :: 'a fract \ 'a fract \ 'a fract) = min" + unfolding abs_fract_def2 not_le [symmetric] + by transfer (auto simp add: zero_less_mult_iff le_less) -definition sup_fract_def: - "(sup :: 'a fract \ 'a fract \ 'a fract) = max" - -instance -by intro_classes (simp_all add: abs_fract_def2 sgn_fract_def inf_fract_def sup_fract_def max_min_distrib2) - -end - -instance fract :: (linordered_idom) linordered_field -proof +instance proof fix q r s :: "'a fract" assume "q \ r" then show "s + q \ s + r" @@ -420,7 +409,23 @@ by (simp add: ac_simps) qed qed -qed +qed (fact sgn_fract_def abs_fract_def2)+ + +end + +instantiation fract :: (linordered_idom) distrib_lattice +begin + +definition inf_fract_def: + "(inf :: 'a fract \ 'a fract \ 'a fract) = min" + +definition sup_fract_def: + "(sup :: 'a fract \ 'a fract \ 'a fract) = max" + +instance + by standard (simp_all add: inf_fract_def sup_fract_def max_min_distrib2) + +end lemma fract_induct_pos [case_names Fract]: fixes P :: "'a::linordered_idom fract \ bool" diff -r 42f28160bad9 -r fb5c74a58796 src/HOL/Nonstandard_Analysis/StarDef.thy --- a/src/HOL/Nonstandard_Analysis/StarDef.thy Tue Oct 18 17:29:28 2016 +0200 +++ b/src/HOL/Nonstandard_Analysis/StarDef.thy Tue Oct 18 18:48:53 2016 +0200 @@ -898,19 +898,15 @@ instance star :: (abs_if) abs_if by (intro_classes; transfer) (fact abs_if) -instance star :: (sgn_if) sgn_if - by (intro_classes; transfer) (fact sgn_if) - instance star :: (linordered_ring_strict) linordered_ring_strict .. instance star :: (ordered_comm_ring) ordered_comm_ring .. instance star :: (linordered_semidom) linordered_semidom - apply intro_classes - apply(transfer, fact zero_less_one) - apply(transfer, fact le_add_diff_inverse2) - done + by (intro_classes; transfer) (fact zero_less_one le_add_diff_inverse2)+ -instance star :: (linordered_idom) linordered_idom .. +instance star :: (linordered_idom) linordered_idom + by (intro_classes; transfer) (fact sgn_if) + instance star :: (linordered_field) linordered_field .. subsection \Power\ diff -r 42f28160bad9 -r fb5c74a58796 src/HOL/Quotient_Examples/Quotient_Rat.thy --- a/src/HOL/Quotient_Examples/Quotient_Rat.thy Tue Oct 18 17:29:28 2016 +0200 +++ b/src/HOL/Quotient_Examples/Quotient_Rat.thy Tue Oct 18 18:48:53 2016 +0200 @@ -28,7 +28,7 @@ quotient_type rat = "int \ int" / partial: ratrel using ratrel_equivp . -instantiation rat :: "{zero, one, plus, uminus, minus, times, ord, abs_if, sgn_if}" +instantiation rat :: "{zero, one, plus, uminus, minus, times, ord, abs, sgn}" begin quotient_definition @@ -100,8 +100,7 @@ definition sgn_rat_def: "sgn (i::rat) = (if i = 0 then 0 else if 0 < i then 1 else - 1)" -instance by intro_classes - (auto simp add: rabs_rat_def sgn_rat_def) +instance .. end diff -r 42f28160bad9 -r fb5c74a58796 src/HOL/Rings.thy --- a/src/HOL/Rings.thy Tue Oct 18 17:29:28 2016 +0200 +++ b/src/HOL/Rings.thy Tue Oct 18 18:48:53 2016 +0200 @@ -532,6 +532,100 @@ end +class idom_abs_sgn = idom + abs + sgn + + assumes sgn_mult_abs: "sgn a * \a\ = a" + and sgn_sgn [simp]: "sgn (sgn a) = sgn a" + and abs_abs [simp]: "\\a\\ = \a\" + and abs_0 [simp]: "\0\ = 0" + and sgn_0 [simp]: "sgn 0 = 0" + and sgn_1 [simp]: "sgn 1 = 1" + and sgn_minus_1: "sgn (- 1) = - 1" + and sgn_mult: "sgn (a * b) = sgn a * sgn b" +begin + +lemma sgn_eq_0_iff: + "sgn a = 0 \ a = 0" +proof - + { assume "sgn a = 0" + then have "sgn a * \a\ = 0" + by simp + then have "a = 0" + by (simp add: sgn_mult_abs) + } then show ?thesis + by auto +qed + +lemma abs_eq_0_iff: + "\a\ = 0 \ a = 0" +proof - + { assume "\a\ = 0" + then have "sgn a * \a\ = 0" + by simp + then have "a = 0" + by (simp add: sgn_mult_abs) + } then show ?thesis + by auto +qed + +lemma abs_mult_sgn: + "\a\ * sgn a = a" + using sgn_mult_abs [of a] by (simp add: ac_simps) + +lemma abs_1 [simp]: + "\1\ = 1" + using sgn_mult_abs [of 1] by simp + +lemma sgn_abs [simp]: + "\sgn a\ = of_bool (a \ 0)" + using sgn_mult_abs [of "sgn a"] mult_cancel_left [of "sgn a" "\sgn a\" 1] + by (auto simp add: sgn_eq_0_iff) + +lemma abs_sgn [simp]: + "sgn \a\ = of_bool (a \ 0)" + using sgn_mult_abs [of "\a\"] mult_cancel_right [of "sgn \a\" "\a\" 1] + by (auto simp add: abs_eq_0_iff) + +lemma abs_mult: + "\a * b\ = \a\ * \b\" +proof (cases "a = 0 \ b = 0") + case True + then show ?thesis + by auto +next + case False + then have *: "sgn (a * b) \ 0" + by (simp add: sgn_eq_0_iff) + from abs_mult_sgn [of "a * b"] abs_mult_sgn [of a] abs_mult_sgn [of b] + have "\a * b\ * sgn (a * b) = \a\ * sgn a * \b\ * sgn b" + by (simp add: ac_simps) + then have "\a * b\ * sgn (a * b) = \a\ * \b\ * sgn (a * b)" + by (simp add: sgn_mult ac_simps) + with * show ?thesis + by simp +qed + +lemma sgn_minus [simp]: + "sgn (- a) = - sgn a" +proof - + from sgn_minus_1 have "sgn (- 1 * a) = - 1 * sgn a" + by (simp only: sgn_mult) + then show ?thesis + by simp +qed + +lemma abs_minus [simp]: + "\- a\ = \a\" +proof - + have [simp]: "\- 1\ = 1" + using sgn_mult_abs [of "- 1"] by simp + then have "\- 1 * a\ = 1 * \a\" + by (simp only: abs_mult) + then show ?thesis + by simp +qed + +end + text \ The theory of partially ordered rings is taken from the books: \<^item> \<^emph>\Lattice Theory\ by Garret Birkhoff, American Mathematical Society, 1979 @@ -1599,6 +1693,9 @@ end +class abs_if = minus + uminus + ord + zero + abs + + assumes abs_if: "\a\ = (if a < 0 then - a else a)" + class linordered_ring = ring + linordered_semiring + linordered_ab_group_add + abs_if begin @@ -1842,7 +1939,8 @@ end class linordered_idom = - comm_ring_1 + linordered_comm_semiring_strict + ordered_ab_group_add + abs_if + sgn_if + comm_ring_1 + linordered_comm_semiring_strict + ordered_ab_group_add + abs_if + sgn + + assumes sgn_if: "sgn x = (if x = 0 then 0 else if 0 < x then 1 else - 1)" begin subclass linordered_semiring_1_strict .. @@ -1857,6 +1955,10 @@ show "b \ a \ a - b + b = a" for a b by simp qed +subclass idom_abs_sgn + by standard + (auto simp add: sgn_if abs_if zero_less_mult_iff) + lemma linorder_neqE_linordered_idom: assumes "x \ y" obtains "x < y" | "y < x" @@ -1888,11 +1990,8 @@ lemma mult_less_cancel_left2: "c * a < c \ (0 \ c \ a < 1) \ (c \ 0 \ 1 < a)" using mult_less_cancel_left [of c a 1] by simp -lemma sgn_sgn [simp]: "sgn (sgn a) = sgn a" - unfolding sgn_if by simp - lemma sgn_0_0: "sgn a = 0 \ a = 0" - unfolding sgn_if by simp + by (fact sgn_eq_0_iff) lemma sgn_1_pos: "sgn a = 1 \ a > 0" unfolding sgn_if by simp @@ -1906,9 +2005,6 @@ lemma sgn_neg [simp]: "a < 0 \ sgn a = - 1" by (simp only: sgn_1_neg) -lemma sgn_mult: "sgn (a * b) = sgn a * sgn b" - by (auto simp add: sgn_if zero_less_mult_iff) - lemma abs_sgn: "\k\ = k * sgn k" unfolding sgn_if abs_if by auto @@ -1920,7 +2016,7 @@ lemma abs_sgn_eq_1 [simp]: "a \ 0 \ \sgn a\ = 1" - by (simp add: abs_if) + by simp lemma abs_sgn_eq: "\sgn a\ = (if a = 0 then 0 else 1)" by (simp add: sgn_if) @@ -2005,10 +2101,10 @@ begin lemma mult_sgn_abs: "sgn x * \x\ = x" - unfolding abs_if sgn_if by auto + by (fact sgn_mult_abs) -lemma abs_one [simp]: "\1\ = 1" - by (simp add: abs_if) +lemma abs_one: "\1\ = 1" + by (fact abs_1) end @@ -2022,9 +2118,6 @@ subclass ordered_ring_abs by standard (auto simp: abs_if not_less mult_less_0_iff) -lemma abs_mult: "\a * b\ = \a\ * \b\" - by (rule abs_eq_mult) auto - lemma abs_mult_self [simp]: "\a\ * \a\ = a * a" by (simp add: abs_if)