# HG changeset patch # User paulson # Date 1556621865 -3600 # Node ID 8371a25ca1779cceda355e38ce1c88594efa9e08 # Parent 58191e01f0b13afc56347175854118a0af4ce8f7 Algebraic closure: moving more theorems into their rightful places diff -r 58191e01f0b1 -r 8371a25ca177 NEWS --- a/NEWS Mon Apr 29 17:11:26 2019 +0100 +++ b/NEWS Tue Apr 30 11:57:45 2019 +0100 @@ -266,7 +266,7 @@ at the level of abstract topological spaces. * Session HOL-Algebra: Free abelian groups, etc., ported from HOL Light; -proofs towards algebraic closure by de Vilhena and Baillon. + algebraic closure of a field by de Vilhena and Baillon. * Session HOL-Homology has been added. It is a port of HOL Light's homology library, with new proofs of "invariance of domain" and related diff -r 58191e01f0b1 -r 8371a25ca177 src/HOL/Algebra/Algebraic_Closure.thy --- a/src/HOL/Algebra/Algebraic_Closure.thy Mon Apr 29 17:11:26 2019 +0100 +++ b/src/HOL/Algebra/Algebraic_Closure.thy Tue Apr 30 11:57:45 2019 +0100 @@ -61,7 +61,7 @@ lemma (in field) law_restrict_is_field: "field (law_restrict R)" proof - have "comm_monoid_axioms (law_restrict R)" - using m_comm unfolding comm_monoid_axioms_def law_restrict_carrier law_restrict_mult by auto + using m_comm unfolding comm_monoid_axioms_def law_restrict_carrier law_restrict_mult by auto then interpret L: cring "law_restrict R" using cring.intro law_restrict_is_ring comm_monoid.intro ring.is_monoid by auto have "Units R = Units (law_restrict R)" @@ -69,7 +69,7 @@ thus ?thesis using L.cring_fieldI unfolding field_Units law_restrict_carrier law_restrict_zero by simp qed - + lemma law_restrict_iso_imp_eq: assumes "id \ ring_iso (law_restrict A) (law_restrict B)" and "ring A" and "ring B" shows "law_restrict A = law_restrict B" @@ -108,33 +108,33 @@ subsection \Partial Order\ -lemma iso_incl_backwards: +lemma iso_incl_backwards: assumes "A \ B" shows "id \ ring_hom A B" using assms by cases -lemma iso_incl_antisym_aux: +lemma iso_incl_antisym_aux: assumes "A \ B" and "B \ A" shows "id \ ring_iso A B" -proof - - have hom: "id \ ring_hom A B" "id \ ring_hom B A" +proof - + have hom: "id \ ring_hom A B" "id \ ring_hom B A" using assms(1-2)[THEN iso_incl_backwards] by auto - thus ?thesis + thus ?thesis using hom[THEN ring_hom_memE(1)] by (auto simp add: ring_iso_def bij_betw_def inj_on_def) qed -lemma iso_incl_refl: "A \ A" +lemma iso_incl_refl: "A \ A" by (rule iso_inclI[OF ring_hom_memI], auto) -lemma iso_incl_trans: +lemma iso_incl_trans: assumes "A \ B" and "B \ C" shows "A \ C" using ring_hom_trans[OF assms[THEN iso_incl_backwards]] by auto lemma (in ring) iso_incl_antisym: assumes "A \ \" "B \ \" and "A \ B" "B \ A" shows "A = B" -proof - - obtain A' B' :: "(('a list \ nat) multiset \ 'a) ring" +proof - + obtain A' B' :: "(('a list \ nat) multiset \ 'a) ring" where A: "A = law_restrict A'" "ring A'" and B: "B = law_restrict B'" "ring B'" using assms(1-2) field.is_ring by (auto simp add: extensions_def) - thus ?thesis + thus ?thesis using law_restrict_iso_imp_eq iso_incl_antisym_aux[OF assms(3-4)] by simp qed @@ -190,7 +190,7 @@ subsection \Chains\ definition union_ring :: "(('a, 'c) ring_scheme) set \ 'a ring" - where "union_ring C = + where "union_ring C = \ carrier = (\(carrier ` C)), monoid.mult = (\a b. (monoid.mult (SOME R. R \ C \ a \ carrier R \ b \ carrier R) a b)), one = one (SOME R. R \ C), @@ -277,7 +277,7 @@ using field_chain by simp show "a \\<^bsub>union_ring C\<^esub> b \ carrier (union_ring C)" - using R(1-3) unfolding same_laws(1)[OF R(1-3)] unfolding union_ring_def by auto + using R(1-3) unfolding same_laws(1)[OF R(1-3)] unfolding union_ring_def by auto show "(a \\<^bsub>union_ring C\<^esub> b) \\<^bsub>union_ring C\<^esub> c = a \\<^bsub>union_ring C\<^esub> (b \\<^bsub>union_ring C\<^esub> c)" and "a \\<^bsub>union_ring C\<^esub> b = b \\<^bsub>union_ring C\<^esub> a" and "\\<^bsub>union_ring C\<^esub> \\<^bsub>union_ring C\<^esub> a = a" @@ -286,7 +286,7 @@ next show "\\<^bsub>union_ring C\<^esub> \ carrier (union_ring C)" using ring.ring_simprules(6)[OF ring_chain] assms same_one_same_zero(1) - unfolding union_ring_carrier by auto + unfolding union_ring_carrier by auto qed lemma union_ring_is_abelian_group: @@ -304,7 +304,7 @@ show "(a \\<^bsub>union_ring C\<^esub> b) \\<^bsub>union_ring C\<^esub> c = (a \\<^bsub>union_ring C\<^esub> c) \\<^bsub>union_ring C\<^esub> (b \\<^bsub>union_ring C\<^esub> c)" and "(a \\<^bsub>union_ring C\<^esub> b) \\<^bsub>union_ring C\<^esub> c = a \\<^bsub>union_ring C\<^esub> (b \\<^bsub>union_ring C\<^esub> c)" and "a \\<^bsub>union_ring C\<^esub> b = b \\<^bsub>union_ring C\<^esub> a" - and "\\<^bsub>union_ring C\<^esub> \\<^bsub>union_ring C\<^esub> a = a" + and "\\<^bsub>union_ring C\<^esub> \\<^bsub>union_ring C\<^esub> a = a" using same_one_same_zero[OF R(1)] same_laws[OF R(1)] R(2-4) l_distr a_assoc a_comm by auto have "\a' \ carrier R. a' \\<^bsub>union_ring C\<^esub> a = \\<^bsub>union_ring C\<^esub>" using same_laws(2)[OF R(1)] R(2) same_one_same_zero[OF R(1)] by simp @@ -330,7 +330,7 @@ using field_chain by simp from \a \ carrier R\ and \a \ \\<^bsub>union_ring C\<^esub>\ have "a \ Units R" - unfolding same_one_same_zero[OF R(1)] field_Units by auto + unfolding same_one_same_zero[OF R(1)] field_Units by auto hence "\a' \ carrier R. a' \\<^bsub>union_ring C\<^esub> a = \\<^bsub>union_ring C\<^esub> \ a \\<^bsub>union_ring C\<^esub> a' = \\<^bsub>union_ring C\<^esub>" using same_laws[OF R(1)] same_one_same_zero[OF R(1)] R(2) unfolding Units_def by auto with \R \ C\ and \a \ carrier (union_ring C)\ show "a \ Units (union_ring C)" @@ -457,11 +457,11 @@ hence "set (map h p) \ carrier S" by (induct p) (auto) moreover have "h a = \\<^bsub>S\<^esub> \ a = \\<^bsub>R\<^esub>" if "a \ carrier R" for a - using non_trivial_field_hom_is_inj[OF assms(1-3)] that unfolding inj_on_def by simp + using non_trivial_field_hom_is_inj[OF assms(1-3)] that unfolding inj_on_def by simp with \set p \ carrier R\ have "lead_coeff (map h p) \ \\<^bsub>S\<^esub>" if "p \ []" using lc[OF that] that by (cases p) (auto) ultimately show ?thesis - unfolding sym[OF univ_poly_carrier] polynomial_def by auto + unfolding sym[OF univ_poly_carrier] polynomial_def by auto qed lemma (in ring_hom_ring) subfield_polynomial_hom: @@ -482,1147 +482,6 @@ qed -(* MOVE ========== *) -subsection \Roots and Multiplicity\ - -definition (in ring) is_root :: "'a list \ 'a \ bool" - where "is_root p x \ (x \ carrier R \ eval p x = \ \ p \ [])" - -definition (in ring) alg_mult :: "'a list \ 'a \ nat" - where "alg_mult p x = - (if p = [] then 0 else - (if x \ carrier R then Greatest (\ n. ([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> n) pdivides p) else 0))" - -definition (in ring) roots :: "'a list \ 'a multiset" - where "roots p = Abs_multiset (alg_mult p)" - -definition (in ring) roots_on :: "'a set \ 'a list \ 'a multiset" - where "roots_on K p = roots p \# mset_set K" - -definition (in ring) splitted :: "'a list \ bool" - where "splitted p \ size (roots p) = degree p" - -definition (in ring) splitted_on :: "'a set \ 'a list \ bool" - where "splitted_on K p \ size (roots_on K p) = degree p" - -lemma (in domain) polynomial_pow_not_zero: - assumes "p \ carrier (poly_ring R)" and "p \ []" - shows "p [^]\<^bsub>poly_ring R\<^esub> (n::nat) \ []" -proof - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - from assms UP.integral show ?thesis - unfolding sym[OF univ_poly_zero[of R "carrier R"]] - by (induction n, auto) -qed - -lemma (in domain) subring_polynomial_pow_not_zero: - assumes "subring K R" and "p \ carrier (K[X])" and "p \ []" - shows "p [^]\<^bsub>K[X]\<^esub> (n::nat) \ []" - using domain.polynomial_pow_not_zero[OF subring_is_domain, of K p n] assms - unfolding univ_poly_consistent[OF assms(1)] by simp - -lemma (in domain) polynomial_pow_degree: - assumes "p \ carrier (poly_ring R)" - shows "degree (p [^]\<^bsub>poly_ring R\<^esub> n) = n * degree p" -proof - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - show ?thesis - proof (induction n) - case 0 thus ?case - using UP.nat_pow_0 unfolding univ_poly_one by auto - next - let ?ppow = "\n. p [^]\<^bsub>poly_ring R\<^esub> n" - case (Suc n) thus ?case - proof (cases "p = []") - case True thus ?thesis - using univ_poly_zero[of R "carrier R"] UP.r_null assms by auto - next - case False - hence "?ppow n \ carrier (poly_ring R)" and "?ppow n \ []" and "p \ []" - using polynomial_pow_not_zero[of p n] assms by (auto simp add: univ_poly_one) - thus ?thesis - using poly_mult_degree_eq[OF carrier_is_subring, of "?ppow n" p] Suc assms - unfolding univ_poly_carrier univ_poly_zero - by (auto simp add: add.commute univ_poly_mult) - qed - qed -qed - -lemma (in domain) polynomial_pow_division: - assumes "p \ carrier (poly_ring R)" and "(n::nat) \ m" - shows "(p [^]\<^bsub>poly_ring R\<^esub> n) pdivides (p [^]\<^bsub>poly_ring R\<^esub> m)" -proof - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - let ?ppow = "\n. p [^]\<^bsub>poly_ring R\<^esub> n" - - have "?ppow n \\<^bsub>poly_ring R\<^esub> ?ppow k = ?ppow (n + k)" for k - using assms(1) by (simp add: UP.nat_pow_mult) - thus ?thesis - using dividesI[of "?ppow (m - n)" "poly_ring R" "?ppow m" "?ppow n"] assms - unfolding pdivides_def by auto -qed - -lemma (in domain) degree_zero_imp_not_is_root: - assumes "p \ carrier (poly_ring R)" and "degree p = 0" shows "\ is_root p x" -proof (cases "p = []", simp add: is_root_def) - case False with \degree p = 0\ have "length p = Suc 0" - using le_SucE by fastforce - then obtain a where "p = [ a ]" and "a \ carrier R" and "a \ \" - using assms unfolding sym[OF univ_poly_carrier] polynomial_def - by (metis False length_0_conv length_Suc_conv list.sel(1) list.set_sel(1) subset_code(1)) - thus ?thesis - unfolding is_root_def by auto -qed - -lemma (in domain) is_root_imp_pdivides: - assumes "p \ carrier (poly_ring R)" - shows "is_root p x \ [ \, \ x ] pdivides p" -proof - - let ?b = "[ \ , \ x ]" - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - assume "is_root p x" hence x: "x \ carrier R" and is_root: "eval p x = \" - unfolding is_root_def by auto - hence b: "?b \ carrier (poly_ring R)" - unfolding sym[OF univ_poly_carrier] polynomial_def by auto - then obtain q r where q: "q \ carrier (poly_ring R)" and r: "r \ carrier (poly_ring R)" - and long_divides: "p = (?b \\<^bsub>poly_ring R\<^esub> q) \\<^bsub>poly_ring R\<^esub> r" "r = [] \ degree r < degree ?b" - using long_division_theorem[OF carrier_is_subring, of p ?b] assms by (auto simp add: univ_poly_carrier) - - show ?thesis - proof (cases "r = []") - case True then have "r = \\<^bsub>poly_ring R\<^esub>" - unfolding univ_poly_zero[of R "carrier R"] . - thus ?thesis - using long_divides(1) q r b dividesI[OF q, of p ?b] by (simp add: pdivides_def) - next - case False then have "length r = Suc 0" - using long_divides(2) le_SucE by fastforce - then obtain a where "r = [ a ]" and a: "a \ carrier R" and "a \ \" - using r unfolding sym[OF univ_poly_carrier] polynomial_def - by (metis False length_0_conv length_Suc_conv list.sel(1) list.set_sel(1) subset_code(1)) - - have "eval p x = ((eval ?b x) \ (eval q x)) \ (eval r x)" - using long_divides(1) ring_hom_memE[OF eval_is_hom[OF carrier_is_subring x]] by (simp add: b q r) - also have " ... = eval r x" - using ring_hom_memE[OF eval_is_hom[OF carrier_is_subring x]] x b q r by (auto, algebra) - finally have "a = \" - using a unfolding \r = [ a ]\ is_root by simp - with \a \ \\ have False .. thus ?thesis .. - qed -qed - -lemma (in domain) pdivides_imp_is_root: - assumes "p \ []" and "x \ carrier R" - shows "[ \, \ x ] pdivides p \ is_root p x" -proof - - assume "[ \, \ x ] pdivides p" - then obtain q where q: "q \ carrier (poly_ring R)" and pdiv: "p = [ \, \ x ] \\<^bsub>poly_ring R\<^esub> q" - unfolding pdivides_def by auto - moreover have "[ \, \ x ] \ carrier (poly_ring R)" - using assms(2) unfolding sym[OF univ_poly_carrier] polynomial_def by simp - ultimately have "eval p x = \" - using ring_hom_memE[OF eval_is_hom[OF carrier_is_subring, of x]] assms(2) by (auto, algebra) - with \p \ []\ and \x \ carrier R\ show "is_root p x" - unfolding is_root_def by simp -qed - -lemma (in domain) associated_polynomials_imp_same_is_root: - assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" and "p \\<^bsub>poly_ring R\<^esub> q" - shows "is_root p x \ is_root q x" -proof (cases "p = []") - case True with \p \\<^bsub>poly_ring R\<^esub> q\ have "q = []" - unfolding associated_def True factor_def univ_poly_def by auto - thus ?thesis - using True unfolding is_root_def by simp -next - case False - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - { fix p q - assume p: "p \ carrier (poly_ring R)" and q: "q \ carrier (poly_ring R)" and pq: "p \\<^bsub>poly_ring R\<^esub> q" - have "is_root p x \ is_root q x" - proof - - assume is_root: "is_root p x" - then have "[ \, \ x ] pdivides p" and "p \ []" and "x \ carrier R" - using is_root_imp_pdivides[OF p] unfolding is_root_def by auto - moreover have "[ \, \ x ] \ carrier (poly_ring R)" - using is_root unfolding is_root_def sym[OF univ_poly_carrier] polynomial_def by simp - ultimately have "[ \, \ x ] pdivides q" - using UP.divides_cong_r[OF _ pq ] unfolding pdivides_def by simp - with \p \ []\ and \x \ carrier R\ show ?thesis - using associated_polynomials_imp_same_length[OF carrier_is_subring p q pq] - pdivides_imp_is_root[of q x] - by fastforce - qed - } - - then show ?thesis - using assms UP.associated_sym[OF assms(3)] by blast -qed - -lemma (in ring) monic_degree_one_root_condition: - assumes "a \ carrier R" shows "is_root [ \, \ a ] b \ a = b" - using assms minus_equality r_neg[OF assms] unfolding is_root_def by (auto, fastforce) - -lemma (in field) degree_one_root_condition: - assumes "p \ carrier (poly_ring R)" and "degree p = 1" - shows "is_root p x \ x = \ (inv (lead_coeff p) \ (const_term p))" -proof - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - from \degree p = 1\ have "length p = Suc (Suc 0)" - by simp - then obtain a b where p: "p = [ a, b ]" - by (metis length_0_conv length_Cons list.exhaust nat.inject) - hence a: "a \ carrier R" "a \ \" and b: "b \ carrier R" - using assms(1) unfolding sym[OF univ_poly_carrier] polynomial_def by auto - hence inv_a: "inv a \ carrier R" "(inv a) \ a = \" - using subfield_m_inv[OF carrier_is_subfield, of a] by auto - hence in_carrier: "[ \, (inv a) \ b ] \ carrier (poly_ring R)" - using b unfolding sym[OF univ_poly_carrier] polynomial_def by auto - - have "p \\<^bsub>poly_ring R\<^esub> [ \, (inv a) \ b ]" - proof (rule UP.associatedI2'[OF _ _ in_carrier, of _ "[ a ]"]) - have "p = [ a ] \\<^bsub>poly_ring R\<^esub> [ \, inv a \ b ]" - using a inv_a b m_assoc[of a "inv a" b] unfolding p univ_poly_mult by (auto, algebra) - also have " ... = [ \, inv a \ b ] \\<^bsub>poly_ring R\<^esub> [ a ]" - using UP.m_comm[OF in_carrier, of "[ a ]"] a - by (auto simp add: sym[OF univ_poly_carrier] polynomial_def) - finally show "p = [ \, inv a \ b ] \\<^bsub>poly_ring R\<^esub> [ a ]" . - next - from \a \ carrier R\ and \a \ \\ show "[ a ] \ Units (poly_ring R)" - unfolding univ_poly_units[OF carrier_is_subfield] by simp - qed - - moreover have "(inv a) \ b = \ (\ (inv (lead_coeff p) \ (const_term p)))" - and "inv (lead_coeff p) \ (const_term p) \ carrier R" - using inv_a a b unfolding p const_term_def by auto - - ultimately show ?thesis - using associated_polynomials_imp_same_is_root[OF assms(1) in_carrier] - monic_degree_one_root_condition - by (metis add.inv_closed) -qed - -lemma (in domain) is_root_imp_is_root_poly_mult: - assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" and "q \ []" - shows "is_root p x \ is_root (p \\<^bsub>poly_ring R\<^esub> q) x" -proof - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - assume "is_root p x" then have x: "x \ carrier R" and eval: "eval p x = \" and not_zero: "p \ []" - unfolding is_root_def by simp+ - hence "p \\<^bsub>poly_ring R\<^esub> q \ []" - using assms UP.integral unfolding sym[OF univ_poly_zero[of R "carrier R"]] by blast - moreover have "eval (p \\<^bsub>poly_ring R\<^esub> q) x = \" - using assms eval ring_hom_memE[OF eval_is_hom[OF carrier_is_subring x]] by auto - ultimately show ?thesis - using x unfolding is_root_def by simp -qed - -lemma (in domain) is_root_poly_mult_imp_is_root: - assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" - shows "is_root (p \\<^bsub>poly_ring R\<^esub> q) x \ (is_root p x) \ (is_root q x)" -proof - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - assume is_root: "is_root (p \\<^bsub>poly_ring R\<^esub> q) x" - hence "p \ []" and "q \ []" - unfolding is_root_def sym[OF univ_poly_zero[of R "carrier R"]] - using UP.l_null[OF assms(2)] UP.r_null[OF assms(1)] by blast+ - moreover have x: "x \ carrier R" and "eval (p \\<^bsub>poly_ring R\<^esub> q) x = \" - using is_root unfolding is_root_def by simp+ - hence "eval p x = \ \ eval q x = \" - using ring_hom_memE[OF eval_is_hom[OF carrier_is_subring], of x] assms integral by auto - ultimately show "(is_root p x) \ (is_root q x)" - using x unfolding is_root_def by auto -qed - -(* -lemma (in domain) - assumes "subfield K R" and "p \ carrier (K[X])" and "degree p = 1" - shows "pprime K p" -proof (rule pprimeI[OF assms(1-2)]) - from \degree p = 1\ show "p \ []" and "p \ Units (K [X])" - unfolding univ_poly_units[OF assms(1)] by auto -next - fix q r - assume "q \ carrier (K[X])" and "r \ carrier (K[X])" - and pdiv: "p pdivides q \\<^bsub>K [X]\<^esub> r" - hence "q \ carrier (poly_ring R)" and "r \ carrier (poly_ring R)" - using carrier_polynomial_shell[OF subfieldE(1)[OF assms(1)]] by auto - moreover obtain b where b: "b \" -qed -*) - -lemma (in domain) finite_number_of_roots: - assumes "p \ carrier (poly_ring R)" shows "finite { x. is_root p x }" - using assms -proof (induction "degree p" arbitrary: p) - case 0 thus ?case - by (simp add: degree_zero_imp_not_is_root) -next - case (Suc n) show ?case - proof (cases "{ x. is_root p x } = {}") - case True thus ?thesis - by (simp add: True) - next - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - case False - then obtain a where is_root: "is_root p a" - by blast - hence a: "a \ carrier R" and eval: "eval p a = \" and p_not_zero: "p \ []" - unfolding is_root_def by auto - hence in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" - unfolding sym[OF univ_poly_carrier] polynomial_def by auto - - obtain q where q: "q \ carrier (poly_ring R)" and p: "p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> q" - using is_root_imp_pdivides[OF Suc(3) is_root] unfolding pdivides_def by auto - with \p \ []\ have q_not_zero: "q \ []" - using UP.r_null UP.integral in_carrier unfolding sym[OF univ_poly_zero[of R "carrier R"]] - by metis - hence "degree q = n" - using poly_mult_degree_eq[OF carrier_is_subring, of "[ \, \ a ]" q] - in_carrier q p_not_zero p Suc(2) - unfolding univ_poly_carrier - by (metis One_nat_def Suc_eq_plus1 diff_Suc_1 list.distinct(1) - list.size(3-4) plus_1_eq_Suc univ_poly_mult) - hence "finite { x. is_root q x }" - using Suc(1)[OF _ q] by simp - - moreover have "{ x. is_root p x } \ insert a { x. is_root q x }" - using is_root_poly_mult_imp_is_root[OF in_carrier q] - monic_degree_one_root_condition[OF a] - unfolding p by auto - - ultimately show ?thesis - using finite_subset by auto - qed -qed - -lemma (in domain) alg_multE: - assumes "x \ carrier R" and "p \ carrier (poly_ring R)" and "p \ []" - shows "([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult p x)) pdivides p" - and "\n. ([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> n) pdivides p \ n \ alg_mult p x" -proof - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - let ?ppow = "\n :: nat. ([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> n)" - - define S :: "nat set" where "S = { n. ?ppow n pdivides p }" - have "?ppow 0 = \\<^bsub>poly_ring R\<^esub>" - using UP.nat_pow_0 by simp - hence "0 \ S" - using UP.one_divides[OF assms(2)] unfolding S_def pdivides_def by simp - hence "S \ {}" - by auto - - moreover have "n \ degree p" if "n \ S" for n :: nat - proof - - have "[ \, \ x ] \ carrier (poly_ring R)" - using assms unfolding sym[OF univ_poly_carrier] polynomial_def by auto - hence "?ppow n \ carrier (poly_ring R)" - using assms unfolding univ_poly_zero by auto - with \n \ S\ have "degree (?ppow n) \ degree p" - using pdivides_imp_degree_le[OF carrier_is_subring _ assms(2-3), of "?ppow n"] by (simp add: S_def) - with \[ \, \ x ] \ carrier (poly_ring R)\ show ?thesis - using polynomial_pow_degree by simp - qed - hence "finite S" - using finite_nat_set_iff_bounded_le by blast - - ultimately have MaxS: "\n. n \ S \ n \ Max S" "Max S \ S" - using Max_ge[of S] Max_in[of S] by auto - with \x \ carrier R\ have "alg_mult p x = Max S" - using Greatest_equality[of "\n. ?ppow n pdivides p" "Max S"] assms(3) - unfolding S_def alg_mult_def by auto - thus "([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult p x)) pdivides p" - and "\n. ([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> n) pdivides p \ n \ alg_mult p x" - using MaxS unfolding S_def by auto -qed - -lemma (in domain) le_alg_mult_imp_pdivides: - assumes "x \ carrier R" and "p \ carrier (poly_ring R)" - shows "n \ alg_mult p x \ ([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> n) pdivides p" -proof - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - assume le_alg_mult: "n \ alg_mult p x" - have in_carrier: "[ \, \ x ] \ carrier (poly_ring R)" - using assms(1) unfolding sym[OF univ_poly_carrier] polynomial_def by auto - hence ppow_pdivides: - "([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> n) pdivides - ([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult p x))" - using polynomial_pow_division[OF _ le_alg_mult] by simp - - show ?thesis - proof (cases "p = []") - case True thus ?thesis - using in_carrier pdivides_zero[OF carrier_is_subring] by auto - next - case False thus ?thesis - using ppow_pdivides UP.divides_trans UP.nat_pow_closed alg_multE(1)[OF assms] in_carrier - unfolding pdivides_def by meson - qed -qed - -lemma (in domain) alg_mult_gt_zero_iff_is_root: - assumes "p \ carrier (poly_ring R)" shows "alg_mult p x > 0 \ is_root p x" -proof - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - show ?thesis - proof - assume is_root: "is_root p x" hence x: "x \ carrier R" and not_zero: "p \ []" - unfolding is_root_def by auto - have "[\, \ x] [^]\<^bsub>poly_ring R\<^esub> (Suc 0) = [\, \ x]" - using x unfolding univ_poly_def by auto - thus "alg_mult p x > 0" - using is_root_imp_pdivides[OF _ is_root] alg_multE(2)[OF x, of p "Suc 0"] not_zero assms by auto - next - assume gt_zero: "alg_mult p x > 0" - hence x: "x \ carrier R" and not_zero: "p \ []" - unfolding alg_mult_def by (cases "p = []", auto, cases "x \ carrier R", auto) - hence in_carrier: "[ \, \ x ] \ carrier (poly_ring R)" - unfolding sym[OF univ_poly_carrier] polynomial_def by auto - with \x \ carrier R\ have "[ \, \ x ] pdivides p" and "eval [ \, \ x ] x = \" - using le_alg_mult_imp_pdivides[of x p "1::nat"] gt_zero assms by (auto, algebra) - thus "is_root p x" - using pdivides_imp_root_sharing[OF in_carrier] not_zero x by (simp add: is_root_def) - qed -qed - -lemma (in domain) alg_mult_in_multiset: - assumes "p \ carrier (poly_ring R)" shows "alg_mult p \ multiset" - using assms alg_mult_gt_zero_iff_is_root finite_number_of_roots unfolding multiset_def by auto - -lemma (in domain) alg_mult_eq_count_roots: - assumes "p \ carrier (poly_ring R)" shows "alg_mult p = count (roots p)" - using alg_mult_in_multiset[OF assms] by (simp add: roots_def) - -lemma (in domain) roots_mem_iff_is_root: - assumes "p \ carrier (poly_ring R)" shows "x \# roots p \ is_root p x" - using alg_mult_eq_count_roots[OF assms] count_greater_zero_iff - unfolding roots_def sym[OF alg_mult_gt_zero_iff_is_root[OF assms]] by metis - -lemma (in domain) degree_zero_imp_empty_roots: - assumes "p \ carrier (poly_ring R)" and "degree p = 0" shows "roots p = {#}" -proof - - have "alg_mult p = (\x. 0)" - proof (cases "p = []") - case True thus ?thesis - using assms unfolding alg_mult_def by auto - next - case False hence "length p = Suc 0" - using assms(2) by (simp add: le_Suc_eq) - then obtain a where "a \ carrier R" and "a \ \" and p: "p = [ a ]" - using assms(1) unfolding sym[OF univ_poly_carrier] polynomial_def - by (metis Suc_length_conv hd_in_set length_0_conv list.sel(1) subset_code(1)) - show ?thesis - proof (rule ccontr) - assume "alg_mult p \ (\x. 0)" - then obtain x where "alg_mult p x > 0" - by auto - with \p \ []\ have "eval p x = \" - using alg_mult_gt_zero_iff_is_root[OF assms(1), of x] unfolding is_root_def by simp - with \a \ carrier R\ have "a = \" - unfolding p by auto - with \a \ \\ show False .. - qed - qed - thus ?thesis - by (simp add: roots_def zero_multiset.abs_eq) -qed - -lemma (in domain) degree_zero_imp_splitted: - assumes "p \ carrier (poly_ring R)" and "degree p = 0" shows "splitted p" - unfolding splitted_def degree_zero_imp_empty_roots[OF assms] assms(2) by simp - -lemma (in domain) roots_inclI': - assumes "p \ carrier (poly_ring R)" and "\a. \ a \ carrier R; p \ [] \ \ alg_mult p a \ count m a" - shows "roots p \# m" -proof (intro mset_subset_eqI) - fix a show "count (roots p) a \ count m a" - using assms unfolding sym[OF alg_mult_eq_count_roots[OF assms(1)]] alg_mult_def - by (cases "p = []", simp, cases "a \ carrier R", auto) -qed - -lemma (in domain) roots_inclI: - assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" "q \ []" - and "\a. \ a \ carrier R; p \ [] \ \ ([ \, \ a ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult p a)) pdivides q" - shows "roots p \# roots q" - using roots_inclI'[OF assms(1), of "roots q"] assms alg_multE(2)[OF _ assms(2-3)] - unfolding sym[OF alg_mult_eq_count_roots[OF assms(2)]] by auto - -lemma (in domain) pdivides_imp_roots_incl: - assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" "q \ []" - shows "p pdivides q \ roots p \# roots q" -proof (rule roots_inclI[OF assms]) - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - fix a assume "p pdivides q" and a: "a \ carrier R" - hence "[ \ , \ a ] \ carrier (poly_ring R)" - unfolding sym[OF univ_poly_carrier] polynomial_def by simp - with \p pdivides q\ show "([\, \ a] [^]\<^bsub>poly_ring R\<^esub> (alg_mult p a)) pdivides q" - using UP.divides_trans[of _p q] le_alg_mult_imp_pdivides[OF a assms(1)] - by (auto simp add: pdivides_def) -qed - -lemma (in domain) associated_polynomials_imp_same_roots: - assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" and "p \\<^bsub>poly_ring R\<^esub> q" - shows "roots p = roots q" - using assms pdivides_imp_roots_incl zero_pdivides - unfolding pdivides_def associated_def - by (metis subset_mset.eq_iff) - -(* MOVE to Polynomial_Divisibility.thy *) -lemma (in comm_monoid_cancel) prime_pow_divides_iff: - assumes "p \ carrier G" "a \ carrier G" "b \ carrier G" and "prime G p" and "\ (p divides a)" - shows "(p [^] (n :: nat)) divides (a \ b) \ (p [^] n) divides b" -proof - assume "(p [^] n) divides b" thus "(p [^] n) divides (a \ b)" - using divides_prod_l[of "p [^] n" b a] assms by simp -next - assume "(p [^] n) divides (a \ b)" thus "(p [^] n) divides b" - proof (induction n) - case 0 with \b \ carrier G\ show ?case - by (simp add: unit_divides) - next - case (Suc n) - hence "(p [^] n) divides (a \ b)" and "(p [^] n) divides b" - using assms(1) divides_prod_r by auto - with \(p [^] (Suc n)) divides (a \ b)\ obtain c d - where c: "c \ carrier G" and "b = (p [^] n) \ c" - and d: "d \ carrier G" and "a \ b = (p [^] (Suc n)) \ d" - using assms by blast - hence "(p [^] n) \ (a \ c) = (p [^] n) \ (p \ d)" - using assms by (simp add: m_assoc m_lcomm) - hence "a \ c = p \ d" - using c d assms(1) assms(2) l_cancel by blast - with \\ (p divides a)\ and \prime G p\ have "p divides c" - by (metis assms(2) c d dividesI' prime_divides) - with \b = (p [^] n) \ c\ show ?case - using assms(1) c by simp - qed -qed - -(* MOVE to Polynomial_Divisibility.thy *) -lemma (in domain) pirreducible_pow_pdivides_iff: - assumes "subfield K R" "p \ carrier (K[X])" "q \ carrier (K[X])" "r \ carrier (K[X])" - and "pirreducible K p" and "\ (p pdivides q)" - shows "(p [^]\<^bsub>K[X]\<^esub> (n :: nat)) pdivides (q \\<^bsub>K[X]\<^esub> r) \ (p [^]\<^bsub>K[X]\<^esub> n) pdivides r" -proof - - interpret UP: principal_domain "K[X]" - using univ_poly_is_principal[OF assms(1)] . - show ?thesis - proof (cases "r = []") - case True with \q \ carrier (K[X])\ have "q \\<^bsub>K[X]\<^esub> r = []" and "r = []" - unfolding sym[OF univ_poly_zero[of R K]] by auto - thus ?thesis - using pdivides_zero[OF subfieldE(1),of K] assms by auto - next - case False then have not_zero: "p \ []" "q \ []" "r \ []" "q \\<^bsub>K[X]\<^esub> r \ []" - using subfieldE(1) pdivides_zero[OF _ assms(2)] assms(1-2,5-6) pirreducibleE(1) - UP.integral_iff[OF assms(3-4)] univ_poly_zero[of R K] by auto - from \p \ []\ - have ppow: "p [^]\<^bsub>K[X]\<^esub> (n :: nat) \ []" "p [^]\<^bsub>K[X]\<^esub> (n :: nat) \ carrier (K[X])" - using subring_polynomial_pow_not_zero[OF subfieldE(1)] assms(1-2) by auto - have not_pdiv: "\ (p divides\<^bsub>mult_of (K[X])\<^esub> q)" - using assms(6) pdivides_iff_shell[OF assms(1-3)] unfolding pdivides_def by auto - have prime: "prime (mult_of (K[X])) p" - using assms(5) pprime_iff_pirreducible[OF assms(1-2)] - unfolding sym[OF UP.prime_eq_prime_mult[OF assms(2)]] ring_prime_def by simp - have "a pdivides b \ a divides\<^bsub>mult_of (K[X])\<^esub> b" - if "a \ carrier (K[X])" "a \ \\<^bsub>K[X]\<^esub>" "b \ carrier (K[X])" "b \ \\<^bsub>K[X]\<^esub>" for a b - using that UP.divides_imp_divides_mult[of a b] divides_mult_imp_divides[of "K[X]" a b] - unfolding pdivides_iff_shell[OF assms(1) that(1,3)] by blast - thus ?thesis - using UP.mult_of.prime_pow_divides_iff[OF _ _ _ prime not_pdiv, of r] ppow not_zero assms(2-4) - unfolding nat_pow_mult_of carrier_mult_of mult_mult_of sym[OF univ_poly_zero[of R K]] - by (metis DiffI UP.m_closed singletonD) - qed -qed - -(* MOVE to Polynomial_Divisibility.thy *) -lemma (in domain) univ_poly_units': - assumes "subfield K R" shows "p \ Units (K[X]) \ p \ carrier (K[X]) \ p \ [] \ degree p = 0" - unfolding univ_poly_units[OF assms] sym[OF univ_poly_carrier] polynomial_def - by (auto, metis hd_in_set le_0_eq le_Suc_eq length_0_conv length_Suc_conv list.sel(1) subsetD) - -(* MOVE to Polynomial_Divisibility.thy *) -lemma (in domain) subring_degree_one_imp_pirreducible: - assumes "subring K R" and "a \ Units (R \ carrier := K \)" and "b \ K" - shows "pirreducible K [ a, b ]" -proof (rule pirreducibleI[OF assms(1)]) - have "a \ K" and "a \ \" - using assms(2) subringE(1)[OF assms(1)] unfolding Units_def by auto - thus "[ a, b ] \ carrier (K[X])" and "[ a, b ] \ []" and "[ a, b ] \ Units (K [X])" - using univ_poly_units_incl[OF assms(1)] assms(2-3) - unfolding sym[OF univ_poly_carrier] polynomial_def by auto -next - interpret UP: domain "K[X]" - using univ_poly_is_domain[OF assms(1)] . - - { fix q r - assume q: "q \ carrier (K[X])" and r: "r \ carrier (K[X])" and "[ a, b ] = q \\<^bsub>K[X]\<^esub> r" - hence not_zero: "q \ []" "r \ []" - by (metis UP.integral_iff list.distinct(1) univ_poly_zero)+ - have "degree (q \\<^bsub>K[X]\<^esub> r) = degree q + degree r" - using not_zero poly_mult_degree_eq[OF assms(1)] q r - by (simp add: univ_poly_carrier univ_poly_mult) - with sym[OF \[ a, b ] = q \\<^bsub>K[X]\<^esub> r\] have "degree q + degree r = 1" and "q \ []" "r \ []" - using not_zero by auto - } note aux_lemma1 = this - - { fix q r - assume q: "q \ carrier (K[X])" "q \ []" and r: "r \ carrier (K[X])" "r \ []" - and "[ a, b ] = q \\<^bsub>K[X]\<^esub> r" and "degree q = 1" and "degree r = 0" - hence "length q = Suc (Suc 0)" and "length r = Suc 0" - by (linarith, metis add.right_neutral add_eq_if length_0_conv) - from \length q = Suc (Suc 0)\ obtain c d where q_def: "q = [ c, d ]" - by (metis length_0_conv length_Cons list.exhaust nat.inject) - from \length r = Suc 0\ obtain e where r_def: "r = [ e ]" - by (metis length_0_conv length_Suc_conv) - from \r = [ e ]\ and \q = [ c, d ]\ - have c: "c \ K" "c \ \" and d: "d \ K" and e: "e \ K" "e \ \" - using r q subringE(1)[OF assms(1)] unfolding sym[OF univ_poly_carrier] polynomial_def by auto - with sym[OF \[ a, b ] = q \\<^bsub>K[X]\<^esub> r\] have "a = c \ e" - using poly_mult_lead_coeff[OF assms(1), of q r] - unfolding polynomial_def sym[OF univ_poly_mult[of R K]] r_def q_def by auto - obtain inv_a where a: "a \ K" and inv_a: "inv_a \ K" "a \ inv_a = \" "inv_a \ a = \" - using assms(2) unfolding Units_def by auto - hence "a \ \" and "inv_a \ \" - using subringE(1)[OF assms(1)] integral_iff by auto - with \c \ K\ and \c \ \\ have in_carrier: "[ c \ inv_a ] \ carrier (K[X])" - using subringE(1,6)[OF assms(1)] inv_a integral - unfolding sym[OF univ_poly_carrier] polynomial_def - by (auto, meson subsetD) - moreover have "[ c \ inv_a ] \\<^bsub>K[X]\<^esub> r = [ \ ]" - using \a = c \ e\ a inv_a c e subsetD[OF subringE(1)[OF assms(1)]] - unfolding r_def univ_poly_mult by (auto) (simp add: m_assoc m_lcomm integral_iff)+ - ultimately have "r \ Units (K[X])" - using r(1) UP.m_comm[OF in_carrier r(1)] unfolding sym[OF univ_poly_one[of R K]] Units_def by auto - } note aux_lemma2 = this - - fix q r - assume q: "q \ carrier (K[X])" and r: "r \ carrier (K[X])" and qr: "[ a, b ] = q \\<^bsub>K[X]\<^esub> r" - thus "q \ Units (K[X]) \ r \ Units (K[X])" - using aux_lemma1[OF q r qr] aux_lemma2[of q r] aux_lemma2[of r q] UP.m_comm add_is_1 by auto -qed - -(* MOVE to Polynomial_Divisibility.thy *) -lemma (in domain) degree_one_imp_pirreducible: - assumes "subfield K R" and "p \ carrier (K[X])" and "degree p = 1" - shows "pirreducible K p" -proof - - from \degree p = 1\ have "length p = Suc (Suc 0)" - by simp - then obtain a b where p: "p = [ a, b ]" - by (metis length_0_conv length_Suc_conv) - with \p \ carrier (K[X])\ show ?thesis - using subring_degree_one_imp_pirreducible[OF subfieldE(1)[OF assms(1)], of a b] - subfield.subfield_Units[OF assms(1)] - unfolding sym[OF univ_poly_carrier] polynomial_def by auto -qed - -(* MOVE to Polynomial_Divisibility.thy *) -lemma (in ring) degree_oneE[elim]: - assumes "p \ carrier (K[X])" and "degree p = 1" - and "\a b. \ a \ K; a \ \; b \ K; p = [ a, b ] \ \ P" - shows P -proof - - from \degree p = 1\ have "length p = Suc (Suc 0)" - by simp - then obtain a b where "p = [ a, b ]" - by (metis length_0_conv length_Cons nat.inject neq_Nil_conv) - with \p \ carrier (K[X])\ have "a \ K" and "a \ \" and "b \ K" - unfolding sym[OF univ_poly_carrier] polynomial_def by auto - with \p = [ a, b ]\ show ?thesis - using assms(3) by simp -qed - -(* MOVE to Polynomial_Divisibility.thy *) -lemma (in domain) subring_degree_one_associatedI: - assumes "subring K R" and "a \ K" "a' \ K" and "b \ K" and "a \ a' = \" - shows "[ a , b ] \\<^bsub>K[X]\<^esub> [ \, a' \ b ]" -proof - - from \a \ a' = \\ have not_zero: "a \ \" "a' \ \" - using subringE(1)[OF assms(1)] assms(2-3) by auto - hence "[ a, b ] = [ a ] \\<^bsub>K[X]\<^esub> [ \, a' \ b ]" - using assms(2-4)[THEN subsetD[OF subringE(1)[OF assms(1)]]] assms(5) m_assoc - unfolding univ_poly_mult by fastforce - moreover have "[ a, b ] \ carrier (K[X])" and "[ \, a' \ b ] \ carrier (K[X])" - using subringE(1,3,6)[OF assms(1)] not_zero one_not_zero assms - unfolding sym[OF univ_poly_carrier] polynomial_def by auto - moreover have "[ a ] \ Units (K[X])" - proof - - from \a \ \\ and \a' \ \\ have "[ a ] \ carrier (K[X])" and "[ a' ] \ carrier (K[X])" - using assms(2-3) unfolding sym[OF univ_poly_carrier] polynomial_def by auto - moreover have "a' \ a = \" - using subsetD[OF subringE(1)[OF assms(1)]] assms m_comm by simp - hence "[ a ] \\<^bsub>K[X]\<^esub> [ a' ] = [ \ ]" and "[ a' ] \\<^bsub>K[X]\<^esub> [ a ] = [ \ ]" - using assms unfolding univ_poly_mult by auto - ultimately show ?thesis - unfolding sym[OF univ_poly_one[of R K]] Units_def by blast - qed - ultimately show ?thesis - using domain.ring_associated_iff[OF univ_poly_is_domain[OF assms(1)]] by blast -qed - -(* MOVE to Polynomial_Divisibility.thy *) -lemma (in domain) degree_one_associatedI: - assumes "subfield K R" and "p \ carrier (K[X])" and "degree p = 1" - shows "p \\<^bsub>K[X]\<^esub> [ \, inv (lead_coeff p) \ (const_term p) ]" -proof - - from \p \ carrier (K[X])\ and \degree p = 1\ - obtain a b where "p = [ a, b ]" and "a \ K" "a \ \" and "b \ K" - by auto - thus ?thesis - using subring_degree_one_associatedI[OF subfieldE(1)[OF assms(1)]] - subfield_m_inv[OF assms(1)] subsetD[OF subfieldE(3)[OF assms(1)]] - unfolding const_term_def - by auto -qed - -lemma (in domain) monic_degree_one_roots: - assumes "a \ carrier R" shows "roots [ \ , \ a ] = {# a #}" -proof - - let ?p = "[ \ , \ a ]" - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - from \a \ carrier R\ have in_carrier: "?p \ carrier (poly_ring R)" - unfolding sym[OF univ_poly_carrier] polynomial_def by simp - show ?thesis - proof (rule subset_mset.antisym) - show "{# a #} \# roots ?p" - using roots_mem_iff_is_root[OF in_carrier] - monic_degree_one_root_condition[OF assms] - by simp - next - show "roots ?p \# {# a #}" - proof (rule mset_subset_eqI, auto) - fix b assume "a \ b" thus "count (roots ?p) b = 0" - using alg_mult_gt_zero_iff_is_root[OF in_carrier] - monic_degree_one_root_condition[OF assms] - unfolding sym[OF alg_mult_eq_count_roots[OF in_carrier]] - by fastforce - next - have "(?p [^]\<^bsub>poly_ring R\<^esub> (alg_mult ?p a)) pdivides ?p" - using le_alg_mult_imp_pdivides[OF assms in_carrier] by simp - hence "degree (?p [^]\<^bsub>poly_ring R\<^esub> (alg_mult ?p a)) \ degree ?p" - using pdivides_imp_degree_le[OF carrier_is_subring, of _ ?p] in_carrier by auto - thus "count (roots ?p) a \ Suc 0" - using polynomial_pow_degree[OF in_carrier] - unfolding sym[OF alg_mult_eq_count_roots[OF in_carrier]] - by auto - qed - qed -qed - -lemma (in domain) degree_one_roots: - assumes "a \ carrier R" "a' \ carrier R" and "b \ carrier R" and "a \ a' = \" - shows "roots [ a , b ] = {# \ (a' \ b) #}" -proof - - have "[ a, b ] \ carrier (poly_ring R)" and "[ \, a' \ b ] \ carrier (poly_ring R)" - using assms unfolding sym[OF univ_poly_carrier] polynomial_def by auto - thus ?thesis - using subring_degree_one_associatedI[OF carrier_is_subring assms] assms - monic_degree_one_roots associated_polynomials_imp_same_roots - by (metis add.inv_closed local.minus_minus m_closed) -qed - -lemma (in field) degree_one_imp_singleton_roots: - assumes "p \ carrier (poly_ring R)" and "degree p = 1" - shows "roots p = {# \ (inv (lead_coeff p) \ (const_term p)) #}" -proof - - from \p \ carrier (poly_ring R)\ and \degree p = 1\ - obtain a b where "p = [ a, b ]" and "a \ carrier R" "a \ \" and "b \ carrier R" - by auto - thus ?thesis - using degree_one_roots[of a "inv a" b] - by (auto simp add: const_term_def field_Units) -qed - -lemma (in field) degree_one_imp_splitted: - assumes "p \ carrier (poly_ring R)" and "degree p = 1" shows "splitted p" - using degree_one_imp_singleton_roots[OF assms] assms(2) unfolding splitted_def by simp - -lemma (in field) no_roots_imp_same_roots: - assumes "p \ carrier (poly_ring R)" "p \ []" and "q \ carrier (poly_ring R)" - shows "roots p = {#} \ roots (p \\<^bsub>poly_ring R\<^esub> q) = roots q" -proof - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - assume no_roots: "roots p = {#}" show "roots (p \\<^bsub>poly_ring R\<^esub> q) = roots q" - proof (intro subset_mset.antisym) - have pdiv: "q pdivides (p \\<^bsub>poly_ring R\<^esub> q)" - using UP.divides_prod_l assms unfolding pdivides_def by blast - show "roots q \# roots (p \\<^bsub>poly_ring R\<^esub> q)" - using pdivides_imp_roots_incl[OF _ _ _ pdiv] assms - degree_zero_imp_empty_roots[OF assms(3)] - by (cases "q = []", auto, metis UP.l_null UP.m_rcancel UP.zero_closed univ_poly_zero) - next - show "roots (p \\<^bsub>poly_ring R\<^esub> q) \# roots q" - proof (cases "p \\<^bsub>poly_ring R\<^esub> q = []") - case True thus ?thesis - using degree_zero_imp_empty_roots[OF UP.m_closed[OF assms(1,3)]] by simp - next - case False with \p \ []\ have q_not_zero: "q \ []" - by (metis UP.r_null assms(1) univ_poly_zero) - show ?thesis - proof (rule roots_inclI[OF UP.m_closed[OF assms(1,3)] assms(3) q_not_zero]) - fix a assume a: "a \ carrier R" - hence "\ ([ \, \ a ] pdivides p)" - using assms(1-2) no_roots pdivides_imp_is_root roots_mem_iff_is_root[of p] by auto - moreover have in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" - using a unfolding sym[OF univ_poly_carrier] polynomial_def by auto - hence "pirreducible (carrier R) [ \, \ a ]" - using degree_one_imp_pirreducible[OF carrier_is_subfield] by simp - moreover - have "([ \, \ a ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult (p \\<^bsub>poly_ring R\<^esub> q) a)) pdivides (p \\<^bsub>poly_ring R\<^esub> q)" - using le_alg_mult_imp_pdivides[OF a UP.m_closed, of p q] assms by simp - ultimately show "([ \, \ a ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult (p \\<^bsub>poly_ring R\<^esub> q) a)) pdivides q" - using pirreducible_pow_pdivides_iff[OF carrier_is_subfield in_carrier] assms by auto - qed - qed - qed -qed - -lemma (in field) poly_mult_degree_one_monic_imp_same_roots: - assumes "a \ carrier R" and "p \ carrier (poly_ring R)" "p \ []" - shows "roots ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p) = add_mset a (roots p)" -proof - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - from \a \ carrier R\ have in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" - unfolding sym[OF univ_poly_carrier] polynomial_def by simp - - show ?thesis - proof (intro subset_mset.antisym[OF roots_inclI' mset_subset_eqI]) - show "([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p) \ carrier (poly_ring R)" - using in_carrier assms(2) by simp - next - fix b assume b: "b \ carrier R" and "[ \, \ a ] \\<^bsub>poly_ring R\<^esub> p \ []" - hence not_zero: "p \ []" - unfolding univ_poly_def by auto - from \b \ carrier R\ have in_carrier': "[ \, \ b ] \ carrier (poly_ring R)" - unfolding sym[OF univ_poly_carrier] polynomial_def by simp - show "alg_mult ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p) b \ count (add_mset a (roots p)) b" - proof (cases "a = b") - case False - hence "\ [ \, \ b ] pdivides [ \, \ a ]" - using assms(1) b monic_degree_one_root_condition pdivides_imp_is_root by blast - moreover have "pirreducible (carrier R) [ \, \ b ]" - using degree_one_imp_pirreducible[OF carrier_is_subfield in_carrier'] by simp - ultimately - have "[ \, \ b ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p) b) pdivides p" - using le_alg_mult_imp_pdivides[OF b UP.m_closed, of _ p] assms(2) in_carrier - pirreducible_pow_pdivides_iff[OF carrier_is_subfield in_carrier' in_carrier, of p] - by auto - with \a \ b\ show ?thesis - using alg_mult_eq_count_roots[OF assms(2)] alg_multE(2)[OF b assms(2) not_zero] by auto - next - case True - have "[ \, \ a ] pdivides ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p)" - using dividesI[OF assms(2)] unfolding pdivides_def by auto - with \[ \, \ a ] \\<^bsub>poly_ring R\<^esub> p \ []\ - have "alg_mult ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p) a \ Suc 0" - using alg_multE(2)[of a _ "Suc 0"] in_carrier assms by auto - then obtain m where m: "alg_mult ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p) a = Suc m" - using Suc_le_D by blast - hence "([ \, \ a ] \\<^bsub>poly_ring R\<^esub> ([ \, \ a ] [^]\<^bsub>poly_ring R\<^esub> m)) pdivides - ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p)" - using le_alg_mult_imp_pdivides[OF _ UP.m_closed, of a _ p] - in_carrier assms UP.nat_pow_Suc2 by force - hence "([ \, \ a ] [^]\<^bsub>poly_ring R\<^esub> m) pdivides p" - using UP.mult_divides in_carrier assms(2) - unfolding univ_poly_zero pdivides_def factor_def - by (simp add: UP.m_assoc UP.m_lcancel univ_poly_zero) - with \a = b\ show ?thesis - using alg_mult_eq_count_roots assms in_carrier UP.nat_pow_Suc2 - alg_multE(2)[OF assms(1) _ not_zero] m - by auto - qed - next - fix b - have not_zero: "[ \, \ a ] \\<^bsub>poly_ring R\<^esub> p \ []" - using assms in_carrier univ_poly_zero[of R] UP.integral by auto - - show "count (add_mset a (roots p)) b \ count (roots ([\, \ a] \\<^bsub>poly_ring R\<^esub> p)) b" - proof (cases "a = b") - case True - have "([ \, \ a ] \\<^bsub>poly_ring R\<^esub> ([ \, \ a ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult p a))) pdivides - ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p)" - using UP.divides_mult[OF _ in_carrier] le_alg_mult_imp_pdivides[OF assms(1,2)] in_carrier assms - by (auto simp add: pdivides_def) - with \a = b\ show ?thesis - using alg_mult_eq_count_roots assms in_carrier UP.nat_pow_Suc2 - alg_multE(2)[OF assms(1) _ not_zero] - by auto - next - case False - have "p pdivides ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p)" - using dividesI[OF in_carrier] UP.m_comm in_carrier assms unfolding pdivides_def by auto - thus ?thesis - using False pdivides_imp_roots_incl assms in_carrier not_zero - by (simp add: subseteq_mset_def) - qed - qed -qed - -lemma (in domain) not_empty_rootsE[elim]: - assumes "p \ carrier (poly_ring R)" and "roots p \ {#}" - and "\a. \ a \ carrier R; a \# roots p; - [ \, \ a ] \ carrier (poly_ring R); [ \, \ a ] pdivides p \ \ P" - shows P -proof - - from \roots p \ {#}\ obtain a where "a \# roots p" - by blast - with \p \ carrier (poly_ring R)\ have "[ \, \ a ] pdivides p" - and "[ \, \ a ] \ carrier (poly_ring R)" and "a \ carrier R" - using is_root_imp_pdivides[of p] roots_mem_iff_is_root[of p] is_root_def[of p a] - unfolding sym[OF univ_poly_carrier] polynomial_def by auto - with \a \# roots p\ show ?thesis - using assms(3)[of a] by auto -qed - -lemma (in field) associated_polynomials_imp_same_roots: - assumes "p \ carrier (poly_ring R)" "p \ []" and "q \ carrier (poly_ring R)" "q \ []" - shows "roots (p \\<^bsub>poly_ring R\<^esub> q) = roots p + roots q" -proof - - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - from assms show ?thesis - proof (induction "degree p" arbitrary: p rule: less_induct) - case less show ?case - proof (cases "roots p = {#}") - case True thus ?thesis - using no_roots_imp_same_roots[of p q] less by simp - next - case False with \p \ carrier (poly_ring R)\ - obtain a where a: "a \ carrier R" and "a \# roots p" and pdiv: "[ \, \ a ] pdivides p" - and in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" - by blast - show ?thesis - proof (cases "degree p = 1") - case True with \p \ carrier (poly_ring R)\ - obtain b c where p: "p = [ b, c ]" and b: "b \ carrier R" "b \ \" and c: "c \ carrier R" - by auto - with \a \# roots p\ have roots: "roots p = {# a #}" and a: "\ a = inv b \ c" "a \ carrier R" - and lead: "lead_coeff p = b" and const: "const_term p = c" - using degree_one_imp_singleton_roots[of p] less(2) field_Units - unfolding const_term_def by auto - hence "(p \\<^bsub>poly_ring R\<^esub> q) \\<^bsub>poly_ring R\<^esub> ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> q)" - using UP.mult_cong_l[OF degree_one_associatedI[OF carrier_is_subfield _ True]] less(2,4) - by (auto simp add: a lead const) - hence "roots (p \\<^bsub>poly_ring R\<^esub> q) = roots ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> q)" - using associated_polynomials_imp_same_roots in_carrier less(2,4) unfolding a by simp - thus ?thesis - unfolding poly_mult_degree_one_monic_imp_same_roots[OF a(2) less(4,5)] roots by simp - next - case False - from \[ \, \ a ] pdivides p\ - obtain r where p: "p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> r" and r: "r \ carrier (poly_ring R)" - unfolding pdivides_def by auto - with \p \ []\ have not_zero: "r \ []" - using in_carrier univ_poly_zero[of R "carrier R"] UP.integral_iff by auto - with \p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> r\ have deg: "degree p = Suc (degree r)" - using poly_mult_degree_eq[OF carrier_is_subring, of _ r] in_carrier r - unfolding univ_poly_carrier sym[OF univ_poly_mult[of R "carrier R"]] by auto - with \r \ []\ and \q \ []\ have "r \\<^bsub>poly_ring R\<^esub> q \ []" - using in_carrier univ_poly_zero[of R "carrier R"] UP.integral less(4) r by auto - hence "roots (p \\<^bsub>poly_ring R\<^esub> q) = add_mset a (roots (r \\<^bsub>poly_ring R\<^esub> q))" - using poly_mult_degree_one_monic_imp_same_roots[OF a UP.m_closed[OF r less(4)]] - UP.m_assoc[OF in_carrier r less(4)] p by auto - also have " ... = add_mset a (roots r + roots q)" - using less(1)[OF _ r not_zero less(4-5)] deg by simp - also have " ... = (add_mset a (roots r)) + roots q" - by simp - also have " ... = roots p + roots q" - using poly_mult_degree_one_monic_imp_same_roots[OF a r not_zero] p by simp - finally show ?thesis . - qed - qed - qed -qed - -lemma (in field) size_roots_le_degree: - assumes "p \ carrier (poly_ring R)" shows "size (roots p) \ degree p" - using assms -proof (induction "degree p" arbitrary: p rule: less_induct) - case less show ?case - proof (cases "roots p = {#}", simp) - interpret UP: domain "poly_ring R" - using univ_poly_is_domain[OF carrier_is_subring] . - - case False with \p \ carrier (poly_ring R)\ - obtain a where a: "a \ carrier R" and "a \# roots p" and "[ \, \ a ] pdivides p" - and in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" - by blast - then obtain q where p: "p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> q" and q: "q \ carrier (poly_ring R)" - unfolding pdivides_def by auto - with \a \# roots p\ have "p \ []" - using degree_zero_imp_empty_roots[OF less(2)] by auto - hence not_zero: "q \ []" - using in_carrier univ_poly_zero[of R "carrier R"] UP.integral_iff p by auto - hence "degree p = Suc (degree q)" - using poly_mult_degree_eq[OF carrier_is_subring, of _ q] in_carrier p q - unfolding univ_poly_carrier sym[OF univ_poly_mult[of R "carrier R"]] by auto - with \q \ []\ show ?thesis - using poly_mult_degree_one_monic_imp_same_roots[OF a q] p less(1)[OF _ q] - by (metis Suc_le_mono lessI size_add_mset) - qed -qed - - -(* MOVE to Polynomial_Divisibility.thy ======== *) -lemma (in ring) divides_pirreducible_condition: - assumes "pirreducible K q" and "p \ carrier (K[X])" - shows "p divides\<^bsub>K[X]\<^esub> q \ p \ Units (K[X]) \ p \\<^bsub>K[X]\<^esub> q" - using divides_irreducible_condition[of "K[X]" q p] assms - unfolding ring_irreducible_def by auto - -lemma (in domain) pirreducible_roots: - assumes "p \ carrier (poly_ring R)" and "pirreducible (carrier R) p" and "degree p \ 1" - shows "roots p = {#}" -proof (rule ccontr) - assume "roots p \ {#}" with \p \ carrier (poly_ring R)\ - obtain a where a: "a \ carrier R" and "a \# roots p" and "[ \, \ a ] pdivides p" - and in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" - by blast - hence "[ \, \ a ] \\<^bsub>poly_ring R\<^esub> p" - using divides_pirreducible_condition[OF assms(2) in_carrier] - univ_poly_units_incl[OF carrier_is_subring] - unfolding pdivides_def by auto - hence "degree p = 1" - using associated_polynomials_imp_same_length[OF carrier_is_subring in_carrier assms(1)] by auto - with \degree p \ 1\ show False .. -qed - -lemma (in field) pirreducible_imp_not_splitted: - assumes "p \ carrier (poly_ring R)" and "pirreducible (carrier R) p" and "degree p \ 1" - shows "\ splitted p" - using pirreducible_roots[of p] pirreducible_degree[OF carrier_is_subfield, of p] assms - by (simp add: splitted_def) - -lemma (in field) - assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" - and "pirreducible (carrier R) p" and "degree p \ 1" - shows "roots (p \\<^bsub>poly_ring R\<^esub> q) = roots q" - using no_roots_imp_same_roots[of p q] pirreducible_roots[of p] assms - unfolding ring_irreducible_def univ_poly_zero by auto - -lemma (in field) trivial_factors_imp_splitted: - assumes "p \ carrier (poly_ring R)" - and "\q. \ q \ carrier (poly_ring R); pirreducible (carrier R) q; q pdivides p \ \ degree q \ 1" - shows "splitted p" - using assms -proof (induction "degree p" arbitrary: p rule: less_induct) - interpret UP: principal_domain "poly_ring R" - using univ_poly_is_principal[OF carrier_is_subfield] . - case less show ?case - proof (cases "degree p = 0", simp add: degree_zero_imp_splitted[OF less(2)]) - case False show ?thesis - proof (cases "roots p = {#}") - case True - from \degree p \ 0\ have "p \ Units (poly_ring R)" and "p \ carrier (poly_ring R) - { [] }" - using univ_poly_units'[OF carrier_is_subfield, of p] less(2) by auto - then obtain q where "q \ carrier (poly_ring R)" "pirreducible (carrier R) q" and "q pdivides p" - using UP.exists_irreducible_divisor[of p] unfolding univ_poly_zero pdivides_def by auto - with \degree p \ 0\ have "roots p \ {#}" - using degree_one_imp_singleton_roots[OF _ , of q] less(3)[of q] - pdivides_imp_roots_incl[OF _ less(2), of q] - pirreducible_degree[OF carrier_is_subfield, of q] - by force - from \roots p = {#}\ and \roots p \ {#}\ have False - by simp - thus ?thesis .. - next - case False with \p \ carrier (poly_ring R)\ - obtain a where a: "a \ carrier R" and "a \# roots p" and "[ \, \ a ] pdivides p" - and in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" - by blast - then obtain q where p: "p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> q" and q: "q \ carrier (poly_ring R)" - unfolding pdivides_def by blast - with \degree p \ 0\ have "p \ []" - by auto - with \p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> q\ have "q \ []" - using in_carrier q unfolding sym[OF univ_poly_zero[of R "carrier R"]] by auto - with \p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> q\ and \p \ []\ have "degree p = Suc (degree q)" - using poly_mult_degree_eq[OF carrier_is_subring] in_carrier q - unfolding univ_poly_carrier sym[OF univ_poly_mult[of R "carrier R"]] by auto - moreover have "q pdivides p" - using p dividesI[OF in_carrier] UP.m_comm[OF in_carrier q] by (auto simp add: pdivides_def) - hence "degree r = 1" if "r \ carrier (poly_ring R)" and "pirreducible (carrier R) r" - and "r pdivides q" for r - using less(3)[OF that(1-2)] UP.divides_trans[OF _ _ that(1), of q p] that(3) - pirreducible_degree[OF carrier_is_subfield that(1-2)] - by (auto simp add: pdivides_def) - ultimately have "splitted q" - using less(1)[OF _ q] by auto - with \degree p = Suc (degree q)\ and \q \ []\ show ?thesis - using poly_mult_degree_one_monic_imp_same_roots[OF a q] - unfolding sym[OF p] splitted_def - by simp - qed - qed -qed - -lemma (in field) pdivides_imp_splitted: - assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" "q \ []" and "splitted q" - shows "p pdivides q \ splitted p" -proof (cases "p = []") - case True thus ?thesis - using degree_zero_imp_splitted[OF assms(1)] by simp -next - interpret UP: principal_domain "poly_ring R" - using univ_poly_is_principal[OF carrier_is_subfield] . - - case False - assume "p pdivides q" - then obtain b where b: "b \ carrier (poly_ring R)" and q: "q = p \\<^bsub>poly_ring R\<^esub> b" - unfolding pdivides_def by auto - with \q \ []\ have "p \ []" and "b \ []" - using assms UP.integral_iff[of p b] unfolding sym[OF univ_poly_zero[of R "carrier R"]] by auto - hence "degree p + degree b = size (roots p) + size (roots b)" - using associated_polynomials_imp_same_roots[of p b] assms b q splitted_def - poly_mult_degree_eq[OF carrier_is_subring,of p b] - unfolding univ_poly_carrier sym[OF univ_poly_mult[of R "carrier R"]] - by auto - moreover have "size (roots p) \ degree p" and "size (roots b) \ degree b" - using size_roots_le_degree assms(1) b by auto - ultimately show ?thesis - unfolding splitted_def by linarith -qed - -lemma (in field) splitted_imp_trivial_factors: - assumes "p \ carrier (poly_ring R)" "p \ []" and "splitted p" - shows "\q. \ q \ carrier (poly_ring R); pirreducible (carrier R) q; q pdivides p \ \ degree q = 1" - using pdivides_imp_splitted[OF _ assms] pirreducible_imp_not_splitted - by auto - lemma (in field) exists_root: assumes "M \ extensions" and "\L. \ L \ extensions; M \ L \ \ law_restrict L = law_restrict M" and "P \ carrier (poly_ring R)" @@ -1664,7 +523,7 @@ qed then obtain i :: nat where "\\

\ carrier M. index_free \

(P, i)" by blast - + then have hyps: \ \i\ "field M" \ \ii\ "\\

. \

\ carrier M \ carrier_coeff \

" @@ -1760,7 +619,7 @@ obtain M where "M \ extensions" and "\L \ extensions. M \ L \ law_restrict L = law_restrict M" using exists_maximal_extension iso_incl_hom by blast thus ?thesis - using exists_root[of M] by auto + using exists_root[of M] by auto qed @@ -1773,9 +632,9 @@ locale algebraically_closed = field L for L (structure) + assumes roots_over_carrier: "P \ carrier (poly_ring L) \ splitted P" -definition (in field) closure :: "(('a list \ nat) multiset \ 'a) ring" ("\") - where "closure = (SOME L \ \such that\. - \ \i\ algebraic_closure L (indexed_const ` (carrier R)) \ +definition (in field) alg_closure :: "(('a list \ nat) multiset \ 'a) ring" + where "alg_closure = (SOME L \ \such that\. + \ \i\ algebraic_closure L (indexed_const ` (carrier R)) \ \ \ii\ indexed_const \ ring_hom R L)" lemma algebraic_hom: @@ -1961,7 +820,7 @@ with \[ \\<^bsub>L\<^esub>, \\<^bsub>L\<^esub> a ] \ carrier (poly_ring ?M)\ and \R \ carrier (poly_ring ?M)\ have "degree R = 1" using domain.associated_polynomials_imp_same_length[OF field.axioms(1)[OF M] - Id.R.carrier_is_subring, of "[ \\<^bsub>L\<^esub>, \\<^bsub>L\<^esub> a ]" R] by force + Id.R.carrier_is_subring, of "[ \\<^bsub>L\<^esub>, \\<^bsub>L\<^esub> a ]" R] by force thus ?thesis by simp qed @@ -1978,11 +837,26 @@ using that by auto qed -lemma (in field) closureE: - shows "algebraic_closure \ (indexed_const ` (carrier R))" and "indexed_const \ ring_hom R \" - using exists_closure unfolding closure_def +lemma (in field) alg_closureE: + shows "algebraic_closure alg_closure (indexed_const ` (carrier R))" + and "indexed_const \ ring_hom R alg_closure" + using exists_closure unfolding alg_closure_def by (metis (mono_tags, lifting) someI2)+ +lemma (in field) algebraically_closedI': + assumes "\p. \ p \ carrier (poly_ring R); degree p > 1 \ \ splitted p" + shows "algebraically_closed R" +proof + fix p assume "p \ carrier (poly_ring R)" show "splitted p" + proof (cases "degree p \ 1") + case True with \p \ carrier (poly_ring R)\ show ?thesis + using degree_zero_imp_splitted degree_one_imp_splitted by fastforce + next + case False with \p \ carrier (poly_ring R)\ show ?thesis + using assms by fastforce + qed +qed + lemma (in field) algebraically_closedI: assumes "\p. \ p \ carrier (poly_ring R); degree p > 1 \ \ \x \ carrier R. eval p x = \" shows "algebraically_closed R" @@ -2014,13 +888,13 @@ moreover have "roots p = add_mset a (roots q)" using poly_mult_degree_one_monic_imp_same_roots[OF a(1) q not_zero] p by simp ultimately show ?thesis - unfolding splitted_def deg by simp + unfolding splitted_def deg by simp qed qed qed sublocale algebraic_closure \ algebraically_closed -proof (rule algebraically_closedI) +proof (rule algebraically_closedI') fix P assume in_carrier: "P \ carrier (poly_ring L)" and gt_one: "degree P > 1" then have gt_zero: "degree P > 0" by simp @@ -2074,11 +948,11 @@ univ_poly_subfield_of_consts[OF subfield_axioms] by auto moreover from \carrier (K[X]) \ carrier (A[X])\ have "poly_of_const ` K \ carrier (A[X])" - using subfieldE(3)[OF univ_poly_subfield_of_consts[OF subfield_axioms]] by simp + using subfieldE(3)[OF univ_poly_subfield_of_consts[OF subfield_axioms]] by simp ultimately have "subalgebra (rupture_surj A P ` poly_of_const ` K) (rupture_surj A P ` carrier (K[X])) (Rupt A P)" - using ring_hom_ring.img_is_subalgebra[OF rupture_surj_hom(2)[OF subfieldE(1)[OF A] P]] by simp + using ring_hom_ring.img_is_subalgebra[OF rupture_surj_hom(2)[OF subfieldE(1)[OF A] P]] by simp moreover have "Rupt.finite_dimension (rupture_surj A P ` poly_of_const ` K) (carrier (Rupt A P))" proof (intro Rupt.telescopic_base_dim(1)[where @@ -2113,7 +987,7 @@ ultimately have "Rupt.finite_dimension (rupture_surj A P ` poly_of_const ` K) (rupture_surj A P ` carrier (K[X]))" - using Rupt.subalbegra_incl_imp_finite_dimension[OF aux_lemmas(1)] by simp + using Rupt.subalbegra_incl_imp_finite_dimension[OF aux_lemmas(1)] by simp hence "\ inj_on (rupture_surj A P) (carrier (K[X]))" using Hom'.infinite_dimension_hom[OF _ rupture_one_not_zero[OF A P gt_zero] _ @@ -2129,14 +1003,11 @@ unfolding cgenideal_def by blast with \P \ carrier (A[X])\ have "P pdivides Q" using dividesI[of _ "A[X]"] UP_A.m_comm pdivides_iff_shell[OF A] by simp - hence "splitted P" + thus "splitted P" using pdivides_imp_splitted[OF in_carrier carrier_polynomial_shell[OF subfieldE(1)[OF subfield_axioms] Q(1)] Q(2) - roots_over_subfield[OF Q(1)]] Q by simp - with \degree P > 1\ obtain a where "a \# roots P" - unfolding splitted_def by force - thus "\x\carrier L. eval P x = \" - unfolding roots_mem_iff_is_root[OF in_carrier] is_root_def by blast + roots_over_subfield[OF Q(1)]] Q + by simp qed end diff -r 58191e01f0b1 -r 8371a25ca177 src/HOL/Algebra/Divisibility.thy --- a/src/HOL/Algebra/Divisibility.thy Mon Apr 29 17:11:26 2019 +0100 +++ b/src/HOL/Algebra/Divisibility.thy Tue Apr 30 11:57:45 2019 +0100 @@ -780,6 +780,36 @@ using A(1) Units_one_closed b'(1) unit_factor by presburger qed +lemma (in comm_monoid_cancel) prime_pow_divides_iff: + assumes "p \ carrier G" "a \ carrier G" "b \ carrier G" and "prime G p" and "\ (p divides a)" + shows "(p [^] (n :: nat)) divides (a \ b) \ (p [^] n) divides b" +proof + assume "(p [^] n) divides b" thus "(p [^] n) divides (a \ b)" + using divides_prod_l[of "p [^] n" b a] assms by simp +next + assume "(p [^] n) divides (a \ b)" thus "(p [^] n) divides b" + proof (induction n) + case 0 with \b \ carrier G\ show ?case + by (simp add: unit_divides) + next + case (Suc n) + hence "(p [^] n) divides (a \ b)" and "(p [^] n) divides b" + using assms(1) divides_prod_r by auto + with \(p [^] (Suc n)) divides (a \ b)\ obtain c d + where c: "c \ carrier G" and "b = (p [^] n) \ c" + and d: "d \ carrier G" and "a \ b = (p [^] (Suc n)) \ d" + using assms by blast + hence "(p [^] n) \ (a \ c) = (p [^] n) \ (p \ d)" + using assms by (simp add: m_assoc m_lcomm) + hence "a \ c = p \ d" + using c d assms(1) assms(2) l_cancel by blast + with \\ (p divides a)\ and \prime G p\ have "p divides c" + by (metis assms(2) c d dividesI' prime_divides) + with \b = (p [^] n) \ c\ show ?case + using assms(1) c by simp + qed +qed + subsection \Factorization and Factorial Monoids\ diff -r 58191e01f0b1 -r 8371a25ca177 src/HOL/Algebra/Finite_Extensions.thy --- a/src/HOL/Algebra/Finite_Extensions.thy Mon Apr 29 17:11:26 2019 +0100 +++ b/src/HOL/Algebra/Finite_Extensions.thy Tue Apr 30 11:57:45 2019 +0100 @@ -293,8 +293,11 @@ using assms(1) lin(2) unfolding polynomial_def by auto hence "eval (normalize (p @ [ k2 ])) x = k1 \ x \ k2" using eval_append_aux[of p k2 x] eval_normalize[of "p @ [ k2 ]" x] assms(2) p(3) by auto - thus ?case - using normalize_gives_polynomial[of "p @ [ k2 ]"] polynomial_incl[OF p(2)] lin(2) + moreover have "set (p @ [k2]) \ K" + using polynomial_incl[OF p(2)] \k2 \ K\ by auto + then have "local.normalize (p @ [k2]) \ carrier (K [X])" + using normalize_gives_polynomial univ_poly_carrier by blast + ultimately show ?case unfolding univ_poly_carrier by force qed qed @@ -720,91 +723,4 @@ qed qed - -(* -proposition (in domain) finite_extension_is_subfield: - assumes "subfield K R" "set xs \ carrier R" - shows "subfield (finite_extension K xs) R \ (algebraic_set over K) (set xs)" -proof - have "(\x. x \ set xs \ (algebraic over K) x) \ subfield (finite_extension K xs) R" - using simple_extension_is_subfield algebraic_mono assms - by (induct xs) (auto, metis finite_extension.simps finite_extension_incl subring_props(1)) - thus "(algebraic_set over K) (set xs) \ subfield (finite_extension K xs) R" - unfolding algebraic_set_def over_def by auto -next - { fix x xs - assume x: "x \ carrier R" and xs: "set xs \ carrier R" - and is_subfield: "subfield (finite_extension K (x # xs)) R" - hence "(algebraic over K) x" sorry } - - assume "subfield (finite_extension K xs) R" thus "(algebraic_set over K) (set xs)" - using assms(2) - proof (induct xs) - case Nil thus ?case - unfolding algebraic_set_def over_def by simp - next - case (Cons x xs) - have "(algebraic over K) x" - using simple_extension_subfield_imp_algebraic[OF - finite_extension_is_subring[of K xs], of x] - - then show ?case sorry - qed -qed -*) - -(* -lemma (in ring) transcendental_imp_trivial_ker: - assumes "x \ carrier R" - shows "(transcendental over K) x \ (\p. \ polynomial R p; set p \ K \ \ eval p x = \ \ p = [])" -proof - - fix p assume "(transcendental over K) x" "polynomial R p" "eval p x = \" "set p \ K" - moreover have "eval [] x = \" and "polynomial R []" - using assms zero_is_polynomial by auto - ultimately show "p = []" - unfolding over_def transcendental_def inj_on_def by auto -qed - -lemma (in domain) trivial_ker_imp_transcendental: - assumes "subring K R" and "x \ carrier R" - shows "(\p. \ polynomial R p; set p \ K \ \ eval p x = \ \ p = []) \ (transcendental over K) x" -proof - - assume "\p. \ polynomial R p; set p \ K \ \ eval p x = \ \ p = []" - hence "a_kernel (univ_poly (R \ carrier := K \)) R (\p. local.eval p x) = { [] }" - unfolding a_kernel_def' univ_poly_subring_def'[OF assms(1)] by auto - moreover have "[] = \\<^bsub>(univ_poly (R \ carrier := K \))\<^esub>" - unfolding univ_poly_def by auto - ultimately have "inj_on (\p. local.eval p x) (carrier (univ_poly (R \ carrier := K \)))" - using ring_hom_ring.trivial_ker_imp_inj[OF eval_ring_hom[OF assms]] by auto - thus "(transcendental over K) x" - unfolding over_def transcendental_def univ_poly_subring_def'[OF assms(1)] by simp -qed - -lemma (in ring) non_trivial_ker_imp_algebraic: - assumes "x \ carrier R" - and "p \ []" "polynomial R p" "set p \ K" "eval p x = \" - shows "(algebraic over K) x" - using transcendental_imp_trivial_ker[OF assms(1) _ assms(3-5)] assms(2) - unfolding over_def algebraic_def by auto - -lemma (in domain) algebraic_imp_non_trivial_ker: - assumes "subring K R" "x \ carrier R" - shows "(algebraic over K) x \ (\p \ []. polynomial R p \ set p \ K \ eval p x = \)" - using trivial_ker_imp_transcendental[OF assms] - unfolding over_def algebraic_def by auto - -lemma (in domain) algebraic_iff: - assumes "subring K R" "x \ carrier R" - shows "(algebraic over K) x \ (\p \ []. polynomial R p \ set p \ K \ eval p x = \)" - using non_trivial_ker_imp_algebraic[OF assms(2)] algebraic_imp_non_trivial_ker[OF assms] by auto -*) - - -(* -lemma (in field) - assumes "subfield K R" - shows "subfield (simple_extension K x) R \ (algebraic over K) x" - sorry - -*) end \ No newline at end of file diff -r 58191e01f0b1 -r 8371a25ca177 src/HOL/Algebra/Ideal.thy --- a/src/HOL/Algebra/Ideal.thy Mon Apr 29 17:11:26 2019 +0100 +++ b/src/HOL/Algebra/Ideal.thy Tue Apr 30 11:57:45 2019 +0100 @@ -193,7 +193,7 @@ qed -subsection \General Ideal Properies\ +subsection \General Ideal Properties\ lemma (in ideal) one_imp_carrier: assumes I_one_closed: "\ \ I" @@ -210,6 +210,30 @@ shows "i \ carrier R" using iI by (rule a_Hcarr) +lemma (in ring) quotient_eq_iff_same_a_r_cos: + assumes "ideal I R" and "a \ carrier R" and "b \ carrier R" + shows "a \ b \ I \ I +> a = I +> b" +proof + assume "I +> a = I +> b" + then obtain i where "i \ I" and "\ \ a = i \ b" + using additive_subgroup.zero_closed[OF ideal.axioms(1)[OF assms(1)]] assms(2) + unfolding a_r_coset_def' by blast + hence "a \ b = i" + using assms(2-3) by (metis a_minus_def add.inv_solve_right assms(1) ideal.Icarr l_zero) + with \i \ I\ show "a \ b \ I" + by simp +next + assume "a \ b \ I" + then obtain i where "i \ I" and "a = i \ b" + using ideal.Icarr[OF assms(1)] assms(2-3) + by (metis a_minus_def add.inv_solve_right) + hence "I +> a = (I +> i) +> b" + using ideal.Icarr[OF assms(1)] assms(3) + by (simp add: a_coset_add_assoc subsetI) + with \i \ I\ show "I +> a = I +> b" + using a_rcos_zero[OF assms(1)] by simp +qed + subsection \Intersection of Ideals\ diff -r 58191e01f0b1 -r 8371a25ca177 src/HOL/Algebra/Polynomial_Divisibility.thy --- a/src/HOL/Algebra/Polynomial_Divisibility.thy Mon Apr 29 17:11:26 2019 +0100 +++ b/src/HOL/Algebra/Polynomial_Divisibility.thy Tue Apr 30 11:57:45 2019 +0100 @@ -122,6 +122,11 @@ using field.univ_poly_carrier_units[OF subfield_iff(2)[OF assms]] univ_poly_consistent[OF subfieldE(1)[OF assms]] by auto +lemma (in domain) univ_poly_units': + assumes "subfield K R" shows "p \ Units (K[X]) \ p \ carrier (K[X]) \ p \ [] \ degree p = 0" + unfolding univ_poly_units[OF assms] sym[OF univ_poly_carrier] polynomial_def + by (auto, metis hd_in_set le_0_eq le_Suc_eq length_0_conv length_Suc_conv list.sel(1) subsetD) + corollary (in domain) rupture_one_not_zero: assumes "subfield K R" and "p \ carrier (K[X])" and "degree p > 0" shows "\\<^bsub>Rupt K p\<^esub> \ \\<^bsub>Rupt K p\<^esub>" @@ -759,6 +764,255 @@ using aux_lemma[OF assms(2-3)] aux_lemma[OF assms(3,2) UP.associated_sym] by simp qed +lemma (in ring) divides_pirreducible_condition: + assumes "pirreducible K q" and "p \ carrier (K[X])" + shows "p divides\<^bsub>K[X]\<^esub> q \ p \ Units (K[X]) \ p \\<^bsub>K[X]\<^esub> q" + using divides_irreducible_condition[of "K[X]" q p] assms + unfolding ring_irreducible_def by auto + +subsection \Polynomial Power\ + +lemma (in domain) polynomial_pow_not_zero: + assumes "p \ carrier (poly_ring R)" and "p \ []" + shows "p [^]\<^bsub>poly_ring R\<^esub> (n::nat) \ []" +proof - + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + from assms UP.integral show ?thesis + unfolding sym[OF univ_poly_zero[of R "carrier R"]] + by (induction n, auto) +qed + +lemma (in domain) subring_polynomial_pow_not_zero: + assumes "subring K R" and "p \ carrier (K[X])" and "p \ []" + shows "p [^]\<^bsub>K[X]\<^esub> (n::nat) \ []" + using domain.polynomial_pow_not_zero[OF subring_is_domain, of K p n] assms + unfolding univ_poly_consistent[OF assms(1)] by simp + +lemma (in domain) polynomial_pow_degree: + assumes "p \ carrier (poly_ring R)" + shows "degree (p [^]\<^bsub>poly_ring R\<^esub> n) = n * degree p" +proof - + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + show ?thesis + proof (induction n) + case 0 thus ?case + using UP.nat_pow_0 unfolding univ_poly_one by auto + next + let ?ppow = "\n. p [^]\<^bsub>poly_ring R\<^esub> n" + case (Suc n) thus ?case + proof (cases "p = []") + case True thus ?thesis + using univ_poly_zero[of R "carrier R"] UP.r_null assms by auto + next + case False + hence "?ppow n \ carrier (poly_ring R)" and "?ppow n \ []" and "p \ []" + using polynomial_pow_not_zero[of p n] assms by (auto simp add: univ_poly_one) + thus ?thesis + using poly_mult_degree_eq[OF carrier_is_subring, of "?ppow n" p] Suc assms + unfolding univ_poly_carrier univ_poly_zero + by (auto simp add: add.commute univ_poly_mult) + qed + qed +qed + +lemma (in domain) subring_polynomial_pow_degree: + assumes "subring K R" and "p \ carrier (K[X])" + shows "degree (p [^]\<^bsub>K[X]\<^esub> n) = n * degree p" + using domain.polynomial_pow_degree[OF subring_is_domain, of K p n] assms + unfolding univ_poly_consistent[OF assms(1)] by simp + +lemma (in domain) polynomial_pow_division: + assumes "p \ carrier (poly_ring R)" and "(n::nat) \ m" + shows "(p [^]\<^bsub>poly_ring R\<^esub> n) pdivides (p [^]\<^bsub>poly_ring R\<^esub> m)" +proof - + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + let ?ppow = "\n. p [^]\<^bsub>poly_ring R\<^esub> n" + + have "?ppow n \\<^bsub>poly_ring R\<^esub> ?ppow k = ?ppow (n + k)" for k + using assms(1) by (simp add: UP.nat_pow_mult) + thus ?thesis + using dividesI[of "?ppow (m - n)" "poly_ring R" "?ppow m" "?ppow n"] assms + unfolding pdivides_def by auto +qed + +lemma (in domain) subring_polynomial_pow_division: + assumes "subring K R" and "p \ carrier (K[X])" and "(n::nat) \ m" + shows "(p [^]\<^bsub>K[X]\<^esub> n) divides\<^bsub>K[X]\<^esub> (p [^]\<^bsub>K[X]\<^esub> m)" + using domain.polynomial_pow_division[OF subring_is_domain, of K p n m] assms + unfolding univ_poly_consistent[OF assms(1)] pdivides_def by simp + +lemma (in domain) pirreducible_pow_pdivides_iff: + assumes "subfield K R" "p \ carrier (K[X])" "q \ carrier (K[X])" "r \ carrier (K[X])" + and "pirreducible K p" and "\ (p pdivides q)" + shows "(p [^]\<^bsub>K[X]\<^esub> (n :: nat)) pdivides (q \\<^bsub>K[X]\<^esub> r) \ (p [^]\<^bsub>K[X]\<^esub> n) pdivides r" +proof - + interpret UP: principal_domain "K[X]" + using univ_poly_is_principal[OF assms(1)] . + show ?thesis + proof (cases "r = []") + case True with \q \ carrier (K[X])\ have "q \\<^bsub>K[X]\<^esub> r = []" and "r = []" + unfolding sym[OF univ_poly_zero[of R K]] by auto + thus ?thesis + using pdivides_zero[OF subfieldE(1),of K] assms by auto + next + case False then have not_zero: "p \ []" "q \ []" "r \ []" "q \\<^bsub>K[X]\<^esub> r \ []" + using subfieldE(1) pdivides_zero[OF _ assms(2)] assms(1-2,5-6) pirreducibleE(1) + UP.integral_iff[OF assms(3-4)] univ_poly_zero[of R K] by auto + from \p \ []\ + have ppow: "p [^]\<^bsub>K[X]\<^esub> (n :: nat) \ []" "p [^]\<^bsub>K[X]\<^esub> (n :: nat) \ carrier (K[X])" + using subring_polynomial_pow_not_zero[OF subfieldE(1)] assms(1-2) by auto + have not_pdiv: "\ (p divides\<^bsub>mult_of (K[X])\<^esub> q)" + using assms(6) pdivides_iff_shell[OF assms(1-3)] unfolding pdivides_def by auto + have prime: "prime (mult_of (K[X])) p" + using assms(5) pprime_iff_pirreducible[OF assms(1-2)] + unfolding sym[OF UP.prime_eq_prime_mult[OF assms(2)]] ring_prime_def by simp + have "a pdivides b \ a divides\<^bsub>mult_of (K[X])\<^esub> b" + if "a \ carrier (K[X])" "a \ \\<^bsub>K[X]\<^esub>" "b \ carrier (K[X])" "b \ \\<^bsub>K[X]\<^esub>" for a b + using that UP.divides_imp_divides_mult[of a b] divides_mult_imp_divides[of "K[X]" a b] + unfolding pdivides_iff_shell[OF assms(1) that(1,3)] by blast + thus ?thesis + using UP.mult_of.prime_pow_divides_iff[OF _ _ _ prime not_pdiv, of r] ppow not_zero assms(2-4) + unfolding nat_pow_mult_of carrier_mult_of mult_mult_of sym[OF univ_poly_zero[of R K]] + by (metis DiffI UP.m_closed singletonD) + qed +qed + +lemma (in domain) subring_degree_one_imp_pirreducible: + assumes "subring K R" and "a \ Units (R \ carrier := K \)" and "b \ K" + shows "pirreducible K [ a, b ]" +proof (rule pirreducibleI[OF assms(1)]) + have "a \ K" and "a \ \" + using assms(2) subringE(1)[OF assms(1)] unfolding Units_def by auto + thus "[ a, b ] \ carrier (K[X])" and "[ a, b ] \ []" and "[ a, b ] \ Units (K [X])" + using univ_poly_units_incl[OF assms(1)] assms(2-3) + unfolding sym[OF univ_poly_carrier] polynomial_def by auto +next + interpret UP: domain "K[X]" + using univ_poly_is_domain[OF assms(1)] . + + { fix q r + assume q: "q \ carrier (K[X])" and r: "r \ carrier (K[X])" and "[ a, b ] = q \\<^bsub>K[X]\<^esub> r" + hence not_zero: "q \ []" "r \ []" + by (metis UP.integral_iff list.distinct(1) univ_poly_zero)+ + have "degree (q \\<^bsub>K[X]\<^esub> r) = degree q + degree r" + using not_zero poly_mult_degree_eq[OF assms(1)] q r + by (simp add: univ_poly_carrier univ_poly_mult) + with sym[OF \[ a, b ] = q \\<^bsub>K[X]\<^esub> r\] have "degree q + degree r = 1" and "q \ []" "r \ []" + using not_zero by auto + } note aux_lemma1 = this + + { fix q r + assume q: "q \ carrier (K[X])" "q \ []" and r: "r \ carrier (K[X])" "r \ []" + and "[ a, b ] = q \\<^bsub>K[X]\<^esub> r" and "degree q = 1" and "degree r = 0" + hence "length q = Suc (Suc 0)" and "length r = Suc 0" + by (linarith, metis add.right_neutral add_eq_if length_0_conv) + from \length q = Suc (Suc 0)\ obtain c d where q_def: "q = [ c, d ]" + by (metis length_0_conv length_Cons list.exhaust nat.inject) + from \length r = Suc 0\ obtain e where r_def: "r = [ e ]" + by (metis length_0_conv length_Suc_conv) + from \r = [ e ]\ and \q = [ c, d ]\ + have c: "c \ K" "c \ \" and d: "d \ K" and e: "e \ K" "e \ \" + using r q subringE(1)[OF assms(1)] unfolding sym[OF univ_poly_carrier] polynomial_def by auto + with sym[OF \[ a, b ] = q \\<^bsub>K[X]\<^esub> r\] have "a = c \ e" + using poly_mult_lead_coeff[OF assms(1), of q r] + unfolding polynomial_def sym[OF univ_poly_mult[of R K]] r_def q_def by auto + obtain inv_a where a: "a \ K" and inv_a: "inv_a \ K" "a \ inv_a = \" "inv_a \ a = \" + using assms(2) unfolding Units_def by auto + hence "a \ \" and "inv_a \ \" + using subringE(1)[OF assms(1)] integral_iff by auto + with \c \ K\ and \c \ \\ have in_carrier: "[ c \ inv_a ] \ carrier (K[X])" + using subringE(1,6)[OF assms(1)] inv_a integral + unfolding sym[OF univ_poly_carrier] polynomial_def + by (auto, meson subsetD) + moreover have "[ c \ inv_a ] \\<^bsub>K[X]\<^esub> r = [ \ ]" + using \a = c \ e\ a inv_a c e subsetD[OF subringE(1)[OF assms(1)]] + unfolding r_def univ_poly_mult by (auto) (simp add: m_assoc m_lcomm integral_iff)+ + ultimately have "r \ Units (K[X])" + using r(1) UP.m_comm[OF in_carrier r(1)] unfolding sym[OF univ_poly_one[of R K]] Units_def by auto + } note aux_lemma2 = this + + fix q r + assume q: "q \ carrier (K[X])" and r: "r \ carrier (K[X])" and qr: "[ a, b ] = q \\<^bsub>K[X]\<^esub> r" + thus "q \ Units (K[X]) \ r \ Units (K[X])" + using aux_lemma1[OF q r qr] aux_lemma2[of q r] aux_lemma2[of r q] UP.m_comm add_is_1 by auto +qed + +lemma (in domain) degree_one_imp_pirreducible: + assumes "subfield K R" and "p \ carrier (K[X])" and "degree p = 1" + shows "pirreducible K p" +proof - + from \degree p = 1\ have "length p = Suc (Suc 0)" + by simp + then obtain a b where p: "p = [ a, b ]" + by (metis length_0_conv length_Suc_conv) + with \p \ carrier (K[X])\ show ?thesis + using subring_degree_one_imp_pirreducible[OF subfieldE(1)[OF assms(1)], of a b] + subfield.subfield_Units[OF assms(1)] + unfolding sym[OF univ_poly_carrier] polynomial_def by auto +qed + +lemma (in ring) degree_oneE[elim]: + assumes "p \ carrier (K[X])" and "degree p = 1" + and "\a b. \ a \ K; a \ \; b \ K; p = [ a, b ] \ \ P" + shows P +proof - + from \degree p = 1\ have "length p = Suc (Suc 0)" + by simp + then obtain a b where "p = [ a, b ]" + by (metis length_0_conv length_Cons nat.inject neq_Nil_conv) + with \p \ carrier (K[X])\ have "a \ K" and "a \ \" and "b \ K" + unfolding sym[OF univ_poly_carrier] polynomial_def by auto + with \p = [ a, b ]\ show ?thesis + using assms(3) by simp +qed + +lemma (in domain) subring_degree_one_associatedI: + assumes "subring K R" and "a \ K" "a' \ K" and "b \ K" and "a \ a' = \" + shows "[ a , b ] \\<^bsub>K[X]\<^esub> [ \, a' \ b ]" +proof - + from \a \ a' = \\ have not_zero: "a \ \" "a' \ \" + using subringE(1)[OF assms(1)] assms(2-3) by auto + hence "[ a, b ] = [ a ] \\<^bsub>K[X]\<^esub> [ \, a' \ b ]" + using assms(2-4)[THEN subsetD[OF subringE(1)[OF assms(1)]]] assms(5) m_assoc + unfolding univ_poly_mult by fastforce + moreover have "[ a, b ] \ carrier (K[X])" and "[ \, a' \ b ] \ carrier (K[X])" + using subringE(1,3,6)[OF assms(1)] not_zero one_not_zero assms + unfolding sym[OF univ_poly_carrier] polynomial_def by auto + moreover have "[ a ] \ Units (K[X])" + proof - + from \a \ \\ and \a' \ \\ have "[ a ] \ carrier (K[X])" and "[ a' ] \ carrier (K[X])" + using assms(2-3) unfolding sym[OF univ_poly_carrier] polynomial_def by auto + moreover have "a' \ a = \" + using subsetD[OF subringE(1)[OF assms(1)]] assms m_comm by simp + hence "[ a ] \\<^bsub>K[X]\<^esub> [ a' ] = [ \ ]" and "[ a' ] \\<^bsub>K[X]\<^esub> [ a ] = [ \ ]" + using assms unfolding univ_poly_mult by auto + ultimately show ?thesis + unfolding sym[OF univ_poly_one[of R K]] Units_def by blast + qed + ultimately show ?thesis + using domain.ring_associated_iff[OF univ_poly_is_domain[OF assms(1)]] by blast +qed + +lemma (in domain) degree_one_associatedI: + assumes "subfield K R" and "p \ carrier (K[X])" and "degree p = 1" + shows "p \\<^bsub>K[X]\<^esub> [ \, inv (lead_coeff p) \ (const_term p) ]" +proof - + from \p \ carrier (K[X])\ and \degree p = 1\ + obtain a b where "p = [ a, b ]" and "a \ K" "a \ \" and "b \ K" + by auto + thus ?thesis + using subring_degree_one_associatedI[OF subfieldE(1)[OF assms(1)]] + subfield_m_inv[OF assms(1)] subsetD[OF subfieldE(3)[OF assms(1)]] + unfolding const_term_def + by auto +qed + subsection \Ideals\ lemma (in domain) exists_unique_gen: @@ -882,6 +1136,26 @@ subsection \Roots and Multiplicity\ +definition (in ring) is_root :: "'a list \ 'a \ bool" + where "is_root p x \ (x \ carrier R \ eval p x = \ \ p \ [])" + +definition (in ring) alg_mult :: "'a list \ 'a \ nat" + where "alg_mult p x = + (if p = [] then 0 else + (if x \ carrier R then Greatest (\ n. ([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> n) pdivides p) else 0))" + +definition (in ring) roots :: "'a list \ 'a multiset" + where "roots p = Abs_multiset (alg_mult p)" + +definition (in ring) roots_on :: "'a set \ 'a list \ 'a multiset" + where "roots_on K p = roots p \# mset_set K" + +definition (in ring) splitted :: "'a list \ bool" + where "splitted p \ size (roots p) = degree p" + +definition (in ring) splitted_on :: "'a set \ 'a list \ bool" + where "splitted_on K p \ size (roots_on K p) = degree p" + lemma (in domain) pdivides_imp_root_sharing: assumes "p \ carrier (poly_ring R)" "p pdivides q" and "a \ carrier R" shows "eval p a = \ \ eval q a = \" @@ -922,6 +1196,782 @@ show "inv (lead_coeff p) \ (const_term p) \ K" using p subringE(6)[OF subfieldE(1)[OF assms(1)]] unfolding ct by auto qed +lemma (in domain) is_root_imp_pdivides: + assumes "p \ carrier (poly_ring R)" + shows "is_root p x \ [ \, \ x ] pdivides p" +proof - + let ?b = "[ \ , \ x ]" + + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + assume "is_root p x" hence x: "x \ carrier R" and is_root: "eval p x = \" + unfolding is_root_def by auto + hence b: "?b \ carrier (poly_ring R)" + unfolding sym[OF univ_poly_carrier] polynomial_def by auto + then obtain q r where q: "q \ carrier (poly_ring R)" and r: "r \ carrier (poly_ring R)" + and long_divides: "p = (?b \\<^bsub>poly_ring R\<^esub> q) \\<^bsub>poly_ring R\<^esub> r" "r = [] \ degree r < degree ?b" + using long_division_theorem[OF carrier_is_subring, of p ?b] assms by (auto simp add: univ_poly_carrier) + + show ?thesis + proof (cases "r = []") + case True then have "r = \\<^bsub>poly_ring R\<^esub>" + unfolding univ_poly_zero[of R "carrier R"] . + thus ?thesis + using long_divides(1) q r b dividesI[OF q, of p ?b] by (simp add: pdivides_def) + next + case False then have "length r = Suc 0" + using long_divides(2) le_SucE by fastforce + then obtain a where "r = [ a ]" and a: "a \ carrier R" and "a \ \" + using r unfolding sym[OF univ_poly_carrier] polynomial_def + by (metis False length_0_conv length_Suc_conv list.sel(1) list.set_sel(1) subset_code(1)) + + have "eval p x = ((eval ?b x) \ (eval q x)) \ (eval r x)" + using long_divides(1) ring_hom_memE[OF eval_is_hom[OF carrier_is_subring x]] by (simp add: b q r) + also have " ... = eval r x" + using ring_hom_memE[OF eval_is_hom[OF carrier_is_subring x]] x b q r by (auto, algebra) + finally have "a = \" + using a unfolding \r = [ a ]\ is_root by simp + with \a \ \\ have False .. thus ?thesis .. + qed +qed + +lemma (in domain) pdivides_imp_is_root: + assumes "p \ []" and "x \ carrier R" + shows "[ \, \ x ] pdivides p \ is_root p x" +proof - + assume "[ \, \ x ] pdivides p" + then obtain q where q: "q \ carrier (poly_ring R)" and pdiv: "p = [ \, \ x ] \\<^bsub>poly_ring R\<^esub> q" + unfolding pdivides_def by auto + moreover have "[ \, \ x ] \ carrier (poly_ring R)" + using assms(2) unfolding sym[OF univ_poly_carrier] polynomial_def by simp + ultimately have "eval p x = \" + using ring_hom_memE[OF eval_is_hom[OF carrier_is_subring, of x]] assms(2) by (auto, algebra) + with \p \ []\ and \x \ carrier R\ show "is_root p x" + unfolding is_root_def by simp +qed + +lemma (in domain) associated_polynomials_imp_same_is_root: + assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" and "p \\<^bsub>poly_ring R\<^esub> q" + shows "is_root p x \ is_root q x" +proof (cases "p = []") + case True with \p \\<^bsub>poly_ring R\<^esub> q\ have "q = []" + unfolding associated_def True factor_def univ_poly_def by auto + thus ?thesis + using True unfolding is_root_def by simp +next + case False + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + { fix p q + assume p: "p \ carrier (poly_ring R)" and q: "q \ carrier (poly_ring R)" and pq: "p \\<^bsub>poly_ring R\<^esub> q" + have "is_root p x \ is_root q x" + proof - + assume is_root: "is_root p x" + then have "[ \, \ x ] pdivides p" and "p \ []" and "x \ carrier R" + using is_root_imp_pdivides[OF p] unfolding is_root_def by auto + moreover have "[ \, \ x ] \ carrier (poly_ring R)" + using is_root unfolding is_root_def sym[OF univ_poly_carrier] polynomial_def by simp + ultimately have "[ \, \ x ] pdivides q" + using UP.divides_cong_r[OF _ pq ] unfolding pdivides_def by simp + with \p \ []\ and \x \ carrier R\ show ?thesis + using associated_polynomials_imp_same_length[OF carrier_is_subring p q pq] + pdivides_imp_is_root[of q x] + by fastforce + qed + } + + then show ?thesis + using assms UP.associated_sym[OF assms(3)] by blast +qed + +lemma (in ring) monic_degree_one_root_condition: + assumes "a \ carrier R" shows "is_root [ \, \ a ] b \ a = b" + using assms minus_equality r_neg[OF assms] unfolding is_root_def by (auto, fastforce) + +lemma (in field) degree_one_root_condition: + assumes "p \ carrier (poly_ring R)" and "degree p = 1" + shows "is_root p x \ x = \ (inv (lead_coeff p) \ (const_term p))" +proof - + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + from \degree p = 1\ have "length p = Suc (Suc 0)" + by simp + then obtain a b where p: "p = [ a, b ]" + by (metis length_0_conv length_Cons list.exhaust nat.inject) + hence a: "a \ carrier R" "a \ \" and b: "b \ carrier R" + using assms(1) unfolding sym[OF univ_poly_carrier] polynomial_def by auto + hence inv_a: "inv a \ carrier R" "(inv a) \ a = \" + using subfield_m_inv[OF carrier_is_subfield, of a] by auto + hence in_carrier: "[ \, (inv a) \ b ] \ carrier (poly_ring R)" + using b unfolding sym[OF univ_poly_carrier] polynomial_def by auto + + have "p \\<^bsub>poly_ring R\<^esub> [ \, (inv a) \ b ]" + proof (rule UP.associatedI2'[OF _ _ in_carrier, of _ "[ a ]"]) + have "p = [ a ] \\<^bsub>poly_ring R\<^esub> [ \, inv a \ b ]" + using a inv_a b m_assoc[of a "inv a" b] unfolding p univ_poly_mult by (auto, algebra) + also have " ... = [ \, inv a \ b ] \\<^bsub>poly_ring R\<^esub> [ a ]" + using UP.m_comm[OF in_carrier, of "[ a ]"] a + by (auto simp add: sym[OF univ_poly_carrier] polynomial_def) + finally show "p = [ \, inv a \ b ] \\<^bsub>poly_ring R\<^esub> [ a ]" . + next + from \a \ carrier R\ and \a \ \\ show "[ a ] \ Units (poly_ring R)" + unfolding univ_poly_units[OF carrier_is_subfield] by simp + qed + + moreover have "(inv a) \ b = \ (\ (inv (lead_coeff p) \ (const_term p)))" + and "inv (lead_coeff p) \ (const_term p) \ carrier R" + using inv_a a b unfolding p const_term_def by auto + + ultimately show ?thesis + using associated_polynomials_imp_same_is_root[OF assms(1) in_carrier] + monic_degree_one_root_condition + by (metis add.inv_closed) +qed + +lemma (in domain) is_root_poly_mult_imp_is_root: + assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" + shows "is_root (p \\<^bsub>poly_ring R\<^esub> q) x \ (is_root p x) \ (is_root q x)" +proof - + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + assume is_root: "is_root (p \\<^bsub>poly_ring R\<^esub> q) x" + hence "p \ []" and "q \ []" + unfolding is_root_def sym[OF univ_poly_zero[of R "carrier R"]] + using UP.l_null[OF assms(2)] UP.r_null[OF assms(1)] by blast+ + moreover have x: "x \ carrier R" and "eval (p \\<^bsub>poly_ring R\<^esub> q) x = \" + using is_root unfolding is_root_def by simp+ + hence "eval p x = \ \ eval q x = \" + using ring_hom_memE[OF eval_is_hom[OF carrier_is_subring], of x] assms integral by auto + ultimately show "(is_root p x) \ (is_root q x)" + using x unfolding is_root_def by auto +qed + +lemma (in domain) degree_zero_imp_not_is_root: + assumes "p \ carrier (poly_ring R)" and "degree p = 0" shows "\ is_root p x" +proof (cases "p = []", simp add: is_root_def) + case False with \degree p = 0\ have "length p = Suc 0" + using le_SucE by fastforce + then obtain a where "p = [ a ]" and "a \ carrier R" and "a \ \" + using assms unfolding sym[OF univ_poly_carrier] polynomial_def + by (metis False length_0_conv length_Suc_conv list.sel(1) list.set_sel(1) subset_code(1)) + thus ?thesis + unfolding is_root_def by auto +qed + +lemma (in domain) finite_number_of_roots: + assumes "p \ carrier (poly_ring R)" shows "finite { x. is_root p x }" + using assms +proof (induction "degree p" arbitrary: p) + case 0 thus ?case + by (simp add: degree_zero_imp_not_is_root) +next + case (Suc n) show ?case + proof (cases "{ x. is_root p x } = {}") + case True thus ?thesis + by (simp add: True) + next + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + case False + then obtain a where is_root: "is_root p a" + by blast + hence a: "a \ carrier R" and eval: "eval p a = \" and p_not_zero: "p \ []" + unfolding is_root_def by auto + hence in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" + unfolding sym[OF univ_poly_carrier] polynomial_def by auto + + obtain q where q: "q \ carrier (poly_ring R)" and p: "p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> q" + using is_root_imp_pdivides[OF Suc(3) is_root] unfolding pdivides_def by auto + with \p \ []\ have q_not_zero: "q \ []" + using UP.r_null UP.integral in_carrier unfolding sym[OF univ_poly_zero[of R "carrier R"]] + by metis + hence "degree q = n" + using poly_mult_degree_eq[OF carrier_is_subring, of "[ \, \ a ]" q] + in_carrier q p_not_zero p Suc(2) + unfolding univ_poly_carrier + by (metis One_nat_def Suc_eq_plus1 diff_Suc_1 list.distinct(1) + list.size(3-4) plus_1_eq_Suc univ_poly_mult) + hence "finite { x. is_root q x }" + using Suc(1)[OF _ q] by simp + + moreover have "{ x. is_root p x } \ insert a { x. is_root q x }" + using is_root_poly_mult_imp_is_root[OF in_carrier q] + monic_degree_one_root_condition[OF a] + unfolding p by auto + + ultimately show ?thesis + using finite_subset by auto + qed +qed + +lemma (in domain) alg_multE: + assumes "x \ carrier R" and "p \ carrier (poly_ring R)" and "p \ []" + shows "([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult p x)) pdivides p" + and "\n. ([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> n) pdivides p \ n \ alg_mult p x" +proof - + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + let ?ppow = "\n :: nat. ([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> n)" + + define S :: "nat set" where "S = { n. ?ppow n pdivides p }" + have "?ppow 0 = \\<^bsub>poly_ring R\<^esub>" + using UP.nat_pow_0 by simp + hence "0 \ S" + using UP.one_divides[OF assms(2)] unfolding S_def pdivides_def by simp + hence "S \ {}" + by auto + + moreover have "n \ degree p" if "n \ S" for n :: nat + proof - + have "[ \, \ x ] \ carrier (poly_ring R)" + using assms unfolding sym[OF univ_poly_carrier] polynomial_def by auto + hence "?ppow n \ carrier (poly_ring R)" + using assms unfolding univ_poly_zero by auto + with \n \ S\ have "degree (?ppow n) \ degree p" + using pdivides_imp_degree_le[OF carrier_is_subring _ assms(2-3), of "?ppow n"] by (simp add: S_def) + with \[ \, \ x ] \ carrier (poly_ring R)\ show ?thesis + using polynomial_pow_degree by simp + qed + hence "finite S" + using finite_nat_set_iff_bounded_le by blast + + ultimately have MaxS: "\n. n \ S \ n \ Max S" "Max S \ S" + using Max_ge[of S] Max_in[of S] by auto + with \x \ carrier R\ have "alg_mult p x = Max S" + using Greatest_equality[of "\n. ?ppow n pdivides p" "Max S"] assms(3) + unfolding S_def alg_mult_def by auto + thus "([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult p x)) pdivides p" + and "\n. ([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> n) pdivides p \ n \ alg_mult p x" + using MaxS unfolding S_def by auto +qed + +lemma (in domain) le_alg_mult_imp_pdivides: + assumes "x \ carrier R" and "p \ carrier (poly_ring R)" + shows "n \ alg_mult p x \ ([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> n) pdivides p" +proof - + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + assume le_alg_mult: "n \ alg_mult p x" + have in_carrier: "[ \, \ x ] \ carrier (poly_ring R)" + using assms(1) unfolding sym[OF univ_poly_carrier] polynomial_def by auto + hence ppow_pdivides: + "([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> n) pdivides + ([ \, \ x ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult p x))" + using polynomial_pow_division[OF _ le_alg_mult] by simp + + show ?thesis + proof (cases "p = []") + case True thus ?thesis + using in_carrier pdivides_zero[OF carrier_is_subring] by auto + next + case False thus ?thesis + using ppow_pdivides UP.divides_trans UP.nat_pow_closed alg_multE(1)[OF assms] in_carrier + unfolding pdivides_def by meson + qed +qed + +lemma (in domain) alg_mult_gt_zero_iff_is_root: + assumes "p \ carrier (poly_ring R)" shows "alg_mult p x > 0 \ is_root p x" +proof - + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + show ?thesis + proof + assume is_root: "is_root p x" hence x: "x \ carrier R" and not_zero: "p \ []" + unfolding is_root_def by auto + have "[\, \ x] [^]\<^bsub>poly_ring R\<^esub> (Suc 0) = [\, \ x]" + using x unfolding univ_poly_def by auto + thus "alg_mult p x > 0" + using is_root_imp_pdivides[OF _ is_root] alg_multE(2)[OF x, of p "Suc 0"] not_zero assms by auto + next + assume gt_zero: "alg_mult p x > 0" + hence x: "x \ carrier R" and not_zero: "p \ []" + unfolding alg_mult_def by (cases "p = []", auto, cases "x \ carrier R", auto) + hence in_carrier: "[ \, \ x ] \ carrier (poly_ring R)" + unfolding sym[OF univ_poly_carrier] polynomial_def by auto + with \x \ carrier R\ have "[ \, \ x ] pdivides p" and "eval [ \, \ x ] x = \" + using le_alg_mult_imp_pdivides[of x p "1::nat"] gt_zero assms by (auto, algebra) + thus "is_root p x" + using pdivides_imp_root_sharing[OF in_carrier] not_zero x by (simp add: is_root_def) + qed +qed + +lemma (in domain) alg_mult_eq_count_roots: + assumes "p \ carrier (poly_ring R)" shows "alg_mult p = count (roots p)" + using finite_number_of_roots[OF assms] + unfolding sym[OF alg_mult_gt_zero_iff_is_root[OF assms]] + by (simp add: multiset_def roots_def) + +lemma (in domain) roots_mem_iff_is_root: + assumes "p \ carrier (poly_ring R)" shows "x \# roots p \ is_root p x" + using alg_mult_eq_count_roots[OF assms] count_greater_zero_iff + unfolding roots_def sym[OF alg_mult_gt_zero_iff_is_root[OF assms]] by metis + +lemma (in domain) degree_zero_imp_empty_roots: + assumes "p \ carrier (poly_ring R)" and "degree p = 0" shows "roots p = {#}" + using degree_zero_imp_not_is_root[of p] roots_mem_iff_is_root[of p] assms by auto + +lemma (in domain) degree_zero_imp_splitted: + assumes "p \ carrier (poly_ring R)" and "degree p = 0" shows "splitted p" + unfolding splitted_def degree_zero_imp_empty_roots[OF assms] assms(2) by simp + +lemma (in domain) roots_inclI': + assumes "p \ carrier (poly_ring R)" and "\a. \ a \ carrier R; p \ [] \ \ alg_mult p a \ count m a" + shows "roots p \# m" +proof (intro mset_subset_eqI) + fix a show "count (roots p) a \ count m a" + using assms unfolding sym[OF alg_mult_eq_count_roots[OF assms(1)]] alg_mult_def + by (cases "p = []", simp, cases "a \ carrier R", auto) +qed + +lemma (in domain) roots_inclI: + assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" "q \ []" + and "\a. \ a \ carrier R; p \ [] \ \ ([ \, \ a ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult p a)) pdivides q" + shows "roots p \# roots q" + using roots_inclI'[OF assms(1), of "roots q"] assms alg_multE(2)[OF _ assms(2-3)] + unfolding sym[OF alg_mult_eq_count_roots[OF assms(2)]] by auto + +lemma (in domain) pdivides_imp_roots_incl: + assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" "q \ []" + shows "p pdivides q \ roots p \# roots q" +proof (rule roots_inclI[OF assms]) + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + fix a assume "p pdivides q" and a: "a \ carrier R" + hence "[ \ , \ a ] \ carrier (poly_ring R)" + unfolding sym[OF univ_poly_carrier] polynomial_def by simp + with \p pdivides q\ show "([\, \ a] [^]\<^bsub>poly_ring R\<^esub> (alg_mult p a)) pdivides q" + using UP.divides_trans[of _p q] le_alg_mult_imp_pdivides[OF a assms(1)] + by (auto simp add: pdivides_def) +qed + +lemma (in domain) associated_polynomials_imp_same_roots: + assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" and "p \\<^bsub>poly_ring R\<^esub> q" + shows "roots p = roots q" + using assms pdivides_imp_roots_incl zero_pdivides + unfolding pdivides_def associated_def + by (metis subset_mset.eq_iff) + +lemma (in domain) monic_degree_one_roots: + assumes "a \ carrier R" shows "roots [ \ , \ a ] = {# a #}" +proof - + let ?p = "[ \ , \ a ]" + + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + from \a \ carrier R\ have in_carrier: "?p \ carrier (poly_ring R)" + unfolding sym[OF univ_poly_carrier] polynomial_def by simp + show ?thesis + proof (rule subset_mset.antisym) + show "{# a #} \# roots ?p" + using roots_mem_iff_is_root[OF in_carrier] + monic_degree_one_root_condition[OF assms] + by simp + next + show "roots ?p \# {# a #}" + proof (rule mset_subset_eqI, auto) + fix b assume "a \ b" thus "count (roots ?p) b = 0" + using alg_mult_gt_zero_iff_is_root[OF in_carrier] + monic_degree_one_root_condition[OF assms] + unfolding sym[OF alg_mult_eq_count_roots[OF in_carrier]] + by fastforce + next + have "(?p [^]\<^bsub>poly_ring R\<^esub> (alg_mult ?p a)) pdivides ?p" + using le_alg_mult_imp_pdivides[OF assms in_carrier] by simp + hence "degree (?p [^]\<^bsub>poly_ring R\<^esub> (alg_mult ?p a)) \ degree ?p" + using pdivides_imp_degree_le[OF carrier_is_subring, of _ ?p] in_carrier by auto + thus "count (roots ?p) a \ Suc 0" + using polynomial_pow_degree[OF in_carrier] + unfolding sym[OF alg_mult_eq_count_roots[OF in_carrier]] + by auto + qed + qed +qed + +lemma (in domain) degree_one_roots: + assumes "a \ carrier R" "a' \ carrier R" and "b \ carrier R" and "a \ a' = \" + shows "roots [ a , b ] = {# \ (a' \ b) #}" +proof - + have "[ a, b ] \ carrier (poly_ring R)" and "[ \, a' \ b ] \ carrier (poly_ring R)" + using assms unfolding sym[OF univ_poly_carrier] polynomial_def by auto + thus ?thesis + using subring_degree_one_associatedI[OF carrier_is_subring assms] assms + monic_degree_one_roots associated_polynomials_imp_same_roots + by (metis add.inv_closed local.minus_minus m_closed) +qed + +lemma (in field) degree_one_imp_singleton_roots: + assumes "p \ carrier (poly_ring R)" and "degree p = 1" + shows "roots p = {# \ (inv (lead_coeff p) \ (const_term p)) #}" +proof - + from \p \ carrier (poly_ring R)\ and \degree p = 1\ + obtain a b where "p = [ a, b ]" and "a \ carrier R" "a \ \" and "b \ carrier R" + by auto + thus ?thesis + using degree_one_roots[of a "inv a" b] + by (auto simp add: const_term_def field_Units) +qed + +lemma (in field) degree_one_imp_splitted: + assumes "p \ carrier (poly_ring R)" and "degree p = 1" shows "splitted p" + using degree_one_imp_singleton_roots[OF assms] assms(2) unfolding splitted_def by simp + +lemma (in field) no_roots_imp_same_roots: + assumes "p \ carrier (poly_ring R)" "p \ []" and "q \ carrier (poly_ring R)" + shows "roots p = {#} \ roots (p \\<^bsub>poly_ring R\<^esub> q) = roots q" +proof - + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + assume no_roots: "roots p = {#}" show "roots (p \\<^bsub>poly_ring R\<^esub> q) = roots q" + proof (intro subset_mset.antisym) + have pdiv: "q pdivides (p \\<^bsub>poly_ring R\<^esub> q)" + using UP.divides_prod_l assms unfolding pdivides_def by blast + show "roots q \# roots (p \\<^bsub>poly_ring R\<^esub> q)" + using pdivides_imp_roots_incl[OF _ _ _ pdiv] assms + degree_zero_imp_empty_roots[OF assms(3)] + by (cases "q = []", auto, metis UP.l_null UP.m_rcancel UP.zero_closed univ_poly_zero) + next + show "roots (p \\<^bsub>poly_ring R\<^esub> q) \# roots q" + proof (cases "p \\<^bsub>poly_ring R\<^esub> q = []") + case True thus ?thesis + using degree_zero_imp_empty_roots[OF UP.m_closed[OF assms(1,3)]] by simp + next + case False with \p \ []\ have q_not_zero: "q \ []" + by (metis UP.r_null assms(1) univ_poly_zero) + show ?thesis + proof (rule roots_inclI[OF UP.m_closed[OF assms(1,3)] assms(3) q_not_zero]) + fix a assume a: "a \ carrier R" + hence "\ ([ \, \ a ] pdivides p)" + using assms(1-2) no_roots pdivides_imp_is_root roots_mem_iff_is_root[of p] by auto + moreover have in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" + using a unfolding sym[OF univ_poly_carrier] polynomial_def by auto + hence "pirreducible (carrier R) [ \, \ a ]" + using degree_one_imp_pirreducible[OF carrier_is_subfield] by simp + moreover + have "([ \, \ a ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult (p \\<^bsub>poly_ring R\<^esub> q) a)) pdivides (p \\<^bsub>poly_ring R\<^esub> q)" + using le_alg_mult_imp_pdivides[OF a UP.m_closed, of p q] assms by simp + ultimately show "([ \, \ a ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult (p \\<^bsub>poly_ring R\<^esub> q) a)) pdivides q" + using pirreducible_pow_pdivides_iff[OF carrier_is_subfield in_carrier] assms by auto + qed + qed + qed +qed + +lemma (in field) poly_mult_degree_one_monic_imp_same_roots: + assumes "a \ carrier R" and "p \ carrier (poly_ring R)" "p \ []" + shows "roots ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p) = add_mset a (roots p)" +proof - + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + from \a \ carrier R\ have in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" + unfolding sym[OF univ_poly_carrier] polynomial_def by simp + + show ?thesis + proof (intro subset_mset.antisym[OF roots_inclI' mset_subset_eqI]) + show "([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p) \ carrier (poly_ring R)" + using in_carrier assms(2) by simp + next + fix b assume b: "b \ carrier R" and "[ \, \ a ] \\<^bsub>poly_ring R\<^esub> p \ []" + hence not_zero: "p \ []" + unfolding univ_poly_def by auto + from \b \ carrier R\ have in_carrier': "[ \, \ b ] \ carrier (poly_ring R)" + unfolding sym[OF univ_poly_carrier] polynomial_def by simp + show "alg_mult ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p) b \ count (add_mset a (roots p)) b" + proof (cases "a = b") + case False + hence "\ [ \, \ b ] pdivides [ \, \ a ]" + using assms(1) b monic_degree_one_root_condition pdivides_imp_is_root by blast + moreover have "pirreducible (carrier R) [ \, \ b ]" + using degree_one_imp_pirreducible[OF carrier_is_subfield in_carrier'] by simp + ultimately + have "[ \, \ b ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p) b) pdivides p" + using le_alg_mult_imp_pdivides[OF b UP.m_closed, of _ p] assms(2) in_carrier + pirreducible_pow_pdivides_iff[OF carrier_is_subfield in_carrier' in_carrier, of p] + by auto + with \a \ b\ show ?thesis + using alg_mult_eq_count_roots[OF assms(2)] alg_multE(2)[OF b assms(2) not_zero] by auto + next + case True + have "[ \, \ a ] pdivides ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p)" + using dividesI[OF assms(2)] unfolding pdivides_def by auto + with \[ \, \ a ] \\<^bsub>poly_ring R\<^esub> p \ []\ + have "alg_mult ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p) a \ Suc 0" + using alg_multE(2)[of a _ "Suc 0"] in_carrier assms by auto + then obtain m where m: "alg_mult ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p) a = Suc m" + using Suc_le_D by blast + hence "([ \, \ a ] \\<^bsub>poly_ring R\<^esub> ([ \, \ a ] [^]\<^bsub>poly_ring R\<^esub> m)) pdivides + ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p)" + using le_alg_mult_imp_pdivides[OF _ UP.m_closed, of a _ p] + in_carrier assms UP.nat_pow_Suc2 by force + hence "([ \, \ a ] [^]\<^bsub>poly_ring R\<^esub> m) pdivides p" + using UP.mult_divides in_carrier assms(2) + unfolding univ_poly_zero pdivides_def factor_def + by (simp add: UP.m_assoc UP.m_lcancel univ_poly_zero) + with \a = b\ show ?thesis + using alg_mult_eq_count_roots assms in_carrier UP.nat_pow_Suc2 + alg_multE(2)[OF assms(1) _ not_zero] m + by auto + qed + next + fix b + have not_zero: "[ \, \ a ] \\<^bsub>poly_ring R\<^esub> p \ []" + using assms in_carrier univ_poly_zero[of R] UP.integral by auto + + show "count (add_mset a (roots p)) b \ count (roots ([\, \ a] \\<^bsub>poly_ring R\<^esub> p)) b" + proof (cases "a = b") + case True + have "([ \, \ a ] \\<^bsub>poly_ring R\<^esub> ([ \, \ a ] [^]\<^bsub>poly_ring R\<^esub> (alg_mult p a))) pdivides + ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p)" + using UP.divides_mult[OF _ in_carrier] le_alg_mult_imp_pdivides[OF assms(1,2)] in_carrier assms + by (auto simp add: pdivides_def) + with \a = b\ show ?thesis + using alg_mult_eq_count_roots assms in_carrier UP.nat_pow_Suc2 + alg_multE(2)[OF assms(1) _ not_zero] + by auto + next + case False + have "p pdivides ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> p)" + using dividesI[OF in_carrier] UP.m_comm in_carrier assms unfolding pdivides_def by auto + thus ?thesis + using False pdivides_imp_roots_incl assms in_carrier not_zero + by (simp add: subseteq_mset_def) + qed + qed +qed + +lemma (in domain) not_empty_rootsE[elim]: + assumes "p \ carrier (poly_ring R)" and "roots p \ {#}" + and "\a. \ a \ carrier R; a \# roots p; + [ \, \ a ] \ carrier (poly_ring R); [ \, \ a ] pdivides p \ \ P" + shows P +proof - + from \roots p \ {#}\ obtain a where "a \# roots p" + by blast + with \p \ carrier (poly_ring R)\ have "[ \, \ a ] pdivides p" + and "[ \, \ a ] \ carrier (poly_ring R)" and "a \ carrier R" + using is_root_imp_pdivides[of p] roots_mem_iff_is_root[of p] is_root_def[of p a] + unfolding sym[OF univ_poly_carrier] polynomial_def by auto + with \a \# roots p\ show ?thesis + using assms(3)[of a] by auto +qed + +lemma (in field) associated_polynomials_imp_same_roots: + assumes "p \ carrier (poly_ring R)" "p \ []" and "q \ carrier (poly_ring R)" "q \ []" + shows "roots (p \\<^bsub>poly_ring R\<^esub> q) = roots p + roots q" +proof - + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + from assms show ?thesis + proof (induction "degree p" arbitrary: p rule: less_induct) + case less show ?case + proof (cases "roots p = {#}") + case True thus ?thesis + using no_roots_imp_same_roots[of p q] less by simp + next + case False with \p \ carrier (poly_ring R)\ + obtain a where a: "a \ carrier R" and "a \# roots p" and pdiv: "[ \, \ a ] pdivides p" + and in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" + by blast + show ?thesis + proof (cases "degree p = 1") + case True with \p \ carrier (poly_ring R)\ + obtain b c where p: "p = [ b, c ]" and b: "b \ carrier R" "b \ \" and c: "c \ carrier R" + by auto + with \a \# roots p\ have roots: "roots p = {# a #}" and a: "\ a = inv b \ c" "a \ carrier R" + and lead: "lead_coeff p = b" and const: "const_term p = c" + using degree_one_imp_singleton_roots[of p] less(2) field_Units + unfolding const_term_def by auto + hence "(p \\<^bsub>poly_ring R\<^esub> q) \\<^bsub>poly_ring R\<^esub> ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> q)" + using UP.mult_cong_l[OF degree_one_associatedI[OF carrier_is_subfield _ True]] less(2,4) + by (auto simp add: a lead const) + hence "roots (p \\<^bsub>poly_ring R\<^esub> q) = roots ([ \, \ a ] \\<^bsub>poly_ring R\<^esub> q)" + using associated_polynomials_imp_same_roots in_carrier less(2,4) unfolding a by simp + thus ?thesis + unfolding poly_mult_degree_one_monic_imp_same_roots[OF a(2) less(4,5)] roots by simp + next + case False + from \[ \, \ a ] pdivides p\ + obtain r where p: "p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> r" and r: "r \ carrier (poly_ring R)" + unfolding pdivides_def by auto + with \p \ []\ have not_zero: "r \ []" + using in_carrier univ_poly_zero[of R "carrier R"] UP.integral_iff by auto + with \p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> r\ have deg: "degree p = Suc (degree r)" + using poly_mult_degree_eq[OF carrier_is_subring, of _ r] in_carrier r + unfolding univ_poly_carrier sym[OF univ_poly_mult[of R "carrier R"]] by auto + with \r \ []\ and \q \ []\ have "r \\<^bsub>poly_ring R\<^esub> q \ []" + using in_carrier univ_poly_zero[of R "carrier R"] UP.integral less(4) r by auto + hence "roots (p \\<^bsub>poly_ring R\<^esub> q) = add_mset a (roots (r \\<^bsub>poly_ring R\<^esub> q))" + using poly_mult_degree_one_monic_imp_same_roots[OF a UP.m_closed[OF r less(4)]] + UP.m_assoc[OF in_carrier r less(4)] p by auto + also have " ... = add_mset a (roots r + roots q)" + using less(1)[OF _ r not_zero less(4-5)] deg by simp + also have " ... = (add_mset a (roots r)) + roots q" + by simp + also have " ... = roots p + roots q" + using poly_mult_degree_one_monic_imp_same_roots[OF a r not_zero] p by simp + finally show ?thesis . + qed + qed + qed +qed + +lemma (in field) size_roots_le_degree: + assumes "p \ carrier (poly_ring R)" shows "size (roots p) \ degree p" + using assms +proof (induction "degree p" arbitrary: p rule: less_induct) + case less show ?case + proof (cases "roots p = {#}", simp) + interpret UP: domain "poly_ring R" + using univ_poly_is_domain[OF carrier_is_subring] . + + case False with \p \ carrier (poly_ring R)\ + obtain a where a: "a \ carrier R" and "a \# roots p" and "[ \, \ a ] pdivides p" + and in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" + by blast + then obtain q where p: "p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> q" and q: "q \ carrier (poly_ring R)" + unfolding pdivides_def by auto + with \a \# roots p\ have "p \ []" + using degree_zero_imp_empty_roots[OF less(2)] by auto + hence not_zero: "q \ []" + using in_carrier univ_poly_zero[of R "carrier R"] UP.integral_iff p by auto + hence "degree p = Suc (degree q)" + using poly_mult_degree_eq[OF carrier_is_subring, of _ q] in_carrier p q + unfolding univ_poly_carrier sym[OF univ_poly_mult[of R "carrier R"]] by auto + with \q \ []\ show ?thesis + using poly_mult_degree_one_monic_imp_same_roots[OF a q] p less(1)[OF _ q] + by (metis Suc_le_mono lessI size_add_mset) + qed +qed + +lemma (in domain) pirreducible_roots: + assumes "p \ carrier (poly_ring R)" and "pirreducible (carrier R) p" and "degree p \ 1" + shows "roots p = {#}" +proof (rule ccontr) + assume "roots p \ {#}" with \p \ carrier (poly_ring R)\ + obtain a where a: "a \ carrier R" and "a \# roots p" and "[ \, \ a ] pdivides p" + and in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" + by blast + hence "[ \, \ a ] \\<^bsub>poly_ring R\<^esub> p" + using divides_pirreducible_condition[OF assms(2) in_carrier] + univ_poly_units_incl[OF carrier_is_subring] + unfolding pdivides_def by auto + hence "degree p = 1" + using associated_polynomials_imp_same_length[OF carrier_is_subring in_carrier assms(1)] by auto + with \degree p \ 1\ show False .. +qed + +lemma (in field) pirreducible_imp_not_splitted: + assumes "p \ carrier (poly_ring R)" and "pirreducible (carrier R) p" and "degree p \ 1" + shows "\ splitted p" + using pirreducible_roots[of p] pirreducible_degree[OF carrier_is_subfield, of p] assms + by (simp add: splitted_def) + +lemma (in field) + assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" + and "pirreducible (carrier R) p" and "degree p \ 1" + shows "roots (p \\<^bsub>poly_ring R\<^esub> q) = roots q" + using no_roots_imp_same_roots[of p q] pirreducible_roots[of p] assms + unfolding ring_irreducible_def univ_poly_zero by auto + +lemma (in field) trivial_factors_imp_splitted: + assumes "p \ carrier (poly_ring R)" + and "\q. \ q \ carrier (poly_ring R); pirreducible (carrier R) q; q pdivides p \ \ degree q \ 1" + shows "splitted p" + using assms +proof (induction "degree p" arbitrary: p rule: less_induct) + interpret UP: principal_domain "poly_ring R" + using univ_poly_is_principal[OF carrier_is_subfield] . + case less show ?case + proof (cases "degree p = 0", simp add: degree_zero_imp_splitted[OF less(2)]) + case False show ?thesis + proof (cases "roots p = {#}") + case True + from \degree p \ 0\ have "p \ Units (poly_ring R)" and "p \ carrier (poly_ring R) - { [] }" + using univ_poly_units'[OF carrier_is_subfield, of p] less(2) by auto + then obtain q where "q \ carrier (poly_ring R)" "pirreducible (carrier R) q" and "q pdivides p" + using UP.exists_irreducible_divisor[of p] unfolding univ_poly_zero pdivides_def by auto + with \degree p \ 0\ have "roots p \ {#}" + using degree_one_imp_singleton_roots[OF _ , of q] less(3)[of q] + pdivides_imp_roots_incl[OF _ less(2), of q] + pirreducible_degree[OF carrier_is_subfield, of q] + by force + from \roots p = {#}\ and \roots p \ {#}\ have False + by simp + thus ?thesis .. + next + case False with \p \ carrier (poly_ring R)\ + obtain a where a: "a \ carrier R" and "a \# roots p" and "[ \, \ a ] pdivides p" + and in_carrier: "[ \, \ a ] \ carrier (poly_ring R)" + by blast + then obtain q where p: "p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> q" and q: "q \ carrier (poly_ring R)" + unfolding pdivides_def by blast + with \degree p \ 0\ have "p \ []" + by auto + with \p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> q\ have "q \ []" + using in_carrier q unfolding sym[OF univ_poly_zero[of R "carrier R"]] by auto + with \p = [ \, \ a ] \\<^bsub>poly_ring R\<^esub> q\ and \p \ []\ have "degree p = Suc (degree q)" + using poly_mult_degree_eq[OF carrier_is_subring] in_carrier q + unfolding univ_poly_carrier sym[OF univ_poly_mult[of R "carrier R"]] by auto + moreover have "q pdivides p" + using p dividesI[OF in_carrier] UP.m_comm[OF in_carrier q] by (auto simp add: pdivides_def) + hence "degree r = 1" if "r \ carrier (poly_ring R)" and "pirreducible (carrier R) r" + and "r pdivides q" for r + using less(3)[OF that(1-2)] UP.divides_trans[OF _ _ that(1), of q p] that(3) + pirreducible_degree[OF carrier_is_subfield that(1-2)] + by (auto simp add: pdivides_def) + ultimately have "splitted q" + using less(1)[OF _ q] by auto + with \degree p = Suc (degree q)\ and \q \ []\ show ?thesis + using poly_mult_degree_one_monic_imp_same_roots[OF a q] + unfolding sym[OF p] splitted_def + by simp + qed + qed +qed + +lemma (in field) pdivides_imp_splitted: + assumes "p \ carrier (poly_ring R)" and "q \ carrier (poly_ring R)" "q \ []" and "splitted q" + shows "p pdivides q \ splitted p" +proof (cases "p = []") + case True thus ?thesis + using degree_zero_imp_splitted[OF assms(1)] by simp +next + interpret UP: principal_domain "poly_ring R" + using univ_poly_is_principal[OF carrier_is_subfield] . + + case False + assume "p pdivides q" + then obtain b where b: "b \ carrier (poly_ring R)" and q: "q = p \\<^bsub>poly_ring R\<^esub> b" + unfolding pdivides_def by auto + with \q \ []\ have "p \ []" and "b \ []" + using assms UP.integral_iff[of p b] unfolding sym[OF univ_poly_zero[of R "carrier R"]] by auto + hence "degree p + degree b = size (roots p) + size (roots b)" + using associated_polynomials_imp_same_roots[of p b] assms b q splitted_def + poly_mult_degree_eq[OF carrier_is_subring,of p b] + unfolding univ_poly_carrier sym[OF univ_poly_mult[of R "carrier R"]] + by auto + moreover have "size (roots p) \ degree p" and "size (roots b) \ degree b" + using size_roots_le_degree assms(1) b by auto + ultimately show ?thesis + unfolding splitted_def by linarith +qed + +lemma (in field) splitted_imp_trivial_factors: + assumes "p \ carrier (poly_ring R)" "p \ []" and "splitted p" + shows "\q. \ q \ carrier (poly_ring R); pirreducible (carrier R) q; q pdivides p \ \ degree q = 1" + using pdivides_imp_splitted[OF _ assms] pirreducible_imp_not_splitted + by auto subsection \Link between @{term \(pmod)\} and @{term rupture_surj}\ @@ -970,32 +2020,6 @@ qed qed -(* Move to Ideal.thy ========================================================= *) -lemma (in ring) quotient_eq_iff_same_a_r_cos: - assumes "ideal I R" and "a \ carrier R" and "b \ carrier R" - shows "a \ b \ I \ I +> a = I +> b" -proof - assume "I +> a = I +> b" - then obtain i where "i \ I" and "\ \ a = i \ b" - using additive_subgroup.zero_closed[OF ideal.axioms(1)[OF assms(1)]] assms(2) - unfolding a_r_coset_def' by blast - hence "a \ b = i" - using assms(2-3) by (metis a_minus_def add.inv_solve_right assms(1) ideal.Icarr l_zero) - with \i \ I\ show "a \ b \ I" - by simp -next - assume "a \ b \ I" - then obtain i where "i \ I" and "a = i \ b" - using ideal.Icarr[OF assms(1)] assms(2-3) - by (metis a_minus_def add.inv_solve_right) - hence "I +> a = (I +> i) +> b" - using ideal.Icarr[OF assms(1)] assms(3) - by (simp add: a_coset_add_assoc subsetI) - with \i \ I\ show "I +> a = I +> b" - using a_rcos_zero[OF assms(1)] by simp -qed -(* ========================================================================== *) - lemma (in domain) rupture_surj_inj_on: assumes "subfield K R" and "p \ carrier (K[X])" shows "inj_on (rupture_surj K p) ((\q. q pmod p) ` (carrier (K[X])))" diff -r 58191e01f0b1 -r 8371a25ca177 src/HOL/Algebra/Pred_Zorn.thy --- a/src/HOL/Algebra/Pred_Zorn.thy Mon Apr 29 17:11:26 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -theory Pred_Zorn - imports HOL.Zorn - -begin - -(* ========== *) -lemma partial_order_onE: - assumes "partial_order_on A r" shows "refl_on A r" and "trans r" and "antisym r" - using assms unfolding partial_order_on_def preorder_on_def by auto -(* ========== *) - -abbreviation rel_of :: "('a \ 'a \ bool) \ 'a set \ ('a \ 'a) set" - where "rel_of P A \ { (a, b) \ A \ A. P a b }" - -lemma Field_rel_of: - assumes "refl_on A (rel_of P A)" shows "Field (rel_of P A) = A" - using assms unfolding refl_on_def Field_def by auto - -(* ========== *) -lemma Chains_rel_of: - assumes "C \ Chains (rel_of P A)" shows "C \ A" - using assms unfolding Chains_def by auto -(* ========== *) - -lemma partial_order_on_rel_ofI: - assumes refl: "\a. a \ A \ P a a" - and trans: "\a b c. \ a \ A; b \ A; c \ A \ \ P a b \ P b c \ P a c" - and antisym: "\a b. \ a \ A; b \ A \ \ P a b \ P b a \ a = b" - shows "partial_order_on A (rel_of P A)" -proof - - from refl have "refl_on A (rel_of P A)" - unfolding refl_on_def by auto - moreover have "trans (rel_of P A)" and "antisym (rel_of P A)" - by (auto intro: transI dest: trans, auto intro: antisymI dest: antisym) - ultimately show ?thesis - unfolding partial_order_on_def preorder_on_def by simp -qed - -lemma Partial_order_rel_ofI: - assumes "partial_order_on A (rel_of P A)" shows "Partial_order (rel_of P A)" - using assms unfolding Field_rel_of[OF partial_order_onE(1)[OF assms]] . - -lemma predicate_Zorn: - assumes "partial_order_on A (rel_of P A)" - and "\C \ Chains (rel_of P A). \u \ A. \a \ C. P a u" - shows "\m \ A. \a \ A. P m a \ a = m" -proof - - have "a \ A" if "a \ C" and "C \ Chains (rel_of P A)" for C a - using that Chains_rel_of by auto - moreover have "(a, u) \ rel_of P A" if "a \ A" and "u \ A" and "P a u" for a u - using that by auto - ultimately show ?thesis - using Zorns_po_lemma[OF Partial_order_rel_ofI[OF assms(1)]] assms(2) - unfolding Field_rel_of[OF partial_order_onE(1)[OF assms(1)]] by auto -qed - -end \ No newline at end of file