author  nipkow 
Wed, 28 Jan 2009 16:29:16 +0100  
changeset 29667  53103fc8ffa3 
parent 29233  ce6d35a0bed6 
child 30027  ab40c5e007e0 
child 30240  5b25fee0362c 
permissions  rwrr 
23252  1 
(* Title: HOL/Groebner_Basis.thy 
2 
Author: Amine Chaieb, TU Muenchen 

3 
*) 

4 

5 
header {* Semiring normalization and Groebner Bases *} 

28402  6 

23252  7 
theory Groebner_Basis 
28402  8 
imports Arith_Tools 
23252  9 
uses 
10 
"Tools/Groebner_Basis/misc.ML" 

11 
"Tools/Groebner_Basis/normalizer_data.ML" 

12 
("Tools/Groebner_Basis/normalizer.ML") 

23312  13 
("Tools/Groebner_Basis/groebner.ML") 
23252  14 
begin 
15 

16 
subsection {* Semiring normalization *} 

17 

18 
setup NormalizerData.setup 

19 

20 

23258
9062e98fdab1
renamed locale ring/semiring to gb_ring/gb_semiring to avoid clash with Ring_and_Field versions;
wenzelm
parents:
23252
diff
changeset

21 
locale gb_semiring = 
23252  22 
fixes add mul pwr r0 r1 
23 
assumes add_a:"(add x (add y z) = add (add x y) z)" 

24 
and add_c: "add x y = add y x" and add_0:"add r0 x = x" 

25 
and mul_a:"mul x (mul y z) = mul (mul x y) z" and mul_c:"mul x y = mul y x" 

26 
and mul_1:"mul r1 x = x" and mul_0:"mul r0 x = r0" 

27 
and mul_d:"mul x (add y z) = add (mul x y) (mul x z)" 

28 
and pwr_0:"pwr x 0 = r1" and pwr_Suc:"pwr x (Suc n) = mul x (pwr x n)" 

29 
begin 

30 

31 
lemma mul_pwr:"mul (pwr x p) (pwr x q) = pwr x (p + q)" 

32 
proof (induct p) 

33 
case 0 

34 
then show ?case by (auto simp add: pwr_0 mul_1) 

35 
next 

36 
case Suc 

37 
from this [symmetric] show ?case 

38 
by (auto simp add: pwr_Suc mul_1 mul_a) 

39 
qed 

40 

41 
lemma pwr_mul: "pwr (mul x y) q = mul (pwr x q) (pwr y q)" 

42 
proof (induct q arbitrary: x y, auto simp add:pwr_0 pwr_Suc mul_1) 

43 
fix q x y 

44 
assume "\<And>x y. pwr (mul x y) q = mul (pwr x q) (pwr y q)" 

45 
have "mul (mul x y) (mul (pwr x q) (pwr y q)) = mul x (mul y (mul (pwr x q) (pwr y q)))" 

46 
by (simp add: mul_a) 

47 
also have "\<dots> = (mul (mul y (mul (pwr y q) (pwr x q))) x)" by (simp add: mul_c) 

48 
also have "\<dots> = (mul (mul y (pwr y q)) (mul (pwr x q) x))" by (simp add: mul_a) 

49 
finally show "mul (mul x y) (mul (pwr x q) (pwr y q)) = 

50 
mul (mul x (pwr x q)) (mul y (pwr y q))" by (simp add: mul_c) 

51 
qed 

52 

53 
lemma pwr_pwr: "pwr (pwr x p) q = pwr x (p * q)" 

54 
proof (induct p arbitrary: q) 

55 
case 0 

56 
show ?case using pwr_Suc mul_1 pwr_0 by (induct q) auto 

57 
next 

58 
case Suc 

59 
thus ?case by (auto simp add: mul_pwr [symmetric] pwr_mul pwr_Suc) 

60 
qed 

61 

62 

63 
subsubsection {* Declaring the abstract theory *} 

64 

65 
lemma semiring_ops: 

66 
shows "TERM (add x y)" and "TERM (mul x y)" and "TERM (pwr x n)" 

28856
5e009a80fe6d
Pure syntax: more coherent treatment of aprop, permanent TERM and &&&;
wenzelm
parents:
28823
diff
changeset

67 
and "TERM r0" and "TERM r1" . 
23252  68 

69 
lemma semiring_rules: 

70 
"add (mul a m) (mul b m) = mul (add a b) m" 

71 
"add (mul a m) m = mul (add a r1) m" 

72 
"add m (mul a m) = mul (add a r1) m" 

73 
"add m m = mul (add r1 r1) m" 

74 
"add r0 a = a" 

75 
"add a r0 = a" 

76 
"mul a b = mul b a" 

77 
"mul (add a b) c = add (mul a c) (mul b c)" 

78 
"mul r0 a = r0" 

79 
"mul a r0 = r0" 

80 
"mul r1 a = a" 

81 
"mul a r1 = a" 

82 
"mul (mul lx ly) (mul rx ry) = mul (mul lx rx) (mul ly ry)" 

83 
"mul (mul lx ly) (mul rx ry) = mul lx (mul ly (mul rx ry))" 

84 
"mul (mul lx ly) (mul rx ry) = mul rx (mul (mul lx ly) ry)" 

85 
"mul (mul lx ly) rx = mul (mul lx rx) ly" 

86 
"mul (mul lx ly) rx = mul lx (mul ly rx)" 

87 
"mul lx (mul rx ry) = mul (mul lx rx) ry" 

88 
"mul lx (mul rx ry) = mul rx (mul lx ry)" 

89 
"add (add a b) (add c d) = add (add a c) (add b d)" 

90 
"add (add a b) c = add a (add b c)" 

91 
"add a (add c d) = add c (add a d)" 

92 
"add (add a b) c = add (add a c) b" 

93 
"add a c = add c a" 

94 
"add a (add c d) = add (add a c) d" 

95 
"mul (pwr x p) (pwr x q) = pwr x (p + q)" 

96 
"mul x (pwr x q) = pwr x (Suc q)" 

97 
"mul (pwr x q) x = pwr x (Suc q)" 

98 
"mul x x = pwr x 2" 

99 
"pwr (mul x y) q = mul (pwr x q) (pwr y q)" 

100 
"pwr (pwr x p) q = pwr x (p * q)" 

101 
"pwr x 0 = r1" 

102 
"pwr x 1 = x" 

103 
"mul x (add y z) = add (mul x y) (mul x z)" 

104 
"pwr x (Suc q) = mul x (pwr x q)" 

105 
"pwr x (2*n) = mul (pwr x n) (pwr x n)" 

106 
"pwr x (Suc (2*n)) = mul x (mul (pwr x n) (pwr x n))" 

107 
proof  

108 
show "add (mul a m) (mul b m) = mul (add a b) m" using mul_d mul_c by simp 

109 
next show"add (mul a m) m = mul (add a r1) m" using mul_d mul_c mul_1 by simp 

110 
next show "add m (mul a m) = mul (add a r1) m" using mul_c mul_d mul_1 add_c by simp 

111 
next show "add m m = mul (add r1 r1) m" using mul_c mul_d mul_1 by simp 

112 
next show "add r0 a = a" using add_0 by simp 

113 
next show "add a r0 = a" using add_0 add_c by simp 

114 
next show "mul a b = mul b a" using mul_c by simp 

115 
next show "mul (add a b) c = add (mul a c) (mul b c)" using mul_c mul_d by simp 

116 
next show "mul r0 a = r0" using mul_0 by simp 

117 
next show "mul a r0 = r0" using mul_0 mul_c by simp 

118 
next show "mul r1 a = a" using mul_1 by simp 

119 
next show "mul a r1 = a" using mul_1 mul_c by simp 

120 
next show "mul (mul lx ly) (mul rx ry) = mul (mul lx rx) (mul ly ry)" 

121 
using mul_c mul_a by simp 

122 
next show "mul (mul lx ly) (mul rx ry) = mul lx (mul ly (mul rx ry))" 

123 
using mul_a by simp 

124 
next 

125 
have "mul (mul lx ly) (mul rx ry) = mul (mul rx ry) (mul lx ly)" by (rule mul_c) 

126 
also have "\<dots> = mul rx (mul ry (mul lx ly))" using mul_a by simp 

127 
finally 

128 
show "mul (mul lx ly) (mul rx ry) = mul rx (mul (mul lx ly) ry)" 

129 
using mul_c by simp 

130 
next show "mul (mul lx ly) rx = mul (mul lx rx) ly" using mul_c mul_a by simp 

131 
next 

132 
show "mul (mul lx ly) rx = mul lx (mul ly rx)" by (simp add: mul_a) 

133 
next show "mul lx (mul rx ry) = mul (mul lx rx) ry" by (simp add: mul_a ) 

134 
next show "mul lx (mul rx ry) = mul rx (mul lx ry)" by (simp add: mul_a,simp add: mul_c) 

135 
next show "add (add a b) (add c d) = add (add a c) (add b d)" 

136 
using add_c add_a by simp 

137 
next show "add (add a b) c = add a (add b c)" using add_a by simp 

138 
next show "add a (add c d) = add c (add a d)" 

139 
apply (simp add: add_a) by (simp only: add_c) 

140 
next show "add (add a b) c = add (add a c) b" using add_a add_c by simp 

141 
next show "add a c = add c a" by (rule add_c) 

142 
next show "add a (add c d) = add (add a c) d" using add_a by simp 

143 
next show "mul (pwr x p) (pwr x q) = pwr x (p + q)" by (rule mul_pwr) 

144 
next show "mul x (pwr x q) = pwr x (Suc q)" using pwr_Suc by simp 

145 
next show "mul (pwr x q) x = pwr x (Suc q)" using pwr_Suc mul_c by simp 

146 
next show "mul x x = pwr x 2" by (simp add: nat_number pwr_Suc pwr_0 mul_1 mul_c) 

147 
next show "pwr (mul x y) q = mul (pwr x q) (pwr y q)" by (rule pwr_mul) 

148 
next show "pwr (pwr x p) q = pwr x (p * q)" by (rule pwr_pwr) 

149 
next show "pwr x 0 = r1" using pwr_0 . 

150 
next show "pwr x 1 = x" by (simp add: nat_number pwr_Suc pwr_0 mul_1 mul_c) 

151 
next show "mul x (add y z) = add (mul x y) (mul x z)" using mul_d by simp 

152 
next show "pwr x (Suc q) = mul x (pwr x q)" using pwr_Suc by simp 

153 
next show "pwr x (2 * n) = mul (pwr x n) (pwr x n)" by (simp add: nat_number mul_pwr) 

154 
next show "pwr x (Suc (2 * n)) = mul x (mul (pwr x n) (pwr x n))" 

155 
by (simp add: nat_number pwr_Suc mul_pwr) 

156 
qed 

157 

158 

26462  159 
lemmas gb_semiring_axioms' = 
26314  160 
gb_semiring_axioms [normalizer 
23252  161 
semiring ops: semiring_ops 
26314  162 
semiring rules: semiring_rules] 
23252  163 

164 
end 

165 

29233  166 
interpretation class_semiring!: gb_semiring 
29223  167 
"op +" "op *" "op ^" "0::'a::{comm_semiring_1, recpower}" "1" 
29667  168 
proof qed (auto simp add: algebra_simps power_Suc) 
23252  169 

170 
lemmas nat_arith = 

28987  171 
add_nat_number_of 
172 
diff_nat_number_of 

173 
mult_nat_number_of 

174 
eq_nat_number_of 

175 
less_nat_number_of 

23252  176 

177 
lemma not_iszero_Numeral1: "\<not> iszero (Numeral1::'a::number_ring)" 

178 
by (simp add: numeral_1_eq_1) 

28986  179 

29039  180 
lemmas comp_arith = 
181 
Let_def arith_simps nat_arith rel_simps neg_simps if_False 

23252  182 
if_True add_0 add_Suc add_number_of_left mult_number_of_left 
183 
numeral_1_eq_1[symmetric] Suc_eq_add_numeral_1 

28986  184 
numeral_0_eq_0[symmetric] numerals[symmetric] 
185 
iszero_simps not_iszero_Numeral1 

23252  186 

187 
lemmas semiring_norm = comp_arith 

188 

189 
ML {* 

23573  190 
local 
23252  191 

23573  192 
open Conv; 
193 

194 
fun numeral_is_const ct = 

195 
can HOLogic.dest_number (Thm.term_of ct); 

23252  196 

23573  197 
fun int_of_rat x = 
198 
(case Rat.quotient_of_rat x of (i, 1) => i 

199 
 _ => error "int_of_rat: bad int"); 

23252  200 

23573  201 
val numeral_conv = 
202 
Simplifier.rewrite (HOL_basic_ss addsimps @{thms semiring_norm}) then_conv 

203 
Simplifier.rewrite (HOL_basic_ss addsimps 

204 
(@{thms numeral_1_eq_1} @ @{thms numeral_0_eq_0} @ @{thms numerals(12)})); 

205 

206 
in 

207 

208 
fun normalizer_funs key = 

209 
NormalizerData.funs key 

23252  210 
{is_const = fn phi => numeral_is_const, 
211 
dest_const = fn phi => fn ct => 

212 
Rat.rat_of_int (snd 

213 
(HOLogic.dest_number (Thm.term_of ct) 

214 
handle TERM _ => error "ring_dest_const")), 

23573  215 
mk_const = fn phi => fn cT => fn x => Numeral.mk_cnumber cT (int_of_rat x), 
23330
01c09922ce59
Conversion for computation on constants now depends on the context
chaieb
parents:
23327
diff
changeset

216 
conv = fn phi => K numeral_conv} 
23573  217 

218 
end 

23252  219 
*} 
220 

26462  221 
declaration {* normalizer_funs @{thm class_semiring.gb_semiring_axioms'} *} 
23573  222 

23252  223 

23258
9062e98fdab1
renamed locale ring/semiring to gb_ring/gb_semiring to avoid clash with Ring_and_Field versions;
wenzelm
parents:
23252
diff
changeset

224 
locale gb_ring = gb_semiring + 
23252  225 
fixes sub :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" 
226 
and neg :: "'a \<Rightarrow> 'a" 

227 
assumes neg_mul: "neg x = mul (neg r1) x" 

228 
and sub_add: "sub x y = add x (neg y)" 

229 
begin 

230 

28856
5e009a80fe6d
Pure syntax: more coherent treatment of aprop, permanent TERM and &&&;
wenzelm
parents:
28823
diff
changeset

231 
lemma ring_ops: shows "TERM (sub x y)" and "TERM (neg x)" . 
23252  232 

233 
lemmas ring_rules = neg_mul sub_add 

234 

26462  235 
lemmas gb_ring_axioms' = 
26314  236 
gb_ring_axioms [normalizer 
237 
semiring ops: semiring_ops 

238 
semiring rules: semiring_rules 

239 
ring ops: ring_ops 

240 
ring rules: ring_rules] 

23252  241 

242 
end 

243 

244 

29233  245 
interpretation class_ring!: gb_ring "op +" "op *" "op ^" 
29223  246 
"0::'a::{comm_semiring_1,recpower,number_ring}" 1 "op " "uminus" 
28823  247 
proof qed simp_all 
23252  248 

249 

26462  250 
declaration {* normalizer_funs @{thm class_ring.gb_ring_axioms'} *} 
23252  251 

252 
use "Tools/Groebner_Basis/normalizer.ML" 

253 

27666  254 

23252  255 
method_setup sring_norm = {* 
256 
Method.ctxt_args (fn ctxt => Method.SIMPLE_METHOD' (Normalizer.semiring_normalize_tac ctxt)) 

23458  257 
*} "semiring normalizer" 
23252  258 

259 

23327  260 
locale gb_field = gb_ring + 
261 
fixes divide :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" 

262 
and inverse:: "'a \<Rightarrow> 'a" 

263 
assumes divide: "divide x y = mul x (inverse y)" 

264 
and inverse: "inverse x = divide r1 x" 

265 
begin 

266 

26462  267 
lemmas gb_field_axioms' = 
26314  268 
gb_field_axioms [normalizer 
269 
semiring ops: semiring_ops 

270 
semiring rules: semiring_rules 

271 
ring ops: ring_ops 

272 
ring rules: ring_rules] 

23327  273 

274 
end 

275 

23458  276 

23266  277 
subsection {* Groebner Bases *} 
23252  278 

23258
9062e98fdab1
renamed locale ring/semiring to gb_ring/gb_semiring to avoid clash with Ring_and_Field versions;
wenzelm
parents:
23252
diff
changeset

279 
locale semiringb = gb_semiring + 
23252  280 
assumes add_cancel: "add (x::'a) y = add x z \<longleftrightarrow> y = z" 
281 
and add_mul_solve: "add (mul w y) (mul x z) = 

282 
add (mul w z) (mul x y) \<longleftrightarrow> w = x \<or> y = z" 

283 
begin 

284 

285 
lemma noteq_reduce: "a \<noteq> b \<and> c \<noteq> d \<longleftrightarrow> add (mul a c) (mul b d) \<noteq> add (mul a d) (mul b c)" 

286 
proof 

287 
have "a \<noteq> b \<and> c \<noteq> d \<longleftrightarrow> \<not> (a = b \<or> c = d)" by simp 

288 
also have "\<dots> \<longleftrightarrow> add (mul a c) (mul b d) \<noteq> add (mul a d) (mul b c)" 

289 
using add_mul_solve by blast 

290 
finally show "a \<noteq> b \<and> c \<noteq> d \<longleftrightarrow> add (mul a c) (mul b d) \<noteq> add (mul a d) (mul b c)" 

291 
by simp 

292 
qed 

293 

294 
lemma add_scale_eq_noteq: "\<lbrakk>r \<noteq> r0 ; (a = b) \<and> ~(c = d)\<rbrakk> 

295 
\<Longrightarrow> add a (mul r c) \<noteq> add b (mul r d)" 

296 
proof(clarify) 

297 
assume nz: "r\<noteq> r0" and cnd: "c\<noteq>d" 

298 
and eq: "add b (mul r c) = add b (mul r d)" 

299 
hence "mul r c = mul r d" using cnd add_cancel by simp 

300 
hence "add (mul r0 d) (mul r c) = add (mul r0 c) (mul r d)" 

301 
using mul_0 add_cancel by simp 

302 
thus "False" using add_mul_solve nz cnd by simp 

303 
qed 

304 

25250
b3a485b98963
(1) added axiom to ringb and theorems to enable algebra to prove the ideal membership problem; (2) Method algebra now calls algebra_tac which first tries to solve a universal formula, then in case of failure trie to solve the ideal membership problem (see HOL/Tools/Groebner_Basis/groebner.ML)
chaieb
parents:
23573
diff
changeset

305 
lemma add_r0_iff: " x = add x a \<longleftrightarrow> a = r0" 
b3a485b98963
(1) added axiom to ringb and theorems to enable algebra to prove the ideal membership problem; (2) Method algebra now calls algebra_tac which first tries to solve a universal formula, then in case of failure trie to solve the ideal membership problem (see HOL/Tools/Groebner_Basis/groebner.ML)
chaieb
parents:
23573
diff
changeset

306 
proof 
b3a485b98963
(1) added axiom to ringb and theorems to enable algebra to prove the ideal membership problem; (2) Method algebra now calls algebra_tac which first tries to solve a universal formula, then in case of failure trie to solve the ideal membership problem (see HOL/Tools/Groebner_Basis/groebner.ML)
chaieb
parents:
23573
diff
changeset

307 
have "a = r0 \<longleftrightarrow> add x a = add x r0" by (simp add: add_cancel) 
b3a485b98963
(1) added axiom to ringb and theorems to enable algebra to prove the ideal membership problem; (2) Method algebra now calls algebra_tac which first tries to solve a universal formula, then in case of failure trie to solve the ideal membership problem (see HOL/Tools/Groebner_Basis/groebner.ML)
chaieb
parents:
23573
diff
changeset

308 
thus "x = add x a \<longleftrightarrow> a = r0" by (auto simp add: add_c add_0) 
b3a485b98963
(1) added axiom to ringb and theorems to enable algebra to prove the ideal membership problem; (2) Method algebra now calls algebra_tac which first tries to solve a universal formula, then in case of failure trie to solve the ideal membership problem (see HOL/Tools/Groebner_Basis/groebner.ML)
chaieb
parents:
23573
diff
changeset

309 
qed 
b3a485b98963
(1) added axiom to ringb and theorems to enable algebra to prove the ideal membership problem; (2) Method algebra now calls algebra_tac which first tries to solve a universal formula, then in case of failure trie to solve the ideal membership problem (see HOL/Tools/Groebner_Basis/groebner.ML)
chaieb
parents:
23573
diff
changeset

310 

26462  311 
declare gb_semiring_axioms' [normalizer del] 
23252  312 

26462  313 
lemmas semiringb_axioms' = semiringb_axioms [normalizer 
23252  314 
semiring ops: semiring_ops 
315 
semiring rules: semiring_rules 

26314  316 
idom rules: noteq_reduce add_scale_eq_noteq] 
23252  317 

318 
end 

319 

25250
b3a485b98963
(1) added axiom to ringb and theorems to enable algebra to prove the ideal membership problem; (2) Method algebra now calls algebra_tac which first tries to solve a universal formula, then in case of failure trie to solve the ideal membership problem (see HOL/Tools/Groebner_Basis/groebner.ML)
chaieb
parents:
23573
diff
changeset

320 
locale ringb = semiringb + gb_ring + 
b3a485b98963
(1) added axiom to ringb and theorems to enable algebra to prove the ideal membership problem; (2) Method algebra now calls algebra_tac which first tries to solve a universal formula, then in case of failure trie to solve the ideal membership problem (see HOL/Tools/Groebner_Basis/groebner.ML)
chaieb
parents:
23573
diff
changeset

321 
assumes subr0_iff: "sub x y = r0 \<longleftrightarrow> x = y" 
23252  322 
begin 
323 

26462  324 
declare gb_ring_axioms' [normalizer del] 
23252  325 

26462  326 
lemmas ringb_axioms' = ringb_axioms [normalizer 
23252  327 
semiring ops: semiring_ops 
328 
semiring rules: semiring_rules 

329 
ring ops: ring_ops 

330 
ring rules: ring_rules 

25250
b3a485b98963
(1) added axiom to ringb and theorems to enable algebra to prove the ideal membership problem; (2) Method algebra now calls algebra_tac which first tries to solve a universal formula, then in case of failure trie to solve the ideal membership problem (see HOL/Tools/Groebner_Basis/groebner.ML)
chaieb
parents:
23573
diff
changeset

331 
idom rules: noteq_reduce add_scale_eq_noteq 
26314  332 
ideal rules: subr0_iff add_r0_iff] 
23252  333 

334 
end 

335 

25250
b3a485b98963
(1) added axiom to ringb and theorems to enable algebra to prove the ideal membership problem; (2) Method algebra now calls algebra_tac which first tries to solve a universal formula, then in case of failure trie to solve the ideal membership problem (see HOL/Tools/Groebner_Basis/groebner.ML)
chaieb
parents:
23573
diff
changeset

336 

23252  337 
lemma no_zero_divirors_neq0: 
338 
assumes az: "(a::'a::no_zero_divisors) \<noteq> 0" 

339 
and ab: "a*b = 0" shows "b = 0" 

340 
proof  

341 
{ assume bz: "b \<noteq> 0" 

342 
from no_zero_divisors [OF az bz] ab have False by blast } 

343 
thus "b = 0" by blast 

344 
qed 

345 

29233  346 
interpretation class_ringb!: ringb 
29223  347 
"op +" "op *" "op ^" "0::'a::{idom,recpower,number_ring}" "1" "op " "uminus" 
29667  348 
proof(unfold_locales, simp add: algebra_simps power_Suc, auto) 
23252  349 
fix w x y z ::"'a::{idom,recpower,number_ring}" 
350 
assume p: "w * y + x * z = w * z + x * y" and ynz: "y \<noteq> z" 

351 
hence ynz': "y  z \<noteq> 0" by simp 

352 
from p have "w * y + x* z  w*z  x*y = 0" by simp 

29667  353 
hence "w* (y  z)  x * (y  z) = 0" by (simp add: algebra_simps) 
354 
hence "(y  z) * (w  x) = 0" by (simp add: algebra_simps) 

23252  355 
with no_zero_divirors_neq0 [OF ynz'] 
356 
have "w  x = 0" by blast 

357 
thus "w = x" by simp 

358 
qed 

359 

26462  360 
declaration {* normalizer_funs @{thm class_ringb.ringb_axioms'} *} 
23252  361 

29233  362 
interpretation natgb!: semiringb 
29223  363 
"op +" "op *" "op ^" "0::nat" "1" 
29667  364 
proof (unfold_locales, simp add: algebra_simps power_Suc) 
23252  365 
fix w x y z ::"nat" 
366 
{ assume p: "w * y + x * z = w * z + x * y" and ynz: "y \<noteq> z" 

367 
hence "y < z \<or> y > z" by arith 

368 
moreover { 

369 
assume lt:"y <z" hence "\<exists>k. z = y + k \<and> k > 0" by (rule_tac x="z  y" in exI, auto) 

370 
then obtain k where kp: "k>0" and yz:"z = y + k" by blast 

29667  371 
from p have "(w * y + x *y) + x*k = (w * y + x*y) + w*k" by (simp add: yz algebra_simps) 
23252  372 
hence "x*k = w*k" by simp 
373 
hence "w = x" using kp by (simp add: mult_cancel2) } 

374 
moreover { 

375 
assume lt: "y >z" hence "\<exists>k. y = z + k \<and> k>0" by (rule_tac x="y  z" in exI, auto) 

376 
then obtain k where kp: "k>0" and yz:"y = z + k" by blast 

29667  377 
from p have "(w * z + x *z) + w*k = (w * z + x*z) + x*k" by (simp add: yz algebra_simps) 
23252  378 
hence "w*k = x*k" by simp 
379 
hence "w = x" using kp by (simp add: mult_cancel2)} 

380 
ultimately have "w=x" by blast } 

381 
thus "(w * y + x * z = w * z + x * y) = (w = x \<or> y = z)" by auto 

382 
qed 

383 

26462  384 
declaration {* normalizer_funs @{thm natgb.semiringb_axioms'} *} 
23252  385 

23327  386 
locale fieldgb = ringb + gb_field 
387 
begin 

388 

26462  389 
declare gb_field_axioms' [normalizer del] 
23327  390 

26462  391 
lemmas fieldgb_axioms' = fieldgb_axioms [normalizer 
23327  392 
semiring ops: semiring_ops 
393 
semiring rules: semiring_rules 

394 
ring ops: ring_ops 

395 
ring rules: ring_rules 

25250
b3a485b98963
(1) added axiom to ringb and theorems to enable algebra to prove the ideal membership problem; (2) Method algebra now calls algebra_tac which first tries to solve a universal formula, then in case of failure trie to solve the ideal membership problem (see HOL/Tools/Groebner_Basis/groebner.ML)
chaieb
parents:
23573
diff
changeset

396 
idom rules: noteq_reduce add_scale_eq_noteq 
26314  397 
ideal rules: subr0_iff add_r0_iff] 
398 

23327  399 
end 
400 

401 

23258
9062e98fdab1
renamed locale ring/semiring to gb_ring/gb_semiring to avoid clash with Ring_and_Field versions;
wenzelm
parents:
23252
diff
changeset

402 
lemmas bool_simps = simp_thms(134) 
23252  403 
lemma dnf: 
404 
"(P & (Q  R)) = ((P&Q)  (P&R))" "((Q  R) & P) = ((Q&P)  (R&P))" 

405 
"(P \<and> Q) = (Q \<and> P)" "(P \<or> Q) = (Q \<or> P)" 

406 
by blast+ 

407 

408 
lemmas weak_dnf_simps = dnf bool_simps 

409 

410 
lemma nnf_simps: 

411 
"(\<not>(P \<and> Q)) = (\<not>P \<or> \<not>Q)" "(\<not>(P \<or> Q)) = (\<not>P \<and> \<not>Q)" "(P \<longrightarrow> Q) = (\<not>P \<or> Q)" 

412 
"(P = Q) = ((P \<and> Q) \<or> (\<not>P \<and> \<not> Q))" "(\<not> \<not>(P)) = P" 

413 
by blast+ 

414 

415 
lemma PFalse: 

416 
"P \<equiv> False \<Longrightarrow> \<not> P" 

417 
"\<not> P \<Longrightarrow> (P \<equiv> False)" 

418 
by auto 

419 
use "Tools/Groebner_Basis/groebner.ML" 

420 

23332
b91295432e6d
algebra_tac moved to file Tools/Groebner_Basis/groebner.ML; Method now takes theorems to be added or deleted from a simpset for simplificatio *before* the core method starts
chaieb
parents:
23330
diff
changeset

421 
method_setup algebra = 
23458  422 
{* 
23332
b91295432e6d
algebra_tac moved to file Tools/Groebner_Basis/groebner.ML; Method now takes theorems to be added or deleted from a simpset for simplificatio *before* the core method starts
chaieb
parents:
23330
diff
changeset

423 
let 
b91295432e6d
algebra_tac moved to file Tools/Groebner_Basis/groebner.ML; Method now takes theorems to be added or deleted from a simpset for simplificatio *before* the core method starts
chaieb
parents:
23330
diff
changeset

424 
fun keyword k = Scan.lift (Args.$$$ k  Args.colon) >> K () 
b91295432e6d
algebra_tac moved to file Tools/Groebner_Basis/groebner.ML; Method now takes theorems to be added or deleted from a simpset for simplificatio *before* the core method starts
chaieb
parents:
23330
diff
changeset

425 
val addN = "add" 
b91295432e6d
algebra_tac moved to file Tools/Groebner_Basis/groebner.ML; Method now takes theorems to be added or deleted from a simpset for simplificatio *before* the core method starts
chaieb
parents:
23330
diff
changeset

426 
val delN = "del" 
b91295432e6d
algebra_tac moved to file Tools/Groebner_Basis/groebner.ML; Method now takes theorems to be added or deleted from a simpset for simplificatio *before* the core method starts
chaieb
parents:
23330
diff
changeset

427 
val any_keyword = keyword addN  keyword delN 
b91295432e6d
algebra_tac moved to file Tools/Groebner_Basis/groebner.ML; Method now takes theorems to be added or deleted from a simpset for simplificatio *before* the core method starts
chaieb
parents:
23330
diff
changeset

428 
val thms = Scan.repeat (Scan.unless any_keyword Attrib.multi_thm) >> flat; 
b91295432e6d
algebra_tac moved to file Tools/Groebner_Basis/groebner.ML; Method now takes theorems to be added or deleted from a simpset for simplificatio *before* the core method starts
chaieb
parents:
23330
diff
changeset

429 
in 
b91295432e6d
algebra_tac moved to file Tools/Groebner_Basis/groebner.ML; Method now takes theorems to be added or deleted from a simpset for simplificatio *before* the core method starts
chaieb
parents:
23330
diff
changeset

430 
fn src => Method.syntax 
b91295432e6d
algebra_tac moved to file Tools/Groebner_Basis/groebner.ML; Method now takes theorems to be added or deleted from a simpset for simplificatio *before* the core method starts
chaieb
parents:
23330
diff
changeset

431 
((Scan.optional (keyword addN  thms) [])  
b91295432e6d
algebra_tac moved to file Tools/Groebner_Basis/groebner.ML; Method now takes theorems to be added or deleted from a simpset for simplificatio *before* the core method starts
chaieb
parents:
23330
diff
changeset

432 
(Scan.optional (keyword delN  thms) [])) src 
b91295432e6d
algebra_tac moved to file Tools/Groebner_Basis/groebner.ML; Method now takes theorems to be added or deleted from a simpset for simplificatio *before* the core method starts
chaieb
parents:
23330
diff
changeset

433 
#> (fn ((add_ths, del_ths), ctxt) => 
25250
b3a485b98963
(1) added axiom to ringb and theorems to enable algebra to prove the ideal membership problem; (2) Method algebra now calls algebra_tac which first tries to solve a universal formula, then in case of failure trie to solve the ideal membership problem (see HOL/Tools/Groebner_Basis/groebner.ML)
chaieb
parents:
23573
diff
changeset

434 
Method.SIMPLE_METHOD' (Groebner.algebra_tac add_ths del_ths ctxt)) 
23332
b91295432e6d
algebra_tac moved to file Tools/Groebner_Basis/groebner.ML; Method now takes theorems to be added or deleted from a simpset for simplificatio *before* the core method starts
chaieb
parents:
23330
diff
changeset

435 
end 
25250
b3a485b98963
(1) added axiom to ringb and theorems to enable algebra to prove the ideal membership problem; (2) Method algebra now calls algebra_tac which first tries to solve a universal formula, then in case of failure trie to solve the ideal membership problem (see HOL/Tools/Groebner_Basis/groebner.ML)
chaieb
parents:
23573
diff
changeset

436 
*} "solve polynomial equations over (semi)rings and ideal membership problems using Groebner bases" 
27666  437 
declare dvd_def[algebra] 
438 
declare dvd_eq_mod_eq_0[symmetric, algebra] 

439 
declare nat_mod_div_trivial[algebra] 

440 
declare nat_mod_mod_trivial[algebra] 

441 
declare conjunct1[OF DIVISION_BY_ZERO, algebra] 

442 
declare conjunct2[OF DIVISION_BY_ZERO, algebra] 

443 
declare zmod_zdiv_equality[symmetric,algebra] 

444 
declare zdiv_zmod_equality[symmetric, algebra] 

445 
declare zdiv_zminus_zminus[algebra] 

446 
declare zmod_zminus_zminus[algebra] 

447 
declare zdiv_zminus2[algebra] 

448 
declare zmod_zminus2[algebra] 

449 
declare zdiv_zero[algebra] 

450 
declare zmod_zero[algebra] 

451 
declare zmod_1[algebra] 

452 
declare zdiv_1[algebra] 

453 
declare zmod_minus1_right[algebra] 

454 
declare zdiv_minus1_right[algebra] 

455 
declare mod_div_trivial[algebra] 

456 
declare mod_mod_trivial[algebra] 

457 
declare zmod_zmult_self1[algebra] 

458 
declare zmod_zmult_self2[algebra] 

459 
declare zmod_eq_0_iff[algebra] 

460 
declare zdvd_0_left[algebra] 

461 
declare zdvd1_eq[algebra] 

462 
declare zmod_eq_dvd_iff[algebra] 

463 
declare nat_mod_eq_iff[algebra] 

23252  464 

28402  465 
subsection{* Groebner Bases for fields *} 
466 

29233  467 
interpretation class_fieldgb!: 
29223  468 
fieldgb "op +" "op *" "op ^" "0::'a::{field,recpower,number_ring}" "1" "op " "uminus" "op /" "inverse" apply (unfold_locales) by (simp_all add: divide_inverse) 
28402  469 

470 
lemma divide_Numeral1: "(x::'a::{field,number_ring}) / Numeral1 = x" by simp 

471 
lemma divide_Numeral0: "(x::'a::{field,number_ring, division_by_zero}) / Numeral0 = 0" 

472 
by simp 

473 
lemma mult_frac_frac: "((x::'a::{field,division_by_zero}) / y) * (z / w) = (x*z) / (y*w)" 

474 
by simp 

475 
lemma mult_frac_num: "((x::'a::{field, division_by_zero}) / y) * z = (x*z) / y" 

476 
by simp 

477 
lemma mult_num_frac: "((x::'a::{field, division_by_zero}) / y) * z = (x*z) / y" 

478 
by simp 

479 

480 
lemma Numeral1_eq1_nat: "(1::nat) = Numeral1" by simp 

481 

482 
lemma add_frac_num: "y\<noteq> 0 \<Longrightarrow> (x::'a::{field, division_by_zero}) / y + z = (x + z*y) / y" 

483 
by (simp add: add_divide_distrib) 

484 
lemma add_num_frac: "y\<noteq> 0 \<Longrightarrow> z + (x::'a::{field, division_by_zero}) / y = (x + z*y) / y" 

485 
by (simp add: add_divide_distrib) 

486 

487 

488 
ML{* 

489 
local 

490 
val zr = @{cpat "0"} 

491 
val zT = ctyp_of_term zr 

492 
val geq = @{cpat "op ="} 

493 
val eqT = Thm.dest_ctyp (ctyp_of_term geq) > hd 

494 
val add_frac_eq = mk_meta_eq @{thm "add_frac_eq"} 

495 
val add_frac_num = mk_meta_eq @{thm "add_frac_num"} 

496 
val add_num_frac = mk_meta_eq @{thm "add_num_frac"} 

497 

498 
fun prove_nz ss T t = 

499 
let 

500 
val z = instantiate_cterm ([(zT,T)],[]) zr 

501 
val eq = instantiate_cterm ([(eqT,T)],[]) geq 

502 
val th = Simplifier.rewrite (ss addsimps simp_thms) 

503 
(Thm.capply @{cterm "Trueprop"} (Thm.capply @{cterm "Not"} 

504 
(Thm.capply (Thm.capply eq t) z))) 

505 
in equal_elim (symmetric th) TrueI 

506 
end 

507 

508 
fun proc phi ss ct = 

509 
let 

510 
val ((x,y),(w,z)) = 

511 
(Thm.dest_binop #> (fn (a,b) => (Thm.dest_binop a, Thm.dest_binop b))) ct 

512 
val _ = map (HOLogic.dest_number o term_of) [x,y,z,w] 

513 
val T = ctyp_of_term x 

514 
val [y_nz, z_nz] = map (prove_nz ss T) [y, z] 

515 
val th = instantiate' [SOME T] (map SOME [y,z,x,w]) add_frac_eq 

516 
in SOME (implies_elim (implies_elim th y_nz) z_nz) 

517 
end 

518 
handle CTERM _ => NONE  TERM _ => NONE  THM _ => NONE 

519 

520 
fun proc2 phi ss ct = 

521 
let 

522 
val (l,r) = Thm.dest_binop ct 

523 
val T = ctyp_of_term l 

524 
in (case (term_of l, term_of r) of 

525 
(Const(@{const_name "HOL.divide"},_)$_$_, _) => 

526 
let val (x,y) = Thm.dest_binop l val z = r 

527 
val _ = map (HOLogic.dest_number o term_of) [x,y,z] 

528 
val ynz = prove_nz ss T y 

529 
in SOME (implies_elim (instantiate' [SOME T] (map SOME [y,x,z]) add_frac_num) ynz) 

530 
end 

531 
 (_, Const (@{const_name "HOL.divide"},_)$_$_) => 

532 
let val (x,y) = Thm.dest_binop r val z = l 

533 
val _ = map (HOLogic.dest_number o term_of) [x,y,z] 

534 
val ynz = prove_nz ss T y 

535 
in SOME (implies_elim (instantiate' [SOME T] (map SOME [y,z,x]) add_num_frac) ynz) 

536 
end 

537 
 _ => NONE) 

538 
end 

539 
handle CTERM _ => NONE  TERM _ => NONE  THM _ => NONE 

540 

541 
fun is_number (Const(@{const_name "HOL.divide"},_)$a$b) = is_number a andalso is_number b 

542 
 is_number t = can HOLogic.dest_number t 

543 

544 
val is_number = is_number o term_of 

545 

546 
fun proc3 phi ss ct = 

547 
(case term_of ct of 

548 
Const(@{const_name HOL.less},_)$(Const(@{const_name "HOL.divide"},_)$_$_)$_ => 

549 
let 

550 
val ((a,b),c) = Thm.dest_binop ct >> Thm.dest_binop 

551 
val _ = map is_number [a,b,c] 

552 
val T = ctyp_of_term c 

553 
val th = instantiate' [SOME T] (map SOME [a,b,c]) @{thm "divide_less_eq"} 

554 
in SOME (mk_meta_eq th) end 

555 
 Const(@{const_name HOL.less_eq},_)$(Const(@{const_name "HOL.divide"},_)$_$_)$_ => 

556 
let 

557 
val ((a,b),c) = Thm.dest_binop ct >> Thm.dest_binop 

558 
val _ = map is_number [a,b,c] 

559 
val T = ctyp_of_term c 

560 
val th = instantiate' [SOME T] (map SOME [a,b,c]) @{thm "divide_le_eq"} 

561 
in SOME (mk_meta_eq th) end 

562 
 Const("op =",_)$(Const(@{const_name "HOL.divide"},_)$_$_)$_ => 

563 
let 

564 
val ((a,b),c) = Thm.dest_binop ct >> Thm.dest_binop 

565 
val _ = map is_number [a,b,c] 

566 
val T = ctyp_of_term c 

567 
val th = instantiate' [SOME T] (map SOME [a,b,c]) @{thm "divide_eq_eq"} 

568 
in SOME (mk_meta_eq th) end 

569 
 Const(@{const_name HOL.less},_)$_$(Const(@{const_name "HOL.divide"},_)$_$_) => 

570 
let 

571 
val (a,(b,c)) = Thm.dest_binop ct > Thm.dest_binop 

572 
val _ = map is_number [a,b,c] 

573 
val T = ctyp_of_term c 

574 
val th = instantiate' [SOME T] (map SOME [a,b,c]) @{thm "less_divide_eq"} 

575 
in SOME (mk_meta_eq th) end 

576 
 Const(@{const_name HOL.less_eq},_)$_$(Const(@{const_name "HOL.divide"},_)$_$_) => 

577 
let 

578 
val (a,(b,c)) = Thm.dest_binop ct > Thm.dest_binop 

579 
val _ = map is_number [a,b,c] 

580 
val T = ctyp_of_term c 

581 
val th = instantiate' [SOME T] (map SOME [a,b,c]) @{thm "le_divide_eq"} 

582 
in SOME (mk_meta_eq th) end 

583 
 Const("op =",_)$_$(Const(@{const_name "HOL.divide"},_)$_$_) => 

584 
let 

585 
val (a,(b,c)) = Thm.dest_binop ct > Thm.dest_binop 

586 
val _ = map is_number [a,b,c] 

587 
val T = ctyp_of_term c 

588 
val th = instantiate' [SOME T] (map SOME [a,b,c]) @{thm "eq_divide_eq"} 

589 
in SOME (mk_meta_eq th) end 

590 
 _ => NONE) 

591 
handle TERM _ => NONE  CTERM _ => NONE  THM _ => NONE 

592 

593 
val add_frac_frac_simproc = 

594 
make_simproc {lhss = [@{cpat "(?x::?'a::field)/?y + (?w::?'a::field)/?z"}], 

595 
name = "add_frac_frac_simproc", 

596 
proc = proc, identifier = []} 

597 

598 
val add_frac_num_simproc = 

599 
make_simproc {lhss = [@{cpat "(?x::?'a::field)/?y + ?z"}, @{cpat "?z + (?x::?'a::field)/?y"}], 

600 
name = "add_frac_num_simproc", 

601 
proc = proc2, identifier = []} 

602 

603 
val ord_frac_simproc = 

604 
make_simproc 

605 
{lhss = [@{cpat "(?a::(?'a::{field, ord}))/?b < ?c"}, 

606 
@{cpat "(?a::(?'a::{field, ord}))/?b \<le> ?c"}, 

607 
@{cpat "?c < (?a::(?'a::{field, ord}))/?b"}, 

608 
@{cpat "?c \<le> (?a::(?'a::{field, ord}))/?b"}, 

609 
@{cpat "?c = ((?a::(?'a::{field, ord}))/?b)"}, 

610 
@{cpat "((?a::(?'a::{field, ord}))/ ?b) = ?c"}], 

611 
name = "ord_frac_simproc", proc = proc3, identifier = []} 

612 

613 
val ths = [@{thm "mult_numeral_1"}, @{thm "mult_numeral_1_right"}, 

614 
@{thm "divide_Numeral1"}, 

615 
@{thm "Ring_and_Field.divide_zero"}, @{thm "divide_Numeral0"}, 

616 
@{thm "divide_divide_eq_left"}, @{thm "mult_frac_frac"}, 

617 
@{thm "mult_num_frac"}, @{thm "mult_frac_num"}, 

618 
@{thm "mult_frac_frac"}, @{thm "times_divide_eq_right"}, 

619 
@{thm "times_divide_eq_left"}, @{thm "divide_divide_eq_right"}, 

620 
@{thm "diff_def"}, @{thm "minus_divide_left"}, 

621 
@{thm "Numeral1_eq1_nat"}, @{thm "add_divide_distrib"} RS sym] 

622 

623 
local 

624 
open Conv 

625 
in 

626 
val comp_conv = (Simplifier.rewrite 

627 
(HOL_basic_ss addsimps @{thms "Groebner_Basis.comp_arith"} 

28987  628 
addsimps ths addsimps simp_thms 
28402  629 
addsimprocs field_cancel_numeral_factors 
630 
addsimprocs [add_frac_frac_simproc, add_frac_num_simproc, 

631 
ord_frac_simproc] 

632 
addcongs [@{thm "if_weak_cong"}])) 

633 
then_conv (Simplifier.rewrite (HOL_basic_ss addsimps 

634 
[@{thm numeral_1_eq_1},@{thm numeral_0_eq_0}] @ @{thms numerals(12)})) 

23252  635 
end 
28402  636 

637 
fun numeral_is_const ct = 

638 
case term_of ct of 

639 
Const (@{const_name "HOL.divide"},_) $ a $ b => 

640 
numeral_is_const (Thm.dest_arg1 ct) andalso numeral_is_const (Thm.dest_arg ct) 

641 
 Const (@{const_name "HOL.uminus"},_)$t => numeral_is_const (Thm.dest_arg ct) 

642 
 t => can HOLogic.dest_number t 

643 

644 
fun dest_const ct = ((case term_of ct of 

645 
Const (@{const_name "HOL.divide"},_) $ a $ b=> 

646 
Rat.rat_of_quotient (snd (HOLogic.dest_number a), snd (HOLogic.dest_number b)) 

647 
 t => Rat.rat_of_int (snd (HOLogic.dest_number t))) 

648 
handle TERM _ => error "ring_dest_const") 

649 

650 
fun mk_const phi cT x = 

651 
let val (a, b) = Rat.quotient_of_rat x 

652 
in if b = 1 then Numeral.mk_cnumber cT a 

653 
else Thm.capply 

654 
(Thm.capply (Drule.cterm_rule (instantiate' [SOME cT] []) @{cpat "op /"}) 

655 
(Numeral.mk_cnumber cT a)) 

656 
(Numeral.mk_cnumber cT b) 

657 
end 

658 

659 
in 

660 
val field_comp_conv = comp_conv; 

661 
val fieldgb_declaration = 

662 
NormalizerData.funs @{thm class_fieldgb.fieldgb_axioms'} 

663 
{is_const = K numeral_is_const, 

664 
dest_const = K dest_const, 

665 
mk_const = mk_const, 

666 
conv = K (K comp_conv)} 

667 
end; 

668 
*} 

669 

670 
declaration fieldgb_declaration 

671 

672 
end 