src/HOL/Algebra/abstract/Ring2.thy
changeset 21423 6cdd0589aa73
parent 21416 f23e4e75dfd3
child 21588 cd0dc678a205
equal deleted inserted replaced
21422:25ed0a4c7dc5 21423:6cdd0589aa73
     6 *)
     6 *)
     7 
     7 
     8 header {* The algebraic hierarchy of rings as axiomatic classes *}
     8 header {* The algebraic hierarchy of rings as axiomatic classes *}
     9 
     9 
    10 theory Ring2 imports Main
    10 theory Ring2 imports Main
    11 uses ("order.ML") begin
    11 begin
    12 
    12 
    13 section {* Constants *}
    13 section {* Constants *}
    14 
    14 
    15 text {* Most constants are already declared by HOL. *}
    15 text {* Most constants are already declared by HOL. *}
    16 
    16 
   100   field_one_not_zero:    "1 ~= 0"
   100   field_one_not_zero:    "1 ~= 0"
   101                 (* Avoid a common superclass as the first thing we will
   101                 (* Avoid a common superclass as the first thing we will
   102                    prove about fields is that they are domains. *)
   102                    prove about fields is that they are domains. *)
   103   field_ax:        "a ~= 0 ==> a dvd 1"
   103   field_ax:        "a ~= 0 ==> a dvd 1"
   104 
   104 
       
   105 
   105 section {* Basic facts *}
   106 section {* Basic facts *}
   106 
   107 
   107 subsection {* Normaliser for rings *}
   108 subsection {* Normaliser for rings *}
   108 
   109 
   109 use "order.ML"
   110 (* derived rewrite rules *)
       
   111 
       
   112 lemma a_lcomm: "(a::'a::ring)+(b+c) = b+(a+c)"
       
   113   apply (rule a_comm [THEN trans])
       
   114   apply (rule a_assoc [THEN trans])
       
   115   apply (rule a_comm [THEN arg_cong])
       
   116   done
       
   117 
       
   118 lemma r_zero: "(a::'a::ring) + 0 = a"
       
   119   apply (rule a_comm [THEN trans])
       
   120   apply (rule l_zero)
       
   121   done
       
   122 
       
   123 lemma r_neg: "(a::'a::ring) + (-a) = 0"
       
   124   apply (rule a_comm [THEN trans])
       
   125   apply (rule l_neg)
       
   126   done
       
   127 
       
   128 lemma r_neg2: "(a::'a::ring) + (-a + b) = b"
       
   129   apply (rule a_assoc [symmetric, THEN trans])
       
   130   apply (simp add: r_neg l_zero)
       
   131   done
       
   132 
       
   133 lemma r_neg1: "-(a::'a::ring) + (a + b) = b"
       
   134   apply (rule a_assoc [symmetric, THEN trans])
       
   135   apply (simp add: l_neg l_zero)
       
   136   done
       
   137 
       
   138 
       
   139 (* auxiliary *)
       
   140 
       
   141 lemma a_lcancel: "!! a::'a::ring. a + b = a + c ==> b = c"
       
   142   apply (rule box_equals)
       
   143   prefer 2
       
   144   apply (rule l_zero)
       
   145   prefer 2
       
   146   apply (rule l_zero)
       
   147   apply (rule_tac a1 = a in l_neg [THEN subst])
       
   148   apply (simp add: a_assoc)
       
   149   done
       
   150 
       
   151 lemma minus_add: "-((a::'a::ring) + b) = (-a) + (-b)"
       
   152   apply (rule_tac a = "a + b" in a_lcancel)
       
   153   apply (simp add: r_neg l_neg l_zero a_assoc a_comm a_lcomm)
       
   154   done
       
   155 
       
   156 lemma minus_minus: "-(-(a::'a::ring)) = a"
       
   157   apply (rule a_lcancel)
       
   158   apply (rule r_neg [THEN trans])
       
   159   apply (rule l_neg [symmetric])
       
   160   done
       
   161 
       
   162 lemma minus0: "- 0 = (0::'a::ring)"
       
   163   apply (rule a_lcancel)
       
   164   apply (rule r_neg [THEN trans])
       
   165   apply (rule l_zero [symmetric])
       
   166   done
       
   167 
       
   168 
       
   169 (* derived rules for multiplication *)
       
   170 
       
   171 lemma m_lcomm: "(a::'a::ring)*(b*c) = b*(a*c)"
       
   172   apply (rule m_comm [THEN trans])
       
   173   apply (rule m_assoc [THEN trans])
       
   174   apply (rule m_comm [THEN arg_cong])
       
   175   done
       
   176 
       
   177 lemma r_one: "(a::'a::ring) * 1 = a"
       
   178   apply (rule m_comm [THEN trans])
       
   179   apply (rule l_one)
       
   180   done
       
   181 
       
   182 lemma r_distr: "(a::'a::ring) * (b + c) = a * b + a * c"
       
   183   apply (rule m_comm [THEN trans])
       
   184   apply (rule l_distr [THEN trans])
       
   185   apply (simp add: m_comm)
       
   186   done
       
   187 
       
   188 
       
   189 (* the following proof is from Jacobson, Basic Algebra I, pp. 88-89 *)
       
   190 lemma l_null: "0 * (a::'a::ring) = 0"
       
   191   apply (rule a_lcancel)
       
   192   apply (rule l_distr [symmetric, THEN trans])
       
   193   apply (simp add: r_zero)
       
   194   done
       
   195 
       
   196 lemma r_null: "(a::'a::ring) * 0 = 0"
       
   197   apply (rule m_comm [THEN trans])
       
   198   apply (rule l_null)
       
   199   done
       
   200 
       
   201 lemma l_minus: "(-(a::'a::ring)) * b = - (a * b)"
       
   202   apply (rule a_lcancel)
       
   203   apply (rule r_neg [symmetric, THEN [2] trans])
       
   204   apply (rule l_distr [symmetric, THEN trans])
       
   205   apply (simp add: l_null r_neg)
       
   206   done
       
   207 
       
   208 lemma r_minus: "(a::'a::ring) * (-b) = - (a * b)"
       
   209   apply (rule a_lcancel)
       
   210   apply (rule r_neg [symmetric, THEN [2] trans])
       
   211   apply (rule r_distr [symmetric, THEN trans])
       
   212   apply (simp add: r_null r_neg)
       
   213   done
       
   214 
       
   215 (*** Term order for commutative rings ***)
       
   216 
       
   217 ML {*
       
   218 fun ring_ord (Const (a, _)) =
       
   219     find_index (fn a' => a = a')
       
   220       ["HOL.zero", "HOL.plus", "HOL.uminus", "HOL.minus", "HOL.one", "HOL.times"]
       
   221   | ring_ord _ = ~1;
       
   222 
       
   223 fun termless_ring (a, b) = (Term.term_lpo ring_ord (a, b) = LESS);
       
   224 
       
   225 val ring_ss = HOL_basic_ss settermless termless_ring addsimps
       
   226   [thm "a_assoc", thm "l_zero", thm "l_neg", thm "a_comm", thm "m_assoc",
       
   227    thm "l_one", thm "l_distr", thm "m_comm", thm "minus_def",
       
   228    thm "r_zero", thm "r_neg", thm "r_neg2", thm "r_neg1", thm "minus_add",
       
   229    thm "minus_minus", thm "minus0", thm "a_lcomm", thm "m_lcomm", (*thm "r_one",*)
       
   230    thm "r_distr", thm "l_null", thm "r_null", thm "l_minus", thm "r_minus"];
       
   231 *}   (* Note: r_one is not necessary in ring_ss *)
   110 
   232 
   111 method_setup ring =
   233 method_setup ring =
   112   {* Method.no_args (Method.SIMPLE_METHOD' HEADGOAL (full_simp_tac ring_ss)) *}
   234   {* Method.no_args (Method.SIMPLE_METHOD' HEADGOAL (full_simp_tac ring_ss)) *}
   113   {* computes distributive normal form in rings *}
   235   {* computes distributive normal form in rings *}
       
   236 
       
   237 lemmas ring_simps =
       
   238   l_zero r_zero l_neg r_neg minus_minus minus0
       
   239   l_one r_one l_null r_null l_minus r_minus
   114 
   240 
   115 
   241 
   116 subsection {* Rings and the summation operator *}
   242 subsection {* Rings and the summation operator *}
   117 
   243 
   118 (* Basic facts --- move to HOL!!! *)
   244 (* Basic facts --- move to HOL!!! *)
   276   ultimately have "c = a * (l * j)" by simp
   402   ultimately have "c = a * (l * j)" by simp
   277   then have "\<exists>k. c = a * k" ..
   403   then have "\<exists>k. c = a * k" ..
   278   then show ?thesis using dvd_def by blast
   404   then show ?thesis using dvd_def by blast
   279 qed
   405 qed
   280 
   406 
   281 lemma dvd_def':
   407 
   282   "m dvd n \<equiv> \<exists>k. n = m * k" unfolding dvd_def by simp
   408 lemma unit_mult: 
       
   409   "!!a::'a::ring. [| a dvd 1; b dvd 1 |] ==> a * b dvd 1"
       
   410   apply (unfold dvd_def)
       
   411   apply clarify
       
   412   apply (rule_tac x = "k * ka" in exI)
       
   413   apply simp
       
   414   done
       
   415 
       
   416 lemma unit_power: "!!a::'a::ring. a dvd 1 ==> a^n dvd 1"
       
   417   apply (induct_tac n)
       
   418    apply simp
       
   419   apply (simp add: unit_mult)
       
   420   done
       
   421 
       
   422 lemma dvd_add_right [simp]:
       
   423   "!! a::'a::ring. [| a dvd b; a dvd c |] ==> a dvd b + c"
       
   424   apply (unfold dvd_def)
       
   425   apply clarify
       
   426   apply (rule_tac x = "k + ka" in exI)
       
   427   apply (simp add: r_distr)
       
   428   done
       
   429 
       
   430 lemma dvd_uminus_right [simp]:
       
   431   "!! a::'a::ring. a dvd b ==> a dvd -b"
       
   432   apply (unfold dvd_def)
       
   433   apply clarify
       
   434   apply (rule_tac x = "-k" in exI)
       
   435   apply (simp add: r_minus)
       
   436   done
       
   437 
       
   438 lemma dvd_l_mult_right [simp]:
       
   439   "!! a::'a::ring. a dvd b ==> a dvd c*b"
       
   440   apply (unfold dvd_def)
       
   441   apply clarify
       
   442   apply (rule_tac x = "c * k" in exI)
       
   443   apply simp
       
   444   done
       
   445 
       
   446 lemma dvd_r_mult_right [simp]:
       
   447   "!! a::'a::ring. a dvd b ==> a dvd b*c"
       
   448   apply (unfold dvd_def)
       
   449   apply clarify
       
   450   apply (rule_tac x = "k * c" in exI)
       
   451   apply simp
       
   452   done
       
   453 
       
   454 
       
   455 (* Inverse of multiplication *)
       
   456 
       
   457 section "inverse"
       
   458 
       
   459 lemma inverse_unique: "!! a::'a::ring. [| a * x = 1; a * y = 1 |] ==> x = y"
       
   460   apply (rule_tac a = "(a*y) * x" and b = "y * (a*x)" in box_equals)
       
   461     apply (simp (no_asm))
       
   462   apply auto
       
   463   done
       
   464 
       
   465 lemma r_inverse_ring: "!! a::'a::ring. a dvd 1 ==> a * inverse a = 1"
       
   466   apply (unfold inverse_def dvd_def)
       
   467   apply (tactic {* asm_full_simp_tac (simpset () delsimprocs [ring_simproc]) 1 *})
       
   468   apply clarify
       
   469   apply (rule theI)
       
   470    apply assumption
       
   471   apply (rule inverse_unique)
       
   472    apply assumption
       
   473   apply assumption
       
   474   done
       
   475 
       
   476 lemma l_inverse_ring: "!! a::'a::ring. a dvd 1 ==> inverse a * a = 1"
       
   477   by (simp add: r_inverse_ring)
       
   478 
       
   479 
       
   480 (* Fields *)
       
   481 
       
   482 section "Fields"
       
   483 
       
   484 lemma field_unit [simp]: "!! a::'a::field. (a dvd 1) = (a ~= 0)"
       
   485   by (auto dest: field_ax dvd_zero_left simp add: field_one_not_zero)
       
   486 
       
   487 lemma r_inverse [simp]: "!! a::'a::field. a ~= 0 ==> a * inverse a = 1"
       
   488   by (simp add: r_inverse_ring)
       
   489 
       
   490 lemma l_inverse [simp]: "!! a::'a::field. a ~= 0 ==> inverse a * a= 1"
       
   491   by (simp add: l_inverse_ring)
       
   492 
       
   493 
       
   494 (* fields are integral domains *)
       
   495 
       
   496 lemma field_integral: "!! a::'a::field. a * b = 0 ==> a = 0 | b = 0"
       
   497   apply (tactic "Step_tac 1")
       
   498   apply (rule_tac a = " (a*b) * inverse b" in box_equals)
       
   499     apply (rule_tac [3] refl)
       
   500    prefer 2
       
   501    apply (simp (no_asm))
       
   502    apply auto
       
   503   done
       
   504 
       
   505 
       
   506 (* fields are factorial domains *)
       
   507 
       
   508 lemma field_fact_prime: "!! a::'a::field. irred a ==> prime a"
       
   509   unfolding prime_def irred_def by (blast intro: field_ax)
   283 
   510 
   284 end
   511 end