author  wenzelm 
Thu, 20 Nov 2008 00:03:47 +0100  
changeset 28856  5e009a80fe6d 
parent 28823  dcbef866c9e2 
child 28986  1ff53ff7041d 
permissions  rwrr 
23252  1 
(* Title: HOL/Groebner_Basis.thy 
2 
ID: $Id$ 

3 
Author: Amine Chaieb, TU Muenchen 

4 
*) 

5 

6 
header {* Semiring normalization and Groebner Bases *} 

28402  7 

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

12 
"Tools/Groebner_Basis/normalizer_data.ML" 

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

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

17 
subsection {* Semiring normalization *} 

18 

19 
setup NormalizerData.setup 

20 

21 

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

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

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

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

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

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

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

30 
begin 

31 

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

33 
proof (induct p) 

34 
case 0 

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

36 
next 

37 
case Suc 

38 
from this [symmetric] show ?case 

39 
by (auto simp add: pwr_Suc mul_1 mul_a) 

40 
qed 

41 

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

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

44 
fix q x y 

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

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

47 
by (simp add: mul_a) 

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

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

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

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

52 
qed 

53 

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

55 
proof (induct p arbitrary: q) 

56 
case 0 

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

58 
next 

59 
case Suc 

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

61 
qed 

62 

63 

64 
subsubsection {* Declaring the abstract theory *} 

65 

66 
lemma semiring_ops: 

67 
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

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

70 
lemma semiring_rules: 

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

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

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

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

75 
"add r0 a = a" 

76 
"add a r0 = a" 

77 
"mul a b = mul b a" 

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

79 
"mul r0 a = r0" 

80 
"mul a r0 = r0" 

81 
"mul r1 a = a" 

82 
"mul a r1 = a" 

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

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

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

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

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

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

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

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

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

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

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

94 
"add a c = add c a" 

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

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

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

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

99 
"mul x x = pwr x 2" 

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

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

102 
"pwr x 0 = r1" 

103 
"pwr x 1 = x" 

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

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

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

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

108 
proof  

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

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

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

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

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

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

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

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

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

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

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

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

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

122 
using mul_c mul_a by simp 

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

124 
using mul_a by simp 

125 
next 

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

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

128 
finally 

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

130 
using mul_c by simp 

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

132 
next 

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

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

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

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

137 
using add_c add_a by simp 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

156 
by (simp add: nat_number pwr_Suc mul_pwr) 

157 
qed 

158 

159 

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

165 
end 

166 

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

167 
interpretation class_semiring: gb_semiring 
23252  168 
["op +" "op *" "op ^" "0::'a::{comm_semiring_1, recpower}" "1"] 
28823  169 
proof qed (auto simp add: ring_simps power_Suc) 
23252  170 

171 
lemmas nat_arith = 

172 
add_nat_number_of diff_nat_number_of mult_nat_number_of eq_nat_number_of less_nat_number_of 

173 

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

175 
by (simp add: numeral_1_eq_1) 

176 
lemmas comp_arith = Let_def arith_simps nat_arith rel_simps if_False 

177 
if_True add_0 add_Suc add_number_of_left mult_number_of_left 

178 
numeral_1_eq_1[symmetric] Suc_eq_add_numeral_1 

179 
numeral_0_eq_0[symmetric] numerals[symmetric] not_iszero_1 

26086
3c243098b64a
New simpler representation of numerals, using Bit0 and Bit1 instead of BIT, B0, and B1
huffman
parents:
25250
diff
changeset

180 
iszero_number_of_Bit1 iszero_number_of_Bit0 nonzero_number_of_Min 
23252  181 
iszero_number_of_Pls iszero_0 not_iszero_Numeral1 
182 

183 
lemmas semiring_norm = comp_arith 

184 

185 
ML {* 

23573  186 
local 
23252  187 

23573  188 
open Conv; 
189 

190 
fun numeral_is_const ct = 

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

23252  192 

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

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

23252  196 

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

199 
Simplifier.rewrite (HOL_basic_ss addsimps 

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

201 

202 
in 

203 

204 
fun normalizer_funs key = 

205 
NormalizerData.funs key 

23252  206 
{is_const = fn phi => numeral_is_const, 
207 
dest_const = fn phi => fn ct => 

208 
Rat.rat_of_int (snd 

209 
(HOLogic.dest_number (Thm.term_of ct) 

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

23573  211 
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

212 
conv = fn phi => K numeral_conv} 
23573  213 

214 
end 

23252  215 
*} 
216 

26462  217 
declaration {* normalizer_funs @{thm class_semiring.gb_semiring_axioms'} *} 
23573  218 

23252  219 

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

220 
locale gb_ring = gb_semiring + 
23252  221 
fixes sub :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" 
222 
and neg :: "'a \<Rightarrow> 'a" 

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

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

225 
begin 

226 

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

227 
lemma ring_ops: shows "TERM (sub x y)" and "TERM (neg x)" . 
23252  228 

229 
lemmas ring_rules = neg_mul sub_add 

230 

26462  231 
lemmas gb_ring_axioms' = 
26314  232 
gb_ring_axioms [normalizer 
233 
semiring ops: semiring_ops 

234 
semiring rules: semiring_rules 

235 
ring ops: ring_ops 

236 
ring rules: ring_rules] 

23252  237 

238 
end 

239 

240 

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

241 
interpretation class_ring: gb_ring ["op +" "op *" "op ^" 
23252  242 
"0::'a::{comm_semiring_1,recpower,number_ring}" 1 "op " "uminus"] 
28823  243 
proof qed simp_all 
23252  244 

245 

26462  246 
declaration {* normalizer_funs @{thm class_ring.gb_ring_axioms'} *} 
23252  247 

248 
use "Tools/Groebner_Basis/normalizer.ML" 

249 

27666  250 

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

23458  253 
*} "semiring normalizer" 
23252  254 

255 

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

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

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

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

261 
begin 

262 

26462  263 
lemmas gb_field_axioms' = 
26314  264 
gb_field_axioms [normalizer 
265 
semiring ops: semiring_ops 

266 
semiring rules: semiring_rules 

267 
ring ops: ring_ops 

268 
ring rules: ring_rules] 

23327  269 

270 
end 

271 

23458  272 

23266  273 
subsection {* Groebner Bases *} 
23252  274 

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

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

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

279 
begin 

280 

281 
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)" 

282 
proof 

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

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

285 
using add_mul_solve by blast 

286 
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)" 

287 
by simp 

288 
qed 

289 

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

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

292 
proof(clarify) 

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

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

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

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

297 
using mul_0 add_cancel by simp 

298 
thus "False" using add_mul_solve nz cnd by simp 

299 
qed 

300 

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

301 
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

302 
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

303 
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

304 
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

305 
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

306 

26462  307 
declare gb_semiring_axioms' [normalizer del] 
23252  308 

26462  309 
lemmas semiringb_axioms' = semiringb_axioms [normalizer 
23252  310 
semiring ops: semiring_ops 
311 
semiring rules: semiring_rules 

26314  312 
idom rules: noteq_reduce add_scale_eq_noteq] 
23252  313 

314 
end 

315 

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

316 
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

317 
assumes subr0_iff: "sub x y = r0 \<longleftrightarrow> x = y" 
23252  318 
begin 
319 

26462  320 
declare gb_ring_axioms' [normalizer del] 
23252  321 

26462  322 
lemmas ringb_axioms' = ringb_axioms [normalizer 
23252  323 
semiring ops: semiring_ops 
324 
semiring rules: semiring_rules 

325 
ring ops: ring_ops 

326 
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

327 
idom rules: noteq_reduce add_scale_eq_noteq 
26314  328 
ideal rules: subr0_iff add_r0_iff] 
23252  329 

330 
end 

331 

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

332 

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

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

336 
proof  

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

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

339 
thus "b = 0" by blast 

340 
qed 

341 

342 
interpretation class_ringb: ringb 

343 
["op +" "op *" "op ^" "0::'a::{idom,recpower,number_ring}" "1" "op " "uminus"] 

23477
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
nipkow
parents:
23458
diff
changeset

344 
proof(unfold_locales, simp add: ring_simps power_Suc, auto) 
23252  345 
fix w x y z ::"'a::{idom,recpower,number_ring}" 
346 
assume p: "w * y + x * z = w * z + x * y" and ynz: "y \<noteq> z" 

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

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

23477
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
nipkow
parents:
23458
diff
changeset

349 
hence "w* (y  z)  x * (y  z) = 0" by (simp add: ring_simps) 
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
nipkow
parents:
23458
diff
changeset

350 
hence "(y  z) * (w  x) = 0" by (simp add: ring_simps) 
23252  351 
with no_zero_divirors_neq0 [OF ynz'] 
352 
have "w  x = 0" by blast 

353 
thus "w = x" by simp 

354 
qed 

355 

26462  356 
declaration {* normalizer_funs @{thm class_ringb.ringb_axioms'} *} 
23252  357 

358 
interpretation natgb: semiringb 

359 
["op +" "op *" "op ^" "0::nat" "1"] 

23477
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
nipkow
parents:
23458
diff
changeset

360 
proof (unfold_locales, simp add: ring_simps power_Suc) 
23252  361 
fix w x y z ::"nat" 
362 
{ assume p: "w * y + x * z = w * z + x * y" and ynz: "y \<noteq> z" 

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

364 
moreover { 

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

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

23477
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
nipkow
parents:
23458
diff
changeset

367 
from p have "(w * y + x *y) + x*k = (w * y + x*y) + w*k" by (simp add: yz ring_simps) 
23252  368 
hence "x*k = w*k" by simp 
369 
hence "w = x" using kp by (simp add: mult_cancel2) } 

370 
moreover { 

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

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

23477
f4b83f03cac9
tuned and renamed group_eq_simps and ring_eq_simps
nipkow
parents:
23458
diff
changeset

373 
from p have "(w * z + x *z) + w*k = (w * z + x*z) + x*k" by (simp add: yz ring_simps) 
23252  374 
hence "w*k = x*k" by simp 
375 
hence "w = x" using kp by (simp add: mult_cancel2)} 

376 
ultimately have "w=x" by blast } 

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

378 
qed 

379 

26462  380 
declaration {* normalizer_funs @{thm natgb.semiringb_axioms'} *} 
23252  381 

23327  382 
locale fieldgb = ringb + gb_field 
383 
begin 

384 

26462  385 
declare gb_field_axioms' [normalizer del] 
23327  386 

26462  387 
lemmas fieldgb_axioms' = fieldgb_axioms [normalizer 
23327  388 
semiring ops: semiring_ops 
389 
semiring rules: semiring_rules 

390 
ring ops: ring_ops 

391 
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

392 
idom rules: noteq_reduce add_scale_eq_noteq 
26314  393 
ideal rules: subr0_iff add_r0_iff] 
394 

23327  395 
end 
396 

397 

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

398 
lemmas bool_simps = simp_thms(134) 
23252  399 
lemma dnf: 
400 
"(P & (Q  R)) = ((P&Q)  (P&R))" "((Q  R) & P) = ((Q&P)  (R&P))" 

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

402 
by blast+ 

403 

404 
lemmas weak_dnf_simps = dnf bool_simps 

405 

406 
lemma nnf_simps: 

407 
"(\<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)" 

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

409 
by blast+ 

410 

411 
lemma PFalse: 

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

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

414 
by auto 

415 
use "Tools/Groebner_Basis/groebner.ML" 

416 

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

417 
method_setup algebra = 
23458  418 
{* 
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

419 
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

420 
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

421 
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

422 
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

423 
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

424 
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

425 
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

426 
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

427 
((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

428 
(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

429 
#> (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

430 
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

431 
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

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

435 
declare nat_mod_div_trivial[algebra] 

436 
declare nat_mod_mod_trivial[algebra] 

437 
declare conjunct1[OF DIVISION_BY_ZERO, algebra] 

438 
declare conjunct2[OF DIVISION_BY_ZERO, algebra] 

439 
declare zmod_zdiv_equality[symmetric,algebra] 

440 
declare zdiv_zmod_equality[symmetric, algebra] 

441 
declare zdiv_zminus_zminus[algebra] 

442 
declare zmod_zminus_zminus[algebra] 

443 
declare zdiv_zminus2[algebra] 

444 
declare zmod_zminus2[algebra] 

445 
declare zdiv_zero[algebra] 

446 
declare zmod_zero[algebra] 

447 
declare zmod_1[algebra] 

448 
declare zdiv_1[algebra] 

449 
declare zmod_minus1_right[algebra] 

450 
declare zdiv_minus1_right[algebra] 

451 
declare mod_div_trivial[algebra] 

452 
declare mod_mod_trivial[algebra] 

453 
declare zmod_zmult_self1[algebra] 

454 
declare zmod_zmult_self2[algebra] 

455 
declare zmod_eq_0_iff[algebra] 

456 
declare zdvd_0_left[algebra] 

457 
declare zdvd1_eq[algebra] 

458 
declare zmod_eq_dvd_iff[algebra] 

459 
declare nat_mod_eq_iff[algebra] 

23252  460 

28402  461 

462 
subsection{* Groebner Bases for fields *} 

463 

464 
interpretation class_fieldgb: 

465 
fieldgb["op +" "op *" "op ^" "0::'a::{field,recpower,number_ring}" "1" "op " "uminus" "op /" "inverse"] apply (unfold_locales) by (simp_all add: divide_inverse) 

466 

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

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

469 
by simp 

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

471 
by simp 

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

473 
by simp 

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

475 
by simp 

476 

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

478 

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

480 
by (simp add: add_divide_distrib) 

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

482 
by (simp add: add_divide_distrib) 

483 

484 

485 
ML{* 

486 
local 

487 
val zr = @{cpat "0"} 

488 
val zT = ctyp_of_term zr 

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

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

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

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

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

494 

495 
fun prove_nz ss T t = 

496 
let 

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

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

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

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

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

502 
in equal_elim (symmetric th) TrueI 

503 
end 

504 

505 
fun proc phi ss ct = 

506 
let 

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

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

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

510 
val T = ctyp_of_term x 

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

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

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

514 
end 

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

516 

517 
fun proc2 phi ss ct = 

518 
let 

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

520 
val T = ctyp_of_term l 

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

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

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

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

525 
val ynz = prove_nz ss T y 

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

527 
end 

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

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

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

531 
val ynz = prove_nz ss T y 

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

533 
end 

534 
 _ => NONE) 

535 
end 

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

537 

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

539 
 is_number t = can HOLogic.dest_number t 

540 

541 
val is_number = is_number o term_of 

542 

543 
fun proc3 phi ss ct = 

544 
(case term_of ct of 

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

546 
let 

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

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

549 
val T = ctyp_of_term c 

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

551 
in SOME (mk_meta_eq th) end 

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

553 
let 

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

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

556 
val T = ctyp_of_term c 

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

558 
in SOME (mk_meta_eq th) end 

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

560 
let 

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

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

563 
val T = ctyp_of_term c 

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

565 
in SOME (mk_meta_eq th) end 

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

567 
let 

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

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

570 
val T = ctyp_of_term c 

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

572 
in SOME (mk_meta_eq th) end 

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

574 
let 

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

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

577 
val T = ctyp_of_term c 

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

579 
in SOME (mk_meta_eq th) end 

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

581 
let 

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

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

584 
val T = ctyp_of_term c 

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

586 
in SOME (mk_meta_eq th) end 

587 
 _ => NONE) 

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

589 

590 
val add_frac_frac_simproc = 

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

592 
name = "add_frac_frac_simproc", 

593 
proc = proc, identifier = []} 

594 

595 
val add_frac_num_simproc = 

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

597 
name = "add_frac_num_simproc", 

598 
proc = proc2, identifier = []} 

599 

600 
val ord_frac_simproc = 

601 
make_simproc 

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

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

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

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

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

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

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

609 

610 
val nat_arith = map thm ["add_nat_number_of", "diff_nat_number_of", 

611 
"mult_nat_number_of", "eq_nat_number_of", "less_nat_number_of"] 

612 

613 
val comp_arith = (map thm ["Let_def", "if_False", "if_True", "add_0", 

614 
"add_Suc", "add_number_of_left", "mult_number_of_left", 

615 
"Suc_eq_add_numeral_1"])@ 

616 
(map (fn s => thm s RS sym) ["numeral_1_eq_1", "numeral_0_eq_0"]) 

617 
@ @{thms arith_simps} @ nat_arith @ @{thms rel_simps} 

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

619 
@{thm "divide_Numeral1"}, 

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

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

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

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

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

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

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

627 

628 
local 

629 
open Conv 

630 
in 

631 
val comp_conv = (Simplifier.rewrite 

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

633 
addsimps ths addsimps comp_arith addsimps simp_thms 

634 
addsimprocs field_cancel_numeral_factors 

635 
addsimprocs [add_frac_frac_simproc, add_frac_num_simproc, 

636 
ord_frac_simproc] 

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

638 
then_conv (Simplifier.rewrite (HOL_basic_ss addsimps 

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

23252  640 
end 
28402  641 

642 
fun numeral_is_const ct = 

643 
case term_of ct of 

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

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

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

647 
 t => can HOLogic.dest_number t 

648 

649 
fun dest_const ct = ((case term_of ct of 

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

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

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

653 
handle TERM _ => error "ring_dest_const") 

654 

655 
fun mk_const phi cT x = 

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

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

658 
else Thm.capply 

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

660 
(Numeral.mk_cnumber cT a)) 

661 
(Numeral.mk_cnumber cT b) 

662 
end 

663 

664 
in 

665 
val field_comp_conv = comp_conv; 

666 
val fieldgb_declaration = 

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

668 
{is_const = K numeral_is_const, 

669 
dest_const = K dest_const, 

670 
mk_const = mk_const, 

671 
conv = K (K comp_conv)} 

672 
end; 

673 
*} 

674 

675 
declaration fieldgb_declaration 

676 

677 
end 