Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - refactor(linear_algebra/finite_dimensional): generalize finite_dimensional.iff_fg to division rings #7644

Closed
wants to merge 9 commits into from
2 changes: 1 addition & 1 deletion src/analysis/normed_space/inner_product.lean
Expand Up @@ -2817,7 +2817,7 @@ lemma orthonormal_basis_orthonormal [finite_dimensional 𝕜 E] :
(exists_subset_is_orthonormal_basis (orthonormal_empty 𝕜 E)).some_spec.some_spec.some_spec.2

instance [finite_dimensional 𝕜 E] : fintype (orthonormal_basis_index 𝕜 E) :=
finite_dimensional.fintype_basis_index (orthonormal_basis 𝕜 E)
is_noetherian.fintype_basis_index (orthonormal_basis 𝕜 E)

variables {𝕜 E}

Expand Down
4 changes: 2 additions & 2 deletions src/data/complex/is_R_or_C.lean
Expand Up @@ -626,7 +626,7 @@ library_note "is_R_or_C instance"

/-- An `is_R_or_C` field is finite-dimensional over `ℝ`, since it is spanned by `{1, I}`. -/
@[nolint dangerous_instance] instance is_R_or_C_to_real : finite_dimensional ℝ K :=
finite_dimensional.iff_fg.mpr ⟨{1, I},
is_noetherian.iff_fg.mpr ⟨{1, I},
begin
rw eq_top_iff,
intros a _,
Expand All @@ -635,7 +635,7 @@ finite_dimensional.iff_fg.mpr ⟨{1, I},
{ rw submodule.mem_span_singleton,
use im a },
simp [re_add_im a, algebra.smul_def, algebra_map_eq_of_real]
end⟩
end⟩

/-- Over an `is_R_or_C` field, we can register the properness of finite-dimensional normed spaces as
an instance. -/
Expand Down
2 changes: 1 addition & 1 deletion src/field_theory/finite/polynomial.lean
Expand Up @@ -176,7 +176,7 @@ calc module.rank K (R σ K) =
... = fintype.card (σ → K) : cardinal.fintype_card _

instance : finite_dimensional K (R σ K) :=
finite_dimensional.finite_dimensional_iff_dim_lt_omega.mpr
is_noetherian.iff_dim_lt_omega.mpr
(by simpa only [dim_R] using cardinal.nat_lt_omega (fintype.card (σ → K)))

lemma finrank_R : finite_dimensional.finrank K (R σ K) = fintype.card (σ → K) :=
Expand Down
114 changes: 114 additions & 0 deletions src/field_theory/finiteness.lean
@@ -0,0 +1,114 @@
/-
Copyright (c) 2019 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes
-/
import ring_theory.finiteness
import linear_algebra.dimension

/-!
# A module over a division ring is noetherian if and only if it is finite.

-/

universes u v

open_locale classical
open cardinal submodule module function

namespace is_noetherian

variables {K : Type u} {V : Type v} [division_ring K] [add_comm_group V] [module K V]

-- PROJECT: Show all division rings are noetherian.
-- This is currently annoying because we only have ideal of commutative rings.
variables [is_noetherian_ring K]

/--
A module over a division ring is noetherian if and only if
its dimension (as a cardinal) is strictly less than the first infinite cardinal `omega`.
-/
lemma iff_dim_lt_omega : is_noetherian K V ↔ module.rank K V < omega.{v} :=
begin
let b := basis.of_vector_space K V,
have := b.mk_eq_dim,
simp only [lift_id] at this,
rw [← this, lt_omega_iff_fintype, ← @set.set_of_mem_eq _ (basis.of_vector_space_index K V),
← subtype.range_coe_subtype],
split,
{ intro,
resetI,
simpa using finite_of_linear_independent (basis.of_vector_space_index.linear_independent K V) },
{ assume hbfinite,
refine @is_noetherian_of_linear_equiv K (⊤ : submodule K V) V _
_ _ _ _ (linear_equiv.of_top _ rfl) (id _),
refine is_noetherian_of_fg_of_noetherian _ ⟨set.finite.to_finset hbfinite, _⟩,
rw [set.finite.coe_to_finset, ← b.span_eq, basis.coe_of_vector_space] }
end

variables (K V)

/-- The dimension of a noetherian module over a division ring, as a cardinal,
is strictly less than the first infinite cardinal `omega`. -/
lemma dim_lt_omega : ∀ [is_noetherian K V], module.rank K V < omega.{v} :=
is_noetherian.iff_dim_lt_omega.1

variables {K V}

/-- In a noetherian module over a division ring, all bases are indexed by a finite type. -/
noncomputable def fintype_basis_index {ι : Type*} [is_noetherian K V] (b : basis ι K V) :
fintype ι :=
b.fintype_index_of_dim_lt_omega (dim_lt_omega K V)

/-- In a noetherian module over a division ring,
`basis.of_vector_space` is indexed by a finite type. -/
noncomputable instance [is_noetherian K V] : fintype (basis.of_vector_space_index K V) :=
fintype_basis_index (basis.of_vector_space K V)

/-- In a noetherian module over a division ring,
if a basis is indexed by a set, that set is finite. -/
lemma finite_basis_index {ι : Type*} {s : set ι} [is_noetherian K V] (b : basis s K V) :
s.finite :=
b.finite_index_of_dim_lt_omega (dim_lt_omega K V)

variables (K V)

/-- In a noetherian module over a division ring,
there exists a finite basis. This is the indexing `finset`. -/
noncomputable def finset_basis_index [is_noetherian K V] :
finset V :=
(finite_basis_index (basis.of_vector_space K V)).to_finset

@[simp] lemma coe_finset_basis_index [is_noetherian K V] :
(↑(finset_basis_index K V) : set V) = basis.of_vector_space_index K V :=
set.finite.coe_to_finset _

/--
In a noetherian module over a division ring, there exists a finite basis.
This is indexed by the `finset` `finite_dimensional.finset_basis_index`.
This is in contrast to the result `finite_basis_index (basis.of_vector_space K V)`,
which provides a set and a `set.finite`.
-/
noncomputable def finset_basis [is_noetherian K V] :
basis (↑(finset_basis_index K V) : set V) K V :=
(basis.of_vector_space K V).reindex (by simp)

@[simp] lemma range_finset_basis [is_noetherian K V] :
set.range (finset_basis K V) = basis.of_vector_space_index K V :=
by rw [finset_basis, basis.range_reindex, basis.range_of_vector_space]

variables {K V}

/-- A module over a division ring is noetherian if and only if it is finitely generated. -/
lemma iff_fg :
is_noetherian K V ↔ module.finite K V :=
begin
split,
{ introI h,
exact ⟨⟨finset_basis_index K V, by { convert (finset_basis K V).span_eq, simp }⟩⟩ },
{ rintros ⟨s, hs⟩,
rw [is_noetherian.iff_dim_lt_omega, ← dim_top, ← hs],
exact lt_of_le_of_lt (dim_span_le _) (lt_omega_iff_finite.2 (set.finite_mem_finset s)) }
end

end is_noetherian
2 changes: 1 addition & 1 deletion src/field_theory/fixed.lean
Expand Up @@ -204,7 +204,7 @@ begin
end

instance : finite_dimensional (fixed_points G F) F :=
finite_dimensional.finite_dimensional_iff_dim_lt_omega.2 $
is_noetherian.iff_dim_lt_omega.2 $
lt_of_le_of_lt (dim_le_card G F) (cardinal.nat_lt_omega _)

lemma finrank_le_card : finrank (fixed_points G F) F ≤ fintype.card G :=
Expand Down
4 changes: 2 additions & 2 deletions src/field_theory/splitting_field.lean
Expand Up @@ -759,12 +759,12 @@ alg_hom.comp (by { rw ← adjoin_roots L f, exact classical.choice (lift_of_spli
algebra.to_top

theorem finite_dimensional (f : polynomial K) [is_splitting_field K L f] : finite_dimensional K L :=
finite_dimensional.iff_fg.2 $ @algebra.top_to_submodule K L _ _ _ ▸ adjoin_roots L f ▸
is_noetherian.iff_fg.2 @algebra.top_to_submodule K L _ _ _ ▸ adjoin_roots L f ▸
fg_adjoin_of_finite (set.finite_mem_finset _) (λ y hy,
if hf : f = 0
then by { rw [hf, map_zero, roots_zero] at hy, cases hy }
else (is_algebraic_iff_is_integral _).1 ⟨f, hf, (eval₂_eq_eval_map _).trans $
(mem_roots $ by exact map_ne_zero hf).1 (multiset.mem_to_finset.mp hy)⟩)
(mem_roots $ by exact map_ne_zero hf).1 (multiset.mem_to_finset.mp hy)⟩)

instance (f : polynomial K) : _root_.finite_dimensional K f.splitting_field :=
finite_dimensional f.splitting_field f
Expand Down
8 changes: 5 additions & 3 deletions src/field_theory/tower.lean
Expand Up @@ -62,15 +62,17 @@ by convert dim_mul_dim' F K A; rw lift_id

namespace finite_dimensional

open is_noetherian

theorem trans [finite_dimensional F K] [finite_dimensional K A] : finite_dimensional F A :=
let b := basis.of_vector_space F K, c := basis.of_vector_space K A in
of_fintype_basis $ b.smul c

lemma right [hf : finite_dimensional F A] : finite_dimensional K A :=
let ⟨b, hb⟩ := iff_fg.1 hf in
iff_fg.2 ⟨b, submodule.restrict_scalars_injective F _ _ $
let ⟨b, hb⟩ := iff_fg.1 hf in
iff_fg.2 ⟨b, submodule.restrict_scalars_injective F _ _ $
by { rw [submodule.restrict_scalars_top, eq_top_iff, ← hb, submodule.span_le],
exact submodule.subset_span }⟩
exact submodule.subset_span }⟩

/-- Tower law: if `A` is a `K`-algebra and `K` is a field extension of `F` then
`dim_F(A) = dim_F(K) * dim_K(A)`. -/
Expand Down
52 changes: 26 additions & 26 deletions src/linear_algebra/dimension.lean
Expand Up @@ -168,6 +168,32 @@ cardinal.card_le_of (λ s, @finset.card_map _ _ ⟨_, subtype.val_injective⟩ s
H _ (by { refine (of_vector_space_index.linear_independent K V).mono (λ y h, _),
rw [finset.mem_coe, finset.mem_map] at h, rcases h with ⟨x, hx, rfl⟩, exact x.2 }))

/-- If a vector space has a finite dimension, all bases are indexed by a finite type. -/
lemma basis.nonempty_fintype_index_of_dim_lt_omega {ι : Type*}
(b : basis ι K V) (h : module.rank K V < cardinal.omega) :
nonempty (fintype ι) :=
by rwa [← cardinal.lift_lt, ← b.mk_eq_dim,
-- ensure `omega` has the correct universe
cardinal.lift_omega, ← cardinal.lift_omega.{u_1 v},
cardinal.lift_lt, cardinal.lt_omega_iff_fintype] at h

/-- If a vector space has a finite dimension, all bases are indexed by a finite type. -/
noncomputable def basis.fintype_index_of_dim_lt_omega {ι : Type*}
(b : basis ι K V) (h : module.rank K V < cardinal.omega) :
fintype ι :=
classical.choice (b.nonempty_fintype_index_of_dim_lt_omega h)

/-- If a vector space has a finite dimension, all bases are indexed by a finite set. -/
lemma basis.finite_index_of_dim_lt_omega {ι : Type*} {s : set ι}
(b : basis s K V) (h : module.rank K V < cardinal.omega) :
s.finite :=
b.nonempty_fintype_index_of_dim_lt_omega h

/-- If a vector space has a finite dimension, the index set of `basis.of_vector_space` is finite. -/
lemma basis.finite_of_vector_space_index_of_dim_lt_omega (h : module.rank K V < cardinal.omega) :
(basis.of_vector_space_index K V).finite :=
(basis.of_vector_space K V).nonempty_fintype_index_of_dim_lt_omega h

variables [add_comm_group V'] [module K V']

/-- Two linearly equivalent vector spaces have the same dimension, a version with different
Expand Down Expand Up @@ -485,32 +511,6 @@ lemma exists_mem_ne_zero_of_dim_pos {s : submodule K V} (h : 0 < module.rank K s
∃ b : V, b ∈ s ∧ b ≠ 0 :=
exists_mem_ne_zero_of_ne_bot $ assume eq, by rw [eq, dim_bot] at h; exact lt_irrefl _ h

/-- If a vector space has a finite dimension, all bases are indexed by a finite type. -/
lemma basis.nonempty_fintype_index_of_dim_lt_omega {ι : Type*}
(b : basis ι K V) (h : module.rank K V < cardinal.omega) :
nonempty (fintype ι) :=
by rwa [← cardinal.lift_lt, ← b.mk_eq_dim,
-- ensure `omega` has the correct universe
cardinal.lift_omega, ← cardinal.lift_omega.{u_1 v},
cardinal.lift_lt, cardinal.lt_omega_iff_fintype] at h

/-- If a vector space has a finite dimension, all bases are indexed by a finite type. -/
noncomputable def basis.fintype_index_of_dim_lt_omega {ι : Type*}
(b : basis ι K V) (h : module.rank K V < cardinal.omega) :
fintype ι :=
classical.choice (b.nonempty_fintype_index_of_dim_lt_omega h)

/-- If a vector space has a finite dimension, all bases are indexed by a finite set. -/
lemma basis.finite_index_of_dim_lt_omega {ι : Type*} {s : set ι}
(b : basis s K V) (h : module.rank K V < cardinal.omega) :
s.finite :=
b.nonempty_fintype_index_of_dim_lt_omega h

/-- If a vector space has a finite dimension, the index set of `basis.of_vector_space` is finite. -/
lemma basis.finite_of_vector_space_index_of_dim_lt_omega (h : module.rank K V < cardinal.omega) :
(basis.of_vector_space_index K V).finite :=
(basis.of_vector_space K V).nonempty_fintype_index_of_dim_lt_omega h

section rank

/-- `rank f` is the rank of a `linear_map f`, defined as the dimension of `f.range`. -/
Expand Down
4 changes: 2 additions & 2 deletions src/linear_algebra/dual.lean
Expand Up @@ -198,8 +198,8 @@ lemma total_dual_basis [fintype ι] (f : ι →₀ R) (i : ι) :
finsupp.total ι (dual R M) R b.dual_basis f (b i) = f i :=
begin
rw [finsupp.total_apply, finsupp.sum_fintype, linear_map.sum_apply],
{ simp_rw [smul_apply, smul_eq_mul, dual_basis_apply_self, mul_boole,
finset.sum_ite_eq, if_pos (finset.mem_univ i)] },
{ simp_rw [linear_map.smul_apply, smul_eq_mul, dual_basis_apply_self, mul_boole,
finset.sum_ite_eq, if_pos (finset.mem_univ i)] },
{ intro, rw zero_smul },
end

Expand Down