src/HOL/Algebra/abstract/Ring.thy
author obua
Tue, 11 May 2004 20:11:08 +0200
changeset 14738 83f1a514dcb4
parent 14439 0f626a712456
child 15020 fcbc73812e6c
permissions -rw-r--r--
changes made due to new Ring_and_Field theory
paulson@7998
     1
(*
ballarin@13735
     2
  Title:     The algebraic hierarchy of rings as axiomatic classes
ballarin@13735
     3
  Id:        $Id$
ballarin@13735
     4
  Author:    Clemens Ballarin, started 9 December 1996
ballarin@13735
     5
  Copyright: Clemens Ballarin
paulson@7998
     6
*)
paulson@7998
     7
ballarin@13735
     8
header {* The algebraic hierarchy of rings as axiomatic classes *}
paulson@7998
     9
ballarin@13735
    10
theory Ring = Main
ballarin@13735
    11
files ("order.ML"):
ballarin@13735
    12
ballarin@13735
    13
section {* Constants *}
ballarin@13735
    14
ballarin@13735
    15
text {* Most constants are already declared by HOL. *}
ballarin@13735
    16
ballarin@13735
    17
consts
ballarin@13735
    18
  assoc         :: "['a::times, 'a] => bool"              (infixl 50)
ballarin@13735
    19
  irred         :: "'a::{zero, one, times} => bool"
ballarin@13735
    20
  prime         :: "'a::{zero, one, times} => bool"
ballarin@13735
    21
ballarin@13735
    22
section {* Axioms *}
ballarin@13735
    23
ballarin@13735
    24
subsection {* Ring axioms *}
ballarin@13735
    25
ballarin@13735
    26
axclass ring < zero, one, plus, minus, times, inverse, power
ballarin@13735
    27
ballarin@13735
    28
  a_assoc:      "(a + b) + c = a + (b + c)"
ballarin@13735
    29
  l_zero:       "0 + a = a"
ballarin@13735
    30
  l_neg:        "(-a) + a = 0"
ballarin@13735
    31
  a_comm:       "a + b = b + a"
ballarin@13735
    32
ballarin@13735
    33
  m_assoc:      "(a * b) * c = a * (b * c)"
ballarin@13735
    34
  l_one:        "1 * a = a"
ballarin@13735
    35
ballarin@13735
    36
  l_distr:      "(a + b) * c = a * c + b * c"
ballarin@13735
    37
ballarin@13735
    38
  m_comm:       "a * b = b * a"
ballarin@13735
    39
ballarin@13735
    40
  -- {* Definition of derived operations *}
ballarin@13735
    41
ballarin@13735
    42
  minus_def:    "a - b = a + (-b)"
ballarin@13735
    43
  inverse_def:  "inverse a = (if a dvd 1 then THE x. a*x = 1 else 0)"
ballarin@13735
    44
  divide_def:   "a / b = a * inverse b"
ballarin@13735
    45
  power_def:    "a ^ n = nat_rec 1 (%u b. b * a) n"
ballarin@13735
    46
ballarin@13735
    47
defs
ballarin@13735
    48
  assoc_def:    "a assoc b == a dvd b & b dvd a"
ballarin@13735
    49
  irred_def:    "irred a == a ~= 0 & ~ a dvd 1
ballarin@13735
    50
                          & (ALL d. d dvd a --> d dvd 1 | a dvd d)"
ballarin@13735
    51
  prime_def:    "prime p == p ~= 0 & ~ p dvd 1
ballarin@13735
    52
                          & (ALL a b. p dvd (a*b) --> p dvd a | p dvd b)"
ballarin@13735
    53
ballarin@13735
    54
subsection {* Integral domains *}
paulson@7998
    55
paulson@7998
    56
axclass
ballarin@13735
    57
  "domain" < ring
paulson@7998
    58
ballarin@13735
    59
  one_not_zero: "1 ~= 0"
ballarin@13735
    60
  integral:     "a * b = 0 ==> a = 0 | b = 0"
paulson@7998
    61
ballarin@13735
    62
subsection {* Factorial domains *}
paulson@7998
    63
paulson@7998
    64
axclass
ballarin@13735
    65
  factorial < "domain"
paulson@7998
    66
paulson@7998
    67
(*
paulson@7998
    68
  Proper definition using divisor chain condition currently not supported.
ballarin@13735
    69
  factorial_divisor:    "wf {(a, b). a dvd b & ~ (b dvd a)}"
paulson@7998
    70
*)
ballarin@13735
    71
  factorial_divisor:	"True"
ballarin@13735
    72
  factorial_prime:      "irred a ==> prime a"
paulson@7998
    73
ballarin@13735
    74
subsection {* Euclidean domains *}
paulson@7998
    75
paulson@7998
    76
(*
paulson@7998
    77
axclass
ballarin@13735
    78
  euclidean < "domain"
paulson@7998
    79
ballarin@13735
    80
  euclidean_ax:  "b ~= 0 ==> Ex (% (q, r, e_size::('a::ringS)=>nat).
paulson@7998
    81
                   a = b * q + r & e_size r < e_size b)"
paulson@7998
    82
ballarin@13735
    83
  Nothing has been proved about Euclidean domains, yet.
paulson@7998
    84
  Design question:
paulson@7998
    85
    Fix quo, rem and e_size as constants that are axiomatised with
paulson@7998
    86
    euclidean_ax?
paulson@7998
    87
    - advantage: more pragmatic and easier to use
paulson@7998
    88
    - disadvantage: for every type, one definition of quo and rem will
paulson@7998
    89
        be fixed, users may want to use differing ones;
paulson@7998
    90
        also, it seems not possible to prove that fields are euclidean
paulson@7998
    91
        domains, because that would require generic (type-independent)
paulson@7998
    92
        definitions of quo and rem.
paulson@7998
    93
*)
paulson@7998
    94
ballarin@13735
    95
subsection {* Fields *}
paulson@7998
    96
paulson@7998
    97
axclass
paulson@7998
    98
  field < ring
paulson@7998
    99
ballarin@13735
   100
  field_one_not_zero:    "1 ~= 0"
ballarin@13735
   101
                (* Avoid a common superclass as the first thing we will
ballarin@13735
   102
                   prove about fields is that they are domains. *)
ballarin@13735
   103
  field_ax:        "a ~= 0 ==> a dvd 1"
ballarin@13735
   104
ballarin@13735
   105
section {* Basic facts *}
ballarin@13735
   106
ballarin@13735
   107
subsection {* Normaliser for rings *}
ballarin@13735
   108
ballarin@13735
   109
use "order.ML"
ballarin@13735
   110
ballarin@13735
   111
method_setup ring =
ballarin@13735
   112
  {* Method.no_args (Method.SIMPLE_METHOD' HEADGOAL (full_simp_tac ring_ss)) *}
ballarin@13735
   113
  {* computes distributive normal form in rings *}
ballarin@13735
   114
ballarin@13735
   115
ballarin@13735
   116
subsection {* Rings and the summation operator *}
ballarin@13735
   117
ballarin@13735
   118
(* Basic facts --- move to HOL!!! *)
ballarin@13735
   119
obua@14738
   120
lemma natsum_0 [simp]: "setsum f {..(0::nat)} = (f 0::'a::comm_monoid_add)"
ballarin@13735
   121
by simp
ballarin@13735
   122
ballarin@13735
   123
lemma natsum_Suc [simp]:
obua@14738
   124
  "setsum f {..Suc n} = (f (Suc n) + setsum f {..n}::'a::comm_monoid_add)"
ballarin@13735
   125
by (simp add: atMost_Suc)
ballarin@13735
   126
ballarin@13735
   127
lemma natsum_Suc2:
obua@14738
   128
  "setsum f {..Suc n} = (setsum (%i. f (Suc i)) {..n} + f 0::'a::comm_monoid_add)"
ballarin@13735
   129
proof (induct n)
ballarin@13735
   130
  case 0 show ?case by simp
ballarin@13735
   131
next
obua@14738
   132
  case Suc thus ?case by (simp add: semigroup_add.add_assoc) 
ballarin@13735
   133
qed
ballarin@13735
   134
ballarin@13735
   135
lemma natsum_cong [cong]:
obua@14738
   136
  "!!k. [| j = k; !!i::nat. i <= k ==> f i = (g i::'a::comm_monoid_add) |] ==>
ballarin@13735
   137
        setsum f {..j} = setsum g {..k}"
ballarin@13735
   138
by (induct j) auto
ballarin@13735
   139
obua@14738
   140
lemma natsum_zero [simp]: "setsum (%i. 0) {..n::nat} = (0::'a::comm_monoid_add)"
ballarin@13735
   141
by (induct n) simp_all
ballarin@13735
   142
ballarin@13735
   143
lemma natsum_add [simp]:
obua@14738
   144
  "!!f::nat=>'a::comm_monoid_add.
ballarin@13735
   145
   setsum (%i. f i + g i) {..n::nat} = setsum f {..n} + setsum g {..n}"
obua@14738
   146
by (induct n) (simp_all add: add_ac)
ballarin@13735
   147
ballarin@13735
   148
(* Facts specific to rings *)
ballarin@13735
   149
obua@14738
   150
instance ring < comm_monoid_add
ballarin@13735
   151
proof
ballarin@13735
   152
  fix x y z
ballarin@13735
   153
  show "(x::'a::ring) + y = y + x" by (rule a_comm)
ballarin@13735
   154
  show "((x::'a::ring) + y) + z = x + (y + z)" by (rule a_assoc)
ballarin@13735
   155
  show "0 + (x::'a::ring) = x" by (rule l_zero)
ballarin@13735
   156
qed
ballarin@13735
   157
ballarin@13735
   158
ML {*
ballarin@13735
   159
  local
ballarin@13735
   160
    val lhss = 
ballarin@13735
   161
        [read_cterm (sign_of (the_context ()))
ballarin@13735
   162
                    ("?t + ?u::'a::ring", TVar (("'z", 0), [])),
ballarin@13735
   163
	 read_cterm (sign_of (the_context ()))
ballarin@13735
   164
                    ("?t - ?u::'a::ring", TVar (("'z", 0), [])),
ballarin@13735
   165
	 read_cterm (sign_of (the_context ()))
ballarin@13735
   166
                    ("?t * ?u::'a::ring", TVar (("'z", 0), [])),
ballarin@13735
   167
	 read_cterm (sign_of (the_context ()))
ballarin@13735
   168
                    ("- ?t::'a::ring", TVar (("'z", 0), []))
ballarin@13735
   169
	];
ballarin@13735
   170
    fun proc sg _ t = 
ballarin@13735
   171
      let val rew = Tactic.prove sg [] []
ballarin@13735
   172
            (HOLogic.mk_Trueprop
ballarin@13735
   173
              (HOLogic.mk_eq (t, Var (("x", Term.maxidx_of_term t + 1), fastype_of t))))
ballarin@13735
   174
                (fn _ => simp_tac ring_ss 1)
ballarin@13735
   175
            |> mk_meta_eq;
ballarin@13735
   176
          val (t', u) = Logic.dest_equals (Thm.prop_of rew);
ballarin@13735
   177
      in if t' aconv u 
ballarin@13735
   178
        then None
ballarin@13735
   179
        else Some rew 
ballarin@13735
   180
    end;
ballarin@13735
   181
  in
ballarin@13735
   182
    val ring_simproc = mk_simproc "ring" lhss proc;
ballarin@13735
   183
  end;
ballarin@13735
   184
*}
ballarin@13735
   185
ballarin@13735
   186
ML_setup {* Addsimprocs [ring_simproc] *}
ballarin@13735
   187
ballarin@13735
   188
lemma natsum_ldistr:
ballarin@13735
   189
  "!!a::'a::ring. setsum f {..n::nat} * a = setsum (%i. f i * a) {..n}"
ballarin@13735
   190
by (induct n) simp_all
ballarin@13735
   191
ballarin@13735
   192
lemma natsum_rdistr:
ballarin@13735
   193
  "!!a::'a::ring. a * setsum f {..n::nat} = setsum (%i. a * f i) {..n}"
ballarin@13735
   194
by (induct n) simp_all
ballarin@13735
   195
ballarin@13735
   196
subsection {* Integral Domains *}
ballarin@13735
   197
ballarin@13735
   198
declare one_not_zero [simp]
ballarin@13735
   199
ballarin@13735
   200
lemma zero_not_one [simp]:
ballarin@13735
   201
  "0 ~= (1::'a::domain)" 
ballarin@13735
   202
by (rule not_sym) simp
ballarin@13735
   203
ballarin@13735
   204
lemma integral_iff: (* not by default a simp rule! *)
ballarin@13735
   205
  "(a * b = (0::'a::domain)) = (a = 0 | b = 0)"
ballarin@13735
   206
proof
ballarin@13735
   207
  assume "a * b = 0" then show "a = 0 | b = 0" by (simp add: integral)
ballarin@13735
   208
next
ballarin@13735
   209
  assume "a = 0 | b = 0" then show "a * b = 0" by auto
ballarin@13735
   210
qed
ballarin@13735
   211
ballarin@13735
   212
(*
ballarin@13735
   213
lemma "(a::'a::ring) - (a - b) = b" apply simp
ballarin@13783
   214
 simproc seems to fail on this example (fixed with new term order)
ballarin@13735
   215
*)
ballarin@13783
   216
(*
ballarin@13735
   217
lemma bug: "(b::'a::ring) - (b - a) = a" by simp
ballarin@13783
   218
   simproc for rings cannot prove "(a::'a::ring) - (a - b) = b" 
ballarin@13783
   219
*)
ballarin@13735
   220
lemma m_lcancel:
ballarin@13735
   221
  assumes prem: "(a::'a::domain) ~= 0" shows conc: "(a * b = a * c) = (b = c)"
ballarin@13735
   222
proof
ballarin@13735
   223
  assume eq: "a * b = a * c"
ballarin@13735
   224
  then have "a * (b - c) = 0" by simp
ballarin@13735
   225
  then have "a = 0 | (b - c) = 0" by (simp only: integral_iff)
ballarin@13735
   226
  with prem have "b - c = 0" by auto 
ballarin@13735
   227
  then have "b = b - (b - c)" by simp 
ballarin@13783
   228
  also have "b - (b - c) = c" by simp
ballarin@13735
   229
  finally show "b = c" .
ballarin@13735
   230
next
ballarin@13735
   231
  assume "b = c" then show "a * b = a * c" by simp
ballarin@13735
   232
qed
ballarin@13735
   233
ballarin@13735
   234
lemma m_rcancel:
ballarin@13735
   235
  "(a::'a::domain) ~= 0 ==> (b * a = c * a) = (b = c)"
ballarin@13735
   236
by (simp add: m_lcancel)
paulson@7998
   237
paulson@7998
   238
end