diff --git a/thys/Nullstellensatz/Nullstellensatz.thy b/thys/Nullstellensatz/Nullstellensatz.thy --- a/thys/Nullstellensatz/Nullstellensatz.thy +++ b/thys/Nullstellensatz/Nullstellensatz.thy @@ -1,1394 +1,1393 @@ (* Author: Alexander Maletzky *) section \Hilbert's Nullstellensatz\ theory Nullstellensatz imports Algebraically_Closed_Fields "HOL-Computational_Algebra.Fraction_Field" Lex_Order_PP Univariate_PM Groebner_Bases.Groebner_PM begin text \We prove the geometric version of Hilbert's Nullstellensatz, i.e. the precise correspondence between algebraic varieties and radical ideals. The field-theoretic version of the Nullstellensatz is proved in theory \Nullstellensatz_Field\.\ subsection \Preliminaries\ lemma finite_linorder_induct [consumes 1, case_names empty insert]: assumes "finite (A::'a::linorder set)" and "P {}" and "\a A. finite A \ A \ {.. P A \ P (insert a A)" shows "P A" proof - define k where "k = card A" thus ?thesis using assms(1) proof (induct k arbitrary: A) case 0 with assms(2) show ?case by simp next case (Suc k) define a where "a = Max A" from Suc.prems(1) have "A \ {}" by auto with Suc.prems(2) have "a \ A" unfolding a_def by (rule Max_in) with Suc.prems have "k = card (A - {a})" by simp moreover from Suc.prems(2) have "finite (A - {a})" by simp ultimately have "P (A - {a})" by (rule Suc.hyps) with \finite (A - {a})\ _ have "P (insert a (A - {a}))" proof (rule assms(3)) show "A - {a} \ {.. A - {a}" hence "b \ A" and "b \ a" by simp_all moreover from Suc.prems(2) this(1) have "b \ a" unfolding a_def by (rule Max_ge) ultimately show "b \ {..a \ A\ show ?case by (simp add: insert_absorb) qed qed lemma Fract_same: "Fract a a = (1 when a \ 0)" by (simp add: One_fract_def Zero_fract_def eq_fract when_def) lemma Fract_eq_zero_iff: "Fract a b = 0 \ a = 0 \ b = 0" by (metis (no_types, lifting) Zero_fract_def eq_fract(1) eq_fract(2) mult_eq_0_iff one_neq_zero) lemma poly_plus_rightE: obtains c where "poly p (x + y) = poly p x + c * y" proof (induct p arbitrary: thesis) case 0 have "poly 0 (x + y) = poly 0 x + 0 * y" by simp thus ?case by (rule 0) next case (pCons a p) obtain c where "poly p (x + y) = poly p x + c * y" by (rule pCons.hyps) hence "poly (pCons a p) (x + y) = a + (x + y) * (poly p x + c * y)" by simp also have "\ = poly (pCons a p) x + (x * c + (poly p x + c * y)) * y" by (simp add: algebra_simps) finally show ?case by (rule pCons.prems) qed lemma poly_minus_rightE: obtains c where "poly p (x - y) = poly p x - c * (y::_::comm_ring)" - by (metis (no_types, hide_lams) add_uminus_conv_diff linordered_field_class.sign_simps(5) - mult_minus_left poly_plus_rightE) + by (metis add_diff_cancel_right' diff_add_cancel poly_plus_rightE) lemma map_poly_plus: assumes "f 0 = 0" and "\a b. f (a + b) = f a + f b" shows "map_poly f (p + q) = map_poly f p + map_poly f q" by (rule Polynomial.poly_eqI) (simp add: coeff_map_poly assms) lemma map_poly_minus: assumes "f 0 = 0" and "\a b. f (a - b) = f a - f b" shows "map_poly f (p - q) = map_poly f p - map_poly f q" by (rule Polynomial.poly_eqI) (simp add: coeff_map_poly assms) lemma map_poly_sum: assumes "f 0 = 0" and "\a b. f (a + b) = f a + f b" shows "map_poly f (sum g A) = (\a\A. map_poly f (g a))" by (induct A rule: infinite_finite_induct) (simp_all add: map_poly_plus assms) lemma map_poly_times: assumes "f 0 = 0" and "\a b. f (a + b) = f a + f b" and "\a b. f (a * b) = f a * f b" shows "map_poly f (p * q) = map_poly f p * map_poly f q" proof (induct p) case 0 show ?case by simp next case (pCons c p) show ?case by (simp add: assms map_poly_plus map_poly_smult map_poly_pCons pCons) qed lemma poly_Fract: assumes "set (Polynomial.coeffs p) \ range (\x. Fract x 1)" obtains q m where "poly p (Fract a b) = Fract q (b ^ m)" using assms proof (induct p arbitrary: thesis) case 0 have "poly 0 (Fract a b) = Fract 0 (b ^ 1)" by (simp add: fract_collapse) thus ?case by (rule 0) next case (pCons c p) from pCons.hyps(1) have "insert c (set (Polynomial.coeffs p)) = set (Polynomial.coeffs (pCons c p))" by auto with pCons.prems(2) have "c \ range (\x. Fract x 1)" and "set (Polynomial.coeffs p) \ range (\x. Fract x 1)" by blast+ from this(2) obtain q0 m0 where poly_p: "poly p (Fract a b) = Fract q0 (b ^ m0)" using pCons.hyps(2) by blast from \c \ _\ obtain c0 where c: "c = Fract c0 1" .. show ?case proof (cases "b = 0") case True hence "poly (pCons c p) (Fract a b) = Fract c0 (b ^ 0)" by (simp add: c fract_collapse) thus ?thesis by (rule pCons.prems) next case False hence "poly (pCons c p) (Fract a b) = Fract (c0 * b ^ Suc m0 + a * q0) (b ^ Suc m0)" by (simp add: poly_p c) thus ?thesis by (rule pCons.prems) qed qed lemma (in ordered_term) lt_sum_le_Max: "lt (sum f A) \\<^sub>t ord_term_lin.Max {lt (f a) | a. a \ A}" proof (induct A rule: infinite_finite_induct) case (infinite A) thus ?case by (simp add: min_term_min) next case empty thus ?case by (simp add: min_term_min) next case (insert a A) show ?case proof (cases "A = {}") case True thus ?thesis by simp next case False from insert.hyps(1, 2) have "lt (sum f (insert a A)) = lt (f a + sum f A)" by simp also have "\ \\<^sub>t ord_term_lin.max (lt (f a)) (lt (sum f A))" by (rule lt_plus_le_max) also have "\ \\<^sub>t ord_term_lin.max (lt (f a)) (ord_term_lin.Max {lt (f a) |a. a \ A})" using insert.hyps(3) ord_term_lin.max.mono by blast also from insert.hyps(1) False have "\ = ord_term_lin.Max (insert (lt (f a)) {lt (f x) |x. x \ A})" by simp also have "\ = ord_term_lin.Max {lt (f x) |x. x \ insert a A}" by (rule arg_cong[where f=ord_term_lin.Max]) blast finally show ?thesis . qed qed subsection \Ideals and Varieties\ definition variety_of :: "(('x \\<^sub>0 nat) \\<^sub>0 'a) set \ ('x \ 'a::comm_semiring_1) set" where "variety_of F = {a. \f\F. poly_eval a f = 0}" definition ideal_of :: "('x \ 'a::comm_semiring_1) set \ (('x \\<^sub>0 nat) \\<^sub>0 'a) set" where "ideal_of A = {f. \a\A. poly_eval a f = 0}" abbreviation "\ \ variety_of" abbreviation "\ \ ideal_of" lemma variety_ofI: "(\f. f \ F \ poly_eval a f = 0) \ a \ \ F" by (simp add: variety_of_def) lemma variety_ofI_alt: "poly_eval a ` F \ {0} \ a \ \ F" by (auto intro: variety_ofI) lemma variety_ofD: "a \ \ F \ f \ F \ poly_eval a f = 0" by (simp add: variety_of_def) lemma variety_of_empty [simp]: "\ {} = UNIV" by (simp add: variety_of_def) lemma variety_of_UNIV [simp]: "\ UNIV = {}" by (metis (mono_tags, lifting) Collect_empty_eq UNIV_I one_neq_zero poly_eval_one variety_of_def) lemma variety_of_antimono: "F \ G \ \ G \ \ F" by (auto simp: variety_of_def) lemma variety_of_ideal [simp]: "\ (ideal F) = \ F" proof show "\ (ideal F) \ \ F" by (intro variety_of_antimono ideal.span_superset) next show "\ F \ \ (ideal F)" proof (intro subsetI variety_ofI) fix a f assume "a \ \ F" and "f \ ideal F" from this(2) show "poly_eval a f = 0" proof (induct f rule: ideal.span_induct_alt) case base show ?case by simp next case (step c f g) with \a \ \ F\ show ?case by (auto simp: poly_eval_plus poly_eval_times dest: variety_ofD) qed qed qed lemma ideal_ofI: "(\a. a \ A \ poly_eval a f = 0) \ f \ \ A" by (simp add: ideal_of_def) lemma ideal_ofD: "f \ \ A \ a \ A \ poly_eval a f = 0" by (simp add: ideal_of_def) lemma ideal_of_empty [simp]: "\ {} = UNIV" by (simp add: ideal_of_def) lemma ideal_of_antimono: "A \ B \ \ B \ \ A" by (auto simp: ideal_of_def) lemma ideal_ideal_of [simp]: "ideal (\ A) = \ A" unfolding ideal.span_eq_iff proof (rule ideal.subspaceI) show "0 \ \ A" by (rule ideal_ofI) simp next fix f g assume "f \ \ A" hence f: "poly_eval a f = 0" if "a \ A" for a using that by (rule ideal_ofD) assume "g \ \ A" hence g: "poly_eval a g = 0" if "a \ A" for a using that by (rule ideal_ofD) show "f + g \ \ A" by (rule ideal_ofI) (simp add: poly_eval_plus f g) next fix c f assume "f \ \ A" hence f: "poly_eval a f = 0" if "a \ A" for a using that by (rule ideal_ofD) show "c * f \ \ A" by (rule ideal_ofI) (simp add: poly_eval_times f) qed lemma ideal_of_UN: "\ (\ (A ` J)) = (\j\J. \ (A j))" proof (intro set_eqI iffI ideal_ofI INT_I) fix p j a assume "p \ \ (\ (A ` J))" assume "j \ J" and "a \ A j" hence "a \ \ (A ` J)" .. with \p \ _\ show "poly_eval a p = 0" by (rule ideal_ofD) next fix p a assume "a \ \ (A ` J)" then obtain j where "j \ J" and "a \ A j" .. assume "p \ (\j\J. \ (A j))" hence "p \ \ (A j)" using \j \ J\ .. thus "poly_eval a p = 0" using \a \ A j\ by (rule ideal_ofD) qed corollary ideal_of_Un: "\ (A \ B) = \ A \ \ B" using ideal_of_UN[of id "{A, B}"] by simp lemma variety_of_ideal_of_variety [simp]: "\ (\ (\ F)) = \ F" (is "_ = ?V") proof have "F \ \ (\ F)" by (auto intro!: ideal_ofI dest: variety_ofD) thus "\ (\ ?V) \ ?V" by (rule variety_of_antimono) next show "?V \ \ (\ ?V)" by (auto intro!: variety_ofI dest: ideal_ofD) qed lemma ideal_of_inj_on: "inj_on \ (range (\::(('x \\<^sub>0 nat) \\<^sub>0 'a::comm_semiring_1) set \ _))" proof (rule inj_onI) fix A B :: "('x \ 'a) set" assume "A \ range \" then obtain F where A: "A = \ F" .. assume "B \ range \" then obtain G where B: "B = \ G" .. assume "\ A = \ B" hence "\ (\ A) = \ (\ B)" by simp thus "A = B" by (simp add: A B) qed lemma ideal_of_variety_of_ideal [simp]: "\ (\ (\ A)) = \ A" (is "_ = ?I") proof have "A \ \ (\ A)" by (auto intro!: variety_ofI dest: ideal_ofD) thus "\ (\ ?I) \ ?I" by (rule ideal_of_antimono) next show "?I \ \ (\ ?I)" by (auto intro!: ideal_ofI dest: variety_ofD) qed lemma variety_of_inj_on: "inj_on \ (range (\::('x \ 'a::comm_semiring_1) set \ _))" proof (rule inj_onI) fix F G :: "(('x \\<^sub>0 nat) \\<^sub>0 'a) set" assume "F \ range \" then obtain A where F: "F = \ A" .. assume "G \ range \" then obtain B where G: "G = \ B" .. assume "\ F = \ G" hence "\ (\ F) = \ (\ G)" by simp thus "F = G" by (simp add: F G) qed lemma image_map_indets_ideal_of: assumes "inj f" shows "map_indets f ` \ A = \ ((\a. a \ f) -` (A::('x \ 'a::comm_semiring_1) set)) \ P[range f]" proof - { fix p and a::"'x \ 'a" assume "\a\(\a. a \ f) -` A. poly_eval (a \ f) p = 0" hence eq: "poly_eval (a \ f) p = 0" if "a \ f \ A" for a using that by simp have "the_inv f \ f = id" by (rule ext) (simp add: assms the_inv_f_f) hence a: "a = a \ the_inv f \ f" by (simp add: comp_assoc) moreover assume "a \ A" ultimately have "(a \ the_inv f) \ f \ A" by simp hence "poly_eval ((a \ the_inv f) \ f) p = 0" by (rule eq) hence "poly_eval a p = 0" by (simp flip: a) } thus ?thesis by (auto simp: ideal_of_def poly_eval_map_indets simp flip: range_map_indets intro!: imageI) qed lemma variety_of_map_indets: "\ (map_indets f ` F) = (\a. a \ f) -` \ F" by (auto simp: variety_of_def poly_eval_map_indets) subsection \Radical Ideals\ definition radical :: "'a::monoid_mult set \ 'a set" ("\(_)" [999] 999) where "radical F = {f. \m. f ^ m \ F}" lemma radicalI: "f ^ m \ F \ f \ \F" by (auto simp: radical_def) lemma radicalE: assumes "f \ \F" obtains m where "f ^ m \ F" using assms by (auto simp: radical_def) lemma radical_empty [simp]: "\{} = {}" by (simp add: radical_def) lemma radical_UNIV [simp]: "\UNIV = UNIV" by (simp add: radical_def) lemma radical_ideal_eq_UNIV_iff: "\ideal F = UNIV \ ideal F = UNIV" proof assume "\ideal F = UNIV" hence "1 \ \ideal F" by simp then obtain m where "1 ^ m \ ideal F" by (rule radicalE) thus "ideal F = UNIV" by (simp add: ideal_eq_UNIV_iff_contains_one) qed simp lemma zero_in_radical_ideal [simp]: "0 \ \ideal F" proof (rule radicalI) show "0 ^ 1 \ ideal F" by (simp add: ideal.span_zero) qed lemma radical_mono: "F \ G \ \F \ \G" by (auto elim!: radicalE intro: radicalI) lemma radical_superset: "F \ \F" proof fix f assume "f \ F" hence "f ^ 1 \ F" by simp thus "f \ \F" by (rule radicalI) qed lemma radical_idem [simp]: "\\F = \F" proof show "\\F \ \F" by (auto elim!: radicalE intro: radicalI simp flip: power_mult) qed (fact radical_superset) lemma radical_Int_subset: "\(A \ B) \ \A \ \B" by (auto intro: radicalI elim: radicalE) lemma radical_ideal_Int: "\(ideal F \ ideal G) = \ideal F \ \ideal G" using radical_Int_subset proof (rule subset_antisym) show "\ideal F \ \ideal G \ \(ideal F \ ideal G)" proof fix p assume "p \ \ideal F \ \ideal G" hence "p \ \ideal F" and "p \ \ideal G" by simp_all from this(1) obtain m1 where p1: "p ^ m1 \ ideal F" by (rule radicalE) from \p \ \ideal G\ obtain m2 where "p ^ m2 \ ideal G" by (rule radicalE) hence "p ^ m1 * p ^ m2 \ ideal G" by (rule ideal.span_scale) moreover from p1 have "p ^ m2 * p ^ m1 \ ideal F" by (rule ideal.span_scale) ultimately have "p ^ (m1 + m2) \ ideal F \ ideal G" by (simp add: power_add mult.commute) thus "p \ \(ideal F \ ideal G)" by (rule radicalI) qed qed lemma ideal_radical_ideal [simp]: "ideal (\ideal F) = \ideal F" (is "_ = ?R") unfolding ideal.span_eq_iff proof (rule ideal.subspaceI) have "0 ^ 1 \ ideal F" by (simp add: ideal.span_zero) thus "0 \ ?R" by (rule radicalI) next fix a b assume "a \ ?R" then obtain m where "a ^ m \ ideal F" by (rule radicalE) have a: "a ^ k \ ideal F" if "m \ k" for k proof - from \a ^ m \ _\ have "a ^ (k - m + m) \ ideal F" by (simp only: power_add ideal.span_scale) with that show ?thesis by simp qed assume "b \ ?R" then obtain n where "b ^ n \ ideal F" by (rule radicalE) have b: "b ^ k \ ideal F" if "n \ k" for k proof - from \b ^ n \ _\ have "b ^ (k - n + n) \ ideal F" by (simp only: power_add ideal.span_scale) with that show ?thesis by simp qed have "(a + b) ^ (m + n) \ ideal F" unfolding binomial_ring proof (rule ideal.span_sum) fix k show "of_nat (m + n choose k) * a ^ k * b ^ (m + n - k) \ ideal F" proof (cases "k \ m") case True hence "n \ m + n - k" by simp hence "b ^ (m + n - k) \ ideal F" by (rule b) thus ?thesis by (rule ideal.span_scale) next case False hence "m \ k" by simp hence "a ^ k \ ideal F" by (rule a) hence "of_nat (m + n choose k) * b ^ (m + n - k) * a ^ k \ ideal F" by (rule ideal.span_scale) thus ?thesis by (simp only: ac_simps) qed qed thus "a + b \ ?R" by (rule radicalI) next fix c a assume "a \ ?R" then obtain m where "a ^ m \ ideal F" by (rule radicalE) hence "(c * a) ^ m \ ideal F" by (simp only: power_mult_distrib ideal.span_scale) thus "c * a \ ?R" by (rule radicalI) qed lemma radical_ideal_of [simp]: "\\ A = \ (A::(_ \ _::semiring_1_no_zero_divisors) set)" proof show "\\ A \ \ A" by (auto elim!: radicalE dest!: ideal_ofD intro!: ideal_ofI simp: poly_eval_power) qed (fact radical_superset) lemma variety_of_radical_ideal [simp]: "\ (\ideal F) = \ (F::(_ \\<^sub>0 _::semiring_1_no_zero_divisors) set)" proof have "F \ ideal F" by (rule ideal.span_superset) also have "\ \ \ideal F" by (rule radical_superset) finally show "\ (\ideal F) \ \ F" by (rule variety_of_antimono) next show "\ F \ \ (\ideal F)" proof (intro subsetI variety_ofI) fix a f assume "a \ \ F" hence "a \ \ (ideal F)" by simp assume "f \ \ideal F" then obtain m where "f ^ m \ ideal F" by (rule radicalE) with \a \ \ (ideal F)\ have "poly_eval a (f ^ m) = 0" by (rule variety_ofD) thus "poly_eval a f = 0" by (simp add: poly_eval_power) qed qed lemma image_map_indets_radical: assumes "inj f" shows "map_indets f ` \F = \(map_indets f ` (F::(_ \\<^sub>0 'a::comm_ring_1) set)) \ P[range f]" proof show "map_indets f ` \F \ \(map_indets f ` F) \ P[range f]" by (auto simp: radical_def simp flip: map_indets_power range_map_indets intro!: imageI) next show "\(map_indets f ` F) \ P[range f] \ map_indets f ` \F" proof fix p assume "p \ \(map_indets f ` F) \ P[range f]" hence "p \ \(map_indets f ` F)" and "p \ range (map_indets f)" by (simp_all add: range_map_indets) from this(1) obtain m where "p ^ m \ map_indets f ` F" by (rule radicalE) then obtain q where "q \ F" and p_m: "p ^ m = map_indets f q" .. from assms obtain g where "g \ f = id" and "map_indets g \ map_indets f = (id::_ \ _ \\<^sub>0 'a)" by (rule map_indets_inverseE) hence eq: "map_indets g (map_indets f p') = p'" for p'::"_ \\<^sub>0 'a" by (simp add: pointfree_idE) from p_m have "map_indets g (p ^ m) = map_indets g (map_indets f q)" by (rule arg_cong) hence "(map_indets g p) ^ m = q" by (simp add: eq) from \p \ range _\ obtain p' where "p = map_indets f p'" .. hence "p = map_indets f (map_indets g p)" by (simp add: eq) moreover have "map_indets g p \ \F" proof (rule radicalI) from \q \ F\ show "map_indets g p ^ m \ F" by (simp add: p_m eq flip: map_indets_power) qed ultimately show "p \ map_indets f ` \F" by (rule image_eqI) qed qed subsection \Geometric Version of the Nullstellensatz\ lemma weak_Nullstellensatz_aux_1: assumes "\i. i \ I \ g i \ ideal B" obtains c where "c \ ideal B" and "(\i\I. (f i + g i) ^ m i) = (\i\I. f i ^ m i) + c" using assms proof (induct I arbitrary: thesis rule: infinite_finite_induct) case (infinite I) from ideal.span_zero show ?case by (rule infinite) (simp add: infinite(1)) next case empty from ideal.span_zero show ?case by (rule empty) simp next case (insert j I) have "g i \ ideal B" if "i \ I" for i by (rule insert.prems) (simp add: that) with insert.hyps(3) obtain c where c: "c \ ideal B" and 1: "(\i\I. (f i + g i) ^ m i) = (\i\I. f i ^ m i) + c" by blast define k where "k = m j" obtain d where 2: "(f j + g j) ^ m j = f j ^ m j + d * g j" unfolding k_def[symmetric] proof (induct k arbitrary: thesis) case 0 have "(f j + g j) ^ 0 = f j ^ 0 + 0 * g j" by simp thus ?case by (rule 0) next case (Suc k) obtain d where "(f j + g j) ^ k = f j ^ k + d * g j" by (rule Suc.hyps) hence "(f j + g j) ^ Suc k = (f j ^ k + d * g j) * (f j + g j)" by simp also have "\ = f j ^ Suc k + (f j ^ k + d * (f j + g j)) * g j" by (simp add: algebra_simps) finally show ?case by (rule Suc.prems) qed from c have *: "f j ^ m j * c + (((\i\I. f i ^ m i) + c) * d) * g j \ ideal B" (is "?c \ _") by (intro ideal.span_add ideal.span_scale insert.prems insertI1) from insert.hyps(1, 2) have "(\i\insert j I. (f i + g i) ^ m i) = (f j ^ m j + d * g j) * ((\i\I. f i ^ m i) + c)" by (simp add: 1 2) also from insert.hyps(1, 2) have "\ = (\i\insert j I. f i ^ m i) + ?c" by (simp add: algebra_simps) finally have "(\i\insert j I. (f i + g i) ^ m i) = (\i\insert j I. f i ^ m i) + ?c" . with * show ?case by (rule insert.prems) qed lemma weak_Nullstellensatz_aux_2: assumes "finite X" and "F \ P[insert x X]" and "X \ {.. ideal F" and "ideal F \ P[{x}] \ {0}" obtains a::"'a::alg_closed_field" where "1 \ ideal (poly_eval (\_. monomial a 0) ` focus {x} ` F)" proof - let ?x = "monomial 1 (Poly_Mapping.single x 1)" from assms(3) have "x \ X" by blast hence eq1: "insert x X - {x} = X" and eq2: "insert x X - X = {x}" by blast+ interpret i: pm_powerprod lex_pm "lex_pm_strict::('x \\<^sub>0 nat) \ _" unfolding lex_pm_def lex_pm_strict_def by standard (simp_all add: lex_pm_zero_min lex_pm_plus_monotone flip: lex_pm_def) have lpp_focus: "i.lpp (focus X g) = except (i.lpp g) {x}" if "g \ P[insert x X]" for g::"_ \\<^sub>0 'a" proof (cases "g = 0") case True thus ?thesis by simp next case False have keys_focus_g: "keys (focus X g) = (\t. except t {x}) ` keys g" unfolding keys_focus using refl proof (rule image_cong) fix t assume "t \ keys g" also from that have "\ \ .[insert x X]" by (rule PolysD) finally have "keys t \ insert x X" by (rule PPsD) hence "except t (- X) = except t (insert x X \ - X)" by (metis (no_types, lifting) Int_commute except_keys_Int inf.orderE inf_left_commute) also from \x \ X\ have "insert x X \ - X = {x}" by simp finally show "except t (- X) = except t {x}" . qed show ?thesis proof (rule i.punit.lt_eqI_keys) from False have "i.lpp g \ keys g" by (rule i.punit.lt_in_keys) thus "except (i.lpp g) {x} \ keys (focus X g)" unfolding keys_focus_g by (rule imageI) fix t assume "t \ keys (focus X g)" then obtain s where "s \ keys g" and t: "t = except s {x}" unfolding keys_focus_g .. from this(1) have "lex_pm s (i.lpp g)" by (rule i.punit.lt_max_keys) moreover have "keys s \ keys (i.lpp g) \ {..x}" proof (rule Un_least) from \g \ P[_]\ have "keys g \ .[insert x X]" by (rule PolysD) with \s \ keys g\ have "s \ .[insert x X]" .. hence "keys s \ insert x X" by (rule PPsD) thus "keys s \ {..x}" using assms(3) by auto from \i.lpp g \ keys g\ \keys g \ _\ have "i.lpp g \ .[insert x X]" .. hence "keys (i.lpp g) \ insert x X" by (rule PPsD) thus "keys (i.lpp g) \ {..x}" using assms(3) by auto qed ultimately show "lex_pm t (except (i.lpp g) {x})" unfolding t by (rule lex_pm_except_max) qed qed define G where "G = i.punit.reduced_GB F" from assms(1) have "finite (insert x X)" by simp hence fin_G: "finite G" and G_sub: "G \ P[insert x X]" and ideal_G: "ideal G = ideal F" and "0 \ G" and G_isGB: "i.punit.is_Groebner_basis G" unfolding G_def using assms(2) by (rule i.finite_reduced_GB_Polys, rule i.reduced_GB_Polys, rule i.reduced_GB_ideal_Polys, rule i.reduced_GB_nonzero_Polys, rule i.reduced_GB_is_GB_Polys) define G' where "G' = focus X ` G" from fin_G \0 \ G\ have fin_G': "finite G'" and "0 \ G'" by (auto simp: G'_def) have G'_sub: "G' \ P[X]" by (auto simp: G'_def intro: focus_in_Polys) define G'' where "G'' = i.lcf ` G'" from \0 \ G'\ have "0 \ G''" by (auto simp: G''_def i.punit.lc_eq_zero_iff) have lookup_focus_in: "lookup (focus X g) t \ P[{x}]" if "g \ G" for g t proof - have "lookup (focus X g) t \ range (lookup (focus X g))" by (rule rangeI) from that G_sub have "g \ P[insert x X]" .. hence "range (lookup (focus X g)) \ P[insert x X - X]" by (rule focus_coeffs_subset_Polys') with \_ \ range _\ have "lookup (focus X g) t \ P[insert x X - X]" .. also have "insert x X - X = {x}" by (simp only: eq2) finally show ?thesis . qed hence lcf_in: "i.lcf (focus X g) \ P[{x}]" if "g \ G" for g unfolding i.punit.lc_def using that by blast have G''_sub: "G'' \ P[{x}]" proof fix c assume "c \ G''" then obtain g' where "g' \ G'" and c: "c = i.lcf g'" unfolding G''_def .. from \g' \ G'\ obtain g where "g \ G" and g': "g' = focus X g" unfolding G'_def .. from this(1) show "c \ P[{x}]" unfolding c g' by (rule lcf_in) qed define P where "P = poly_of_pm x ` G''" from fin_G' have fin_P: "finite P" by (simp add: P_def G''_def) have "0 \ P" proof assume "0 \ P" then obtain g'' where "g'' \ G''" and "0 = poly_of_pm x g''" unfolding P_def .. from this(2) have *: "keys g'' \ .[{x}] = {}" by (simp add: poly_of_pm_eq_zero_iff) from \g'' \ G''\ G''_sub have "g'' \ P[{x}]" .. hence "keys g'' \ .[{x}]" by (rule PolysD) with * have "keys g'' = {}" by blast with \g'' \ G''\ \0 \ G''\ show False by simp qed define Z where "Z = (\p\P. {z. poly p z = 0})" have "finite Z" unfolding Z_def using fin_P proof (rule finite_UN_I) fix p assume "p \ P" with \0 \ P\ have "p \ 0" by blast thus "finite {z. poly p z = 0}" by (rule poly_roots_finite) qed with infinite_UNIV[where 'a='a] have "- Z \ {}" using finite_compl by fastforce then obtain a where "a \ Z" by blast have a_nz: "poly_eval (\_. a) (i.lcf (focus X g)) \ 0" if "g \ G" for g proof - from that G_sub have "g \ P[insert x X]" .. have "poly_eval (\_. a) (i.lcf (focus X g)) = poly (poly_of_pm x (i.lcf (focus X g))) a" by (rule sym, intro poly_eq_poly_eval' lcf_in that) moreover have "poly_of_pm x (i.lcf (focus X g)) \ P" by (auto simp: P_def G''_def G'_def that intro!: imageI) ultimately show ?thesis using \a \ Z\ by (simp add: Z_def) qed let ?e = "poly_eval (\_. monomial a 0)" have lookup_e_focus: "lookup (?e (focus {x} g)) t = poly_eval (\_. a) (lookup (focus X g) t)" if "g \ P[insert x X]" for g t proof - have "focus (- {x}) g = focus (- {x} \ insert x X) g" by (rule sym) (rule focus_Int, fact) also have "\ = focus X g" by (simp add: Int_commute eq1 flip: Diff_eq) finally show ?thesis by (simp add: lookup_poly_eval_focus) qed have lpp_e_focus: "i.lpp (?e (focus {x} g)) = except (i.lpp g) {x}" if "g \ G" for g proof (rule i.punit.lt_eqI_keys) from that G_sub have "g \ P[insert x X]" .. hence "lookup (?e (focus {x} g)) (except (i.lpp g) {x}) = poly_eval (\_. a) (i.lcf (focus X g))" by (simp only: lookup_e_focus lpp_focus i.punit.lc_def) also from that have "\ \ 0" by (rule a_nz) finally show "except (i.lpp g) {x} \ keys (?e (focus {x} g))" by (simp add: in_keys_iff) fix t assume "t \ keys (?e (focus {x} g))" hence "0 \ lookup (?e (focus {x} g)) t" by (simp add: in_keys_iff) also from \g \ P[_]\ have "lookup (?e (focus {x} g)) t = poly_eval (\_. a) (lookup (focus X g) t)" by (rule lookup_e_focus) finally have "t \ keys (focus X g)" by (auto simp flip: lookup_not_eq_zero_eq_in_keys) hence "lex_pm t (i.lpp (focus X g))" by (rule i.punit.lt_max_keys) with \g \ P[_]\ show "lex_pm t (except (i.lpp g) {x})" by (simp only: lpp_focus) qed show ?thesis proof define G3 where "G3 = ?e ` focus {x} ` G" have "G3 \ P[X]" proof fix h assume "h \ G3" then obtain h0 where "h0 \ G" and h: "h = ?e (focus {x} h0)" by (auto simp: G3_def) from this(1) G_sub have "h0 \ P[insert x X]" .. hence "h \ P[insert x X - {x}]" unfolding h by (rule poly_eval_focus_in_Polys) thus "h \ P[X]" by (simp only: eq1) qed from fin_G have "finite G3" by (simp add: G3_def) have "ideal G3 \ P[- {x}] = ?e ` focus {x} ` ideal G" by (simp only: G3_def image_poly_eval_focus_ideal) also have "\ = ideal (?e ` focus {x} ` F) \ P[- {x}]" by (simp only: ideal_G image_poly_eval_focus_ideal) finally have eq3: "ideal G3 \ P[- {x}] = ideal (?e ` focus {x} ` F) \ P[- {x}]" . from assms(1) \G3 \ P[X]\ \finite G3\ have G3_isGB: "i.punit.is_Groebner_basis G3" proof (rule i.punit.isGB_I_spoly_rep[simplified, OF dickson_grading_varnum, where m=0, simplified i.dgrad_p_set_varnum]) fix g1 g2 assume "g1 \ G3" then obtain g1' where "g1' \ G" and g1: "g1 = ?e (focus {x} g1')" unfolding G3_def by blast from this(1) have lpp1: "i.lpp g1 = except (i.lpp g1') {x}" unfolding g1 by (rule lpp_e_focus) from \g1' \ G\ G_sub have "g1' \ P[insert x X]" .. assume "g2 \ G3" then obtain g2' where "g2' \ G" and g2: "g2 = ?e (focus {x} g2')" unfolding G3_def by blast from this(1) have lpp2: "i.lpp g2 = except (i.lpp g2') {x}" unfolding g2 by (rule lpp_e_focus) from \g2' \ G\ G_sub have "g2' \ P[insert x X]" .. define l where "l = lcs (except (i.lpp g1') {x}) (except (i.lpp g2') {x})" define c1 where "c1 = i.lcf (focus X g1')" define c2 where "c2 = i.lcf (focus X g2')" define c where "c = poly_eval (\_. a) c1 * poly_eval (\_. a) c2" define s where "s = c2 * punit.monom_mult 1 (l - except (i.lpp g1') {x}) g1' - c1 * punit.monom_mult 1 (l - except (i.lpp g2') {x}) g2'" have "c1 \ P[{x}]" unfolding c1_def using \g1' \ G\ by (rule lcf_in) hence eval_c1: "poly_eval (\_. monomial a 0) (focus {x} c1) = monomial (poly_eval (\_. a) c1) 0" by (simp add: focus_Polys poly_eval_sum poly_eval_monomial monomial_power_map_scale times_monomial_monomial flip: punit.monomial_prod_sum monomial_sum) (simp add: poly_eval_alt) have "c2 \ P[{x}]" unfolding c2_def using \g2' \ G\ by (rule lcf_in) hence eval_c2: "poly_eval (\_. monomial a 0) (focus {x} c2) = monomial (poly_eval (\_. a) c2) 0" by (simp add: focus_Polys poly_eval_sum poly_eval_monomial monomial_power_map_scale times_monomial_monomial flip: punit.monomial_prod_sum monomial_sum) (simp add: poly_eval_alt) assume spoly_nz: "i.punit.spoly g1 g2 \ 0" assume "g1 \ 0" and "g2 \ 0" hence "g1' \ 0" and "g2' \ 0" by (auto simp: g1 g2) have c1_nz: "poly_eval (\_. a) c1 \ 0" unfolding c1_def using \g1' \ G\ by (rule a_nz) moreover have c2_nz: "poly_eval (\_. a) c2 \ 0" unfolding c2_def using \g2' \ G\ by (rule a_nz) ultimately have "c \ 0" by (simp add: c_def) hence "inverse c \ 0" by simp from \g1' \ P[_]\ have "except (i.lpp g1') {x} \ .[insert x X - {x}]" by (intro PPs_closed_except' i.PPs_closed_lpp) moreover from \g2' \ P[_]\ have "except (i.lpp g2') {x} \ .[insert x X - {x}]" by (intro PPs_closed_except' i.PPs_closed_lpp) ultimately have "l \ .[insert x X - {x}]" unfolding l_def by (rule PPs_closed_lcs) hence "l \ .[X]" by (simp only: eq1) hence "l \ .[insert x X]" by rule (rule PPs_mono, blast) moreover from \c1 \ P[{x}]\ have "c1 \ P[insert x X]" by rule (intro Polys_mono, simp) moreover from \c2 \ P[{x}]\ have "c2 \ P[insert x X]" by rule (intro Polys_mono, simp) ultimately have "s \ P[insert x X]" using \g1' \ P[_]\ \g2' \ P[_]\ unfolding s_def by (intro Polys_closed_minus Polys_closed_times Polys_closed_monom_mult PPs_closed_minus) have "s \ ideal G" unfolding s_def times_monomial_left[symmetric] by (intro ideal.span_diff ideal.span_scale ideal.span_base \g1' \ G\ \g2' \ G\) with G_isGB have "(i.punit.red G)\<^sup>*\<^sup>* s 0" by (rule i.punit.GB_imp_zero_reducibility[simplified]) with \finite (insert x X)\ G_sub fin_G \s \ P[_]\ obtain q0 where 1: "s = 0 + (\g\G. q0 g * g)" and 2: "\g. q0 g \ P[insert x X]" and 3: "\g. lex_pm (i.lpp (q0 g * g)) (i.lpp s)" by (rule i.punit.red_rtrancl_repE[simplified, OF dickson_grading_varnum, where m=0, simplified i.dgrad_p_set_varnum]) blast define q where "q = (\g. inverse c \ (\h\{y\G. ?e (focus {x} y) = g}. ?e (focus {x} (q0 h))))" have eq4: "?e (focus {x} (monomial 1 (l - t))) = monomial 1 (l - t)" for t proof - have "focus {x} (monomial (1::'a) (l - t)) = monomial (monomial 1 (l - t)) 0" proof (intro focus_Polys_Compl Polys_closed_monomial PPs_closed_minus) from \x \ X\ have "X \ - {x}" by simp hence ".[X] \ .[- {x}]" by (rule PPs_mono) with \l \ .[X]\ show "l \ .[- {x}]" .. qed thus ?thesis by (simp add: poly_eval_monomial) qed from c2_nz have eq5: "inverse c * poly_eval (\_. a) c2 = 1 / lookup g1 (i.lpp g1)" unfolding lpp1 using \g1' \ P[_]\ by (simp add: c_def mult.assoc divide_inverse_commute g1 lookup_e_focus flip: lpp_focus i.punit.lc_def c1_def) from c1_nz have eq6: "inverse c * poly_eval (\_. a) c1 = 1 / lookup g2 (i.lpp g2)" unfolding lpp2 using \g2' \ P[_]\ by (simp add: c_def mult.assoc mult.left_commute[of "inverse (poly_eval (\_. a) c1)"] divide_inverse_commute g2 lookup_e_focus flip: lpp_focus i.punit.lc_def c2_def) have l_alt: "l = lcs (i.lpp g1) (i.lpp g2)" by (simp only: l_def lpp1 lpp2) have spoly_eq: "i.punit.spoly g1 g2 = (inverse c) \ ?e (focus {x} s)" by (simp add: s_def focus_minus focus_times poly_eval_minus poly_eval_times eval_c1 eval_c2 eq4 eq5 eq6 map_scale_eq_times times_monomial_monomial right_diff_distrib i.punit.spoly_def Let_def flip: mult.assoc times_monomial_left g1 g2 lpp1 lpp2 l_alt) also have "\ = (\g\G. inverse c \ (?e (focus {x} (q0 g)) * ?e (focus {x} g)))" by (simp add: 1 focus_sum poly_eval_sum focus_times poly_eval_times map_scale_sum_distrib_left) also have "\ = (\g\G3. \h\{y\G. ?e (focus{x} y) = g}. inverse c \ (?e (focus {x} (q0 h)) * ?e (focus {x} h)))" unfolding G3_def image_image using fin_G by (rule sum.image_gen) also have "\ = (\g\G3. inverse c \ (\h\{y\G. ?e (focus{x} y) = g}. ?e (focus {x} (q0 h))) * g)" by (intro sum.cong refl) (simp add: map_scale_eq_times sum_distrib_left sum_distrib_right mult.assoc) also from refl have "\ = (\g\G3. q g * g)" by (rule sum.cong) (simp add: q_def sum_distrib_right) finally have "i.punit.spoly g1 g2 = (\g\G3. q g * g)" . thus "i.punit.spoly_rep (varnum X) 0 G3 g1 g2" proof (rule i.punit.spoly_repI[simplified, where m=0 and d="varnum X", simplified i.dgrad_p_set_varnum]) fix g show "q g \ P[X]" unfolding q_def proof (intro Polys_closed_map_scale Polys_closed_sum) fix g0 from \q0 g0 \ P[insert x X]\ have "?e (focus {x} (q0 g0)) \ P[insert x X - {x}]" by (rule poly_eval_focus_in_Polys) thus "?e (focus {x} (q0 g0)) \ P[X]" by (simp only: eq1) qed assume "q g \ 0 \ g \ 0" hence "q g \ 0" .. have "i.lpp (q g * g) = i.lpp (\h\{y\G. ?e (focus {x} y) = g}. inverse c \ ?e (focus {x} (q0 h)) * g)" by (simp add: q_def map_scale_sum_distrib_left sum_distrib_right) also have "lex_pm \ (i.ordered_powerprod_lin.Max {i.lpp (inverse c \ ?e (focus {x} (q0 h)) * g) | h. h \ {y\G. ?e (focus {x} y) = g}})" (is "lex_pm _ (i.ordered_powerprod_lin.Max ?A)") by (fact i.punit.lt_sum_le_Max) also have "lex_pm \ (i.lpp s)" proof (rule i.ordered_powerprod_lin.Max.boundedI) from fin_G show "finite ?A" by simp next show "?A \ {}" proof assume "?A = {}" hence "{h \ G. ?e (focus {x} h) = g} = {}" by simp hence "q g = 0" by (simp only: q_def sum.empty map_scale_zero_right) with \q g \ 0\ show False .. qed next fix t assume "t \ ?A" then obtain h where "h \ G" and g[symmetric]: "?e (focus {x} h) = g" and "t = i.lpp (inverse c \ ?e (focus {x} (q0 h)) * g)" by blast note this(3) also have "i.lpp (inverse c \ ?e (focus {x} (q0 h)) * g) = i.lpp (inverse c \ (?e (focus {x} (q0 h * h))))" by (simp only: map_scale_eq_times mult.assoc g poly_eval_times focus_times) also from \inverse c \ 0\ have "\ = i.lpp (?e (focus {x} (q0 h * h)))" by (rule i.punit.lt_map_scale) also have "lex_pm \ (i.lpp (q0 h * h))" proof (rule i.punit.lt_le, rule ccontr) fix u assume "lookup (?e (focus {x} (q0 h * h))) u \ 0" hence "u \ keys (?e (focus {x} (q0 h * h)))" by (simp add: in_keys_iff) with keys_poly_eval_focus_subset have "u \ (\v. except v {x}) ` keys (q0 h * h)" .. then obtain v where "v \ keys (q0 h * h)" and u: "u = except v {x}" .. have "lex_pm u (Poly_Mapping.single x (lookup v x) + u)" by (metis add.commute add.right_neutral i.plus_monotone_left lex_pm_zero_min) also have "\ = v" by (simp only: u flip: plus_except) also from \v \ _\ have "lex_pm v (i.lpp (q0 h * h))" by (rule i.punit.lt_max_keys) finally have "lex_pm u (i.lpp (q0 h * h))" . moreover assume "lex_pm_strict (i.lpp (q0 h * h)) u" ultimately show False by simp qed also have "lex_pm \ (i.lpp s)" by fact finally show "lex_pm t (i.lpp s)" . qed also have "lex_pm_strict \ l" proof (rule i.punit.lt_less) from spoly_nz show "s \ 0" by (auto simp: spoly_eq) next fix t assume "lex_pm l t" have "g1' = flatten (focus X g1')" by simp also have "\ = flatten (monomial c1 (i.lpp (focus X g1')) + i.punit.tail (focus X g1'))" by (simp only: c1_def flip: i.punit.leading_monomial_tail) also from \g1' \ P[_]\ have "\ = punit.monom_mult 1 (except (i.lpp g1') {x}) c1 + flatten (i.punit.tail (focus X g1'))" by (simp only: flatten_plus flatten_monomial lpp_focus) finally have "punit.monom_mult 1 (except (i.lpp g1') {x}) c1 + flatten (i.punit.tail (focus X g1')) = g1'" (is "?l = _") by (rule sym) moreover have "c2 * punit.monom_mult 1 (l - except (i.lpp g1') {x}) ?l = punit.monom_mult 1 l (c1 * c2) + c2 * punit.monom_mult 1 (l - i.lpp (focus X g1')) (flatten (i.punit.tail (focus X g1')))" (is "_ = punit.monom_mult 1 l (c1 * c2) + ?a") by (simp add: punit.monom_mult_dist_right punit.monom_mult_assoc l_def minus_plus adds_lcs) (simp add: distrib_left lpp_focus \g1' \ P[_]\ flip: times_monomial_left) ultimately have a: "c2 * punit.monom_mult 1 (l - except (i.lpp g1') {x}) g1' = punit.monom_mult 1 l (c1 * c2) + ?a" by simp have "g2' = flatten (focus X g2')" by simp also have "\ = flatten (monomial c2 (i.lpp (focus X g2')) + i.punit.tail (focus X g2'))" by (simp only: c2_def flip: i.punit.leading_monomial_tail) also from \g2' \ P[_]\ have "\ = punit.monom_mult 1 (except (i.lpp g2') {x}) c2 + flatten (i.punit.tail (focus X g2'))" by (simp only: flatten_plus flatten_monomial lpp_focus) finally have "punit.monom_mult 1 (except (i.lpp g2') {x}) c2 + flatten (i.punit.tail (focus X g2')) = g2'" (is "?l = _") by (rule sym) moreover have "c1 * punit.monom_mult 1 (l - except (i.lpp g2') {x}) ?l = punit.monom_mult 1 l (c1 * c2) + c1 * punit.monom_mult 1 (l - i.lpp (focus X g2')) (flatten (i.punit.tail (focus X g2')))" (is "_ = punit.monom_mult 1 l (c1 * c2) + ?b") by (simp add: punit.monom_mult_dist_right punit.monom_mult_assoc l_def minus_plus adds_lcs_2) (simp add: distrib_left lpp_focus \g2' \ P[_]\ flip: times_monomial_left) ultimately have b: "c1 * punit.monom_mult 1 (l - except (i.lpp g2') {x}) g2' = punit.monom_mult 1 l (c1 * c2) + ?b" by simp have lex_pm_strict_t: "lex_pm_strict t (l - i.lpp (focus X h) + i.lpp (focus X h))" if "t \ keys (d * punit.monom_mult 1 (l - i.lpp (focus X h)) (flatten (i.punit.tail (focus X h))))" and "h \ G" and "d \ P[{x}]" for d h proof - have 0: "lex_pm_strict (u + v) w" if "lex_pm_strict v w" and "w \ .[X]" and "u \ .[{x}]" for u v w using that(1) proof (rule lex_pm_strict_plus_left) fix y z assume "y \ keys w" also from that(2) have "\ \ X" by (rule PPsD) also have "\ \ {.. keys u" also from that(3) have "\ \ {x}" by (rule PPsD) finally show "y < z" using \y < x\ by simp qed let ?h = "focus X h" from that(2) have "?h \ G'" by (simp add: G'_def) with \G' \ P[X]\ have "?h \ P[X]" .. hence "i.lpp ?h \ .[X]" by (rule i.PPs_closed_lpp) from that(1) obtain t1 t2 where "t1 \ keys d" and "t2 \ keys (punit.monom_mult 1 (l - i.lpp ?h) (flatten (i.punit.tail ?h)))" and t: "t = t1 + t2" by (rule in_keys_timesE) from this(2) obtain t3 where "t3 \ keys (flatten (i.punit.tail ?h))" and t2: "t2 = l - i.lpp ?h + t3" by (auto simp: punit.keys_monom_mult) from this(1) obtain t4 t5 where "t4 \ keys (i.punit.tail ?h)" and t5_in: "t5 \ keys (lookup (i.punit.tail ?h) t4)" and t3: "t3 = t4 + t5" using keys_flatten_subset by blast from this(1) have 1: "lex_pm_strict t4 (i.lpp ?h)" by (rule i.punit.keys_tail_less_lt) from that(2) have "lookup ?h t4 \ P[{x}]" by (rule lookup_focus_in) hence "keys (lookup ?h t4) \ .[{x}]" by (rule PolysD) moreover from t5_in have t5_in: "t5 \ keys (lookup ?h t4)" by (simp add: i.punit.lookup_tail split: if_split_asm) ultimately have "t5 \ .[{x}]" .. with 1 \i.lpp ?h \ _\ have "lex_pm_strict (t5 + t4) (i.lpp ?h)" by (rule 0) hence "lex_pm_strict t3 (i.lpp ?h)" by (simp only: t3 add.commute) hence "lex_pm_strict t2 (l - i.lpp ?h + i.lpp ?h)" unfolding t2 by (rule i.plus_monotone_strict_left) moreover from \l \ .[X]\ \i.lpp ?h \ .[X]\ have "l - i.lpp ?h + i.lpp ?h \ .[X]" by (intro PPs_closed_plus PPs_closed_minus) moreover from \t1 \ keys d\ that(3) have "t1 \ .[{x}]" by (auto dest: PolysD) ultimately show ?thesis unfolding t by (rule 0) qed show "lookup s t = 0" proof (rule ccontr) assume "lookup s t \ 0" hence "t \ keys s" by (simp add: in_keys_iff) also have "\ = keys (?a - ?b)" by (simp add: s_def a b) also have "\ \ keys ?a \ keys ?b" by (fact keys_minus) finally show False proof assume "t \ keys ?a" hence "lex_pm_strict t (l - i.lpp (focus X g1') + i.lpp (focus X g1'))" using \g1' \ G\ \c2 \ P[{x}]\ by (rule lex_pm_strict_t) with \g1' \ P[_]\ have "lex_pm_strict t l" by (simp add: lpp_focus l_def minus_plus adds_lcs) with \lex_pm l t\ show ?thesis by simp next assume "t \ keys ?b" hence "lex_pm_strict t (l - i.lpp (focus X g2') + i.lpp (focus X g2'))" using \g2' \ G\ \c1 \ P[{x}]\ by (rule lex_pm_strict_t) with \g2' \ P[_]\ have "lex_pm_strict t l" by (simp add: lpp_focus l_def minus_plus adds_lcs_2) with \lex_pm l t\ show ?thesis by simp qed qed qed also have "\ = lcs (i.lpp g1) (i.lpp g2)" by (simp only: l_def lpp1 lpp2) finally show "lex_pm_strict (i.lpp (q g * g)) (lcs (i.lpp g1) (i.lpp g2))" . qed qed have "1 \ ideal (?e ` focus {x} ` F) \ 1 \ ideal (?e ` focus {x} ` F) \ P[- {x}]" by (simp add: one_in_Polys) also have "\ \ 1 \ ideal G3" by (simp add: one_in_Polys flip: eq3) also have "\ \" proof note G3_isGB moreover assume "1 \ ideal G3" moreover have "1 \ (0::_ \\<^sub>0 'a)" by simp ultimately obtain g where "g \ G3" and "g \ 0" and "i.lpp g adds i.lpp (1::_ \\<^sub>0 'a)" by (rule i.punit.GB_adds_lt[simplified]) from this(3) have "i.lpp g = 0" by (simp add: i.punit.lt_monomial adds_zero flip: single_one) hence "monomial (i.lcf g) 0 = g" by (rule i.punit.lt_eq_min_term_monomial[simplified]) from \g \ G3\ obtain g' where "g' \ G" and g: "g = ?e (focus {x} g')" by (auto simp: G3_def) from this(1) have "i.lpp g = except (i.lpp g') {x}" unfolding g by (rule lpp_e_focus) hence "keys (i.lpp g') \ {x}" by (simp add: \i.lpp g = 0\ except_eq_zero_iff) have "g' \ P[{x}]" proof (intro PolysI subsetI PPsI) fix t y assume "t \ keys g'" hence "lex_pm t (i.lpp g')" by (rule i.punit.lt_max_keys) moreover assume "y \ keys t" ultimately obtain z where "z \ keys (i.lpp g')" and "z \ y" by (rule lex_pm_keys_leE) with \keys (i.lpp g') \ {x}\ have "x \ y" by blast from \g' \ G\ G_sub have "g' \ P[insert x X]" .. hence "indets g' \ insert x X" by (rule PolysD) moreover from \y \ _\ \t \ _\ have "y \ indets g'" by (rule in_indetsI) ultimately have "y \ insert x X" .. thus "y \ {x}" proof assume "y \ X" with assms(3) have "y \ {..x \ y\ show ?thesis by simp qed simp qed moreover from \g' \ G\ have "g' \ ideal G" by (rule ideal.span_base) ultimately have "g' \ ideal F \ P[{x}]" by (simp add: ideal_G) with assms(5) have "g' = 0" by blast hence "g = 0" by (simp add: g) with \g \ 0\ show False .. qed finally show "1 \ ideal (?e ` focus {x} ` F)" . qed qed lemma weak_Nullstellensatz_aux_3: assumes "F \ P[insert x X]" and "x \ X" and "1 \ ideal F" and "\ ideal F \ P[{x}] \ {0}" obtains a::"'a::alg_closed_field" where "1 \ ideal (poly_eval (\_. monomial a 0) ` focus {x} ` F)" proof - let ?x = "monomial 1 (Poly_Mapping.single x 1)" from assms(4) obtain f where "f \ ideal F" and "f \ P[{x}]" and "f \ 0" by blast define p where "p = poly_of_pm x f" from \f \ P[{x}]\ \f \ 0\ have "p \ 0" by (auto simp: p_def poly_of_pm_eq_zero_iff simp flip: keys_eq_empty dest!: PolysD(1)) obtain c A m where A: "finite A" and p: "p = Polynomial.smult c (\a\A. [:- a, 1:] ^ m a)" and "\x. m x = 0 \ x \ A" and "c = 0 \ p = 0" and "\z. poly p z = 0 \ (c = 0 \ z \ A)" by (rule linear_factorsE) blast from this(4, 5) have "c \ 0" and "\z. poly p z = 0 \ z \ A" by (simp_all add: \p \ 0\) have "\a\A. 1 \ ideal (poly_eval (\_. monomial a 0) ` focus {x} ` F)" proof (rule ccontr) assume asm: "\ (\a\A. 1 \ ideal (poly_eval (\_. monomial a 0) ` focus {x} ` F))" obtain g h where "g a \ ideal F" and 1: "h a * (?x - monomial a 0) + g a = 1" if "a \ A" for a proof - define P where "P = (\gh a. fst gh \ ideal F \ fst gh + snd gh * (?x - monomial a 0) = 1)" define gh where "gh = (\a. SOME gh. P gh a)" show ?thesis proof fix a assume "a \ A" with asm have "1 \ ideal (poly_eval (\_. monomial a 0) ` focus {x} ` F)" by blast hence "1 \ poly_eval (\_. monomial a 0) ` focus {x} ` ideal F" by (simp add: image_poly_eval_focus_ideal one_in_Polys) then obtain g where "g \ ideal F" and "1 = poly_eval (\_. monomial a 0) (focus {x} g)" unfolding image_image .. note this(2) also have "poly_eval (\_. monomial a 0) (focus {x} g) = poly (poly_of_focus x g) (monomial a 0)" by (simp only: poly_poly_of_focus) also have "\ = poly (poly_of_focus x g) (?x - (?x - monomial a 0))" by simp also obtain h where "\ = poly (poly_of_focus x g) ?x - h * (?x - monomial a 0)" by (rule poly_minus_rightE) also have "\ = g - h * (?x - monomial a 0)" by (simp only: poly_poly_of_focus_monomial) finally have "g - h * (?x - monomial a 0) = 1" by (rule sym) with \g \ ideal F\ have "P (g, - h) a" by (simp add: P_def) hence "P (gh a) a" unfolding gh_def by (rule someI) thus "fst (gh a) \ ideal F" and "snd (gh a) * (?x - monomial a 0) + fst (gh a) = 1" by (simp_all only: P_def add.commute) qed qed from this(1) obtain g' where "g' \ ideal F" and 2: "(\a\A. (h a * (?x - monomial a 0) + g a) ^ m a) = (\a\A. (h a * (?x - monomial a 0)) ^ m a) + g'" by (rule weak_Nullstellensatz_aux_1) have "1 = (\a\A. (h a * (?x - monomial a 0) + g a) ^ m a)" by (rule sym) (intro prod.neutral ballI, simp only: 1 power_one) also have "\ = (\a\A. h a ^ m a) * (\a\A. (?x - monomial a 0) ^ m a) + g'" by (simp only: 2 power_mult_distrib prod.distrib) also have "(\a\A. (?x - monomial a 0) ^ m a) = pm_of_poly x (\a\A. [:- a, 1:] ^ m a)" by (simp add: pm_of_poly_prod pm_of_poly_pCons single_uminus punit.monom_mult_monomial flip: single_one) also from \c \ 0\ have "\ = monomial (inverse c) 0 * pm_of_poly x p" by (simp add: p map_scale_assoc flip: map_scale_eq_times) also from \f \ P[{x}]\ have "\ = monomial (inverse c) 0 * f" by (simp only: \p = poly_of_pm x f\ pm_of_poly_of_pm) finally have "1 = ((\a\A. h a ^ m a) * monomial (inverse c) 0) * f + g'" by (simp only: mult.assoc) also from \f \ ideal F\ \g' \ ideal F\ have "\ \ ideal F" by (intro ideal.span_add ideal.span_scale) finally have "1 \ ideal F" . with assms(3) show False .. qed then obtain a where "1 \ ideal (poly_eval (\_. monomial a 0) ` focus {x} ` F)" .. thus ?thesis .. qed theorem weak_Nullstellensatz: assumes "finite X" and "F \ P[X]" and "\ F = ({}::('x::{countable,linorder} \ 'a::alg_closed_field) set)" shows "ideal F = UNIV" unfolding ideal_eq_UNIV_iff_contains_one proof (rule ccontr) assume "1 \ ideal F" with assms(1, 2) obtain a where "1 \ ideal (poly_eval a ` F)" proof (induct X arbitrary: F thesis rule: finite_linorder_induct) case empty have "F \ {0}" proof fix f assume "f \ F" with empty.prems(2) have "f \ P[{}]" .. then obtain c where f: "f = monomial c 0" unfolding Polys_empty .. also have "c = 0" proof (rule ccontr) assume "c \ 0" from \f \ F\ have "f \ ideal F" by (rule ideal.span_base) hence "monomial (inverse c) 0 * f \ ideal F" by (rule ideal.span_scale) with \c \ 0\ have "1 \ ideal F" by (simp add: f times_monomial_monomial) with empty.prems(3) show False .. qed finally show "f \ {0}" by simp qed hence "poly_eval 0 ` F \ {0}" by auto hence "ideal (poly_eval 0 ` F) = {0}" by simp hence "1 \ ideal (poly_eval 0 ` F)" by (simp del: ideal_eq_zero_iff) thus ?case by (rule empty.prems) next case (insert x X) obtain a0 where "1 \ ideal (poly_eval (\_. monomial a0 0) ` focus {x} ` F)" (is "_ \ ideal ?F") proof (cases "ideal F \ P[{x}] \ {0}") case True with insert.hyps(1) insert.prems(2) insert.hyps(2) insert.prems(3) obtain a0 where "1 \ ideal (poly_eval (\_. monomial a0 0) ` focus {x} ` F)" by (rule weak_Nullstellensatz_aux_2) thus ?thesis .. next case False from insert.hyps(2) have "x \ X" by blast with insert.prems(2) obtain a0 where "1 \ ideal (poly_eval (\_. monomial a0 0) ` focus {x} ` F)" using insert.prems(3) False by (rule weak_Nullstellensatz_aux_3) thus ?thesis .. qed moreover have "?F \ P[X]" proof - { fix f assume "f \ F" with insert.prems(2) have "f \ P[insert x X]" .. hence "poly_eval (\_. monomial a0 0) (focus {x} f) \ P[insert x X - {x}]" by (rule poly_eval_focus_in_Polys) also have "\ \ P[X]" by (rule Polys_mono) simp finally have "poly_eval (\_. monomial a0 0) (focus {x} f) \ P[X]" . } thus ?thesis by blast qed ultimately obtain a1 where "1 \ ideal (poly_eval a1 ` ?F)" using insert.hyps(3) by blast also have "poly_eval a1 ` ?F = poly_eval (a1(x := poly_eval a1 (monomial a0 0))) ` F" by (simp add: image_image poly_eval_poly_eval_focus fun_upd_def) finally show ?case by (rule insert.prems) qed hence "ideal (poly_eval a ` F) \ UNIV" by (simp add: ideal_eq_UNIV_iff_contains_one) hence "ideal (poly_eval a ` F) = {0}" using ideal_field_disj[of "poly_eval a ` F"] by blast hence "poly_eval a ` F \ {0}" by simp hence "a \ \ F" by (rule variety_ofI_alt) thus False by (simp add: assms(3)) qed lemma radical_idealI: assumes "finite X" and "F \ P[X]" and "f \ P[X]" and "x \ X" and "\ (insert (1 - punit.monom_mult 1 (Poly_Mapping.single x 1) f) F) = {}" shows "(f::('x::{countable,linorder} \\<^sub>0 nat) \\<^sub>0 'a::alg_closed_field) \ \ideal F" proof (cases "f = 0") case True thus ?thesis by simp next case False from assms(4) have "P[X] \ P[- {x}]" by (auto simp: Polys_alt) with assms(3) have "f \ P[- {x}]" .. let ?x = "Poly_Mapping.single x 1" let ?f = "punit.monom_mult 1 ?x f" from assms(1) have "finite (insert x X)" by simp moreover have "insert (1 - ?f) F \ P[insert x X]" unfolding insert_subset proof (intro conjI Polys_closed_minus one_in_Polys Polys_closed_monom_mult PPs_closed_single) have "P[X] \ P[insert x X]" by (rule Polys_mono) blast with assms(2, 3) show "f \ P[insert x X]" and "F \ P[insert x X]" by blast+ qed simp ultimately have "ideal (insert (1 - ?f) F) = UNIV" using assms(5) by (rule weak_Nullstellensatz) hence "1 \ ideal (insert (1 - ?f) F)" by simp then obtain F' q where fin': "finite F'" and F'_sub: "F' \ insert (1 - ?f) F" and eq: "1 = (\f'\F'. q f' * f')" by (rule ideal.spanE) show "f \ \ideal F" proof (cases "1 - ?f \ F'") case True define g where "g = (\x::('x \\<^sub>0 nat) \\<^sub>0 'a. Fract x 1)" define F'' where "F'' = F' - {1 - ?f}" define q0 where "q0 = q (1 - ?f)" have g_0: "g 0 = 0" by (simp add: g_def fract_collapse) have g_1: "g 1 = 1" by (simp add: g_def fract_collapse) have g_plus: "g (a + b) = g a + g b" for a b by (simp add: g_def) have g_minus: "g (a - b) = g a - g b" for a b by (simp add: g_def) have g_times: "g (a * b) = g a * g b" for a b by (simp add: g_def) from fin' have fin'': "finite F''" by (simp add: F''_def) from F'_sub have F''_sub: "F'' \ F" by (auto simp: F''_def) have "focus {x} ?f = monomial 1 ?x * focus {x} f" by (simp add: focus_times focus_monomial except_single flip: times_monomial_left) also from \f \ P[- {x}]\ have "focus {x} f = monomial f 0" by (rule focus_Polys_Compl) finally have "focus {x} ?f = monomial f ?x" by (simp add: times_monomial_monomial) hence eq1: "poly (map_poly g (poly_of_focus x (1 - ?f))) (Fract 1 f) = 0" by (simp add: poly_of_focus_def focus_minus poly_of_pm_minus poly_of_pm_monomial PPs_closed_single map_poly_minus g_0 g_1 g_minus map_poly_monom poly_monom) (simp add: g_def Fract_same \f \ 0\) have eq2: "poly (map_poly g (poly_of_focus x f')) (Fract 1 f) = Fract f' 1" if "f' \ F''" for f' proof - from that F''_sub have "f' \ F" .. with assms(2) have "f' \ P[X]" .. with \P[X] \ _\ have "f' \ P[- {x}]" .. hence "focus {x} f' = monomial f' 0" by (rule focus_Polys_Compl) thus ?thesis by (simp add: poly_of_focus_def focus_minus poly_of_pm_minus poly_of_pm_monomial zero_in_PPs map_poly_minus g_0 g_1 g_minus map_poly_monom poly_monom) (simp only: g_def) qed define p0m0 where "p0m0 = (\f'. SOME z. poly (map_poly g (poly_of_focus x (q f'))) (Fract 1 f) = Fract (fst z) (f ^ snd z))" define p0 where "p0 = fst \ p0m0" define m0 where "m0 = snd \ p0m0" define m where "m = Max (m0 ` F'')" have eq3: "poly (map_poly g (poly_of_focus x (q f'))) (Fract 1 f) = Fract (p0 f') (f ^ m0 f')" for f' proof - have "g a = 0 \ a = 0" for a by (simp add: g_def Fract_eq_zero_iff) hence "set (Polynomial.coeffs (map_poly g (poly_of_focus x (q f')))) \ range (\x. Fract x 1)" by (auto simp: set_coeffs_map_poly g_def) then obtain p m' where "poly (map_poly g (poly_of_focus x (q f'))) (Fract 1 f) = Fract p (f ^ m')" by (rule poly_Fract) hence "poly (map_poly g (poly_of_focus x (q f'))) (Fract 1 f) = Fract (fst (p, m')) (f ^ snd (p, m'))" by simp thus ?thesis unfolding p0_def m0_def p0m0_def o_def by (rule someI) qed note eq also from True fin' have "(\f'\F'. q f' * f') = q0 * (1 - ?f) + (\f'\F''. q f' * f')" by (simp add: q0_def F''_def sum.remove) finally have "poly_of_focus x 1 = poly_of_focus x (q0 * (1 - ?f) + (\f'\F''. q f' * f'))" by (rule arg_cong) hence "1 = poly (map_poly g (poly_of_focus x (q0 * (1 - ?f) + (\f'\F''. q f' * f')))) (Fract 1 f)" by (simp add: g_1) also have "\ = poly (map_poly g (poly_of_focus x (\f'\F''. q f' * f'))) (Fract 1 f)" by (simp only: poly_of_focus_plus map_poly_plus g_0 g_plus g_times poly_add poly_of_focus_times map_poly_times poly_mult eq1 mult_zero_right add_0_left) also have "\ = (\f'\F''. Fract (p0 f') (f ^ m0 f') * Fract f' 1)" by (simp only: poly_of_focus_sum poly_of_focus_times map_poly_sum map_poly_times g_0 g_plus g_times poly_sum poly_mult eq2 eq3 cong: sum.cong) finally have "Fract (f ^ m) 1 = Fract (f ^ m) 1 * (\f'\F''. Fract (p0 f' * f') (f ^ m0 f'))" by simp also have "\ = (\f'\F''. Fract (f ^ m * (p0 f' * f')) (f ^ m0 f'))" by (simp add: sum_distrib_left) also from refl have "\ = (\f'\F''. Fract ((f ^ (m - m0 f') * p0 f') * f') 1)" proof (rule sum.cong) fix f' assume "f' \ F''" hence "m0 f' \ m0 ` F''" by (rule imageI) with _ have "m0 f' \ m" unfolding m_def by (rule Max_ge) (simp add: fin'') hence "f ^ m = f ^ (m0 f') * f ^ (m - m0 f')" by (simp flip: power_add) hence "Fract (f ^ m * (p0 f' * f')) (f ^ m0 f') = Fract (f ^ m0 f') (f ^ m0 f') * Fract (f ^ (m - m0 f') * (p0 f' * f')) 1" by (simp add: ac_simps) also from \f \ 0\ have "Fract (f ^ m0 f') (f ^ m0 f') = 1" by (simp add: Fract_same) finally show "Fract (f ^ m * (p0 f' * f')) (f ^ m0 f') = Fract (f ^ (m - m0 f') * p0 f' * f') 1" by (simp add: ac_simps) qed also from fin'' have "\ = Fract (\f'\F''. (f ^ (m - m0 f') * p0 f') * f') 1" by (induct F'') (simp_all add: fract_collapse) finally have "f ^ m = (\f'\F''. (f ^ (m - m0 f') * p0 f') * f')" by (simp add: eq_fract) also have "\ \ ideal F''" by (rule ideal.sum_in_spanI) also from \F'' \ F\ have "\ \ ideal F" by (rule ideal.span_mono) finally show "f \ \ideal F" by (rule radicalI) next case False with F'_sub have "F' \ F" by blast have "1 \ ideal F'" unfolding eq by (rule ideal.sum_in_spanI) also from \F' \ F\ have "\ \ ideal F" by (rule ideal.span_mono) finally have "ideal F = UNIV" by (simp only: ideal_eq_UNIV_iff_contains_one) thus ?thesis by simp qed qed corollary radical_idealI_extend_indets: assumes "finite X" and "F \ P[X]" and "\ (insert (1 - punit.monom_mult 1 (Poly_Mapping.single None 1) (extend_indets f)) (extend_indets ` F)) = {}" shows "(f::(_::{countable,linorder} \\<^sub>0 nat) \\<^sub>0 _::alg_closed_field) \ \ideal F" proof - define Y where "Y = X \ indets f" from assms(1) have fin_Y: "finite Y" by (simp add: Y_def finite_indets) have "P[X] \ P[Y]" by (rule Polys_mono) (simp add: Y_def) with assms(2) have F_sub: "F \ P[Y]" by (rule subset_trans) have f_in: "f \ P[Y]" by (simp add: Y_def Polys_alt) let ?F = "extend_indets ` F" let ?f = "extend_indets f" let ?X = "Some ` Y" from fin_Y have "finite ?X" by (rule finite_imageI) moreover from F_sub have "?F \ P[?X]" by (auto simp: indets_extend_indets intro!: PolysI_alt imageI dest!: PolysD(2) subsetD[of F]) moreover from f_in have "?f \ P[?X]" by (auto simp: indets_extend_indets intro!: PolysI_alt imageI dest!: PolysD(2)) moreover have "None \ ?X" by simp ultimately have "?f \ \ideal ?F" using assms(3) by (rule radical_idealI) also have "?f \ \ideal ?F \ f \ \ideal F" proof assume "f \ \ideal F" then obtain m where "f ^ m \ ideal F" by (rule radicalE) hence "extend_indets (f ^ m) \ extend_indets ` ideal F" by (rule imageI) with extend_indets_ideal_subset have "?f ^ m \ ideal ?F" unfolding extend_indets_power .. thus "?f \ \ideal ?F" by (rule radicalI) next assume "?f \ \ideal ?F" then obtain m where "?f ^ m \ ideal ?F" by (rule radicalE) moreover have "?f ^ m \ P[- {None}]" by (rule Polys_closed_power) (auto intro!: PolysI_alt simp: indets_extend_indets) ultimately have "extend_indets (f ^ m) \ extend_indets ` ideal F" by (simp add: extend_indets_ideal extend_indets_power) hence "f ^ m \ ideal F" by (simp only: inj_image_mem_iff[OF inj_extend_indets]) thus "f \ \ideal F" by (rule radicalI) qed finally show ?thesis . qed theorem Nullstellensatz: assumes "finite X" and "F \ P[X]" and "(f::(_::{countable,linorder} \\<^sub>0 nat) \\<^sub>0 _::alg_closed_field) \ \ (\ F)" shows "f \ \ideal F" using assms(1, 2) proof (rule radical_idealI_extend_indets) let ?f = "punit.monom_mult 1 (monomial 1 None) (extend_indets f)" show "\ (insert (1 - ?f) (extend_indets ` F)) = {}" proof (intro subset_antisym subsetI) fix a assume "a \ \ (insert (1 - ?f) (extend_indets ` F))" moreover have "1 - ?f \ insert (1 - ?f) (extend_indets ` F)" by simp ultimately have "poly_eval a (1 - ?f) = 0" by (rule variety_ofD) hence "poly_eval a (extend_indets f) \ 0" by (auto simp: poly_eval_minus poly_eval_times simp flip: times_monomial_left) hence "poly_eval (a \ Some) f \ 0" by (simp add: poly_eval_extend_indets) have "a \ Some \ \ F" proof (rule variety_ofI) fix f' assume "f' \ F" hence "extend_indets f' \ insert (1 - ?f) (extend_indets ` F)" by simp with \a \ _\ have "poly_eval a (extend_indets f') = 0" by (rule variety_ofD) thus "poly_eval (a \ Some) f' = 0" by (simp only: poly_eval_extend_indets) qed with assms(3) have "poly_eval (a \ Some) f = 0" by (rule ideal_ofD) with \poly_eval (a \ Some) f \ 0\ show "a \ {}" .. qed simp qed theorem strong_Nullstellensatz: assumes "finite X" and "F \ P[X]" shows "\ (\ F) = \ideal (F::((_::{countable,linorder} \\<^sub>0 nat) \\<^sub>0 _::alg_closed_field) set)" proof (intro subset_antisym subsetI) fix f assume "f \ \ (\ F)" with assms show "f \ \ideal F" by (rule Nullstellensatz) qed (metis ideal_ofI variety_ofD variety_of_radical_ideal) text \The following lemma can be used for actually \<^emph>\deciding\ whether a polynomial is contained in the radical of an ideal or not.\ lemma radical_ideal_iff: assumes "finite X" and "F \ P[X]" and "f \ P[X]" and "x \ X" shows "(f::(_::{countable,linorder} \\<^sub>0 nat) \\<^sub>0 _::alg_closed_field) \ \ideal F \ 1 \ ideal (insert (1 - punit.monom_mult 1 (Poly_Mapping.single x 1) f) F)" proof - let ?f = "punit.monom_mult 1 (Poly_Mapping.single x 1) f" show ?thesis proof assume "f \ \ideal F" then obtain m where "f ^ m \ ideal F" by (rule radicalE) from assms(1) have "finite (insert x X)" by simp moreover have "insert (1 - ?f) F \ P[insert x X]" unfolding insert_subset proof (intro conjI Polys_closed_minus one_in_Polys Polys_closed_monom_mult PPs_closed_single) have "P[X] \ P[insert x X]" by (rule Polys_mono) blast with assms(2, 3) show "f \ P[insert x X]" and "F \ P[insert x X]" by blast+ qed simp moreover have "\ (insert (1 - ?f) F) = {}" proof (intro subset_antisym subsetI) fix a assume "a \ \ (insert (1 - ?f) F)" moreover have "1 - ?f \ insert (1 - ?f) F" by simp ultimately have "poly_eval a (1 - ?f) = 0" by (rule variety_ofD) hence "poly_eval a (f ^ m) \ 0" by (auto simp: poly_eval_minus poly_eval_times poly_eval_power simp flip: times_monomial_left) from \a \ _\ have "a \ \ (ideal (insert (1 - ?f) F))" by (simp only: variety_of_ideal) moreover from \f ^ m \ ideal F\ ideal.span_mono have "f ^ m \ ideal (insert (1 - ?f) F)" by (rule rev_subsetD) blast ultimately have "poly_eval a (f ^ m) = 0" by (rule variety_ofD) with \poly_eval a (f ^ m) \ 0\ show "a \ {}" .. qed simp ultimately have "ideal (insert (1 - ?f) F) = UNIV" by (rule weak_Nullstellensatz) thus "1 \ ideal (insert (1 - ?f) F)" by simp next assume "1 \ ideal (insert (1 - ?f) F)" have "\ (insert (1 - ?f) F) = {}" proof (intro subset_antisym subsetI) fix a assume "a \ \ (insert (1 - ?f) F)" hence "a \ \ (ideal (insert (1 - ?f) F))" by (simp only: variety_of_ideal) hence "poly_eval a 1 = 0" using \1 \ _\ by (rule variety_ofD) thus "a \ {}" by simp qed simp with assms show "f \ \ideal F" by (rule radical_idealI) qed qed end (* theory *)