Theory Closure_Algebraic
section ‹The Algebraic Closure of a Field›
theory Closure_Algebraic
imports Closure_Extension Poly_Typeclass Algebraic_Transitivity Extension_Properties
Finite_Generated_Extension Linear_System
"HOL-Computational_Algebra.Polynomial_Factorial" "HOL-Computational_Algebra.Field_as_Ring"
begin
text ‹
‹Closure_Extension› produces, for any field, an extension inside the indexed
polynomial ring in which every polynomial over the base field splits. That extension is not yet an
algebraic closure: it is far too big, being generated by one indeterminate for every polynomial and
root index, and it is not algebraic over the base. The closure is cut out of it as the set of
elements algebraic over the base.
Rather than redo the theory of algebraicity over a subfield for locale fields, we transport the
extension onto a type. The development's field-extension and Galois theory already works with an
ambient type-class field and subfields as carrier sets, and once the extension is a type all of it
applies --- in particular @{thm [source] subfield_algebraic_elements}, which is the statement that
the algebraic elements form a subfield.
›
subsection ‹An extension of the whole type in which every polynomial splits›
context poly_TC
begin
text ‹A definite choice among the extensions supplied by @{thm [source] exists_extension_with_roots},
so that the type constructed from it below depends on nothing but @{typ 'a}.›
definition wide_extension
where "wide_extension ≡
(SOME M. is_extension M
∧ (∀P ∈ poly_carrier.
Field.splits (ecarrier M) (eadd M) (emult M) ipoly_zero ipoly_one (lift_poly P)))"
lemma wide_extension_spec:
"is_extension wide_extension
∧ (∀P ∈ poly_carrier.
Field.splits (ecarrier wide_extension) (eadd wide_extension) (emult wide_extension)
ipoly_zero ipoly_one (lift_poly P))"
unfolding wide_extension_def
by (rule someI_ex) (metis exists_extension_with_roots)
lemmas is_extension_wide_extension = wide_extension_spec [THEN conjunct1]
lemma wide_extension_splits:
"P ∈ poly_carrier
⟹ Field.splits (ecarrier wide_extension) (eadd wide_extension) (emult wide_extension)
ipoly_zero ipoly_one (lift_poly P)"
using wide_extension_spec by blast
text ‹The field structure of the chosen extension, named once for the transport below.›
lemma field_wide_extension:
"Field (ecarrier wide_extension) (eadd wide_extension) (emult wide_extension)
ipoly_zero ipoly_one"
by (rule is_extension_field [OF is_extension_wide_extension])
lemma wide_extension_nonempty: "ipoly_zero ∈ ecarrier wide_extension"
proof -
interpret W: Field "ecarrier wide_extension" "eadd wide_extension" "emult wide_extension"
ipoly_zero ipoly_one
by (rule field_wide_extension)
show ?thesis by (rule W.additive.unit_closed)
qed
text ‹How the base field sits inside the extension. These are restatements of the extension
conditions at the chosen extension: only facts proved ∗‹in this locale› are available once it is
left, and the type constructed below can only be spoken of outside it.›
lemma wide_const_mem: "ipoly_const a ∈ ecarrier wide_extension"
by (simp add: is_extension_const_mem [OF is_extension_wide_extension])
lemma wide_const_add:
"eadd wide_extension (ipoly_const a) (ipoly_const b) = ipoly_const (a + b)"
by (simp add: is_extension_const_add [OF is_extension_wide_extension])
lemma wide_const_mult:
"emult wide_extension (ipoly_const a) (ipoly_const b) = ipoly_const (a * b)"
by (simp add: is_extension_const_mult [OF is_extension_wide_extension])
lemmas wide_const_inj = ipoly_const_inj_on
lemmas wide_lift_poly_apply = lift_poly_apply
lemmas wide_const_zero = ipoly_const_zero
lemmas wide_const_one = ipoly_const_one
end
subsection ‹The extension as a type›
text ‹The extension is a field, but a locale one, on a carrier set inside the indexed polynomial
ring. Carving that carrier out as a type and transporting the operations onto it makes it a
type-class field, which is what the rest of the development can use.›
typedef (overloaded) 'a :: field wide = "ecarrier (poly_TC.wide_extension :: 'a iext)"
using wide_extension_nonempty by blast
setup_lifting type_definition_wide
text ‹Names for the transported structure. The locale's constants must be spelled out here because
@{locale poly_TC} fixes no parameters, so its abbreviations do not reach outside it; each takes
only the parameters occurring in its definition.›
abbreviation wcarrier :: "'a :: field ipoly set"
where "wcarrier ≡ ecarrier (poly_TC.wide_extension :: 'a iext)"
abbreviation wadd :: "'a :: field ipoly ⇒ 'a ipoly ⇒ 'a ipoly"
where "wadd ≡ eadd (poly_TC.wide_extension :: 'a iext)"
abbreviation wmult :: "'a :: field ipoly ⇒ 'a ipoly ⇒ 'a ipoly"
where "wmult ≡ emult (poly_TC.wide_extension :: 'a iext)"
abbreviation wzero :: "'a :: field ipoly"
where "wzero ≡ Ring.ipoly_zero 0"
abbreviation wone :: "'a :: field ipoly"
where "wone ≡ Ring.ipoly_one 0 1"
abbreviation wneg :: "'a :: field ipoly ⇒ 'a ipoly"
where "wneg ≡ Monoid.inverse wcarrier wadd wzero"
abbreviation winv :: "'a :: field ipoly ⇒ 'a ipoly"
where "winv ≡ Monoid.inverse wcarrier wmult wone"