From ef997baa41b5c428be3fb50089a7139bf4ee886b Mon Sep 17 00:00:00 2001 From: Amelia Livingston <101damnations@github.com> Date: Wed, 3 May 2023 13:04:49 +0000 Subject: [PATCH 01/17] feat(representation_theory/group_cohomology/basic): add standard definition of group cohomology (#18341) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We define the complex of inhomogeneous cochains, define group cohomology to be its cohomology, and prove this is isomorphic to the appropriate Ext groups. Co-authored-by: Joël Riou Co-authored-by: Amelia Livingston --- src/algebra/big_operators/fin.lean | 34 ++++ src/data/fin/tuple/basic.lean | 40 ++++ .../group_cohomology/basic.lean | 184 ++++++++++++++++++ .../resolution.lean} | 26 ++- 4 files changed, 279 insertions(+), 5 deletions(-) create mode 100644 src/representation_theory/group_cohomology/basic.lean rename src/representation_theory/{group_cohomology_resolution.lean => group_cohomology/resolution.lean} (96%) diff --git a/src/algebra/big_operators/fin.lean b/src/algebra/big_operators/fin.lean index d0182e6396d4e..9b07547122eb8 100644 --- a/src/algebra/big_operators/fin.lean +++ b/src/algebra/big_operators/fin.lean @@ -208,6 +208,40 @@ begin assoc_rw [hi, inv_mul_cancel_left] } end +/-- Let `(g₀, g₁, ..., gₙ)` be a tuple of elements in `Gⁿ⁺¹`. +Then if `k < j`, this says `(g₀g₁...gₖ₋₁)⁻¹ * g₀g₁...gₖ = gₖ`. +If `k = j`, it says `(g₀g₁...gₖ₋₁)⁻¹ * g₀g₁...gₖ₊₁ = gₖgₖ₊₁`. +If `k > j`, it says `(g₀g₁...gₖ)⁻¹ * g₀g₁...gₖ₊₁ = gₖ₊₁.` +Useful for defining group cohomology. -/ +@[to_additive "Let `(g₀, g₁, ..., gₙ)` be a tuple of elements in `Gⁿ⁺¹`. +Then if `k < j`, this says `-(g₀ + g₁ + ... + gₖ₋₁) + (g₀ + g₁ + ... + gₖ) = gₖ`. +If `k = j`, it says `-(g₀ + g₁ + ... + gₖ₋₁) + (g₀ + g₁ + ... + gₖ₊₁) = gₖ + gₖ₊₁`. +If `k > j`, it says `-(g₀ + g₁ + ... + gₖ) + (g₀ + g₁ + ... + gₖ₊₁) = gₖ₊₁.` +Useful for defining group cohomology."] +lemma inv_partial_prod_mul_eq_contract_nth {G : Type*} [group G] + (g : fin (n + 1) → G) (j : fin (n + 1)) (k : fin n) : + (partial_prod g (j.succ.succ_above k.cast_succ))⁻¹ * partial_prod g (j.succ_above k).succ + = j.contract_nth has_mul.mul g k := +begin + have := partial_prod_right_inv (1 : G) g, + simp only [one_smul, coe_eq_cast_succ] at this, + rcases lt_trichotomy (k : ℕ) j with (h|h|h), + { rwa [succ_above_below, succ_above_below, this, contract_nth_apply_of_lt], + { assumption }, + { rw [cast_succ_lt_iff_succ_le, succ_le_succ_iff, le_iff_coe_le_coe], + exact le_of_lt h }}, + { rwa [succ_above_below, succ_above_above, partial_prod_succ, cast_succ_fin_succ, ←mul_assoc, + this, contract_nth_apply_of_eq], + { simpa only [le_iff_coe_le_coe, ←h] }, + { rw [cast_succ_lt_iff_succ_le, succ_le_succ_iff, le_iff_coe_le_coe], + exact le_of_eq h }}, + { rwa [succ_above_above, succ_above_above, partial_prod_succ, partial_prod_succ, + cast_succ_fin_succ, partial_prod_succ, inv_mul_cancel_left, contract_nth_apply_of_gt], + { exact le_iff_coe_le_coe.2 (le_of_lt h) }, + { rw [le_iff_coe_le_coe, coe_succ], + exact nat.succ_le_of_lt h }}, +end + end partial_prod end fin diff --git a/src/data/fin/tuple/basic.lean b/src/data/fin/tuple/basic.lean index eddc29b8946b3..e9509b715fdca 100644 --- a/src/data/fin/tuple/basic.lean +++ b/src/data/fin/tuple/basic.lean @@ -847,6 +847,46 @@ lemma mem_find_of_unique {p : fin n → Prop} [decidable_pred p] mem_find_iff.2 ⟨hi, λ j hj, le_of_eq $ h i j hi hj⟩ end find +section contract_nth + +variables {α : Type*} + +/-- Sends `(g₀, ..., gₙ)` to `(g₀, ..., op gⱼ gⱼ₊₁, ..., gₙ)`. -/ +def contract_nth (j : fin (n + 1)) (op : α → α → α) (g : fin (n + 1) → α) (k : fin n) : α := +if (k : ℕ) < j then g k.cast_succ else +if (k : ℕ) = j then op (g k.cast_succ) (g k.succ) +else g k.succ + +lemma contract_nth_apply_of_lt (j : fin (n + 1)) (op : α → α → α) (g : fin (n + 1) → α) + (k : fin n) (h : (k : ℕ) < j) : + contract_nth j op g k = g k.cast_succ := if_pos h + +lemma contract_nth_apply_of_eq (j : fin (n + 1)) (op : α → α → α) (g : fin (n + 1) → α) + (k : fin n) (h : (k : ℕ) = j) : + contract_nth j op g k = op (g k.cast_succ) (g k.succ) := +begin + have : ¬(k : ℕ) < j, from not_lt.2 (le_of_eq h.symm), + rw [contract_nth, if_neg this, if_pos h], +end + +lemma contract_nth_apply_of_gt (j : fin (n + 1)) (op : α → α → α) (g : fin (n + 1) → α) + (k : fin n) (h : (j : ℕ) < k) : + contract_nth j op g k = g k.succ := +by rw [contract_nth, if_neg (not_lt_of_gt h), if_neg (ne.symm $ ne_of_lt h)] + +lemma contract_nth_apply_of_ne (j : fin (n + 1)) (op : α → α → α) (g : fin (n + 1) → α) + (k : fin n) (hjk : (j : ℕ) ≠ k) : + contract_nth j op g k = g (j.succ_above k) := +begin + rcases lt_trichotomy (k : ℕ) j with (h|h|h), + { rwa [j.succ_above_below, contract_nth_apply_of_lt], + { rwa [ fin.lt_iff_coe_lt_coe] }}, + { exact false.elim (hjk h.symm) }, + { rwa [j.succ_above_above, contract_nth_apply_of_gt], + { exact fin.le_iff_coe_le_coe.2 (le_of_lt h) }} +end + +end contract_nth /-- To show two sigma pairs of tuples agree, it to show the second elements are related via `fin.cast`. -/ diff --git a/src/representation_theory/group_cohomology/basic.lean b/src/representation_theory/group_cohomology/basic.lean new file mode 100644 index 0000000000000..e63ce48b3af5c --- /dev/null +++ b/src/representation_theory/group_cohomology/basic.lean @@ -0,0 +1,184 @@ +/- +Copyright (c) 2023 Amelia Livingston. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Amelia Livingston +-/ + +import algebra.homology.opposite +import representation_theory.group_cohomology.resolution + +/-! +# The group cohomology of a `k`-linear `G`-representation + +Let `k` be a commutative ring and `G` a group. This file defines the group cohomology of +`A : Rep k G` to be the cohomology of the complex +$$0 \to \mathrm{Fun}(G^0, A) \to \mathrm{Fun}(G^1, A) \to \mathrm{Fun}(G^2, A) \to \dots$$ +with differential $d^n$ sending $f: G^n \to A$ to the function mapping $(g_0, \dots, g_n)$ to +$$\rho(g_0)(f(g_1, \dots, g_n)) ++ \sum_{i = 0}^{n - 1} (-1)^{i + 1}\cdot f(g_0, \dots, g_ig_{i + 1}, \dots, g_n)$$ +$$+ (-1)^{n + 1}\cdot f(g_0, \dots, g_{n - 1})$$ (where `ρ` is the representation attached to `A`). + +We have a `k`-linear isomorphism $\mathrm{Fun}(G^n, A) \cong \mathrm{Hom}(k[G^{n + 1}], A)$, where +the righthand side is morphisms in `Rep k G`, and the representation on $k[G^{n + 1}]$ +is induced by the diagonal action of `G`. If we conjugate the $n$th differential in +$\mathrm{Hom}(P, A)$ by this isomorphism, where `P` is the standard resolution of `k` as a trivial +`k`-linear `G`-representation, then the resulting map agrees with the differential $d^n$ defined +above, a fact we prove. + +This gives us for free a proof that our $d^n$ squares to zero. It also gives us an isomorphism +$\mathrm{H}^n(G, A) \cong \mathrm{Ext}^n(k, A),$ where $\mathrm{Ext}$ is taken in the category +`Rep k G`. + +## Main definitions + +* `group_cohomology.linear_yoneda_obj_resolution A`: a complex whose objects are the representation +morphisms $\mathrm{Hom}(k[G^{n + 1}], A)$ and whose cohomology is the group cohomology +$\mathrm{H}^n(G, A)$. +* `group_cohomology.inhomogeneous_cochains A`: a complex whose objects are +$\mathrm{Fun}(G^n, A)$ and whose cohomology is the group cohomology $\mathrm{H}^n(G, A).$ +* `group_cohomology.inhomogeneous_cochains_iso A`: an isomorphism between the above two complexes. +* `group_cohomology A n`: this is $\mathrm{H}^n(G, A),$ defined as the $n$th cohomology of the +second complex, `inhomogeneous_cochains A`. +* `group_cohomology_iso_Ext A n`: an isomorphism $\mathrm{H}^n(G, A) \cong \mathrm{Ext}^n(k, A)$ +(where $\mathrm{Ext}$ is taken in the category `Rep k G`) induced by `inhomogeneous_cochains_iso A`. + +## Implementation notes + +Group cohomology is typically stated for `G`-modules, or equivalently modules over the group ring +`ℤ[G].` However, `ℤ` can be generalized to any commutative ring `k`, which is what we use. +Moreover, we express `k[G]`-module structures on a module `k`-module `A` using the `Rep` +definition. We avoid using instances `module (monoid_algebra k G) A` so that we do not run into +possible scalar action diamonds. + +## TODO + +* API for cohomology in low degree: $\mathrm{H}^0, \mathrm{H}^1$ and $\mathrm{H}^2.$ For example, +the inflation-restriction exact sequence. +* The long exact sequence in cohomology attached to a short exact sequence of representations. +* Upgrading `group_cohomology_iso_Ext` to an isomorphism of derived functors. +* Profinite cohomology. + +Longer term: +* The Hochschild-Serre spectral sequence (this is perhaps a good toy example for the theory of +spectral sequences in general). +-/ + +noncomputable theory +universes u + +variables {k G : Type u} [comm_ring k] {n : ℕ} + +open category_theory +namespace group_cohomology +variables [monoid G] + +/-- The complex `Hom(P, A)`, where `P` is the standard resolution of `k` as a trivial `k`-linear +`G`-representation. -/ +abbreviation linear_yoneda_obj_resolution (A : Rep k G) : cochain_complex (Module.{u} k) ℕ := +homological_complex.unop + ((((linear_yoneda k (Rep k G)).obj A).right_op.map_homological_complex _).obj (resolution k G)) + +lemma linear_yoneda_obj_resolution_d_apply {A : Rep k G} (i j : ℕ) (x : (resolution k G).X i ⟶ A) : + (linear_yoneda_obj_resolution A).d i j x = (resolution k G).d j i ≫ x := +rfl + +end group_cohomology +namespace inhomogeneous_cochains +open Rep group_cohomology + +/-- The differential in the complex of inhomogeneous cochains used to +calculate group cohomology. -/ +@[simps] def d [monoid G] (n : ℕ) (A : Rep k G) : + ((fin n → G) → A) →ₗ[k] (fin (n + 1) → G) → A := +{ to_fun := λ f g, A.ρ (g 0) (f (λ i, g i.succ)) + + finset.univ.sum (λ j : fin (n + 1), (-1 : k) ^ ((j : ℕ) + 1) • f (fin.contract_nth j (*) g)), + map_add' := λ f g, + begin + ext x, + simp only [pi.add_apply, map_add, smul_add, finset.sum_add_distrib, add_add_add_comm], + end, + map_smul' := λ r f, + begin + ext x, + simp only [pi.smul_apply, ring_hom.id_apply, map_smul, smul_add, finset.smul_sum, + ←smul_assoc, smul_eq_mul, mul_comm r], + end } + +variables [group G] (n) (A : Rep k G) + +/-- The theorem that our isomorphism `Fun(Gⁿ, A) ≅ Hom(k[Gⁿ⁺¹], A)` (where the righthand side is +morphisms in `Rep k G`) commutes with the differentials in the complex of inhomogeneous cochains +and the homogeneous `linear_yoneda_obj_resolution`. -/ +lemma d_eq : + d n A = ((diagonal_hom_equiv n A).to_Module_iso.inv + ≫ (linear_yoneda_obj_resolution A).d n (n + 1) + ≫ (diagonal_hom_equiv (n + 1) A).to_Module_iso.hom) := +begin + ext f g, + simp only [Module.coe_comp, linear_equiv.coe_coe, function.comp_app, + linear_equiv.to_Module_iso_inv, linear_yoneda_obj_resolution_d_apply, + linear_equiv.to_Module_iso_hom, diagonal_hom_equiv_apply, Action.comp_hom, + resolution.d_eq k G n, resolution.d_of (fin.partial_prod g), linear_map.map_sum, + ←finsupp.smul_single_one _ ((-1 : k) ^ _), map_smul, d_apply], + simp only [@fin.sum_univ_succ _ _ (n + 1), fin.coe_zero, pow_zero, one_smul, fin.succ_above_zero, + diagonal_hom_equiv_symm_apply f (fin.partial_prod g ∘ @fin.succ (n + 1)), function.comp_app, + fin.partial_prod_succ, fin.cast_succ_zero, fin.partial_prod_zero, one_mul], + congr' 1, + { congr, + ext, + have := fin.partial_prod_right_inv (1 : G) g (fin.cast_succ x), + simp only [mul_inv_rev, fin.coe_eq_cast_succ, one_smul, fin.cast_succ_fin_succ] at *, + rw [mul_assoc, ←mul_assoc _ _ (g x.succ), this, inv_mul_cancel_left] }, + { exact finset.sum_congr rfl (λ j hj, + by rw [diagonal_hom_equiv_symm_partial_prod_succ, fin.coe_succ]) } +end + +end inhomogeneous_cochains +namespace group_cohomology +variables [group G] (n) (A : Rep k G) + +open inhomogeneous_cochains + +/-- Given a `k`-linear `G`-representation `A`, this is the complex of inhomogeneous cochains +$$0 \to \mathrm{Fun}(G^0, A) \to \mathrm{Fun}(G^1, A) \to \mathrm{Fun}(G^2, A) \to \dots$$ +which calculates the group cohomology of `A`. -/ +noncomputable abbreviation inhomogeneous_cochains : cochain_complex (Module k) ℕ := +cochain_complex.of (λ n, Module.of k ((fin n → G) → A)) +(λ n, inhomogeneous_cochains.d n A) (λ n, +begin + ext x y, + have := linear_map.ext_iff.1 ((linear_yoneda_obj_resolution A).d_comp_d n (n + 1) (n + 2)), + simp only [Module.coe_comp, function.comp_app] at this, + simp only [Module.coe_comp, function.comp_app, d_eq, linear_equiv.to_Module_iso_hom, + linear_equiv.to_Module_iso_inv, linear_equiv.coe_coe, linear_equiv.symm_apply_apply, + this, linear_map.zero_apply, map_zero, pi.zero_apply], +end) + +/-- Given a `k`-linear `G`-representation `A`, the complex of inhomogeneous cochains is isomorphic +to `Hom(P, A)`, where `P` is the standard resolution of `k` as a trivial `G`-representation. -/ +def inhomogeneous_cochains_iso : + inhomogeneous_cochains A ≅ linear_yoneda_obj_resolution A := +homological_complex.hom.iso_of_components + (λ i, (Rep.diagonal_hom_equiv i A).to_Module_iso.symm) $ +begin + rintros i j (h : i + 1 = j), + subst h, + simp only [cochain_complex.of_d, d_eq, category.assoc, iso.symm_hom, + iso.hom_inv_id, category.comp_id], +end + +end group_cohomology +open group_cohomology + +/-- The group cohomology of a `k`-linear `G`-representation `A`, as the cohomology of its complex +of inhomogeneous cochains. -/ +def group_cohomology [group G] (A : Rep k G) (n : ℕ) : Module k := +(inhomogeneous_cochains A).homology n + +/-- The `n`th group cohomology of a `k`-linear `G`-representation `A` is isomorphic to +`Extⁿ(k, A)` (taken in `Rep k G`), where `k` is a trivial `k`-linear `G`-representation. -/ +def group_cohomology_iso_Ext [group G] (A : Rep k G) (n : ℕ) : + group_cohomology A n ≅ ((Ext k (Rep k G) n).obj + (opposite.op $ Rep.trivial k G k)).obj A := +(homology_obj_iso_of_homotopy_equiv (homotopy_equiv.of_iso (inhomogeneous_cochains_iso _)) _) + ≪≫ (homological_complex.homology_unop _ _) ≪≫ (Ext_iso k G A n).symm diff --git a/src/representation_theory/group_cohomology_resolution.lean b/src/representation_theory/group_cohomology/resolution.lean similarity index 96% rename from src/representation_theory/group_cohomology_resolution.lean rename to src/representation_theory/group_cohomology/resolution.lean index aae7db290557f..d6049837d2f81 100644 --- a/src/representation_theory/group_cohomology_resolution.lean +++ b/src/representation_theory/group_cohomology/resolution.lean @@ -232,25 +232,25 @@ module.free.of_basis (of_mul_action_basis k G n) end basis end group_cohomology.resolution namespace Rep -variables (n) [group G] +variables (n) [group G] (A : Rep k G) open group_cohomology.resolution /-- Given a `k`-linear `G`-representation `A`, the set of representation morphisms `Hom(k[Gⁿ⁺¹], A)` is `k`-linearly isomorphic to the set of functions `Gⁿ → A`. -/ -noncomputable def diagonal_hom_equiv (A : Rep k G) : +noncomputable def diagonal_hom_equiv : (Rep.of_mul_action k G (fin (n + 1) → G) ⟶ A) ≃ₗ[k] ((fin n → G) → A) := linear.hom_congr k ((diagonal_succ k G n).trans ((representation.of_mul_action k G G).Rep_of_tprod_iso 1)) (iso.refl _) ≪≫ₗ ((Rep.monoidal_closed.linear_hom_equiv_comm _ _ _) ≪≫ₗ (Rep.left_regular_hom_equiv _)) ≪≫ₗ (finsupp.llift A k k (fin n → G)).symm -variables {n} +variables {n A} /-- Given a `k`-linear `G`-representation `A`, `diagonal_hom_equiv` is a `k`-linear isomorphism of the set of representation morphisms `Hom(k[Gⁿ⁺¹], A)` with `Fun(Gⁿ, A)`. This lemma says that this sends a morphism of representations `f : k[Gⁿ⁺¹] ⟶ A` to the function `(g₁, ..., gₙ) ↦ f(1, g₁, g₁g₂, ..., g₁g₂...gₙ).` -/ -lemma diagonal_hom_equiv_apply {A : Rep k G} (f : Rep.of_mul_action k G (fin (n + 1) → G) ⟶ A) +lemma diagonal_hom_equiv_apply (f : Rep.of_mul_action k G (fin (n + 1) → G) ⟶ A) (x : fin n → G) : diagonal_hom_equiv n A f x = f.hom (finsupp.single (fin.partial_prod x) 1) := begin unfold diagonal_hom_equiv, @@ -266,7 +266,7 @@ the set of representation morphisms `Hom(k[Gⁿ⁺¹], A)` with `Fun(Gⁿ, A)`. inverse map sends a function `f : Gⁿ → A` to the representation morphism sending `(g₀, ... gₙ) ↦ ρ(g₀)(f(g₀⁻¹g₁, g₁⁻¹g₂, ..., gₙ₋₁⁻¹gₙ))`, where `ρ` is the representation attached to `A`. -/ -lemma diagonal_hom_equiv_symm_apply {A : Rep k G} (f : (fin n → G) → A) (x : fin (n + 1) → G) : +lemma diagonal_hom_equiv_symm_apply (f : (fin n → G) → A) (x : fin (n + 1) → G) : ((diagonal_hom_equiv n A).symm f).hom (finsupp.single x 1) = A.ρ (x 0) (f (λ (i : fin n), (x ↑i)⁻¹ * x i.succ)) := begin @@ -281,6 +281,22 @@ begin finsupp.llift_apply A k k], end +/-- Auxiliary lemma for defining group cohomology, used to show that the isomorphism +`diagonal_hom_equiv` commutes with the differentials in two complexes which compute +group cohomology. -/ +lemma diagonal_hom_equiv_symm_partial_prod_succ + (f : (fin n → G) → A) (g : fin (n + 1) → G) (a : fin (n + 1)) : + ((diagonal_hom_equiv n A).symm f).hom (finsupp.single (fin.partial_prod g ∘ a.succ.succ_above) 1) + = f (fin.contract_nth a (*) g) := +begin + simp only [diagonal_hom_equiv_symm_apply, function.comp_app, fin.succ_succ_above_zero, + fin.partial_prod_zero, map_one, fin.coe_eq_cast_succ, fin.succ_succ_above_succ, + linear_map.one_apply, fin.partial_prod_succ], + congr, + ext, + rw [←fin.partial_prod_succ, fin.inv_partial_prod_mul_eq_contract_nth], +end + end Rep variables (G) From c163ec99dfc664628ca15d215fce0a5b9c265b68 Mon Sep 17 00:00:00 2001 From: "Filippo A. E. Nuccio" Date: Wed, 3 May 2023 16:34:41 +0000 Subject: [PATCH 02/17] chore(ring_theory/discrete_valuation_ring): create folder ring_theory/discrete_valuation_ring (#18867) Moved the file `ring_theory/discrete_valuation_ring.lean` inside the folder and renamed it as `basic.lean`; also, added the file `valuation.tfae` giving equivalent conditions for being a dvr to the folder. --- src/number_theory/padics/padic_integers.lean | 2 +- src/ring_theory/dedekind_domain/dvr.lean | 4 ++-- .../basic.lean} | 0 .../{valuation => discrete_valuation_ring}/tfae.lean | 0 src/ring_theory/valuation/valuation_ring.lean | 2 +- src/ring_theory/witt_vector/discrete_valuation_ring.lean | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) rename src/ring_theory/{discrete_valuation_ring.lean => discrete_valuation_ring/basic.lean} (100%) rename src/ring_theory/{valuation => discrete_valuation_ring}/tfae.lean (100%) diff --git a/src/number_theory/padics/padic_integers.lean b/src/number_theory/padics/padic_integers.lean index 89711aa75ff29..83af846ac091a 100644 --- a/src/number_theory/padics/padic_integers.lean +++ b/src/number_theory/padics/padic_integers.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Robert Y. Lewis, Mario Carneiro, Johan Commelin -/ import number_theory.padics.padic_numbers -import ring_theory.discrete_valuation_ring +import ring_theory.discrete_valuation_ring.basic import topology.metric_space.cau_seq_filter /-! diff --git a/src/ring_theory/dedekind_domain/dvr.lean b/src/ring_theory/dedekind_domain/dvr.lean index 4d4397ea2e091..64659de77d46e 100644 --- a/src/ring_theory/dedekind_domain/dvr.lean +++ b/src/ring_theory/dedekind_domain/dvr.lean @@ -4,10 +4,10 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Kenji Nakagawa, Anne Baanen, Filippo A. E. Nuccio -/ import ring_theory.dedekind_domain.ideal -import ring_theory.discrete_valuation_ring +import ring_theory.discrete_valuation_ring.tfae import ring_theory.localization.at_prime import ring_theory.localization.submodule -import ring_theory.valuation.tfae + /-! # Dedekind domains diff --git a/src/ring_theory/discrete_valuation_ring.lean b/src/ring_theory/discrete_valuation_ring/basic.lean similarity index 100% rename from src/ring_theory/discrete_valuation_ring.lean rename to src/ring_theory/discrete_valuation_ring/basic.lean diff --git a/src/ring_theory/valuation/tfae.lean b/src/ring_theory/discrete_valuation_ring/tfae.lean similarity index 100% rename from src/ring_theory/valuation/tfae.lean rename to src/ring_theory/discrete_valuation_ring/tfae.lean diff --git a/src/ring_theory/valuation/valuation_ring.lean b/src/ring_theory/valuation/valuation_ring.lean index 979cc5c29a425..e52900b6e6bfa 100644 --- a/src/ring_theory/valuation/valuation_ring.lean +++ b/src/ring_theory/valuation/valuation_ring.lean @@ -7,7 +7,7 @@ import ring_theory.valuation.integers import ring_theory.ideal.local_ring import ring_theory.localization.fraction_ring import ring_theory.localization.integer -import ring_theory.discrete_valuation_ring +import ring_theory.discrete_valuation_ring.basic import ring_theory.bezout import tactic.field_simp diff --git a/src/ring_theory/witt_vector/discrete_valuation_ring.lean b/src/ring_theory/witt_vector/discrete_valuation_ring.lean index b21fa0fa572e6..abe97d3cecbc2 100644 --- a/src/ring_theory/witt_vector/discrete_valuation_ring.lean +++ b/src/ring_theory/witt_vector/discrete_valuation_ring.lean @@ -6,7 +6,7 @@ Authors: Robert Y. Lewis, Heather Macbeth, Johan Commelin import ring_theory.witt_vector.domain import ring_theory.witt_vector.mul_coeff -import ring_theory.discrete_valuation_ring +import ring_theory.discrete_valuation_ring.basic import tactic.linear_combination /-! From 726d2fe4fd196a6e796d3bc827d025abd32673ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= Date: Wed, 3 May 2023 18:24:34 +0000 Subject: [PATCH 03/17] feat(measure_theory/constructions/prod): marginal measures (#18915) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For `ρ : measure (α × β)`, define `ρ.fst : measure α := ρ.map prod.fst`, and define `ρ.snd` similarly. --- src/measure_theory/constructions/prod.lean | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/measure_theory/constructions/prod.lean b/src/measure_theory/constructions/prod.lean index 43b1c74bd77e6..642c354a80fb6 100644 --- a/src/measure_theory/constructions/prod.lean +++ b/src/measure_theory/constructions/prod.lean @@ -1102,4 +1102,43 @@ lemma set_integral_prod_mul {L : Type*} [is_R_or_C L] ∫ z in s ×ˢ t, f z.1 * g z.2 ∂(μ.prod ν) = (∫ x in s, f x ∂μ) * (∫ y in t, g y ∂ν) := by simp only [← measure.prod_restrict s t, integrable_on, integral_prod_mul] +/-! ### Marginals of a measure defined on a product -/ + +namespace measure + +variables {ρ : measure (α × β)} + +/-- Marginal measure on `α` obtained from a measure `ρ` on `α × β`, defined by `ρ.map prod.fst`. -/ +noncomputable +def fst (ρ : measure (α × β)) : measure α := ρ.map prod.fst + +lemma fst_apply {s : set α} (hs : measurable_set s) : ρ.fst s = ρ (prod.fst ⁻¹' s) := +by rw [fst, measure.map_apply measurable_fst hs] + +lemma fst_univ : ρ.fst univ = ρ univ := +by rw [fst_apply measurable_set.univ, preimage_univ] + +instance [is_finite_measure ρ] : is_finite_measure ρ.fst := by { rw fst, apply_instance, } + +instance [is_probability_measure ρ] : is_probability_measure ρ.fst := +{ measure_univ := by { rw fst_univ, exact measure_univ, } } + +/-- Marginal measure on `β` obtained from a measure on `ρ` `α × β`, defined by `ρ.map prod.snd`. -/ +noncomputable +def snd (ρ : measure (α × β)) : measure β := ρ.map prod.snd + +lemma snd_apply {s : set β} (hs : measurable_set s) : ρ.snd s = ρ (prod.snd ⁻¹' s) := +by rw [snd, measure.map_apply measurable_snd hs] + +lemma snd_univ : ρ.snd univ = ρ univ := +by rw [snd_apply measurable_set.univ, preimage_univ] + +instance [is_finite_measure ρ] : is_finite_measure ρ.snd := by { rw snd, apply_instance, } + +instance [is_probability_measure ρ] : is_probability_measure ρ.snd := +{ measure_univ := by { rw snd_univ, exact measure_univ, } } + +end measure + + end measure_theory From 92c69b77c5a7dc0f7eeddb552508633305157caa Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Wed, 3 May 2023 18:24:36 +0000 Subject: [PATCH 04/17] chore(analysis/inner_product_space/basic): golf, add/merge lemmas (#18928) - Merge `inner_product_space.of_core.inner_self_nonneg_im` and `inner_product_space.of_core.inner_self_im_zero` into `inner_product_space.of_core.inner_self_im`. - Rename `inner_product_space.of_core.inner_abs_conj_symm` to `inner_product_space.of_core.abs_inner_symm`. - Rename `inner_abs_conj_symm` to `abs_inner_symm`. - Add `inner_product_space.of_core.norm_sq_eq_zero`. - Merge `inner_self_nonneg_im` and `inner_self_im_zero` into `inner_self_im`. - Reorder, golf. --- src/analysis/inner_product_space/basic.lean | 160 ++++++-------------- 1 file changed, 47 insertions(+), 113 deletions(-) diff --git a/src/analysis/inner_product_space/basic.lean b/src/analysis/inner_product_space/basic.lean index 0d1f1aba17dd4..0c771833488a5 100644 --- a/src/analysis/inner_product_space/basic.lean +++ b/src/analysis/inner_product_space/basic.lean @@ -162,12 +162,9 @@ lemma inner_conj_symm (x y : F) : ⟪y, x⟫† = ⟪x, y⟫ := c.conj_symm x y lemma inner_self_nonneg {x : F} : 0 ≤ re ⟪x, x⟫ := c.nonneg_re _ -lemma inner_self_nonneg_im (x : F) : im ⟪x, x⟫ = 0 := +lemma inner_self_im (x : F) : im ⟪x, x⟫ = 0 := by rw [← @of_real_inj 𝕜, im_eq_conj_sub]; simp [inner_conj_symm] -lemma inner_self_im_zero (x : F) : im ⟪x, x⟫ = 0 := -inner_self_nonneg_im _ - lemma inner_add_left (x y z : F) : ⟪x + y, z⟫ = ⟪x, z⟫ + ⟪y, z⟫ := c.add_left _ _ _ @@ -177,7 +174,7 @@ by rw [←inner_conj_symm, inner_add_left, ring_hom.map_add]; simp only [inner_c lemma inner_norm_sq_eq_inner_self (x : F) : (norm_sqF x : 𝕜) = ⟪x, x⟫ := begin rw ext_iff, - exact ⟨by simp only [of_real_re]; refl, by simp only [inner_self_nonneg_im, of_real_im]⟩ + exact ⟨by simp only [of_real_re]; refl, by simp only [inner_self_im, of_real_im]⟩ end lemma inner_re_symm (x y : F) : re ⟪x, y⟫ = re ⟪y, x⟫ := @@ -199,15 +196,19 @@ lemma inner_zero_right (x : F) : ⟪x, 0⟫ = 0 := by rw [←inner_conj_symm, inner_zero_left]; simp only [ring_hom.map_zero] lemma inner_self_eq_zero {x : F} : ⟪x, x⟫ = 0 ↔ x = 0 := -iff.intro (c.definite _) (by { rintro rfl, exact inner_zero_left _ }) +⟨c.definite _, by { rintro rfl, exact inner_zero_left _ }⟩ + +lemma norm_sq_eq_zero {x : F} : norm_sqF x = 0 ↔ x = 0 := +iff.trans (by simp only [norm_sq, ext_iff, map_zero, inner_self_im, eq_self_iff_true, and_true]) + (@inner_self_eq_zero 𝕜 _ _ _ _ _ x) lemma inner_self_ne_zero {x : F} : ⟪x, x⟫ ≠ 0 ↔ x ≠ 0 := inner_self_eq_zero.not lemma inner_self_re_to_K (x : F) : (re ⟪x, x⟫ : 𝕜) = ⟪x, x⟫ := -by norm_num [ext_iff, inner_self_nonneg_im] +by norm_num [ext_iff, inner_self_im] -lemma inner_abs_conj_symm (x y : F) : abs ⟪x, y⟫ = abs ⟪y, x⟫ := +lemma abs_inner_symm (x y : F) : abs ⟪x, y⟫ = abs ⟪y, x⟫ := by rw [←inner_conj_symm, abs_conj] lemma inner_neg_left (x y : F) : ⟪-x, y⟫ = -⟪x, y⟫ := @@ -259,7 +260,7 @@ begin apply hy', rw ext_iff, exact ⟨by simp only [H, zero_re'], - by simp only [inner_self_nonneg_im, add_monoid_hom.map_zero]⟩ }, + by simp only [inner_self_im, add_monoid_hom.map_zero]⟩ }, have h₆ : re ⟪y, y⟫ ≠ 0 := ne_of_gt h₅, have hmain := calc 0 ≤ re ⟪x - T • y, x - T • y⟫ @@ -311,7 +312,7 @@ begin rw H, conv begin - to_lhs, congr, rw [inner_abs_conj_symm], + to_lhs, congr, rw [abs_inner_symm], end, exact inner_mul_inner_self_le y x, end @@ -332,11 +333,7 @@ add_group_norm.to_normed_add_comm_group linarith }, exact nonneg_le_nonneg_of_sq_le_sq (add_nonneg (sqrt_nonneg _) (sqrt_nonneg _)) this, end, - eq_zero_of_map_eq_zero' := λ x hx, (inner_self_eq_zero : ⟪x, x⟫ = 0 ↔ x = 0).1 $ begin - change sqrt (re ⟪x, x⟫) = 0 at hx, - rw [sqrt_eq_zero inner_self_nonneg] at hx, - exact ext (by simp [hx]) (by simp [inner_self_im_zero]), - end } + eq_zero_of_map_eq_zero' := λ x hx, norm_sq_eq_zero.1 $ (sqrt_eq_zero inner_self_nonneg).1 hx } local attribute [instance] to_normed_add_comm_group @@ -395,11 +392,9 @@ lemma real_inner_comm (x y : F) : ⟪y, x⟫_ℝ = ⟪x, y⟫_ℝ := @inner_conj lemma inner_eq_zero_symm {x y : E} : ⟪x, y⟫ = 0 ↔ ⟪y, x⟫ = 0 := ⟨λ h, by simp [←inner_conj_symm, h], λ h, by simp [←inner_conj_symm, h]⟩ -@[simp] lemma inner_self_nonneg_im (x : E) : im ⟪x, x⟫ = 0 := +@[simp] lemma inner_self_im (x : E) : im ⟪x, x⟫ = 0 := by rw [← @of_real_inj 𝕜, im_eq_conj_sub]; simp -lemma inner_self_im_zero (x : E) : im ⟪x, x⟫ = 0 := inner_self_nonneg_im _ - lemma inner_add_left (x y z : E) : ⟪x + y, z⟫ = ⟪x, z⟫ + ⟪y, z⟫ := inner_product_space.add_left _ _ _ @@ -497,47 +492,11 @@ lemma inner_self_nonneg {x : E} : 0 ≤ re ⟪x, x⟫ := by rw [←norm_sq_eq_inner]; exact pow_nonneg (norm_nonneg x) 2 lemma real_inner_self_nonneg {x : F} : 0 ≤ ⟪x, x⟫_ℝ := @inner_self_nonneg ℝ F _ _ _ x -@[simp] lemma inner_self_eq_zero {x : E} : ⟪x, x⟫ = 0 ↔ x = 0 := -begin - split, - { intro h, - have h₁ : re ⟪x, x⟫ = 0 := - by rw is_R_or_C.ext_iff at h; simp only [h.1, zero_re'], - rw [←norm_sq_eq_inner x] at h₁, - rw [←norm_eq_zero], - exact pow_eq_zero h₁ }, - { rintro rfl, - exact inner_zero_left _ } -end - -lemma inner_self_ne_zero {x : E} : ⟪x, x⟫ ≠ 0 ↔ x ≠ 0 := -inner_self_eq_zero.not - -@[simp] lemma inner_self_nonpos {x : E} : re ⟪x, x⟫ ≤ 0 ↔ x = 0 := -begin - split, - { intro h, - rw ←@inner_self_eq_zero 𝕜, - have H₁ : re ⟪x, x⟫ ≥ 0, exact inner_self_nonneg, - have H₂ : re ⟪x, x⟫ = 0, exact le_antisymm h H₁, - rw is_R_or_C.ext_iff, - exact ⟨by simp [H₂], by simp [inner_self_nonneg_im]⟩ }, - { rintro rfl, - simp only [inner_zero_left, add_monoid_hom.map_zero] } -end - -lemma real_inner_self_nonpos {x : F} : ⟪x, x⟫_ℝ ≤ 0 ↔ x = 0 := -by { have h := @inner_self_nonpos ℝ F _ _ _ x, simpa using h } - @[simp] lemma inner_self_re_to_K (x : E) : (re ⟪x, x⟫ : 𝕜) = ⟪x, x⟫ := -is_R_or_C.ext_iff.2 ⟨by simp only [of_real_re], by simp only [inner_self_nonneg_im, of_real_im]⟩ +is_R_or_C.ext_iff.2 ⟨by simp only [of_real_re], by simp only [inner_self_im, of_real_im]⟩ lemma inner_self_eq_norm_sq_to_K (x : E) : ⟪x, x⟫ = (‖x‖ ^ 2 : 𝕜) := -begin - suffices : (is_R_or_C.re ⟪x, x⟫ : 𝕜) = ‖x‖ ^ 2, - { simpa only [inner_self_re_to_K] using this }, - exact_mod_cast (norm_sq_eq_inner x).symm -end +by rw [← inner_self_re_to_K, ← norm_sq_eq_inner, of_real_pow] lemma inner_self_re_abs (x : E) : re ⟪x, x⟫ = abs ⟪x, x⟫ := begin @@ -549,10 +508,22 @@ end lemma inner_self_abs_to_K (x : E) : (absK ⟪x, x⟫ : 𝕜) = ⟪x, x⟫ := by { rw [←inner_self_re_abs], exact inner_self_re_to_K _ } +@[simp] lemma inner_self_eq_zero {x : E} : ⟪x, x⟫ = 0 ↔ x = 0 := +by rw [inner_self_eq_norm_sq_to_K, sq_eq_zero_iff, of_real_eq_zero, norm_eq_zero] + +lemma inner_self_ne_zero {x : E} : ⟪x, x⟫ ≠ 0 ↔ x ≠ 0 := +inner_self_eq_zero.not + +@[simp] lemma inner_self_nonpos {x : E} : re ⟪x, x⟫ ≤ 0 ↔ x = 0 := +by rw [← norm_sq_eq_inner, (sq_nonneg _).le_iff_eq, sq_eq_zero_iff, norm_eq_zero] + +lemma real_inner_self_nonpos {x : F} : ⟪x, x⟫_ℝ ≤ 0 ↔ x = 0 := +@inner_self_nonpos ℝ F _ _ _ x + lemma real_inner_self_abs (x : F) : absR ⟪x, x⟫_ℝ = ⟪x, x⟫_ℝ := by { have h := @inner_self_abs_to_K ℝ F _ _ _ x, simpa using h } -lemma inner_abs_conj_symm (x y : E) : abs ⟪x, y⟫ = abs ⟪y, x⟫ := +lemma abs_inner_symm (x y : E) : abs ⟪x, y⟫ = abs ⟪y, x⟫ := by rw [←inner_conj_symm, abs_conj] @[simp] lemma inner_neg_left (x y : E) : ⟪-x, y⟫ = -⟪x, y⟫ := @@ -564,7 +535,7 @@ by rw [←inner_conj_symm, inner_neg_left]; simp only [ring_hom.map_neg, inner_c lemma inner_neg_neg (x y : E) : ⟪-x, -y⟫ = ⟪x, y⟫ := by simp @[simp] lemma inner_self_conj (x : E) : ⟪x, x⟫† = ⟪x, x⟫ := -by rw [is_R_or_C.ext_iff]; exact ⟨by rw [conj_re], by rw [conj_im, inner_self_im_zero, neg_zero]⟩ +by rw [is_R_or_C.ext_iff]; exact ⟨by rw [conj_re], by rw [conj_im, inner_self_im, neg_zero]⟩ lemma inner_sub_left (x y z : E) : ⟪x - y, z⟫ = ⟪x, z⟫ - ⟪y, z⟫ := by { simp [sub_eq_add_neg, inner_add_left] } @@ -637,7 +608,7 @@ begin apply hy', rw is_R_or_C.ext_iff, exact ⟨by simp only [H, zero_re'], - by simp only [inner_self_nonneg_im, add_monoid_hom.map_zero]⟩ }, + by simp only [inner_self_im, add_monoid_hom.map_zero]⟩ }, have h₆ : re ⟪y, y⟫ ≠ 0 := ne_of_gt h₅, have hmain := calc 0 ≤ re ⟪x - T • y, x - T • y⟫ @@ -668,14 +639,9 @@ end /-- Cauchy–Schwarz inequality for real inner products. -/ lemma real_inner_mul_inner_self_le (x y : F) : ⟪x, y⟫_ℝ * ⟪x, y⟫_ℝ ≤ ⟪x, x⟫_ℝ * ⟪y, y⟫_ℝ := -begin - have h₁ : ⟪y, x⟫_ℝ = ⟪x, y⟫_ℝ := by rw [←inner_conj_symm]; refl, - have h₂ := @inner_mul_inner_self_le ℝ F _ _ _ x y, - dsimp at h₂, - have h₃ := abs_mul_abs_self ⟪x, y⟫_ℝ, - rw [h₁] at h₂, - simpa [h₃] using h₂, -end +calc ⟪x, y⟫_ℝ * ⟪x, y⟫_ℝ ≤ is_R_or_C.abs ⟪x, y⟫_ℝ * is_R_or_C.abs ⟪y, x⟫_ℝ : + by { rw [real_inner_comm y, ← is_R_or_C.abs_mul, ← is_R_or_C.norm_eq_abs], exact le_abs_self _ } +... ≤ ⟪x, x⟫_ℝ * ⟪y, y⟫_ℝ : @inner_mul_inner_self_le ℝ _ _ _ _ x y /-- A family of vectors is linearly independent if they are nonzero and orthogonal. -/ @@ -1004,17 +970,8 @@ by { have h := @norm_add_mul_self ℝ _ _ _ _ x y, simpa using h } /-- Expand the square -/ lemma norm_sub_sq (x y : E) : ‖x - y‖^2 = ‖x‖^2 - 2 * (re ⟪x, y⟫) + ‖y‖^2 := -begin - repeat {rw [sq, ←@inner_self_eq_norm_mul_norm 𝕜]}, - rw [inner_sub_sub_self], - calc - re (⟪x, x⟫ - ⟪x, y⟫ - ⟪y, x⟫ + ⟪y, y⟫) - = re ⟪x, x⟫ - re ⟪x, y⟫ - re ⟪y, x⟫ + re ⟪y, y⟫ : by simp only [map_add, map_sub] - ... = -re ⟪y, x⟫ - re ⟪x, y⟫ + re ⟪x, x⟫ + re ⟪y, y⟫ : by ring - ... = -re (⟪x, y⟫†) - re ⟪x, y⟫ + re ⟪x, x⟫ + re ⟪y, y⟫ : by rw [inner_conj_symm] - ... = -re ⟪x, y⟫ - re ⟪x, y⟫ + re ⟪x, x⟫ + re ⟪y, y⟫ : by rw [conj_re] - ... = re ⟪x, x⟫ - 2*re ⟪x, y⟫ + re ⟪y, y⟫ : by ring -end +by rw [sub_eq_add_neg, @norm_add_sq 𝕜 _ _ _ _ x (-y), norm_neg, inner_neg_right, map_neg, mul_neg, + sub_eq_add_neg] alias norm_sub_sq ← norm_sub_pow_two @@ -1039,7 +996,7 @@ begin have : ‖x‖ * ‖y‖ * (‖x‖ * ‖y‖) = (re ⟪x, x⟫) * (re ⟪y, y⟫), simp only [inner_self_eq_norm_mul_norm], ring, rw this, - conv_lhs { congr, skip, rw [inner_abs_conj_symm] }, + conv_lhs { congr, skip, rw [abs_inner_symm] }, exact inner_mul_inner_self_le _ _ end @@ -1428,15 +1385,8 @@ end norms, has absolute value at most 1. -/ lemma abs_real_inner_div_norm_mul_norm_le_one (x y : F) : absR (⟪x, y⟫_ℝ / (‖x‖ * ‖y‖)) ≤ 1 := begin - rw _root_.abs_div, - by_cases h : 0 = absR (‖x‖ * ‖y‖), - { rw [←h, div_zero], - norm_num }, - { change 0 ≠ absR (‖x‖ * ‖y‖) at h, - rw div_le_iff' (lt_of_le_of_ne (ge_iff_le.mp (_root_.abs_nonneg (‖x‖ * ‖y‖))) h), - convert abs_real_inner_le_norm x y using 1, - rw [_root_.abs_mul, _root_.abs_of_nonneg (norm_nonneg x), _root_.abs_of_nonneg (norm_nonneg y), - mul_one] } + rw [_root_.abs_div, _root_.abs_mul, abs_norm, abs_norm], + exact div_le_one_of_le (abs_real_inner_le_norm x y) (by positivity) end /-- The inner product of a vector with a multiple of itself. -/ @@ -1604,23 +1554,10 @@ a negative multiple of the other. -/ lemma real_inner_div_norm_mul_norm_eq_neg_one_iff (x y : F) : ⟪x, y⟫_ℝ / (‖x‖ * ‖y‖) = -1 ↔ (x ≠ 0 ∧ ∃ (r : ℝ), r < 0 ∧ y = r • x) := begin - split, - { intro h, - have ha := h, - apply_fun absR at ha, - norm_num at ha, - rcases (abs_real_inner_div_norm_mul_norm_eq_one_iff x y).1 ha with ⟨hx, ⟨r, ⟨hr, hy⟩⟩⟩, - use [hx, r], - refine and.intro _ hy, - by_contradiction hrpos, - rw hy at h, - rw real_inner_div_norm_mul_norm_eq_one_of_ne_zero_of_pos_mul hx - (lt_of_le_of_ne (le_of_not_lt hrpos) hr.symm) at h, - norm_num at h }, - { intro h, - rcases h with ⟨hx, ⟨r, ⟨hr, hy⟩⟩⟩, - rw hy, - exact real_inner_div_norm_mul_norm_eq_neg_one_of_ne_zero_of_neg_mul hx hr } + rw [← neg_eq_iff_eq_neg, ← neg_div, ← inner_neg_right, ← norm_neg y, + real_inner_div_norm_mul_norm_eq_one_iff, (@neg_surjective ℝ _).exists], + refine iff.rfl.and (exists_congr $ λ r, _), + rw [neg_pos, neg_smul, neg_inj] end /-- If the inner product of two vectors is equal to the product of their norms (i.e., @@ -1722,14 +1659,11 @@ linear_map.mk_continuous₂ (innerₛₗ 𝕜) 1 begin refine le_antisymm ((innerSL 𝕜 x).op_norm_le_bound (norm_nonneg _) (λ y, norm_inner_le_norm _ _)) _, - cases eq_or_lt_of_le (norm_nonneg x) with h h, - { have : x = 0 := norm_eq_zero.mp (eq.symm h), - simp [this] }, - { refine (mul_le_mul_right h).mp _, - calc ‖x‖ * ‖x‖ = ‖x‖ ^ 2 : by ring - ... = re ⟪x, x⟫ : norm_sq_eq_inner _ - ... ≤ abs ⟪x, x⟫ : re_le_abs _ - ... = ‖⟪x, x⟫‖ : by rw [←is_R_or_C.norm_eq_abs] + rcases eq_or_ne x 0 with (rfl | h), + { simp }, + { refine (mul_le_mul_right (norm_pos_iff.2 h)).mp _, + calc ‖x‖ * ‖x‖ = ‖(⟪x, x⟫ : 𝕜)‖ : by rw [← sq, inner_self_eq_norm_sq_to_K, norm_pow, + norm_of_real, norm_norm] ... ≤ ‖innerSL 𝕜 x‖ * ‖x‖ : (innerSL 𝕜 x).le_op_norm _ } end From 73f96237417835f148a1f7bc1ff55f67119b7166 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Wed, 3 May 2023 23:08:00 +0000 Subject: [PATCH 05/17] chore(ring_theory/kaehler): extract from `ring_theory/derivation` (#18935) This section of the file needs heavier imports than the first half; and this splits the content nicely in two. The lemmas are moved without modification. One very minor docstring typo is fixed. --- src/ring_theory/derivation.lean | 624 +------------------------------ src/ring_theory/etale.lean | 2 +- src/ring_theory/kaehler.lean | 639 ++++++++++++++++++++++++++++++++ 3 files changed, 642 insertions(+), 623 deletions(-) create mode 100644 src/ring_theory/kaehler.lean diff --git a/src/ring_theory/derivation.lean b/src/ring_theory/derivation.lean index 7860637d85bfe..5d70b42f02def 100644 --- a/src/ring_theory/derivation.lean +++ b/src/ring_theory/derivation.lean @@ -4,10 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Nicolò Cavalleri, Andrew Yang -/ -import ring_theory.adjoin.basic import algebra.lie.of_associative -import ring_theory.ideal.cotangent -import ring_theory.is_tensor_product +import ring_theory.adjoin.basic +import ring_theory.ideal.quotient_operations /-! # Derivations @@ -23,25 +22,10 @@ This file defines derivation. A derivation `D` from the `R`-algebra `A` to the ` - `derivation.lie_algebra`: The `R`-derivations from `A` to `A` form an lie algebra over `R`. - `derivation_to_square_zero_equiv_lift`: The `R`-derivations from `A` into a square-zero ideal `I` of `B` corresponds to the lifts `A →ₐ[R] B` of the map `A →ₐ[R] B ⧸ I`. -- `kaehler_differential`: The module of kaehler differentials. For an `R`-algebra `S`, we provide - the notation `Ω[S⁄R]` for `kaehler_differential R S`. - Note that the slash is `\textfractionsolidus`. -- `kaehler_differential.D`: The derivation into the module of kaehler differentials. -- `kaehler_differential.span_range_derivation`: The image of `D` spans `Ω[S⁄R]` as an `S`-module. -- `kaehler_differential.linear_map_equiv_derivation`: - The isomorphism `Hom_R(Ω[S⁄R], M) ≃ₗ[S] Der_R(S, M)`. -- `kaehler_differential.quot_ker_total_equiv`: An alternative description of `Ω[S⁄R]` as `S` copies - of `S` with kernel (`kaehler_differential.ker_total`) generated by the relations: - 1. `dx + dy = d(x + y)` - 2. `x dy + y dx = d(x * y)` - 3. `dr = 0` for `r ∈ R` -- `kaehler_differential.map`: Given a map between the arrows `R → A` and `S → B`, we have an - `A`-linear map `Ω[A⁄R] → Ω[B⁄S]`. ## Future project - Generalize derivations into bimodules. -- Define a `is_kaehler_differential` predicate. -/ @@ -492,607 +476,3 @@ begin end end to_square_zero - -section kaehler_differential - -open_locale tensor_product - -variables (R S : Type*) [comm_ring R] [comm_ring S] [algebra R S] - -/-- The kernel of the multiplication map `S ⊗[R] S →ₐ[R] S`. -/ -abbreviation kaehler_differential.ideal : ideal (S ⊗[R] S) := -ring_hom.ker (tensor_product.lmul' R : S ⊗[R] S →ₐ[R] S) - -variable {S} - -lemma kaehler_differential.one_smul_sub_smul_one_mem_ideal (a : S) : - (1 : S) ⊗ₜ[R] a - a ⊗ₜ[R] (1 : S) ∈ kaehler_differential.ideal R S := -by simp [ring_hom.mem_ker] - -variables {R} - -variables {M : Type*} [add_comm_group M] [module R M] [module S M] [is_scalar_tower R S M] - -/-- For a `R`-derivation `S → M`, this is the map `S ⊗[R] S →ₗ[S] M` sending `s ⊗ₜ t ↦ s • D t`. -/ -def derivation.tensor_product_to (D : derivation R S M) : S ⊗[R] S →ₗ[S] M := -tensor_product.algebra_tensor_module.lift ((linear_map.lsmul S (S →ₗ[R] M)).flip D.to_linear_map) - -lemma derivation.tensor_product_to_tmul (D : derivation R S M) (s t : S) : - D.tensor_product_to (s ⊗ₜ t) = s • D t := -rfl - -lemma derivation.tensor_product_to_mul (D : derivation R S M) (x y : S ⊗[R] S) : - D.tensor_product_to (x * y) = tensor_product.lmul' R x • D.tensor_product_to y + - tensor_product.lmul' R y • D.tensor_product_to x := -begin - apply tensor_product.induction_on x, - { rw [zero_mul, map_zero, map_zero, zero_smul, smul_zero, add_zero] }, - swap, { rintros, simp only [add_mul, map_add, add_smul, *, smul_add], rw add_add_add_comm }, - intros x₁ x₂, - apply tensor_product.induction_on y, - { rw [mul_zero, map_zero, map_zero, zero_smul, smul_zero, add_zero] }, - swap, { rintros, simp only [mul_add, map_add, add_smul, *, smul_add], rw add_add_add_comm }, - intros x y, - simp only [tensor_product.tmul_mul_tmul, derivation.tensor_product_to, - tensor_product.algebra_tensor_module.lift_apply, tensor_product.lift.tmul', - tensor_product.lmul'_apply_tmul], - dsimp, - rw D.leibniz, - simp only [smul_smul, smul_add, mul_comm (x * y) x₁, mul_right_comm x₁ x₂, ← mul_assoc], -end - -variables (R S) - -/-- The kernel of `S ⊗[R] S →ₐ[R] S` is generated by `1 ⊗ s - s ⊗ 1` as a `S`-module. -/ -lemma kaehler_differential.submodule_span_range_eq_ideal : - submodule.span S (set.range $ λ s : S, (1 : S) ⊗ₜ[R] s - s ⊗ₜ[R] (1 : S)) = - (kaehler_differential.ideal R S).restrict_scalars S := -begin - apply le_antisymm, - { rw submodule.span_le, - rintros _ ⟨s, rfl⟩, - exact kaehler_differential.one_smul_sub_smul_one_mem_ideal _ _ }, - { rintros x (hx : _ = _), - have : x - (tensor_product.lmul' R x) ⊗ₜ[R] (1 : S) = x, - { rw [hx, tensor_product.zero_tmul, sub_zero] }, - rw ← this, - clear this hx, - apply tensor_product.induction_on x; clear x, - { rw [map_zero, tensor_product.zero_tmul, sub_zero], exact zero_mem _ }, - { intros x y, - convert_to x • (1 ⊗ₜ y - y ⊗ₜ 1) ∈ _, - { rw [tensor_product.lmul'_apply_tmul, smul_sub, tensor_product.smul_tmul', - tensor_product.smul_tmul', smul_eq_mul, smul_eq_mul, mul_one] }, - { refine submodule.smul_mem _ x _, - apply submodule.subset_span, - exact set.mem_range_self y } }, - { intros x y hx hy, - rw [map_add, tensor_product.add_tmul, ← sub_add_sub_comm], - exact add_mem hx hy } } -end - -lemma kaehler_differential.span_range_eq_ideal : - ideal.span (set.range $ λ s : S, (1 : S) ⊗ₜ[R] s - s ⊗ₜ[R] (1 : S)) = - kaehler_differential.ideal R S := -begin - apply le_antisymm, - { rw ideal.span_le, - rintros _ ⟨s, rfl⟩, - exact kaehler_differential.one_smul_sub_smul_one_mem_ideal _ _ }, - { change (kaehler_differential.ideal R S).restrict_scalars S ≤ (ideal.span _).restrict_scalars S, - rw [← kaehler_differential.submodule_span_range_eq_ideal, ideal.span], - conv_rhs { rw ← submodule.span_span_of_tower S }, - exact submodule.subset_span } -end - -/-- -The module of Kähler differentials (Kahler differentials, Kaehler differentials). -This is implemented as `I / I ^ 2` with `I` the kernel of the multiplication map `S ⊗[R] S →ₐ[R] S`. -To view elements as a linear combination of the form `s • D s'`, use -`kaehler_differential.tensor_product_to_surjective` and `derivation.tensor_product_to_tmul`. - -We also provide the notation `Ω[S⁄R]` for `kaehler_differential R S`. -Note that the slash is `\textfractionsolidus`. --/ -@[derive [add_comm_group, module (S ⊗[R] S)]] -def kaehler_differential : Type* := (kaehler_differential.ideal R S).cotangent - -notation `Ω[`:100 S `⁄`:0 R `]`:0 := kaehler_differential R S - -instance : nonempty Ω[S⁄R] := ⟨0⟩ - -instance kaehler_differential.module' {R' : Type*} [comm_ring R'] [algebra R' S] : - module R' Ω[S⁄R] := -(module.comp_hom (kaehler_differential.ideal R S).cotangent (algebra_map R' S) : _) - -instance : is_scalar_tower S (S ⊗[R] S) Ω[S⁄R] := -ideal.cotangent.is_scalar_tower _ - -instance kaehler_differential.is_scalar_tower_of_tower {R₁ R₂ : Type*} [comm_ring R₁] [comm_ring R₂] - [algebra R₁ S] [algebra R₂ S] [algebra R₁ R₂] [is_scalar_tower R₁ R₂ S] : - is_scalar_tower R₁ R₂ Ω[S⁄R] := -begin - convert restrict_scalars.is_scalar_tower R₁ R₂ Ω[S⁄R] using 1, - ext x m, - show algebra_map R₁ S x • m = algebra_map R₂ S (algebra_map R₁ R₂ x) • m, - rw ← is_scalar_tower.algebra_map_apply, -end - -instance kaehler_differential.is_scalar_tower' : - is_scalar_tower R (S ⊗[R] S) Ω[S⁄R] := -begin - convert restrict_scalars.is_scalar_tower R (S ⊗[R] S) Ω[S⁄R] using 1, - ext x m, - show algebra_map R S x • m = algebra_map R (S ⊗[R] S) x • m, - simp_rw [is_scalar_tower.algebra_map_apply R S (S ⊗[R] S), is_scalar_tower.algebra_map_smul] -end - -/-- The quotient map `I → Ω[S⁄R]` with `I` being the kernel of `S ⊗[R] S → S`. -/ -def kaehler_differential.from_ideal : kaehler_differential.ideal R S →ₗ[S ⊗[R] S] Ω[S⁄R] := -(kaehler_differential.ideal R S).to_cotangent - -/-- (Implementation) The underlying linear map of the derivation into `Ω[S⁄R]`. -/ -def kaehler_differential.D_linear_map : S →ₗ[R] Ω[S⁄R] := -((kaehler_differential.from_ideal R S).restrict_scalars R).comp - ((tensor_product.include_right.to_linear_map - tensor_product.include_left.to_linear_map : - S →ₗ[R] S ⊗[R] S).cod_restrict ((kaehler_differential.ideal R S).restrict_scalars R) - (kaehler_differential.one_smul_sub_smul_one_mem_ideal R) : _ →ₗ[R] _) - -lemma kaehler_differential.D_linear_map_apply (s : S) : - kaehler_differential.D_linear_map R S s = (kaehler_differential.ideal R S).to_cotangent - ⟨1 ⊗ₜ s - s ⊗ₜ 1, kaehler_differential.one_smul_sub_smul_one_mem_ideal R s⟩ := -rfl - -/-- The universal derivation into `Ω[S⁄R]`. -/ -def kaehler_differential.D : derivation R S Ω[S⁄R] := -{ map_one_eq_zero' := begin - dsimp [kaehler_differential.D_linear_map_apply], - rw [ideal.to_cotangent_eq_zero, subtype.coe_mk, sub_self], - exact zero_mem _ - end, - leibniz' := λ a b, begin - dsimp [kaehler_differential.D_linear_map_apply], - rw [← linear_map.map_smul_of_tower, ← linear_map.map_smul_of_tower, ← map_add, - ideal.to_cotangent_eq, pow_two], - convert submodule.mul_mem_mul (kaehler_differential.one_smul_sub_smul_one_mem_ideal R a : _) - (kaehler_differential.one_smul_sub_smul_one_mem_ideal R b : _) using 1, - simp only [add_subgroup_class.coe_sub, submodule.coe_add, submodule.coe_mk, - tensor_product.tmul_mul_tmul, mul_sub, sub_mul, mul_comm b, - submodule.coe_smul_of_tower, smul_sub, tensor_product.smul_tmul', smul_eq_mul, mul_one], - ring_nf, - end, - ..(kaehler_differential.D_linear_map R S) } - -lemma kaehler_differential.D_apply (s : S) : - kaehler_differential.D R S s = (kaehler_differential.ideal R S).to_cotangent - ⟨1 ⊗ₜ s - s ⊗ₜ 1, kaehler_differential.one_smul_sub_smul_one_mem_ideal R s⟩ := -rfl - -lemma kaehler_differential.span_range_derivation : - submodule.span S (set.range $ kaehler_differential.D R S) = ⊤ := -begin - rw _root_.eq_top_iff, - rintros x -, - obtain ⟨⟨x, hx⟩, rfl⟩ := ideal.to_cotangent_surjective _ x, - have : x ∈ (kaehler_differential.ideal R S).restrict_scalars S := hx, - rw ← kaehler_differential.submodule_span_range_eq_ideal at this, - suffices : ∃ hx, (kaehler_differential.ideal R S).to_cotangent ⟨x, hx⟩ ∈ - submodule.span S (set.range $ kaehler_differential.D R S), - { exact this.some_spec }, - apply submodule.span_induction this, - { rintros _ ⟨x, rfl⟩, - refine ⟨kaehler_differential.one_smul_sub_smul_one_mem_ideal R x, _⟩, - apply submodule.subset_span, - exact ⟨x, kaehler_differential.D_linear_map_apply R S x⟩ }, - { exact ⟨zero_mem _, submodule.zero_mem _⟩ }, - { rintros x y ⟨hx₁, hx₂⟩ ⟨hy₁, hy₂⟩, exact ⟨add_mem hx₁ hy₁, submodule.add_mem _ hx₂ hy₂⟩ }, - { rintros r x ⟨hx₁, hx₂⟩, exact ⟨((kaehler_differential.ideal R S).restrict_scalars S).smul_mem - r hx₁, submodule.smul_mem _ r hx₂⟩ } -end - -variables {R S} - -/-- The linear map from `Ω[S⁄R]`, associated with a derivation. -/ -def derivation.lift_kaehler_differential (D : derivation R S M) : Ω[S⁄R] →ₗ[S] M := -begin - refine ((kaehler_differential.ideal R S • ⊤ : - submodule (S ⊗[R] S) (kaehler_differential.ideal R S)).restrict_scalars S).liftq _ _, - { exact D.tensor_product_to.comp ((kaehler_differential.ideal R S).subtype.restrict_scalars S) }, - { intros x hx, - change _ = _, - apply submodule.smul_induction_on hx; clear hx x, - { rintros x (hx : _ = _) ⟨y, hy : _ = _⟩ -, - dsimp, - rw [derivation.tensor_product_to_mul, hx, hy, zero_smul, zero_smul, zero_add] }, - { intros x y ex ey, rw [map_add, ex, ey, zero_add] } } -end - -lemma derivation.lift_kaehler_differential_apply (D : derivation R S M) (x) : - D.lift_kaehler_differential - ((kaehler_differential.ideal R S).to_cotangent x) = D.tensor_product_to x := -rfl - -lemma derivation.lift_kaehler_differential_comp (D : derivation R S M) : - D.lift_kaehler_differential.comp_der (kaehler_differential.D R S) = D := -begin - ext a, - dsimp [kaehler_differential.D_apply], - refine (D.lift_kaehler_differential_apply _).trans _, - rw [subtype.coe_mk, map_sub, derivation.tensor_product_to_tmul, - derivation.tensor_product_to_tmul, one_smul, D.map_one_eq_zero, smul_zero, sub_zero], -end - -@[simp] lemma derivation.lift_kaehler_differential_comp_D (D' : derivation R S M) (x : S) : - D'.lift_kaehler_differential (kaehler_differential.D R S x) = D' x := -derivation.congr_fun D'.lift_kaehler_differential_comp x - -@[ext] -lemma derivation.lift_kaehler_differential_unique - (f f' : Ω[S⁄R] →ₗ[S] M) - (hf : f.comp_der (kaehler_differential.D R S) = - f'.comp_der (kaehler_differential.D R S)) : - f = f' := -begin - apply linear_map.ext, - intro x, - have : x ∈ submodule.span S (set.range $ kaehler_differential.D R S), - { rw kaehler_differential.span_range_derivation, trivial }, - apply submodule.span_induction this, - { rintros _ ⟨x, rfl⟩, exact congr_arg (λ D : derivation R S M, D x) hf }, - { rw [map_zero, map_zero] }, - { intros x y hx hy, rw [map_add, map_add, hx, hy] }, - { intros a x e, rw [map_smul, map_smul, e] } -end - -variables (R S) - -lemma derivation.lift_kaehler_differential_D : - (kaehler_differential.D R S).lift_kaehler_differential = linear_map.id := -derivation.lift_kaehler_differential_unique _ _ - (kaehler_differential.D R S).lift_kaehler_differential_comp - -variables {R S} - -lemma kaehler_differential.D_tensor_product_to (x : kaehler_differential.ideal R S) : - (kaehler_differential.D R S).tensor_product_to x = - (kaehler_differential.ideal R S).to_cotangent x := -begin - rw [← derivation.lift_kaehler_differential_apply, derivation.lift_kaehler_differential_D], - refl, -end - -variables (R S) - -lemma kaehler_differential.tensor_product_to_surjective : - function.surjective (kaehler_differential.D R S).tensor_product_to := -begin - intro x, obtain ⟨x, rfl⟩ := (kaehler_differential.ideal R S).to_cotangent_surjective x, - exact ⟨x, kaehler_differential.D_tensor_product_to x⟩ -end - -/-- The `S`-linear maps from `Ω[S⁄R]` to `M` are (`S`-linearly) equivalent to `R`-derivations -from `S` to `M`. -/ -def kaehler_differential.linear_map_equiv_derivation : (Ω[S⁄R] →ₗ[S] M) ≃ₗ[S] derivation R S M := -{ inv_fun := derivation.lift_kaehler_differential, - left_inv := λ f, derivation.lift_kaehler_differential_unique _ _ - (derivation.lift_kaehler_differential_comp _), - right_inv := derivation.lift_kaehler_differential_comp, - ..(derivation.llcomp.flip $ kaehler_differential.D R S) } - -/-- The quotient ring of `S ⊗ S ⧸ J ^ 2` by `Ω[S⁄R]` is isomorphic to `S`. -/ -def kaehler_differential.quotient_cotangent_ideal_ring_equiv : - (S ⊗ S ⧸ kaehler_differential.ideal R S ^ 2) ⧸ - (kaehler_differential.ideal R S).cotangent_ideal ≃+* S := -begin - have : function.right_inverse tensor_product.include_left - (↑(tensor_product.lmul' R : S ⊗[R] S →ₐ[R] S) : S ⊗[R] S →+* S), - { intro x, rw [alg_hom.coe_to_ring_hom, ← alg_hom.comp_apply, - tensor_product.lmul'_comp_include_left], refl }, - refine (ideal.quot_cotangent _).trans _, - refine (ideal.quot_equiv_of_eq _).trans (ring_hom.quotient_ker_equiv_of_right_inverse this), - ext, refl, -end - -/-- The quotient ring of `S ⊗ S ⧸ J ^ 2` by `Ω[S⁄R]` is isomorphic to `S` as an `S`-algebra. -/ -def kaehler_differential.quotient_cotangent_ideal : - ((S ⊗ S ⧸ kaehler_differential.ideal R S ^ 2) ⧸ - (kaehler_differential.ideal R S).cotangent_ideal) ≃ₐ[S] S := -{ commutes' := (kaehler_differential.quotient_cotangent_ideal_ring_equiv R S).apply_symm_apply, - ..kaehler_differential.quotient_cotangent_ideal_ring_equiv R S } - -lemma kaehler_differential.End_equiv_aux (f : S →ₐ[R] S ⊗ S ⧸ kaehler_differential.ideal R S ^ 2) : - (ideal.quotient.mkₐ R (kaehler_differential.ideal R S).cotangent_ideal).comp f = - is_scalar_tower.to_alg_hom R S _ ↔ - (tensor_product.lmul' R : S ⊗[R] S →ₐ[R] S).ker_square_lift.comp f = alg_hom.id R S := -begin - rw [alg_hom.ext_iff, alg_hom.ext_iff], - apply forall_congr, - intro x, - have e₁ : (tensor_product.lmul' R : S ⊗[R] S →ₐ[R] S).ker_square_lift (f x) = - kaehler_differential.quotient_cotangent_ideal_ring_equiv R S - (ideal.quotient.mk (kaehler_differential.ideal R S).cotangent_ideal $ f x), - { generalize : f x = y, obtain ⟨y, rfl⟩ := ideal.quotient.mk_surjective y, refl }, - have e₂ : x = kaehler_differential.quotient_cotangent_ideal_ring_equiv - R S (is_scalar_tower.to_alg_hom R S _ x), - { exact (mul_one x).symm }, - split, - { intro e, - exact (e₁.trans (@ring_equiv.congr_arg _ _ _ _ _ _ - (kaehler_differential.quotient_cotangent_ideal_ring_equiv R S) _ _ e)).trans e₂.symm }, - { intro e, apply (kaehler_differential.quotient_cotangent_ideal_ring_equiv R S).injective, - exact e₁.symm.trans (e.trans e₂) } -end - -/-- Derivations into `Ω[S⁄R]` is equivalent to derivations -into `(kaehler_differential.ideal R S).cotangent_ideal` -/ --- This has type --- `derivation R S Ω[ S / R ] ≃ₗ[R] derivation R S (kaehler_differential.ideal R S).cotangent_ideal` --- But lean times-out if this is given explicitly. -noncomputable -def kaehler_differential.End_equiv_derivation' := -@linear_equiv.comp_der R _ _ _ _ Ω[S⁄R] _ _ _ _ _ _ _ _ _ - ((kaehler_differential.ideal R S).cotangent_equiv_ideal.restrict_scalars S) - -/-- (Implementation) An `equiv` version of `kaehler_differential.End_equiv_aux`. -Used in `kaehler_differential.End_equiv`. -/ -def kaehler_differential.End_equiv_aux_equiv : - {f // (ideal.quotient.mkₐ R (kaehler_differential.ideal R S).cotangent_ideal).comp f = - is_scalar_tower.to_alg_hom R S _ } ≃ - { f // (tensor_product.lmul' R : S ⊗[R] S →ₐ[R] S).ker_square_lift.comp f = alg_hom.id R S } := -(equiv.refl _).subtype_equiv (kaehler_differential.End_equiv_aux R S) - -/-- -The endomorphisms of `Ω[S⁄R]` corresponds to sections of the surjection `S ⊗[R] S ⧸ J ^ 2 →ₐ[R] S`, -with `J` being the kernel of the multiplication map `S ⊗[R] S →ₐ[R] S`. --/ -noncomputable -def kaehler_differential.End_equiv : - module.End S Ω[S⁄R] ≃ - { f // (tensor_product.lmul' R : S ⊗[R] S →ₐ[R] S).ker_square_lift.comp f = alg_hom.id R S } := -(kaehler_differential.linear_map_equiv_derivation R S).to_equiv.trans $ - (kaehler_differential.End_equiv_derivation' R S).to_equiv.trans $ - (derivation_to_square_zero_equiv_lift - (kaehler_differential.ideal R S).cotangent_ideal - (kaehler_differential.ideal R S).cotangent_ideal_square).trans $ - kaehler_differential.End_equiv_aux_equiv R S - -section presentation - -open kaehler_differential (D) -open finsupp (single) - -/-- The `S`-submodule of `S →₀ S` (the direct sum of copies of `S` indexed by `S`) generated by -the relations: -1. `dx + dy = d(x + y)` -2. `x dy + y dx = d(x * y)` -3. `dr = 0` for `r ∈ R` -where `db` is the unit in the copy of `S` with index `b`. - -This is the kernel of the surjection `finsupp.total S Ω[S⁄R] S (kaehler_differential.D R S)`. -See `kaehler_differential.ker_total_eq` and `kaehler_differential.total_surjective`. --/ -noncomputable -def kaehler_differential.ker_total : submodule S (S →₀ S) := -submodule.span S - ((set.range (λ (x : S × S), single x.1 1 + single x.2 1 - single (x.1 + x.2) 1)) ∪ - (set.range (λ (x : S × S), single x.2 x.1 + single x.1 x.2 - single (x.1 * x.2) 1)) ∪ - (set.range (λ x : R, single (algebra_map R S x) 1))) - -local notation x `𝖣` y := (kaehler_differential.ker_total R S).mkq (single y x) - -lemma kaehler_differential.ker_total_mkq_single_add (x y z) : - (z 𝖣 (x + y)) = (z 𝖣 x) + (z 𝖣 y) := -begin - rw [← map_add, eq_comm, ← sub_eq_zero, ← map_sub, submodule.mkq_apply, - submodule.quotient.mk_eq_zero], - simp_rw [← finsupp.smul_single_one _ z, ← smul_add, ← smul_sub], - exact submodule.smul_mem _ _ (submodule.subset_span (or.inl $ or.inl $ ⟨⟨_, _⟩, rfl⟩)), -end - -lemma kaehler_differential.ker_total_mkq_single_mul (x y z) : - (z 𝖣 (x * y)) = ((z * x) 𝖣 y) + ((z * y) 𝖣 x) := -begin - rw [← map_add, eq_comm, ← sub_eq_zero, ← map_sub, submodule.mkq_apply, - submodule.quotient.mk_eq_zero], - simp_rw [← finsupp.smul_single_one _ z, ← @smul_eq_mul _ _ z, - ← finsupp.smul_single, ← smul_add, ← smul_sub], - exact submodule.smul_mem _ _ (submodule.subset_span (or.inl $ or.inr $ ⟨⟨_, _⟩, rfl⟩)), -end - -lemma kaehler_differential.ker_total_mkq_single_algebra_map (x y) : - (y 𝖣 (algebra_map R S x)) = 0 := -begin - rw [submodule.mkq_apply, submodule.quotient.mk_eq_zero, ← finsupp.smul_single_one _ y], - exact submodule.smul_mem _ _ (submodule.subset_span (or.inr $ ⟨_, rfl⟩)), -end - -lemma kaehler_differential.ker_total_mkq_single_algebra_map_one (x) : - (x 𝖣 1) = 0 := -begin - rw [← (algebra_map R S).map_one, kaehler_differential.ker_total_mkq_single_algebra_map], -end - -lemma kaehler_differential.ker_total_mkq_single_smul (r : R) (x y) : - (y 𝖣 (r • x)) = r • (y 𝖣 x) := -begin - rw [algebra.smul_def, kaehler_differential.ker_total_mkq_single_mul, - kaehler_differential.ker_total_mkq_single_algebra_map, add_zero, - ← linear_map.map_smul_of_tower, finsupp.smul_single, mul_comm, algebra.smul_def], -end - -/-- The (universal) derivation into `(S →₀ S) ⧸ kaehler_differential.ker_total R S`. -/ -noncomputable -def kaehler_differential.derivation_quot_ker_total : - derivation R S ((S →₀ S) ⧸ kaehler_differential.ker_total R S) := -{ to_fun := λ x, 1 𝖣 x, - map_add' := λ x y, kaehler_differential.ker_total_mkq_single_add _ _ _ _ _, - map_smul' := λ r s, kaehler_differential.ker_total_mkq_single_smul _ _ _ _ _, - map_one_eq_zero' := kaehler_differential.ker_total_mkq_single_algebra_map_one _ _ _, - leibniz' := λ a b, (kaehler_differential.ker_total_mkq_single_mul _ _ _ _ _).trans - (by { simp_rw [← finsupp.smul_single_one _ (1 * _ : S)], dsimp, simp }) } - -lemma kaehler_differential.derivation_quot_ker_total_apply (x) : - kaehler_differential.derivation_quot_ker_total R S x = (1 𝖣 x) := rfl - -lemma kaehler_differential.derivation_quot_ker_total_lift_comp_total : - (kaehler_differential.derivation_quot_ker_total R S).lift_kaehler_differential.comp - (finsupp.total S Ω[S⁄R] S (kaehler_differential.D R S)) = submodule.mkq _ := -begin - apply finsupp.lhom_ext, - intros a b, - conv_rhs { rw [← finsupp.smul_single_one a b, linear_map.map_smul] }, - simp [kaehler_differential.derivation_quot_ker_total_apply], -end - -lemma kaehler_differential.ker_total_eq : - (finsupp.total S Ω[S⁄R] S (kaehler_differential.D R S)).ker = - kaehler_differential.ker_total R S := -begin - apply le_antisymm, - { conv_rhs { rw ← (kaehler_differential.ker_total R S).ker_mkq }, - rw ← kaehler_differential.derivation_quot_ker_total_lift_comp_total, - exact linear_map.ker_le_ker_comp _ _ }, - { rw [kaehler_differential.ker_total, submodule.span_le], - rintros _ ((⟨⟨x, y⟩, rfl⟩|⟨⟨x, y⟩, rfl⟩)|⟨x, rfl⟩); dsimp; simp [linear_map.mem_ker] }, -end - -lemma kaehler_differential.total_surjective : - function.surjective (finsupp.total S Ω[S⁄R] S (kaehler_differential.D R S)) := -begin - rw [← linear_map.range_eq_top, finsupp.range_total, kaehler_differential.span_range_derivation], -end - -/-- `Ω[S⁄R]` is isomorphic to `S` copies of `S` with kernel `kaehler_differential.ker_total`. -/ -@[simps] noncomputable -def kaehler_differential.quot_ker_total_equiv : - ((S →₀ S) ⧸ kaehler_differential.ker_total R S) ≃ₗ[S] Ω[S⁄R] := -{ inv_fun := (kaehler_differential.derivation_quot_ker_total R S).lift_kaehler_differential, - left_inv := begin - intro x, - obtain ⟨x, rfl⟩ := submodule.mkq_surjective _ x, - exact linear_map.congr_fun - (kaehler_differential.derivation_quot_ker_total_lift_comp_total R S : _) x, - end, - right_inv := begin - intro x, - obtain ⟨x, rfl⟩ := kaehler_differential.total_surjective R S x, - erw linear_map.congr_fun - (kaehler_differential.derivation_quot_ker_total_lift_comp_total R S : _) x, - refl - end, - ..(kaehler_differential.ker_total R S).liftq - (finsupp.total S Ω[S⁄R] S (kaehler_differential.D R S)) - (kaehler_differential.ker_total_eq R S).ge } - -lemma kaehler_differential.quot_ker_total_equiv_symm_comp_D : - (kaehler_differential.quot_ker_total_equiv R S).symm.to_linear_map.comp_der - (kaehler_differential.D R S) = kaehler_differential.derivation_quot_ker_total R S := -by convert - (kaehler_differential.derivation_quot_ker_total R S).lift_kaehler_differential_comp using 0 - -variables (A B : Type*) [comm_ring A] [comm_ring B] [algebra R A] [algebra S B] [algebra R B] -variables [algebra A B] [is_scalar_tower R S B] [is_scalar_tower R A B] - --- The map `(A →₀ A) →ₗ[A] (B →₀ B)` -local notation `finsupp_map` := ((finsupp.map_range.linear_map (algebra.of_id A B).to_linear_map) - .comp (finsupp.lmap_domain A A (algebra_map A B))) - -lemma kaehler_differential.ker_total_map (h : function.surjective (algebra_map A B)) : - (kaehler_differential.ker_total R A).map finsupp_map ⊔ - submodule.span A (set.range (λ x : S, single (algebra_map S B x) (1 : B))) = - (kaehler_differential.ker_total S B).restrict_scalars _ := -begin - rw [kaehler_differential.ker_total, submodule.map_span, kaehler_differential.ker_total, - submodule.restrict_scalars_span _ _ h], - simp_rw [set.image_union, submodule.span_union, ← set.image_univ, set.image_image, - set.image_univ, map_sub, map_add], - simp only [linear_map.comp_apply, finsupp.map_range.linear_map_apply, finsupp.map_range_single, - finsupp.lmap_domain_apply, finsupp.map_domain_single, alg_hom.to_linear_map_apply, - algebra.of_id_apply, ← is_scalar_tower.algebra_map_apply, map_one, map_add, map_mul], - simp_rw [sup_assoc, ← (h.prod_map h).range_comp], - congr' 3, - rw [sup_eq_right], - apply submodule.span_mono, - simp_rw is_scalar_tower.algebra_map_apply R S B, - exact set.range_comp_subset_range (algebra_map R S) (λ x, single (algebra_map S B x) (1 : B)) -end - -end presentation - -section exact_sequence - -local attribute [irreducible] kaehler_differential - -/- We have the commutative diagram -A --→ B -↑ ↑ -| | -R --→ S -/ -variables (A B : Type*) [comm_ring A] [comm_ring B] [algebra R A] [algebra R B] -variables [algebra A B] [algebra S B] [is_scalar_tower R A B] [is_scalar_tower R S B] - -variables {R B} - -/-- For a tower `R → A → B` and an `R`-derivation `B → M`, we may compose with `A → B` to obtain an -`R`-derivation `A → M`. -/ -def derivation.comp_algebra_map [module A M] [module B M] [is_scalar_tower A B M] - (d : derivation R B M) : derivation R A M := -{ map_one_eq_zero' := by simp, - leibniz' := λ a b, by simp, - to_linear_map := d.to_linear_map.comp (is_scalar_tower.to_alg_hom R A B).to_linear_map } - -variables (R B) - -/-- The map `Ω[A⁄R] →ₗ[A] Ω[B⁄R]` given a square -A --→ B -↑ ↑ -| | -R --→ S -/ -def kaehler_differential.map : Ω[A⁄R] →ₗ[A] Ω[B⁄S] := -derivation.lift_kaehler_differential - (((kaehler_differential.D S B).restrict_scalars R).comp_algebra_map A) - -lemma kaehler_differential.map_comp_der : - (kaehler_differential.map R S A B).comp_der (kaehler_differential.D R A) = - (((kaehler_differential.D S B).restrict_scalars R).comp_algebra_map A) := -derivation.lift_kaehler_differential_comp _ - -lemma kaehler_differential.map_D (x : A) : - kaehler_differential.map R S A B (kaehler_differential.D R A x) = - kaehler_differential.D S B (algebra_map A B x) := -derivation.congr_fun (kaehler_differential.map_comp_der R S A B) x - -open is_scalar_tower (to_alg_hom) - -lemma kaehler_differential.map_surjective_of_surjective - (h : function.surjective (algebra_map A B)) : - function.surjective (kaehler_differential.map R S A B) := -begin - rw [← linear_map.range_eq_top, _root_.eq_top_iff, ← @submodule.restrict_scalars_top B A, - ← kaehler_differential.span_range_derivation, submodule.restrict_scalars_span _ _ h, - submodule.span_le], - rintros _ ⟨x, rfl⟩, - obtain ⟨y, rfl⟩ := h x, - rw ← kaehler_differential.map_D R S A B, - exact ⟨_, rfl⟩, -end - -/-- The lift of the map `Ω[A⁄R] →ₗ[A] Ω[B⁄R]` to the base change along `A → B`. -This is the first map in the exact sequence `B ⊗[A] Ω[A⁄R] → Ω[B⁄R] → Ω[B⁄A] → 0`. -/ -noncomputable -def kaehler_differential.map_base_change : B ⊗[A] Ω[A⁄R] →ₗ[B] Ω[B⁄R] := -(tensor_product.is_base_change A Ω[A⁄R] B).lift (kaehler_differential.map R R A B) - -@[simp] -lemma kaehler_differential.map_base_change_tmul (x : B) (y : Ω[A⁄R]) : - kaehler_differential.map_base_change R A B (x ⊗ₜ y) = - x • kaehler_differential.map R R A B y := -begin - conv_lhs { rw [← mul_one x, ← smul_eq_mul, ← tensor_product.smul_tmul', linear_map.map_smul] }, - congr' 1, - exact is_base_change.lift_eq _ _ _ -end - -end exact_sequence - -end kaehler_differential diff --git a/src/ring_theory/etale.lean b/src/ring_theory/etale.lean index f3d9a2a562c67..09b4302def2a3 100644 --- a/src/ring_theory/etale.lean +++ b/src/ring_theory/etale.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Andrew Yang -/ import ring_theory.quotient_nilpotent -import ring_theory.derivation +import ring_theory.kaehler /-! diff --git a/src/ring_theory/kaehler.lean b/src/ring_theory/kaehler.lean new file mode 100644 index 0000000000000..8e910ef0c9657 --- /dev/null +++ b/src/ring_theory/kaehler.lean @@ -0,0 +1,639 @@ +/- +Copyright © 2020 Nicolò Cavalleri. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Nicolò Cavalleri, Andrew Yang +-/ + +import ring_theory.derivation +import ring_theory.ideal.cotangent +import ring_theory.is_tensor_product + +/-! +# The module of kaehler differentials + +## Main results + +- `kaehler_differential`: The module of kaehler differentials. For an `R`-algebra `S`, we provide + the notation `Ω[S⁄R]` for `kaehler_differential R S`. + Note that the slash is `\textfractionsolidus`. +- `kaehler_differential.D`: The derivation into the module of kaehler differentials. +- `kaehler_differential.span_range_derivation`: The image of `D` spans `Ω[S⁄R]` as an `S`-module. +- `kaehler_differential.linear_map_equiv_derivation`: + The isomorphism `Hom_R(Ω[S⁄R], M) ≃ₗ[S] Der_R(S, M)`. +- `kaehler_differential.quot_ker_total_equiv`: An alternative description of `Ω[S⁄R]` as `S` copies + of `S` with kernel (`kaehler_differential.ker_total`) generated by the relations: + 1. `dx + dy = d(x + y)` + 2. `x dy + y dx = d(x * y)` + 3. `dr = 0` for `r ∈ R` +- `kaehler_differential.map`: Given a map between the arrows `R → A` and `S → B`, we have an + `A`-linear map `Ω[A⁄R] → Ω[B⁄S]`. + +## Future project + +- Define a `is_kaehler_differential` predicate. +-/ + +section kaehler_differential + +open_locale tensor_product +open algebra + +variables (R S : Type*) [comm_ring R] [comm_ring S] [algebra R S] + +/-- The kernel of the multiplication map `S ⊗[R] S →ₐ[R] S`. -/ +abbreviation kaehler_differential.ideal : ideal (S ⊗[R] S) := +ring_hom.ker (tensor_product.lmul' R : S ⊗[R] S →ₐ[R] S) + +variable {S} + +lemma kaehler_differential.one_smul_sub_smul_one_mem_ideal (a : S) : + (1 : S) ⊗ₜ[R] a - a ⊗ₜ[R] (1 : S) ∈ kaehler_differential.ideal R S := +by simp [ring_hom.mem_ker] + +variables {R} + +variables {M : Type*} [add_comm_group M] [module R M] [module S M] [is_scalar_tower R S M] + +/-- For a `R`-derivation `S → M`, this is the map `S ⊗[R] S →ₗ[S] M` sending `s ⊗ₜ t ↦ s • D t`. -/ +def derivation.tensor_product_to (D : derivation R S M) : S ⊗[R] S →ₗ[S] M := +tensor_product.algebra_tensor_module.lift ((linear_map.lsmul S (S →ₗ[R] M)).flip D.to_linear_map) + +lemma derivation.tensor_product_to_tmul (D : derivation R S M) (s t : S) : + D.tensor_product_to (s ⊗ₜ t) = s • D t := +rfl + +lemma derivation.tensor_product_to_mul (D : derivation R S M) (x y : S ⊗[R] S) : + D.tensor_product_to (x * y) = tensor_product.lmul' R x • D.tensor_product_to y + + tensor_product.lmul' R y • D.tensor_product_to x := +begin + apply tensor_product.induction_on x, + { rw [zero_mul, map_zero, map_zero, zero_smul, smul_zero, add_zero] }, + swap, { rintros, simp only [add_mul, map_add, add_smul, *, smul_add], rw add_add_add_comm }, + intros x₁ x₂, + apply tensor_product.induction_on y, + { rw [mul_zero, map_zero, map_zero, zero_smul, smul_zero, add_zero] }, + swap, { rintros, simp only [mul_add, map_add, add_smul, *, smul_add], rw add_add_add_comm }, + intros x y, + simp only [tensor_product.tmul_mul_tmul, derivation.tensor_product_to, + tensor_product.algebra_tensor_module.lift_apply, tensor_product.lift.tmul', + tensor_product.lmul'_apply_tmul], + dsimp, + rw D.leibniz, + simp only [smul_smul, smul_add, mul_comm (x * y) x₁, mul_right_comm x₁ x₂, ← mul_assoc], +end + +variables (R S) + +/-- The kernel of `S ⊗[R] S →ₐ[R] S` is generated by `1 ⊗ s - s ⊗ 1` as a `S`-module. -/ +lemma kaehler_differential.submodule_span_range_eq_ideal : + submodule.span S (set.range $ λ s : S, (1 : S) ⊗ₜ[R] s - s ⊗ₜ[R] (1 : S)) = + (kaehler_differential.ideal R S).restrict_scalars S := +begin + apply le_antisymm, + { rw submodule.span_le, + rintros _ ⟨s, rfl⟩, + exact kaehler_differential.one_smul_sub_smul_one_mem_ideal _ _ }, + { rintros x (hx : _ = _), + have : x - (tensor_product.lmul' R x) ⊗ₜ[R] (1 : S) = x, + { rw [hx, tensor_product.zero_tmul, sub_zero] }, + rw ← this, + clear this hx, + apply tensor_product.induction_on x; clear x, + { rw [map_zero, tensor_product.zero_tmul, sub_zero], exact zero_mem _ }, + { intros x y, + convert_to x • (1 ⊗ₜ y - y ⊗ₜ 1) ∈ _, + { rw [tensor_product.lmul'_apply_tmul, smul_sub, tensor_product.smul_tmul', + tensor_product.smul_tmul', smul_eq_mul, smul_eq_mul, mul_one] }, + { refine submodule.smul_mem _ x _, + apply submodule.subset_span, + exact set.mem_range_self y } }, + { intros x y hx hy, + rw [map_add, tensor_product.add_tmul, ← sub_add_sub_comm], + exact add_mem hx hy } } +end + +lemma kaehler_differential.span_range_eq_ideal : + ideal.span (set.range $ λ s : S, (1 : S) ⊗ₜ[R] s - s ⊗ₜ[R] (1 : S)) = + kaehler_differential.ideal R S := +begin + apply le_antisymm, + { rw ideal.span_le, + rintros _ ⟨s, rfl⟩, + exact kaehler_differential.one_smul_sub_smul_one_mem_ideal _ _ }, + { change (kaehler_differential.ideal R S).restrict_scalars S ≤ (ideal.span _).restrict_scalars S, + rw [← kaehler_differential.submodule_span_range_eq_ideal, ideal.span], + conv_rhs { rw ← submodule.span_span_of_tower S }, + exact submodule.subset_span } +end + +/-- +The module of Kähler differentials (Kahler differentials, Kaehler differentials). +This is implemented as `I / I ^ 2` with `I` the kernel of the multiplication map `S ⊗[R] S →ₐ[R] S`. +To view elements as a linear combination of the form `s • D s'`, use +`kaehler_differential.tensor_product_to_surjective` and `derivation.tensor_product_to_tmul`. + +We also provide the notation `Ω[S⁄R]` for `kaehler_differential R S`. +Note that the slash is `\textfractionsolidus`. +-/ +@[derive [add_comm_group, module (S ⊗[R] S)]] +def kaehler_differential : Type* := (kaehler_differential.ideal R S).cotangent + +notation `Ω[`:100 S `⁄`:0 R `]`:0 := kaehler_differential R S + +instance : nonempty Ω[S⁄R] := ⟨0⟩ + +instance kaehler_differential.module' {R' : Type*} [comm_ring R'] [algebra R' S] : + module R' Ω[S⁄R] := +(module.comp_hom (kaehler_differential.ideal R S).cotangent (algebra_map R' S) : _) + +instance : is_scalar_tower S (S ⊗[R] S) Ω[S⁄R] := +ideal.cotangent.is_scalar_tower _ + +instance kaehler_differential.is_scalar_tower_of_tower {R₁ R₂ : Type*} [comm_ring R₁] [comm_ring R₂] + [algebra R₁ S] [algebra R₂ S] [algebra R₁ R₂] [is_scalar_tower R₁ R₂ S] : + is_scalar_tower R₁ R₂ Ω[S⁄R] := +begin + convert restrict_scalars.is_scalar_tower R₁ R₂ Ω[S⁄R] using 1, + ext x m, + show algebra_map R₁ S x • m = algebra_map R₂ S (algebra_map R₁ R₂ x) • m, + rw ← is_scalar_tower.algebra_map_apply, +end + +instance kaehler_differential.is_scalar_tower' : + is_scalar_tower R (S ⊗[R] S) Ω[S⁄R] := +begin + convert restrict_scalars.is_scalar_tower R (S ⊗[R] S) Ω[S⁄R] using 1, + ext x m, + show algebra_map R S x • m = algebra_map R (S ⊗[R] S) x • m, + simp_rw [is_scalar_tower.algebra_map_apply R S (S ⊗[R] S), is_scalar_tower.algebra_map_smul] +end + +/-- The quotient map `I → Ω[S⁄R]` with `I` being the kernel of `S ⊗[R] S → S`. -/ +def kaehler_differential.from_ideal : kaehler_differential.ideal R S →ₗ[S ⊗[R] S] Ω[S⁄R] := +(kaehler_differential.ideal R S).to_cotangent + +/-- (Implementation) The underlying linear map of the derivation into `Ω[S⁄R]`. -/ +def kaehler_differential.D_linear_map : S →ₗ[R] Ω[S⁄R] := +((kaehler_differential.from_ideal R S).restrict_scalars R).comp + ((tensor_product.include_right.to_linear_map - tensor_product.include_left.to_linear_map : + S →ₗ[R] S ⊗[R] S).cod_restrict ((kaehler_differential.ideal R S).restrict_scalars R) + (kaehler_differential.one_smul_sub_smul_one_mem_ideal R) : _ →ₗ[R] _) + +lemma kaehler_differential.D_linear_map_apply (s : S) : + kaehler_differential.D_linear_map R S s = (kaehler_differential.ideal R S).to_cotangent + ⟨1 ⊗ₜ s - s ⊗ₜ 1, kaehler_differential.one_smul_sub_smul_one_mem_ideal R s⟩ := +rfl + +/-- The universal derivation into `Ω[S⁄R]`. -/ +def kaehler_differential.D : derivation R S Ω[S⁄R] := +{ map_one_eq_zero' := begin + dsimp [kaehler_differential.D_linear_map_apply], + rw [ideal.to_cotangent_eq_zero, subtype.coe_mk, sub_self], + exact zero_mem _ + end, + leibniz' := λ a b, begin + dsimp [kaehler_differential.D_linear_map_apply], + rw [← linear_map.map_smul_of_tower, ← linear_map.map_smul_of_tower, ← map_add, + ideal.to_cotangent_eq, pow_two], + convert submodule.mul_mem_mul (kaehler_differential.one_smul_sub_smul_one_mem_ideal R a : _) + (kaehler_differential.one_smul_sub_smul_one_mem_ideal R b : _) using 1, + simp only [add_subgroup_class.coe_sub, submodule.coe_add, submodule.coe_mk, + tensor_product.tmul_mul_tmul, mul_sub, sub_mul, mul_comm b, + submodule.coe_smul_of_tower, smul_sub, tensor_product.smul_tmul', smul_eq_mul, mul_one], + ring_nf, + end, + ..(kaehler_differential.D_linear_map R S) } + +lemma kaehler_differential.D_apply (s : S) : + kaehler_differential.D R S s = (kaehler_differential.ideal R S).to_cotangent + ⟨1 ⊗ₜ s - s ⊗ₜ 1, kaehler_differential.one_smul_sub_smul_one_mem_ideal R s⟩ := +rfl + +lemma kaehler_differential.span_range_derivation : + submodule.span S (set.range $ kaehler_differential.D R S) = ⊤ := +begin + rw _root_.eq_top_iff, + rintros x -, + obtain ⟨⟨x, hx⟩, rfl⟩ := ideal.to_cotangent_surjective _ x, + have : x ∈ (kaehler_differential.ideal R S).restrict_scalars S := hx, + rw ← kaehler_differential.submodule_span_range_eq_ideal at this, + suffices : ∃ hx, (kaehler_differential.ideal R S).to_cotangent ⟨x, hx⟩ ∈ + submodule.span S (set.range $ kaehler_differential.D R S), + { exact this.some_spec }, + apply submodule.span_induction this, + { rintros _ ⟨x, rfl⟩, + refine ⟨kaehler_differential.one_smul_sub_smul_one_mem_ideal R x, _⟩, + apply submodule.subset_span, + exact ⟨x, kaehler_differential.D_linear_map_apply R S x⟩ }, + { exact ⟨zero_mem _, submodule.zero_mem _⟩ }, + { rintros x y ⟨hx₁, hx₂⟩ ⟨hy₁, hy₂⟩, exact ⟨add_mem hx₁ hy₁, submodule.add_mem _ hx₂ hy₂⟩ }, + { rintros r x ⟨hx₁, hx₂⟩, exact ⟨((kaehler_differential.ideal R S).restrict_scalars S).smul_mem + r hx₁, submodule.smul_mem _ r hx₂⟩ } +end + +variables {R S} + +/-- The linear map from `Ω[S⁄R]`, associated with a derivation. -/ +def derivation.lift_kaehler_differential (D : derivation R S M) : Ω[S⁄R] →ₗ[S] M := +begin + refine ((kaehler_differential.ideal R S • ⊤ : + submodule (S ⊗[R] S) (kaehler_differential.ideal R S)).restrict_scalars S).liftq _ _, + { exact D.tensor_product_to.comp ((kaehler_differential.ideal R S).subtype.restrict_scalars S) }, + { intros x hx, + change _ = _, + apply submodule.smul_induction_on hx; clear hx x, + { rintros x (hx : _ = _) ⟨y, hy : _ = _⟩ -, + dsimp, + rw [derivation.tensor_product_to_mul, hx, hy, zero_smul, zero_smul, zero_add] }, + { intros x y ex ey, rw [map_add, ex, ey, zero_add] } } +end + +lemma derivation.lift_kaehler_differential_apply (D : derivation R S M) (x) : + D.lift_kaehler_differential + ((kaehler_differential.ideal R S).to_cotangent x) = D.tensor_product_to x := +rfl + +lemma derivation.lift_kaehler_differential_comp (D : derivation R S M) : + D.lift_kaehler_differential.comp_der (kaehler_differential.D R S) = D := +begin + ext a, + dsimp [kaehler_differential.D_apply], + refine (D.lift_kaehler_differential_apply _).trans _, + rw [subtype.coe_mk, map_sub, derivation.tensor_product_to_tmul, + derivation.tensor_product_to_tmul, one_smul, D.map_one_eq_zero, smul_zero, sub_zero], +end + +@[simp] lemma derivation.lift_kaehler_differential_comp_D (D' : derivation R S M) (x : S) : + D'.lift_kaehler_differential (kaehler_differential.D R S x) = D' x := +derivation.congr_fun D'.lift_kaehler_differential_comp x + +@[ext] +lemma derivation.lift_kaehler_differential_unique + (f f' : Ω[S⁄R] →ₗ[S] M) + (hf : f.comp_der (kaehler_differential.D R S) = + f'.comp_der (kaehler_differential.D R S)) : + f = f' := +begin + apply linear_map.ext, + intro x, + have : x ∈ submodule.span S (set.range $ kaehler_differential.D R S), + { rw kaehler_differential.span_range_derivation, trivial }, + apply submodule.span_induction this, + { rintros _ ⟨x, rfl⟩, exact congr_arg (λ D : derivation R S M, D x) hf }, + { rw [map_zero, map_zero] }, + { intros x y hx hy, rw [map_add, map_add, hx, hy] }, + { intros a x e, rw [map_smul, map_smul, e] } +end + +variables (R S) + +lemma derivation.lift_kaehler_differential_D : + (kaehler_differential.D R S).lift_kaehler_differential = linear_map.id := +derivation.lift_kaehler_differential_unique _ _ + (kaehler_differential.D R S).lift_kaehler_differential_comp + +variables {R S} + +lemma kaehler_differential.D_tensor_product_to (x : kaehler_differential.ideal R S) : + (kaehler_differential.D R S).tensor_product_to x = + (kaehler_differential.ideal R S).to_cotangent x := +begin + rw [← derivation.lift_kaehler_differential_apply, derivation.lift_kaehler_differential_D], + refl, +end + +variables (R S) + +lemma kaehler_differential.tensor_product_to_surjective : + function.surjective (kaehler_differential.D R S).tensor_product_to := +begin + intro x, obtain ⟨x, rfl⟩ := (kaehler_differential.ideal R S).to_cotangent_surjective x, + exact ⟨x, kaehler_differential.D_tensor_product_to x⟩ +end + +/-- The `S`-linear maps from `Ω[S⁄R]` to `M` are (`S`-linearly) equivalent to `R`-derivations +from `S` to `M`. -/ +def kaehler_differential.linear_map_equiv_derivation : (Ω[S⁄R] →ₗ[S] M) ≃ₗ[S] derivation R S M := +{ inv_fun := derivation.lift_kaehler_differential, + left_inv := λ f, derivation.lift_kaehler_differential_unique _ _ + (derivation.lift_kaehler_differential_comp _), + right_inv := derivation.lift_kaehler_differential_comp, + ..(derivation.llcomp.flip $ kaehler_differential.D R S) } + +/-- The quotient ring of `S ⊗ S ⧸ J ^ 2` by `Ω[S⁄R]` is isomorphic to `S`. -/ +def kaehler_differential.quotient_cotangent_ideal_ring_equiv : + (S ⊗ S ⧸ kaehler_differential.ideal R S ^ 2) ⧸ + (kaehler_differential.ideal R S).cotangent_ideal ≃+* S := +begin + have : function.right_inverse tensor_product.include_left + (↑(tensor_product.lmul' R : S ⊗[R] S →ₐ[R] S) : S ⊗[R] S →+* S), + { intro x, rw [alg_hom.coe_to_ring_hom, ← alg_hom.comp_apply, + tensor_product.lmul'_comp_include_left], refl }, + refine (ideal.quot_cotangent _).trans _, + refine (ideal.quot_equiv_of_eq _).trans (ring_hom.quotient_ker_equiv_of_right_inverse this), + ext, refl, +end + +/-- The quotient ring of `S ⊗ S ⧸ J ^ 2` by `Ω[S⁄R]` is isomorphic to `S` as an `S`-algebra. -/ +def kaehler_differential.quotient_cotangent_ideal : + ((S ⊗ S ⧸ kaehler_differential.ideal R S ^ 2) ⧸ + (kaehler_differential.ideal R S).cotangent_ideal) ≃ₐ[S] S := +{ commutes' := (kaehler_differential.quotient_cotangent_ideal_ring_equiv R S).apply_symm_apply, + ..kaehler_differential.quotient_cotangent_ideal_ring_equiv R S } + +lemma kaehler_differential.End_equiv_aux (f : S →ₐ[R] S ⊗ S ⧸ kaehler_differential.ideal R S ^ 2) : + (ideal.quotient.mkₐ R (kaehler_differential.ideal R S).cotangent_ideal).comp f = + is_scalar_tower.to_alg_hom R S _ ↔ + (tensor_product.lmul' R : S ⊗[R] S →ₐ[R] S).ker_square_lift.comp f = alg_hom.id R S := +begin + rw [alg_hom.ext_iff, alg_hom.ext_iff], + apply forall_congr, + intro x, + have e₁ : (tensor_product.lmul' R : S ⊗[R] S →ₐ[R] S).ker_square_lift (f x) = + kaehler_differential.quotient_cotangent_ideal_ring_equiv R S + (ideal.quotient.mk (kaehler_differential.ideal R S).cotangent_ideal $ f x), + { generalize : f x = y, obtain ⟨y, rfl⟩ := ideal.quotient.mk_surjective y, refl }, + have e₂ : x = kaehler_differential.quotient_cotangent_ideal_ring_equiv + R S (is_scalar_tower.to_alg_hom R S _ x), + { exact (mul_one x).symm }, + split, + { intro e, + exact (e₁.trans (@ring_equiv.congr_arg _ _ _ _ _ _ + (kaehler_differential.quotient_cotangent_ideal_ring_equiv R S) _ _ e)).trans e₂.symm }, + { intro e, apply (kaehler_differential.quotient_cotangent_ideal_ring_equiv R S).injective, + exact e₁.symm.trans (e.trans e₂) } +end + +/-- Derivations into `Ω[S⁄R]` is equivalent to derivations +into `(kaehler_differential.ideal R S).cotangent_ideal` -/ +-- This has type +-- `derivation R S Ω[S⁄R] ≃ₗ[R] derivation R S (kaehler_differential.ideal R S).cotangent_ideal` +-- But lean times-out if this is given explicitly. +noncomputable +def kaehler_differential.End_equiv_derivation' := +@linear_equiv.comp_der R _ _ _ _ Ω[S⁄R] _ _ _ _ _ _ _ _ _ + ((kaehler_differential.ideal R S).cotangent_equiv_ideal.restrict_scalars S) + +/-- (Implementation) An `equiv` version of `kaehler_differential.End_equiv_aux`. +Used in `kaehler_differential.End_equiv`. -/ +def kaehler_differential.End_equiv_aux_equiv : + {f // (ideal.quotient.mkₐ R (kaehler_differential.ideal R S).cotangent_ideal).comp f = + is_scalar_tower.to_alg_hom R S _ } ≃ + { f // (tensor_product.lmul' R : S ⊗[R] S →ₐ[R] S).ker_square_lift.comp f = alg_hom.id R S } := +(equiv.refl _).subtype_equiv (kaehler_differential.End_equiv_aux R S) + +/-- +The endomorphisms of `Ω[S⁄R]` corresponds to sections of the surjection `S ⊗[R] S ⧸ J ^ 2 →ₐ[R] S`, +with `J` being the kernel of the multiplication map `S ⊗[R] S →ₐ[R] S`. +-/ +noncomputable +def kaehler_differential.End_equiv : + module.End S Ω[S⁄R] ≃ + { f // (tensor_product.lmul' R : S ⊗[R] S →ₐ[R] S).ker_square_lift.comp f = alg_hom.id R S } := +(kaehler_differential.linear_map_equiv_derivation R S).to_equiv.trans $ + (kaehler_differential.End_equiv_derivation' R S).to_equiv.trans $ + (derivation_to_square_zero_equiv_lift + (kaehler_differential.ideal R S).cotangent_ideal + (kaehler_differential.ideal R S).cotangent_ideal_square).trans $ + kaehler_differential.End_equiv_aux_equiv R S + +section presentation + +open kaehler_differential (D) +open finsupp (single) + +/-- The `S`-submodule of `S →₀ S` (the direct sum of copies of `S` indexed by `S`) generated by +the relations: +1. `dx + dy = d(x + y)` +2. `x dy + y dx = d(x * y)` +3. `dr = 0` for `r ∈ R` +where `db` is the unit in the copy of `S` with index `b`. + +This is the kernel of the surjection `finsupp.total S Ω[S⁄R] S (kaehler_differential.D R S)`. +See `kaehler_differential.ker_total_eq` and `kaehler_differential.total_surjective`. +-/ +noncomputable +def kaehler_differential.ker_total : submodule S (S →₀ S) := +submodule.span S + ((set.range (λ (x : S × S), single x.1 1 + single x.2 1 - single (x.1 + x.2) 1)) ∪ + (set.range (λ (x : S × S), single x.2 x.1 + single x.1 x.2 - single (x.1 * x.2) 1)) ∪ + (set.range (λ x : R, single (algebra_map R S x) 1))) + +local notation x `𝖣` y := (kaehler_differential.ker_total R S).mkq (single y x) + +lemma kaehler_differential.ker_total_mkq_single_add (x y z) : + (z 𝖣 (x + y)) = (z 𝖣 x) + (z 𝖣 y) := +begin + rw [← map_add, eq_comm, ← sub_eq_zero, ← map_sub, submodule.mkq_apply, + submodule.quotient.mk_eq_zero], + simp_rw [← finsupp.smul_single_one _ z, ← smul_add, ← smul_sub], + exact submodule.smul_mem _ _ (submodule.subset_span (or.inl $ or.inl $ ⟨⟨_, _⟩, rfl⟩)), +end + +lemma kaehler_differential.ker_total_mkq_single_mul (x y z) : + (z 𝖣 (x * y)) = ((z * x) 𝖣 y) + ((z * y) 𝖣 x) := +begin + rw [← map_add, eq_comm, ← sub_eq_zero, ← map_sub, submodule.mkq_apply, + submodule.quotient.mk_eq_zero], + simp_rw [← finsupp.smul_single_one _ z, ← @smul_eq_mul _ _ z, + ← finsupp.smul_single, ← smul_add, ← smul_sub], + exact submodule.smul_mem _ _ (submodule.subset_span (or.inl $ or.inr $ ⟨⟨_, _⟩, rfl⟩)), +end + +lemma kaehler_differential.ker_total_mkq_single_algebra_map (x y) : + (y 𝖣 (algebra_map R S x)) = 0 := +begin + rw [submodule.mkq_apply, submodule.quotient.mk_eq_zero, ← finsupp.smul_single_one _ y], + exact submodule.smul_mem _ _ (submodule.subset_span (or.inr $ ⟨_, rfl⟩)), +end + +lemma kaehler_differential.ker_total_mkq_single_algebra_map_one (x) : + (x 𝖣 1) = 0 := +begin + rw [← (algebra_map R S).map_one, kaehler_differential.ker_total_mkq_single_algebra_map], +end + +lemma kaehler_differential.ker_total_mkq_single_smul (r : R) (x y) : + (y 𝖣 (r • x)) = r • (y 𝖣 x) := +begin + rw [algebra.smul_def, kaehler_differential.ker_total_mkq_single_mul, + kaehler_differential.ker_total_mkq_single_algebra_map, add_zero, + ← linear_map.map_smul_of_tower, finsupp.smul_single, mul_comm, algebra.smul_def], +end + +/-- The (universal) derivation into `(S →₀ S) ⧸ kaehler_differential.ker_total R S`. -/ +noncomputable +def kaehler_differential.derivation_quot_ker_total : + derivation R S ((S →₀ S) ⧸ kaehler_differential.ker_total R S) := +{ to_fun := λ x, 1 𝖣 x, + map_add' := λ x y, kaehler_differential.ker_total_mkq_single_add _ _ _ _ _, + map_smul' := λ r s, kaehler_differential.ker_total_mkq_single_smul _ _ _ _ _, + map_one_eq_zero' := kaehler_differential.ker_total_mkq_single_algebra_map_one _ _ _, + leibniz' := λ a b, (kaehler_differential.ker_total_mkq_single_mul _ _ _ _ _).trans + (by { simp_rw [← finsupp.smul_single_one _ (1 * _ : S)], dsimp, simp }) } + +lemma kaehler_differential.derivation_quot_ker_total_apply (x) : + kaehler_differential.derivation_quot_ker_total R S x = (1 𝖣 x) := rfl + +lemma kaehler_differential.derivation_quot_ker_total_lift_comp_total : + (kaehler_differential.derivation_quot_ker_total R S).lift_kaehler_differential.comp + (finsupp.total S Ω[S⁄R] S (kaehler_differential.D R S)) = submodule.mkq _ := +begin + apply finsupp.lhom_ext, + intros a b, + conv_rhs { rw [← finsupp.smul_single_one a b, linear_map.map_smul] }, + simp [kaehler_differential.derivation_quot_ker_total_apply], +end + +lemma kaehler_differential.ker_total_eq : + (finsupp.total S Ω[S⁄R] S (kaehler_differential.D R S)).ker = + kaehler_differential.ker_total R S := +begin + apply le_antisymm, + { conv_rhs { rw ← (kaehler_differential.ker_total R S).ker_mkq }, + rw ← kaehler_differential.derivation_quot_ker_total_lift_comp_total, + exact linear_map.ker_le_ker_comp _ _ }, + { rw [kaehler_differential.ker_total, submodule.span_le], + rintros _ ((⟨⟨x, y⟩, rfl⟩|⟨⟨x, y⟩, rfl⟩)|⟨x, rfl⟩); dsimp; simp [linear_map.mem_ker] }, +end + +lemma kaehler_differential.total_surjective : + function.surjective (finsupp.total S Ω[S⁄R] S (kaehler_differential.D R S)) := +begin + rw [← linear_map.range_eq_top, finsupp.range_total, kaehler_differential.span_range_derivation], +end + +/-- `Ω[S⁄R]` is isomorphic to `S` copies of `S` with kernel `kaehler_differential.ker_total`. -/ +@[simps] noncomputable +def kaehler_differential.quot_ker_total_equiv : + ((S →₀ S) ⧸ kaehler_differential.ker_total R S) ≃ₗ[S] Ω[S⁄R] := +{ inv_fun := (kaehler_differential.derivation_quot_ker_total R S).lift_kaehler_differential, + left_inv := begin + intro x, + obtain ⟨x, rfl⟩ := submodule.mkq_surjective _ x, + exact linear_map.congr_fun + (kaehler_differential.derivation_quot_ker_total_lift_comp_total R S : _) x, + end, + right_inv := begin + intro x, + obtain ⟨x, rfl⟩ := kaehler_differential.total_surjective R S x, + erw linear_map.congr_fun + (kaehler_differential.derivation_quot_ker_total_lift_comp_total R S : _) x, + refl + end, + ..(kaehler_differential.ker_total R S).liftq + (finsupp.total S Ω[S⁄R] S (kaehler_differential.D R S)) + (kaehler_differential.ker_total_eq R S).ge } + +lemma kaehler_differential.quot_ker_total_equiv_symm_comp_D : + (kaehler_differential.quot_ker_total_equiv R S).symm.to_linear_map.comp_der + (kaehler_differential.D R S) = kaehler_differential.derivation_quot_ker_total R S := +by convert + (kaehler_differential.derivation_quot_ker_total R S).lift_kaehler_differential_comp using 0 + +variables (A B : Type*) [comm_ring A] [comm_ring B] [algebra R A] [algebra S B] [algebra R B] +variables [algebra A B] [is_scalar_tower R S B] [is_scalar_tower R A B] + +-- The map `(A →₀ A) →ₗ[A] (B →₀ B)` +local notation `finsupp_map` := ((finsupp.map_range.linear_map (algebra.of_id A B).to_linear_map) + .comp (finsupp.lmap_domain A A (algebra_map A B))) + +lemma kaehler_differential.ker_total_map (h : function.surjective (algebra_map A B)) : + (kaehler_differential.ker_total R A).map finsupp_map ⊔ + submodule.span A (set.range (λ x : S, single (algebra_map S B x) (1 : B))) = + (kaehler_differential.ker_total S B).restrict_scalars _ := +begin + rw [kaehler_differential.ker_total, submodule.map_span, kaehler_differential.ker_total, + submodule.restrict_scalars_span _ _ h], + simp_rw [set.image_union, submodule.span_union, ← set.image_univ, set.image_image, + set.image_univ, map_sub, map_add], + simp only [linear_map.comp_apply, finsupp.map_range.linear_map_apply, finsupp.map_range_single, + finsupp.lmap_domain_apply, finsupp.map_domain_single, alg_hom.to_linear_map_apply, + algebra.of_id_apply, ← is_scalar_tower.algebra_map_apply, map_one, map_add, map_mul], + simp_rw [sup_assoc, ← (h.prod_map h).range_comp], + congr' 3, + rw [sup_eq_right], + apply submodule.span_mono, + simp_rw is_scalar_tower.algebra_map_apply R S B, + exact set.range_comp_subset_range (algebra_map R S) (λ x, single (algebra_map S B x) (1 : B)) +end + +end presentation + +section exact_sequence + +local attribute [irreducible] kaehler_differential + +/- We have the commutative diagram +A --→ B +↑ ↑ +| | +R --→ S -/ +variables (A B : Type*) [comm_ring A] [comm_ring B] [algebra R A] [algebra R B] +variables [algebra A B] [algebra S B] [is_scalar_tower R A B] [is_scalar_tower R S B] + +variables {R B} + +/-- For a tower `R → A → B` and an `R`-derivation `B → M`, we may compose with `A → B` to obtain an +`R`-derivation `A → M`. -/ +def derivation.comp_algebra_map [module A M] [module B M] [is_scalar_tower A B M] + (d : derivation R B M) : derivation R A M := +{ map_one_eq_zero' := by simp, + leibniz' := λ a b, by simp, + to_linear_map := d.to_linear_map.comp (is_scalar_tower.to_alg_hom R A B).to_linear_map } + +variables (R B) + +/-- The map `Ω[A⁄R] →ₗ[A] Ω[B⁄R]` given a square +A --→ B +↑ ↑ +| | +R --→ S -/ +def kaehler_differential.map : Ω[A⁄R] →ₗ[A] Ω[B⁄S] := +derivation.lift_kaehler_differential + (((kaehler_differential.D S B).restrict_scalars R).comp_algebra_map A) + +lemma kaehler_differential.map_comp_der : + (kaehler_differential.map R S A B).comp_der (kaehler_differential.D R A) = + (((kaehler_differential.D S B).restrict_scalars R).comp_algebra_map A) := +derivation.lift_kaehler_differential_comp _ + +lemma kaehler_differential.map_D (x : A) : + kaehler_differential.map R S A B (kaehler_differential.D R A x) = + kaehler_differential.D S B (algebra_map A B x) := +derivation.congr_fun (kaehler_differential.map_comp_der R S A B) x + +open is_scalar_tower (to_alg_hom) + +lemma kaehler_differential.map_surjective_of_surjective + (h : function.surjective (algebra_map A B)) : + function.surjective (kaehler_differential.map R S A B) := +begin + rw [← linear_map.range_eq_top, _root_.eq_top_iff, ← @submodule.restrict_scalars_top B A, + ← kaehler_differential.span_range_derivation, submodule.restrict_scalars_span _ _ h, + submodule.span_le], + rintros _ ⟨x, rfl⟩, + obtain ⟨y, rfl⟩ := h x, + rw ← kaehler_differential.map_D R S A B, + exact ⟨_, rfl⟩, +end + +/-- The lift of the map `Ω[A⁄R] →ₗ[A] Ω[B⁄R]` to the base change along `A → B`. +This is the first map in the exact sequence `B ⊗[A] Ω[A⁄R] → Ω[B⁄R] → Ω[B⁄A] → 0`. -/ +noncomputable +def kaehler_differential.map_base_change : B ⊗[A] Ω[A⁄R] →ₗ[B] Ω[B⁄R] := +(tensor_product.is_base_change A Ω[A⁄R] B).lift (kaehler_differential.map R R A B) + +@[simp] +lemma kaehler_differential.map_base_change_tmul (x : B) (y : Ω[A⁄R]) : + kaehler_differential.map_base_change R A B (x ⊗ₜ y) = + x • kaehler_differential.map R R A B y := +begin + conv_lhs { rw [← mul_one x, ← smul_eq_mul, ← tensor_product.smul_tmul', linear_map.map_smul] }, + congr' 1, + exact is_base_change.lift_eq _ _ _ +end + +end exact_sequence + +end kaehler_differential From f0c8bf9245297a541f468be517f1bde6195105e9 Mon Sep 17 00:00:00 2001 From: Scott Morrison Date: Thu, 4 May 2023 01:42:12 +0000 Subject: [PATCH 06/17] chore(*): removed unneeded imports (#18926) This is another run of https://github.com/leanprover-community/mathlib/pull/17568, scrubbing unnecessary imports. Like last time we only remove genuinely unneeded imports, and leave merely transitively redundant imports alone. (I *still* disagree with the objectors to removing transitively redundant imports Co-authored-by: Scott Morrison Co-authored-by: Eric Wieser --- src/algebra/category/Module/biproducts.lean | 1 - .../computation/approximation_corollaries.lean | 3 ++- src/algebra/direct_limit.lean | 2 +- src/algebra/order/interval.lean | 2 +- src/algebraic_geometry/Spec.lean | 1 - src/algebraic_geometry/elliptic_curve/point.lean | 2 -- src/algebraic_geometry/locally_ringed_space.lean | 1 - src/algebraic_geometry/morphisms/open_immersion.lean | 2 +- src/algebraic_geometry/open_immersion.lean | 1 - src/analysis/bounded_variation.lean | 1 - src/analysis/calculus/bump_function_findim.lean | 1 + src/analysis/complex/upper_half_plane/topology.lean | 1 - src/analysis/constant_speed.lean | 2 -- src/analysis/convex/between.lean | 2 +- src/analysis/convex/cone/proper.lean | 2 +- src/analysis/convex/intrinsic.lean | 1 - src/analysis/fourier/fourier_transform.lean | 3 +-- src/analysis/fourier/riemann_lebesgue_lemma.lean | 2 -- src/analysis/inner_product_space/orthogonal.lean | 6 ------ src/analysis/normed_space/affine_isometry.lean | 2 +- src/analysis/normed_space/compact_operator.lean | 2 +- src/analysis/normed_space/quaternion_exponential.lean | 1 - src/analysis/normed_space/star/spectrum.lean | 1 - src/analysis/special_functions/japanese_bracket.lean | 1 + src/category_theory/abelian/generator.lean | 2 +- src/category_theory/abelian/injective_resolution.lean | 1 - src/category_theory/abelian/projective.lean | 1 - src/category_theory/sites/cover_preserving.lean | 4 ++-- src/data/array/lemmas.lean | 4 ++-- src/data/buffer/basic.lean | 1 + src/data/hash_map.lean | 1 + src/field_theory/galois.lean | 1 - src/field_theory/minpoly/basic.lean | 1 - src/field_theory/minpoly/is_integrally_closed.lean | 1 - src/geometry/euclidean/angle/oriented/basic.lean | 1 - src/geometry/euclidean/angle/oriented/rotation.lean | 1 + src/linear_algebra/bilinear_form.lean | 1 - src/linear_algebra/bilinear_form/tensor_product.lean | 1 - src/linear_algebra/eigenspace.lean | 1 - src/measure_theory/integral/interval_integral.lean | 2 +- src/measure_theory/integral/periodic.lean | 1 + src/measure_theory/measure/complex_lebesgue.lean | 1 + src/measure_theory/measure/haar_of_basis.lean | 1 - src/measure_theory/measure/probability_measure.lean | 1 - src/measure_theory/tactic.lean | 1 + src/number_theory/cyclotomic/basic.lean | 2 -- src/number_theory/diophantine_approximation.lean | 1 - src/number_theory/kummer_dedekind.lean | 1 - src/number_theory/legendre_symbol/mul_character.lean | 2 +- src/number_theory/modular_forms/jacobi_theta.lean | 4 ++-- src/number_theory/number_field/basic.lean | 1 - src/number_theory/padics/padic_integers.lean | 1 - src/number_theory/primes_congruent_one.lean | 1 - src/number_theory/well_approximable.lean | 1 - src/number_theory/zeta_values.lean | 2 -- src/probability/density.lean | 2 +- src/probability/variance.lean | 1 + src/ring_theory/dedekind_domain/adic_valuation.lean | 2 +- src/ring_theory/dedekind_domain/dvr.lean | 6 ++---- src/ring_theory/dedekind_domain/finite_adele_ring.lean | 1 - src/ring_theory/discrete_valuation_ring/tfae.lean | 1 + src/ring_theory/ideal/associated_prime.lean | 5 ++--- src/ring_theory/ideal/norm.lean | 1 - src/ring_theory/nakayama.lean | 2 +- src/ring_theory/polynomial/gauss_lemma.lean | 1 - src/topology/algebra/nonarchimedean/adic_topology.lean | 2 ++ src/topology/instances/add_circle.lean | 1 - src/topology/instances/complex.lean | 4 ++-- 68 files changed, 40 insertions(+), 77 deletions(-) diff --git a/src/algebra/category/Module/biproducts.lean b/src/algebra/category/Module/biproducts.lean index 24be464b445ce..ac7e918c8c678 100644 --- a/src/algebra/category/Module/biproducts.lean +++ b/src/algebra/category/Module/biproducts.lean @@ -5,7 +5,6 @@ Authors: Scott Morrison -/ import algebra.group.pi import category_theory.limits.shapes.biproducts -import algebra.category.Module.limits import algebra.category.Module.abelian import algebra.homology.short_exact.abelian diff --git a/src/algebra/continued_fractions/computation/approximation_corollaries.lean b/src/algebra/continued_fractions/computation/approximation_corollaries.lean index 9c22e4f9aa49b..df71b81f9db55 100644 --- a/src/algebra/continued_fractions/computation/approximation_corollaries.lean +++ b/src/algebra/continued_fractions/computation/approximation_corollaries.lean @@ -6,7 +6,8 @@ Authors: Kevin Kappelmann import algebra.continued_fractions.computation.approximations import algebra.continued_fractions.convergents_equiv import algebra.order.archimedean -import topology.algebra.order.field +import algebra.algebra.basic +import topology.order.basic /-! # Corollaries From Approximation Lemmas (`algebra.continued_fractions.computation.approximations`) diff --git a/src/algebra/direct_limit.lean b/src/algebra/direct_limit.lean index df4262c66a427..891830bcf9987 100644 --- a/src/algebra/direct_limit.lean +++ b/src/algebra/direct_limit.lean @@ -6,7 +6,7 @@ Authors: Kenny Lau, Chris Hughes import data.finset.order import algebra.direct_sum.module import ring_theory.free_comm_ring -import ring_theory.ideal.quotient_operations +import ring_theory.ideal.quotient /-! # Direct limit of modules, abelian groups, rings, and fields. diff --git a/src/algebra/order/interval.lean b/src/algebra/order/interval.lean index aa63d9e1d7b84..77cdf30d29b8e 100644 --- a/src/algebra/order/interval.lean +++ b/src/algebra/order/interval.lean @@ -15,7 +15,7 @@ import tactic.positivity This file defines arithmetic operations on intervals and prove their correctness. Note that this is full precision operations. The essentials of float operations can be found -in `data.fp.basic`. We hsve not yet integrated these with the rest of the library. +in `data.fp.basic`. We have not yet integrated these with the rest of the library. -/ open function set diff --git a/src/algebraic_geometry/Spec.lean b/src/algebraic_geometry/Spec.lean index 2b6fe31315a2c..8663af3575c76 100644 --- a/src/algebraic_geometry/Spec.lean +++ b/src/algebraic_geometry/Spec.lean @@ -5,7 +5,6 @@ Authors: Scott Morrison, Justus Springer -/ import algebraic_geometry.locally_ringed_space import algebraic_geometry.structure_sheaf -import logic.equiv.transfer_instance import ring_theory.localization.localization_localization import topology.sheaves.sheaf_condition.sites import topology.sheaves.functors diff --git a/src/algebraic_geometry/elliptic_curve/point.lean b/src/algebraic_geometry/elliptic_curve/point.lean index eee73fcbb56f5..59c6aa82ed658 100644 --- a/src/algebraic_geometry/elliptic_curve/point.lean +++ b/src/algebraic_geometry/elliptic_curve/point.lean @@ -5,8 +5,6 @@ Authors: David Kurniadi Angdinata -/ import algebraic_geometry.elliptic_curve.weierstrass -import field_theory.galois -- temporary import to enable point notation -import ring_theory.class_group /-! # The group of nonsingular rational points on a Weierstrass curve over a field diff --git a/src/algebraic_geometry/locally_ringed_space.lean b/src/algebraic_geometry/locally_ringed_space.lean index a1f0c6682c4a1..3e88bfb7a6cdf 100644 --- a/src/algebraic_geometry/locally_ringed_space.lean +++ b/src/algebraic_geometry/locally_ringed_space.lean @@ -6,7 +6,6 @@ Authors: Johan Commelin import algebraic_geometry.ringed_space import algebraic_geometry.stalks -import logic.equiv.transfer_instance /-! # The category of locally ringed spaces diff --git a/src/algebraic_geometry/morphisms/open_immersion.lean b/src/algebraic_geometry/morphisms/open_immersion.lean index 1294196c149bf..62465fea56bb8 100644 --- a/src/algebraic_geometry/morphisms/open_immersion.lean +++ b/src/algebraic_geometry/morphisms/open_immersion.lean @@ -3,8 +3,8 @@ Copyright (c) 2022 Andrew Yang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Andrew Yang -/ -import algebraic_geometry.morphisms.ring_hom_properties import topology.local_at_target +import algebraic_geometry.morphisms.basic /-! diff --git a/src/algebraic_geometry/open_immersion.lean b/src/algebraic_geometry/open_immersion.lean index 66068eb2190b0..87d243476e371 100644 --- a/src/algebraic_geometry/open_immersion.lean +++ b/src/algebraic_geometry/open_immersion.lean @@ -12,7 +12,6 @@ import algebraic_geometry.Scheme import category_theory.limits.shapes.strict_initial import category_theory.limits.shapes.comm_sq import algebra.category.Ring.instances -import topology.local_at_target /-! # Open immersions of structured spaces diff --git a/src/analysis/bounded_variation.lean b/src/analysis/bounded_variation.lean index b224ea147a178..98b2b765cfdf7 100644 --- a/src/analysis/bounded_variation.lean +++ b/src/analysis/bounded_variation.lean @@ -3,7 +3,6 @@ Copyright (c) 2022 Sébastien Gouëzel. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel -/ -import measure_theory.measure.lebesgue import analysis.calculus.monotone import data.set.function import algebra.group.basic diff --git a/src/analysis/calculus/bump_function_findim.lean b/src/analysis/calculus/bump_function_findim.lean index e44927acf9dd9..453e2bc05af9b 100644 --- a/src/analysis/calculus/bump_function_findim.lean +++ b/src/analysis/calculus/bump_function_findim.lean @@ -6,6 +6,7 @@ Authors: Sébastien Gouëzel import analysis.calculus.series import analysis.convolution import analysis.inner_product_space.euclidean_dist +import measure_theory.measure.haar_lebesgue import data.set.pointwise.support /-! diff --git a/src/analysis/complex/upper_half_plane/topology.lean b/src/analysis/complex/upper_half_plane/topology.lean index 9bbe36ca3bba2..c441e99fcfe93 100644 --- a/src/analysis/complex/upper_half_plane/topology.lean +++ b/src/analysis/complex/upper_half_plane/topology.lean @@ -9,7 +9,6 @@ import analysis.convex.normed import analysis.convex.complex import analysis.complex.re_im_topology import topology.homotopy.contractible -import geometry.manifold.mfderiv import geometry.manifold.cont_mdiff_mfderiv /-! diff --git a/src/analysis/constant_speed.lean b/src/analysis/constant_speed.lean index ea5e9d545fe72..c6ac9e016baf7 100644 --- a/src/analysis/constant_speed.lean +++ b/src/analysis/constant_speed.lean @@ -3,8 +3,6 @@ Copyright (c) 2023 Rémi Bottinelli. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Rémi Bottinelli -/ -import measure_theory.measure.lebesgue -import analysis.calculus.monotone import data.set.function import analysis.bounded_variation import tactic.swap_var diff --git a/src/analysis/convex/between.lean b/src/analysis/convex/between.lean index 5d192618f9e2c..6c1c1e94a8834 100644 --- a/src/analysis/convex/between.lean +++ b/src/analysis/convex/between.lean @@ -6,8 +6,8 @@ Authors: Joseph Myers import data.set.intervals.group import analysis.convex.segment import linear_algebra.affine_space.finite_dimensional -import linear_algebra.affine_space.midpoint_zero import tactic.field_simp +import algebra.char_p.invertible /-! # Betweenness in affine spaces diff --git a/src/analysis/convex/cone/proper.lean b/src/analysis/convex/cone/proper.lean index 2bc6da0856b11..96ee065db043c 100644 --- a/src/analysis/convex/cone/proper.lean +++ b/src/analysis/convex/cone/proper.lean @@ -3,7 +3,7 @@ Copyright (c) 2022 Apurva Nakade All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Apurva Nakade -/ -import analysis.inner_product_space.adjoint +import analysis.convex.cone.basic /-! diff --git a/src/analysis/convex/intrinsic.lean b/src/analysis/convex/intrinsic.lean index 035e2ea3e4686..5d36a26c91ffe 100644 --- a/src/analysis/convex/intrinsic.lean +++ b/src/analysis/convex/intrinsic.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Paul Reichert, Yaël Dillies -/ import analysis.normed_space.add_torsor_bases -import analysis.normed_space.linear_isometry /-! # Intrinsic frontier and interior diff --git a/src/analysis/fourier/fourier_transform.lean b/src/analysis/fourier/fourier_transform.lean index cea8feb24a888..c3dd53ccf025c 100644 --- a/src/analysis/fourier/fourier_transform.lean +++ b/src/analysis/fourier/fourier_transform.lean @@ -4,9 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: David Loeffler -/ -import analysis.special_functions.complex.circle import measure_theory.group.integration -import measure_theory.integral.integral_eq_improper +import measure_theory.measure.haar_of_basis /-! # The Fourier transform diff --git a/src/analysis/fourier/riemann_lebesgue_lemma.lean b/src/analysis/fourier/riemann_lebesgue_lemma.lean index 5813bab5b2938..befd529ada06b 100644 --- a/src/analysis/fourier/riemann_lebesgue_lemma.lean +++ b/src/analysis/fourier/riemann_lebesgue_lemma.lean @@ -5,9 +5,7 @@ Authors: David Loeffler -/ import measure_theory.function.continuous_map_dense -import measure_theory.integral.integral_eq_improper import measure_theory.group.integration -import topology.continuous_function.zero_at_infty import analysis.fourier.fourier_transform import analysis.inner_product_space.dual import topology.metric_space.emetric_paracompact diff --git a/src/analysis/inner_product_space/orthogonal.lean b/src/analysis/inner_product_space/orthogonal.lean index 67955868a091d..e97459a37a164 100644 --- a/src/analysis/inner_product_space/orthogonal.lean +++ b/src/analysis/inner_product_space/orthogonal.lean @@ -3,13 +3,7 @@ Copyright (c) 2019 Zhouhang Zhou. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Zhouhang Zhou, Sébastien Gouëzel, Frédéric Dupuis -/ -import algebra.direct_sum.module -import analysis.complex.basic -import analysis.convex.uniform -import analysis.normed_space.completion -import analysis.normed_space.bounded_linear_maps import linear_algebra.bilinear_form - import analysis.inner_product_space.basic /-! diff --git a/src/analysis/normed_space/affine_isometry.lean b/src/analysis/normed_space/affine_isometry.lean index 0f62bc036be7c..c3e5a9e350546 100644 --- a/src/analysis/normed_space/affine_isometry.lean +++ b/src/analysis/normed_space/affine_isometry.lean @@ -7,7 +7,7 @@ import analysis.normed_space.linear_isometry import analysis.normed.group.add_torsor import analysis.normed_space.basic import linear_algebra.affine_space.restrict -import linear_algebra.affine_space.midpoint_zero +import algebra.char_p.invertible /-! # Affine isometries diff --git a/src/analysis/normed_space/compact_operator.lean b/src/analysis/normed_space/compact_operator.lean index 7b1d943287552..793e39757aa21 100644 --- a/src/analysis/normed_space/compact_operator.lean +++ b/src/analysis/normed_space/compact_operator.lean @@ -3,8 +3,8 @@ Copyright (c) 2022 Anatole Dedecker. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Anatole Dedecker -/ -import analysis.normed_space.operator_norm import analysis.locally_convex.bounded +import topology.algebra.module.strong_topology /-! # Compact operators diff --git a/src/analysis/normed_space/quaternion_exponential.lean b/src/analysis/normed_space/quaternion_exponential.lean index dec605b571e51..4a6786af9568d 100644 --- a/src/analysis/normed_space/quaternion_exponential.lean +++ b/src/analysis/normed_space/quaternion_exponential.lean @@ -5,7 +5,6 @@ Authors: Eric Wieser -/ import analysis.quaternion import analysis.normed_space.exponential -import analysis.inner_product_space.pi_L2 import analysis.special_functions.trigonometric.series /-! diff --git a/src/analysis/normed_space/star/spectrum.lean b/src/analysis/normed_space/star/spectrum.lean index 8994342eb2cb8..c9cf202ad89d5 100644 --- a/src/analysis/normed_space/star/spectrum.lean +++ b/src/analysis/normed_space/star/spectrum.lean @@ -5,7 +5,6 @@ Authors: Jireh Loreaux -/ import analysis.normed_space.star.basic import analysis.normed_space.spectrum -import analysis.normed_space.star.exponential import analysis.special_functions.exponential import algebra.star.star_alg_hom diff --git a/src/analysis/special_functions/japanese_bracket.lean b/src/analysis/special_functions/japanese_bracket.lean index 3ed378923a66a..d287916d88f20 100644 --- a/src/analysis/special_functions/japanese_bracket.lean +++ b/src/analysis/special_functions/japanese_bracket.lean @@ -3,6 +3,7 @@ Copyright (c) 2022 Moritz Doll. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Moritz Doll -/ +import measure_theory.measure.haar_lebesgue import measure_theory.integral.layercake /-! diff --git a/src/category_theory/abelian/generator.lean b/src/category_theory/abelian/generator.lean index 806c76e1f6398..ef01a1539af08 100644 --- a/src/category_theory/abelian/generator.lean +++ b/src/category_theory/abelian/generator.lean @@ -7,7 +7,7 @@ import category_theory.abelian.subobject import category_theory.limits.essentially_small import category_theory.preadditive.injective import category_theory.preadditive.generator -import category_theory.preadditive.yoneda.limits +import category_theory.abelian.opposite /-! # A complete abelian category with enough injectives and a separator has an injective coseparator diff --git a/src/category_theory/abelian/injective_resolution.lean b/src/category_theory/abelian/injective_resolution.lean index b72be7a1ac788..fa70a18e89435 100644 --- a/src/category_theory/abelian/injective_resolution.lean +++ b/src/category_theory/abelian/injective_resolution.lean @@ -5,7 +5,6 @@ Authors: Jujian Zhang, Scott Morrison -/ import algebra.homology.quasi_iso import category_theory.preadditive.injective_resolution -import category_theory.abelian.homology import algebra.homology.homotopy_category /-! diff --git a/src/category_theory/abelian/projective.lean b/src/category_theory/abelian/projective.lean index 0868de8756aaa..68156ef0055fd 100644 --- a/src/category_theory/abelian/projective.lean +++ b/src/category_theory/abelian/projective.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Markus Himmel, Scott Morrison, Jakob von Raumer -/ import algebra.homology.quasi_iso -import category_theory.abelian.homology import category_theory.preadditive.projective_resolution import category_theory.preadditive.yoneda.limits import category_theory.preadditive.yoneda.projective diff --git a/src/category_theory/sites/cover_preserving.lean b/src/category_theory/sites/cover_preserving.lean index 46403554b14e5..2b3133f5f98ab 100644 --- a/src/category_theory/sites/cover_preserving.lean +++ b/src/category_theory/sites/cover_preserving.lean @@ -3,9 +3,9 @@ Copyright (c) 2021 Andrew Yang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Andrew Yang -/ -import category_theory.sites.limits import category_theory.functor.flat -import category_theory.limits.preserves.filtered +import category_theory.sites.sheaf +import tactic.apply_fun /-! # Cover-preserving functors between sites. diff --git a/src/data/array/lemmas.lean b/src/data/array/lemmas.lean index 2f0f22eff241c..c459b4f2800dc 100644 --- a/src/data/array/lemmas.lean +++ b/src/data/array/lemmas.lean @@ -3,8 +3,8 @@ Copyright (c) 2017 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura, Mario Carneiro -/ -import control.traversable.equiv -import data.vector.basic +import data.fin.basic +import data.list.basic universes u v w diff --git a/src/data/buffer/basic.lean b/src/data/buffer/basic.lean index fe4df9b0ffeef..cdff3d2644bd8 100644 --- a/src/data/buffer/basic.lean +++ b/src/data/buffer/basic.lean @@ -7,6 +7,7 @@ General utility functions for buffers. -/ import data.array.lemmas import control.traversable.instances +import control.traversable.equiv namespace buffer diff --git a/src/data/hash_map.lean b/src/data/hash_map.lean index e51219833c6c8..e9293d372477a 100644 --- a/src/data/hash_map.lean +++ b/src/data/hash_map.lean @@ -6,6 +6,7 @@ Authors: Leonardo de Moura, Mario Carneiro import data.array.lemmas import data.list.join import data.list.range +import data.list.nodup import data.pnat.defs /-! diff --git a/src/field_theory/galois.lean b/src/field_theory/galois.lean index c760d259fb005..f818b32d57dba 100644 --- a/src/field_theory/galois.lean +++ b/src/field_theory/galois.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Thomas Browning, Patrick Lutz -/ -import field_theory.is_alg_closed.algebraic_closure import field_theory.primitive_element import field_theory.fixed import group_theory.group_action.fixing_subgroup diff --git a/src/field_theory/minpoly/basic.lean b/src/field_theory/minpoly/basic.lean index fd66cfcd422f6..1538c6bad695a 100644 --- a/src/field_theory/minpoly/basic.lean +++ b/src/field_theory/minpoly/basic.lean @@ -3,7 +3,6 @@ Copyright (c) 2019 Chris Hughes. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Hughes, Johan Commelin -/ -import data.polynomial.field_division import ring_theory.integral_closure /-! diff --git a/src/field_theory/minpoly/is_integrally_closed.lean b/src/field_theory/minpoly/is_integrally_closed.lean index 8351ee5ba343f..837cc2ad4face 100644 --- a/src/field_theory/minpoly/is_integrally_closed.lean +++ b/src/field_theory/minpoly/is_integrally_closed.lean @@ -3,7 +3,6 @@ Copyright (c) 2019 Riccardo Brasca. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Riccardo Brasca, Paul Lezeau, Junyan Xu -/ -import data.polynomial.field_division import ring_theory.adjoin_root import field_theory.minpoly.field import ring_theory.polynomial.gauss_lemma diff --git a/src/geometry/euclidean/angle/oriented/basic.lean b/src/geometry/euclidean/angle/oriented/basic.lean index 1a588447295da..34957f68fe9b2 100644 --- a/src/geometry/euclidean/angle/oriented/basic.lean +++ b/src/geometry/euclidean/angle/oriented/basic.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Joseph Myers, Heather Macbeth -/ import analysis.inner_product_space.two_dim -import analysis.special_functions.complex.circle import geometry.euclidean.angle.unoriented.basic /-! diff --git a/src/geometry/euclidean/angle/oriented/rotation.lean b/src/geometry/euclidean/angle/oriented/rotation.lean index 0b2e8d1bbb0ee..890777df7fb5f 100644 --- a/src/geometry/euclidean/angle/oriented/rotation.lean +++ b/src/geometry/euclidean/angle/oriented/rotation.lean @@ -3,6 +3,7 @@ Copyright (c) 2022 Joseph Myers. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joseph Myers, Heather Macbeth -/ +import analysis.special_functions.complex.circle import geometry.euclidean.angle.oriented.basic /-! diff --git a/src/linear_algebra/bilinear_form.lean b/src/linear_algebra/bilinear_form.lean index c87fd45ebb10e..8befd53e09164 100644 --- a/src/linear_algebra/bilinear_form.lean +++ b/src/linear_algebra/bilinear_form.lean @@ -6,7 +6,6 @@ Authors: Andreas Swerdlow, Kexing Ying import linear_algebra.dual import linear_algebra.free_module.finite.matrix -import linear_algebra.matrix.to_lin /-! # Bilinear form diff --git a/src/linear_algebra/bilinear_form/tensor_product.lean b/src/linear_algebra/bilinear_form/tensor_product.lean index fb28fadf3d5d4..97fdc9fcd996f 100644 --- a/src/linear_algebra/bilinear_form/tensor_product.lean +++ b/src/linear_algebra/bilinear_form/tensor_product.lean @@ -5,7 +5,6 @@ Authors: Eric Wieser -/ import linear_algebra.bilinear_form import linear_algebra.tensor_product -import linear_algebra.contraction /-! # The bilinear form on a tensor product diff --git a/src/linear_algebra/eigenspace.lean b/src/linear_algebra/eigenspace.lean index f1551a369b413..1ea0617830ae5 100644 --- a/src/linear_algebra/eigenspace.lean +++ b/src/linear_algebra/eigenspace.lean @@ -6,7 +6,6 @@ Authors: Alexander Bentkamp import algebra.algebra.spectrum import order.hom.basic -import linear_algebra.free_module.finite.basic import linear_algebra.general_linear_group /-! diff --git a/src/measure_theory/integral/interval_integral.lean b/src/measure_theory/integral/interval_integral.lean index 4b7abf014c516..15062741e82dc 100644 --- a/src/measure_theory/integral/interval_integral.lean +++ b/src/measure_theory/integral/interval_integral.lean @@ -5,7 +5,7 @@ Authors: Yury G. Kudryashov, Patrick Massot, Sébastien Gouëzel -/ import data.set.intervals.disjoint import measure_theory.integral.set_integral -import measure_theory.measure.haar_lebesgue +import measure_theory.measure.lebesgue /-! # Integral over an interval diff --git a/src/measure_theory/integral/periodic.lean b/src/measure_theory/integral/periodic.lean index c93969a6b5810..288be8f6d012a 100644 --- a/src/measure_theory/integral/periodic.lean +++ b/src/measure_theory/integral/periodic.lean @@ -3,6 +3,7 @@ Copyright (c) 2021 Yury Kudryashov. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Yury Kudryashov, Alex Kontorovich, Heather Macbeth -/ +import measure_theory.measure.haar_lebesgue import measure_theory.measure.haar_quotient import measure_theory.integral.interval_integral import topology.algebra.order.floor diff --git a/src/measure_theory/measure/complex_lebesgue.lean b/src/measure_theory/measure/complex_lebesgue.lean index dc00eaa45138e..07066e07eec81 100644 --- a/src/measure_theory/measure/complex_lebesgue.lean +++ b/src/measure_theory/measure/complex_lebesgue.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Yury Kudryashov -/ import measure_theory.measure.lebesgue +import measure_theory.measure.haar_of_basis /-! # Lebesgue measure on `ℂ` diff --git a/src/measure_theory/measure/haar_of_basis.lean b/src/measure_theory/measure/haar_of_basis.lean index ed046f5070061..dfbf34e1b7ff7 100644 --- a/src/measure_theory/measure/haar_of_basis.lean +++ b/src/measure_theory/measure/haar_of_basis.lean @@ -5,7 +5,6 @@ Authors: Sébastien Gouëzel -/ import measure_theory.measure.haar import analysis.inner_product_space.pi_L2 -import measure_theory.constructions.pi /-! # Additive Haar measure constructed from a basis diff --git a/src/measure_theory/measure/probability_measure.lean b/src/measure_theory/measure/probability_measure.lean index b56872b82a18a..8e79c08d4f447 100644 --- a/src/measure_theory/measure/probability_measure.lean +++ b/src/measure_theory/measure/probability_measure.lean @@ -5,7 +5,6 @@ Authors: Kalle Kytölä -/ import measure_theory.measure.finite_measure import measure_theory.integral.average -import probability.conditional_probability /-! # Probability measures diff --git a/src/measure_theory/tactic.lean b/src/measure_theory/tactic.lean index 55bccc36e39fb..8cc6cb66f517f 100644 --- a/src/measure_theory/tactic.lean +++ b/src/measure_theory/tactic.lean @@ -7,6 +7,7 @@ import measure_theory.measure.measure_space_def import tactic.auto_cases import tactic.tidy import tactic.with_local_reducibility + /-! # Tactics for measure theory diff --git a/src/number_theory/cyclotomic/basic.lean b/src/number_theory/cyclotomic/basic.lean index 2d936346d0181..05c071519e7f2 100644 --- a/src/number_theory/cyclotomic/basic.lean +++ b/src/number_theory/cyclotomic/basic.lean @@ -3,10 +3,8 @@ Copyright (c) 2021 Riccardo Brasca. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Riccardo Brasca -/ - import ring_theory.polynomial.cyclotomic.basic import number_theory.number_field.basic -import algebra.char_p.algebra import field_theory.galois /-! diff --git a/src/number_theory/diophantine_approximation.lean b/src/number_theory/diophantine_approximation.lean index b3bf3e84d7cce..0eb722539cf24 100644 --- a/src/number_theory/diophantine_approximation.lean +++ b/src/number_theory/diophantine_approximation.lean @@ -5,7 +5,6 @@ Authors: Michael Geißer, Michael Stoll -/ import tactic.basic import data.real.irrational -import combinatorics.pigeonhole /-! # Diophantine Approximation diff --git a/src/number_theory/kummer_dedekind.lean b/src/number_theory/kummer_dedekind.lean index b15acf6f64974..0ee9f05a5c58d 100644 --- a/src/number_theory/kummer_dedekind.lean +++ b/src/number_theory/kummer_dedekind.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Anne Baanen, Paul Lezeau -/ -import ring_theory.algebra_tower import ring_theory.dedekind_domain.ideal import ring_theory.is_adjoin_root diff --git a/src/number_theory/legendre_symbol/mul_character.lean b/src/number_theory/legendre_symbol/mul_character.lean index 648797dd56d15..e3c827cc2fb1b 100644 --- a/src/number_theory/legendre_symbol/mul_character.lean +++ b/src/number_theory/legendre_symbol/mul_character.lean @@ -5,7 +5,7 @@ Authors: Michael Stoll -/ import algebra.char_p.basic import algebra.euclidean_domain.instances -import algebra.group.conj_finite +import data.fintype.units /-! # Multiplicative characters of finite rings and fields diff --git a/src/number_theory/modular_forms/jacobi_theta.lean b/src/number_theory/modular_forms/jacobi_theta.lean index 3711225ad9523..dd6578c6a37ae 100644 --- a/src/number_theory/modular_forms/jacobi_theta.lean +++ b/src/number_theory/modular_forms/jacobi_theta.lean @@ -3,10 +3,10 @@ Copyright (c) 2023 David Loeffler. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: David Loeffler -/ -import number_theory.modular_forms.basic import analysis.special_functions.gaussian -import analysis.calculus.series import analysis.complex.locally_uniform_limit +import analysis.complex.upper_half_plane.functions_bounded_at_infty +import analysis.complex.upper_half_plane.topology /-! # Jacobi's theta function diff --git a/src/number_theory/number_field/basic.lean b/src/number_theory/number_field/basic.lean index 0344e0afbced0..537628af9ebf9 100644 --- a/src/number_theory/number_field/basic.lean +++ b/src/number_theory/number_field/basic.lean @@ -3,7 +3,6 @@ Copyright (c) 2021 Ashvni Narayanan. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Ashvni Narayanan, Anne Baanen -/ - import algebra.char_p.algebra import ring_theory.dedekind_domain.integral_closure diff --git a/src/number_theory/padics/padic_integers.lean b/src/number_theory/padics/padic_integers.lean index 83af846ac091a..aac1d3115ce20 100644 --- a/src/number_theory/padics/padic_integers.lean +++ b/src/number_theory/padics/padic_integers.lean @@ -5,7 +5,6 @@ Authors: Robert Y. Lewis, Mario Carneiro, Johan Commelin -/ import number_theory.padics.padic_numbers import ring_theory.discrete_valuation_ring.basic -import topology.metric_space.cau_seq_filter /-! # p-adic integers diff --git a/src/number_theory/primes_congruent_one.lean b/src/number_theory/primes_congruent_one.lean index 98cb1db00ec5d..21e0107bb3e66 100644 --- a/src/number_theory/primes_congruent_one.lean +++ b/src/number_theory/primes_congruent_one.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Riccardo Brasca -/ -import data.nat.prime_fin import ring_theory.polynomial.cyclotomic.eval /-! diff --git a/src/number_theory/well_approximable.lean b/src/number_theory/well_approximable.lean index 05e5a4fc84720..93e703e48f198 100644 --- a/src/number_theory/well_approximable.lean +++ b/src/number_theory/well_approximable.lean @@ -5,7 +5,6 @@ Authors: Oliver Nash -/ import dynamics.ergodic.add_circle import measure_theory.covering.liminf_limsup -import data.nat.totient /-! # Well-approximable numbers and Gallagher's ergodic theorem diff --git a/src/number_theory/zeta_values.lean b/src/number_theory/zeta_values.lean index 9f3340f03eb37..bb90b628f09d4 100644 --- a/src/number_theory/zeta_values.lean +++ b/src/number_theory/zeta_values.lean @@ -5,12 +5,10 @@ Authors: David Loeffler -/ import number_theory.bernoulli_polynomials -import analysis.special_functions.integrals import measure_theory.integral.interval_integral import analysis.fourier.add_circle import analysis.p_series - /-! # Critical values of the Riemann zeta function diff --git a/src/probability/density.lean b/src/probability/density.lean index 5545c5925759d..2e622d3848004 100644 --- a/src/probability/density.lean +++ b/src/probability/density.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Kexing Ying -/ import measure_theory.decomposition.radon_nikodym -import measure_theory.measure.lebesgue +import measure_theory.measure.haar_of_basis /-! # Probability density function diff --git a/src/probability/variance.lean b/src/probability/variance.lean index ce7e4589021ff..a0b0c08c87d91 100644 --- a/src/probability/variance.lean +++ b/src/probability/variance.lean @@ -5,6 +5,7 @@ Authors: Sébastien Gouëzel, Kexing Ying -/ import probability.notation import probability.integration +import measure_theory.function.l2_space /-! # Variance of random variables diff --git a/src/ring_theory/dedekind_domain/adic_valuation.lean b/src/ring_theory/dedekind_domain/adic_valuation.lean index 2dfb9e9d972a8..86e0bac6f8b44 100644 --- a/src/ring_theory/dedekind_domain/adic_valuation.lean +++ b/src/ring_theory/dedekind_domain/adic_valuation.lean @@ -6,8 +6,8 @@ Authors: María Inés de Frutos-Fernández import ring_theory.dedekind_domain.ideal import ring_theory.valuation.extend_to_localization import ring_theory.valuation.valuation_subring -import ring_theory.polynomial.cyclotomic.basic import topology.algebra.valued_field +import algebra.order.group.type_tags /-! # Adic valuations on Dedekind domains diff --git a/src/ring_theory/dedekind_domain/dvr.lean b/src/ring_theory/dedekind_domain/dvr.lean index 64659de77d46e..62b3fd3e1307b 100644 --- a/src/ring_theory/dedekind_domain/dvr.lean +++ b/src/ring_theory/dedekind_domain/dvr.lean @@ -3,11 +3,9 @@ Copyright (c) 2020 Kenji Nakagawa. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kenji Nakagawa, Anne Baanen, Filippo A. E. Nuccio -/ -import ring_theory.dedekind_domain.ideal -import ring_theory.discrete_valuation_ring.tfae -import ring_theory.localization.at_prime +import ring_theory.localization.localization_localization import ring_theory.localization.submodule - +import ring_theory.discrete_valuation_ring.tfae /-! # Dedekind domains diff --git a/src/ring_theory/dedekind_domain/finite_adele_ring.lean b/src/ring_theory/dedekind_domain/finite_adele_ring.lean index 48c95752f18df..8c599af57d482 100644 --- a/src/ring_theory/dedekind_domain/finite_adele_ring.lean +++ b/src/ring_theory/dedekind_domain/finite_adele_ring.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: María Inés de Frutos-Fernández -/ import ring_theory.dedekind_domain.adic_valuation -import topology.algebra.uniform_ring /-! diff --git a/src/ring_theory/discrete_valuation_ring/tfae.lean b/src/ring_theory/discrete_valuation_ring/tfae.lean index 0981915865428..bae86b2c29902 100644 --- a/src/ring_theory/discrete_valuation_ring/tfae.lean +++ b/src/ring_theory/discrete_valuation_ring/tfae.lean @@ -7,6 +7,7 @@ import ring_theory.ideal.cotangent import ring_theory.dedekind_domain.basic import ring_theory.valuation.valuation_ring import ring_theory.nakayama + /-! # Equivalent conditions for DVR diff --git a/src/ring_theory/ideal/associated_prime.lean b/src/ring_theory/ideal/associated_prime.lean index c85ea9e010818..db5a3e4f96180 100644 --- a/src/ring_theory/ideal/associated_prime.lean +++ b/src/ring_theory/ideal/associated_prime.lean @@ -5,9 +5,8 @@ Authors: Andrew Yang -/ import linear_algebra.span import ring_theory.ideal.operations -import ring_theory.finiteness -import ring_theory.localization.ideal -import ring_theory.ideal.minimal_prime +import ring_theory.ideal.quotient_operations +import ring_theory.noetherian /-! diff --git a/src/ring_theory/ideal/norm.lean b/src/ring_theory/ideal/norm.lean index 5311fe018ee5b..b0e0cdd6fcd75 100644 --- a/src/ring_theory/ideal/norm.lean +++ b/src/ring_theory/ideal/norm.lean @@ -8,7 +8,6 @@ import algebra.char_p.quotient import data.finsupp.fintype import data.int.absolute_value import data.int.associated -import number_theory.ramification_inertia import linear_algebra.free_module.determinant import linear_algebra.free_module.ideal_quotient import ring_theory.dedekind_domain.pid diff --git a/src/ring_theory/nakayama.lean b/src/ring_theory/nakayama.lean index 58714ac589368..e1ee04629f7c5 100644 --- a/src/ring_theory/nakayama.lean +++ b/src/ring_theory/nakayama.lean @@ -3,8 +3,8 @@ Copyright (c) 2021 Chris Hughes. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Hughes -/ -import ring_theory.noetherian import ring_theory.jacobson_ideal + /-! # Nakayama's lemma diff --git a/src/ring_theory/polynomial/gauss_lemma.lean b/src/ring_theory/polynomial/gauss_lemma.lean index 6df229789277c..427d8cca5a60d 100644 --- a/src/ring_theory/polynomial/gauss_lemma.lean +++ b/src/ring_theory/polynomial/gauss_lemma.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Aaron Anderson -/ import ring_theory.int.basic -import field_theory.splitting_field import ring_theory.localization.integral import ring_theory.integrally_closed diff --git a/src/topology/algebra/nonarchimedean/adic_topology.lean b/src/topology/algebra/nonarchimedean/adic_topology.lean index c5382d5f73c57..e72e630fc6767 100644 --- a/src/topology/algebra/nonarchimedean/adic_topology.lean +++ b/src/topology/algebra/nonarchimedean/adic_topology.lean @@ -6,7 +6,9 @@ Authors: Patrick Massot import ring_theory.ideal.operations import topology.algebra.nonarchimedean.bases +import topology.uniform_space.completion import topology.algebra.uniform_ring + /-! # Adic topology diff --git a/src/topology/instances/add_circle.lean b/src/topology/instances/add_circle.lean index 944ff5878b3b9..145643fd5f7a2 100644 --- a/src/topology/instances/add_circle.lean +++ b/src/topology/instances/add_circle.lean @@ -7,7 +7,6 @@ import data.nat.totient import algebra.ring.add_aut import group_theory.divisible import group_theory.order_of_element -import ring_theory.int.basic import algebra.order.floor import algebra.order.to_interval_mod import topology.instances.real diff --git a/src/topology/instances/complex.lean b/src/topology/instances/complex.lean index 5b88f2cf55212..bf183b83e7a88 100644 --- a/src/topology/instances/complex.lean +++ b/src/topology/instances/complex.lean @@ -4,9 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Xavier Roblot -/ -import topology.algebra.uniform_field import analysis.complex.basic -import field_theory.adjoin +import field_theory.intermediate_field +import topology.algebra.uniform_ring /-! # Some results about the topology of ℂ From aa1dbeab548d61bc840a099abae4437046eaaf00 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Thu, 4 May 2023 03:36:49 +0000 Subject: [PATCH 07/17] chore(analysis/normed_space/extend): golf, add aux lemmas (#18927) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add `linear_map.extend_to_𝕜'_apply_re`, `linear_map.sq_norm_extend_to_𝕜'_apply`, `continuous_linear_map.norm_extend_to_𝕜`, and `continuous_linear_map.norm_extend_to_𝕜'`. * Rename `norm_bound` to `continuous_linear_map.norm_extend_to_𝕜'_bound`. * Golf, use `namespace`s. --- src/analysis/normed_space/extend.lean | 89 ++++++++++--------- .../normed_space/hahn_banach/extension.lean | 2 +- 2 files changed, 47 insertions(+), 44 deletions(-) diff --git a/src/analysis/normed_space/extend.lean b/src/analysis/normed_space/extend.lean index f0a198fc8ed45..bc01ce94c0d2b 100644 --- a/src/analysis/normed_space/extend.lean +++ b/src/analysis/normed_space/extend.lean @@ -32,14 +32,17 @@ Alternate forms which operate on `[is_scalar_tower ℝ 𝕜 F]` instead are prov -/ open is_R_or_C +open_locale complex_conjugate variables {𝕜 : Type*} [is_R_or_C 𝕜] {F : Type*} [seminormed_add_comm_group F] [normed_space 𝕜 F] -local notation `abs𝕜` := @is_R_or_C.abs 𝕜 _ + +namespace linear_map + +variables [module ℝ F] [is_scalar_tower ℝ 𝕜 F] /-- Extend `fr : F →ₗ[ℝ] ℝ` to `F →ₗ[𝕜] 𝕜` in a way that will also be continuous and have its norm bounded by `‖fr‖` if `fr` is continuous. -/ -noncomputable def linear_map.extend_to_𝕜' - [module ℝ F] [is_scalar_tower ℝ 𝕜 F] (fr : F →ₗ[ℝ] ℝ) : F →ₗ[𝕜] 𝕜 := +noncomputable def extend_to_𝕜' (fr : F →ₗ[ℝ] ℝ) : F →ₗ[𝕜] 𝕜 := begin let fc : F → 𝕜 := λ x, (fr x : 𝕜) - (I : 𝕜) * (fr ((I : 𝕜) • x)), have add : ∀ x y : F, fc (x + y) = fc x + fc y, @@ -73,61 +76,57 @@ begin exact { to_fun := fc, map_add' := add, map_smul' := smul_𝕜 } end -lemma linear_map.extend_to_𝕜'_apply [module ℝ F] [is_scalar_tower ℝ 𝕜 F] - (fr : F →ₗ[ℝ] ℝ) (x : F) : +lemma extend_to_𝕜'_apply (fr : F →ₗ[ℝ] ℝ) (x : F) : fr.extend_to_𝕜' x = (fr x : 𝕜) - (I : 𝕜) * fr ((I : 𝕜) • x) := rfl +@[simp] lemma extend_to_𝕜'_apply_re (fr : F →ₗ[ℝ] ℝ) (x : F) : re (fr.extend_to_𝕜' x : 𝕜) = fr x := +by simp only [extend_to_𝕜'_apply, map_sub, zero_mul, mul_zero, sub_zero] with is_R_or_C_simps + +lemma norm_extend_to_𝕜'_apply_sq (f : F →ₗ[ℝ] ℝ) (x : F) : + ‖(f.extend_to_𝕜' x : 𝕜)‖ ^ 2 = f (conj (f.extend_to_𝕜' x : 𝕜) • x) := +calc ‖(f.extend_to_𝕜' x : 𝕜)‖ ^ 2 = re (conj (f.extend_to_𝕜' x) * f.extend_to_𝕜' x : 𝕜) : + by rw [is_R_or_C.conj_mul_eq_norm_sq_left, norm_sq_eq_def', of_real_re] +... = f (conj (f.extend_to_𝕜' x : 𝕜) • x) : + by rw [← smul_eq_mul, ← map_smul, extend_to_𝕜'_apply_re] + +end linear_map + +namespace continuous_linear_map + +variables [normed_space ℝ F] [is_scalar_tower ℝ 𝕜 F] + /-- The norm of the extension is bounded by `‖fr‖`. -/ -lemma norm_bound [normed_space ℝ F] [is_scalar_tower ℝ 𝕜 F] (fr : F →L[ℝ] ℝ) (x : F) : +lemma norm_extend_to_𝕜'_bound (fr : F →L[ℝ] ℝ) (x : F) : ‖(fr.to_linear_map.extend_to_𝕜' x : 𝕜)‖ ≤ ‖fr‖ * ‖x‖ := begin - let lm : F →ₗ[𝕜] 𝕜 := fr.to_linear_map.extend_to_𝕜', - -- We aim to find a `t : 𝕜` such that - -- * `lm (t • x) = fr (t • x)` (so `lm (t • x) = t * lm x ∈ ℝ`) - -- * `‖lm x‖ = ‖lm (t • x)‖` (so `t.abs` must be 1) - -- If `lm x ≠ 0`, `(lm x)⁻¹` satisfies the first requirement, and after normalizing, it - -- satisfies the second. - -- (If `lm x = 0`, the goal is trivial.) + set lm : F →ₗ[𝕜] 𝕜 := fr.to_linear_map.extend_to_𝕜', classical, by_cases h : lm x = 0, { rw [h, norm_zero], apply mul_nonneg; exact norm_nonneg _ }, - let fx := (lm x)⁻¹, - let t := fx / (abs𝕜 fx : 𝕜), - have ht : abs𝕜 t = 1, by field_simp [abs_of_real, of_real_inv, is_R_or_C.abs_inv, - is_R_or_C.abs_div, is_R_or_C.abs_abs, h], - have h1 : (fr (t • x) : 𝕜) = lm (t • x), - { apply ext, - { simp only [lm, of_real_re, linear_map.extend_to_𝕜'_apply, mul_re, I_re, of_real_im, zero_mul, - add_monoid_hom.map_sub, sub_zero, mul_zero], - refl }, - { symmetry, - calc im (lm (t • x)) - = im (t * lm x) : by rw [lm.map_smul, smul_eq_mul] - ... = im ((lm x)⁻¹ / (abs𝕜 (lm x)⁻¹) * lm x) : rfl - ... = im (1 / (abs𝕜 (lm x)⁻¹ : 𝕜)) : by rw [div_mul_eq_mul_div, inv_mul_cancel h] - ... = 0 : by rw [← of_real_one, ← of_real_div, of_real_im] - ... = im (fr (t • x) : 𝕜) : by rw [of_real_im] } }, - calc ‖lm x‖ = abs𝕜 t * ‖lm x‖ : by rw [ht, one_mul] - ... = ‖t * lm x‖ : by rw [← norm_eq_abs, norm_mul] - ... = ‖lm (t • x)‖ : by rw [←smul_eq_mul, lm.map_smul] - ... = ‖(fr (t • x) : 𝕜)‖ : by rw h1 - ... = ‖fr (t • x)‖ : by rw [norm_eq_abs, abs_of_real, norm_eq_abs, abs_to_real] - ... ≤ ‖fr‖ * ‖t • x‖ : continuous_linear_map.le_op_norm _ _ - ... = ‖fr‖ * (‖t‖ * ‖x‖) : by rw norm_smul - ... ≤ ‖fr‖ * ‖x‖ : by rw [norm_eq_abs, ht, one_mul] + rw [← mul_le_mul_left (norm_pos_iff.2 h), ← sq], + calc ‖lm x‖ ^ 2 = fr (conj (lm x : 𝕜) • x) : fr.to_linear_map.norm_extend_to_𝕜'_apply_sq x + ... ≤ ‖fr (conj (lm x : 𝕜) • x)‖ : le_abs_self _ + ... ≤ ‖fr‖ * ‖conj (lm x : 𝕜) • x‖ : le_op_norm _ _ + ... = ‖(lm x : 𝕜)‖ * (‖fr‖ * ‖x‖) : by rw [norm_smul, norm_conj, mul_left_comm] end /-- Extend `fr : F →L[ℝ] ℝ` to `F →L[𝕜] 𝕜`. -/ -noncomputable def continuous_linear_map.extend_to_𝕜' [normed_space ℝ F] [is_scalar_tower ℝ 𝕜 F] - (fr : F →L[ℝ] ℝ) : - F →L[𝕜] 𝕜 := -linear_map.mk_continuous _ (‖fr‖) (norm_bound _) +noncomputable def extend_to_𝕜' (fr : F →L[ℝ] ℝ) : F →L[𝕜] 𝕜 := +linear_map.mk_continuous _ (‖fr‖) fr.norm_extend_to_𝕜'_bound -lemma continuous_linear_map.extend_to_𝕜'_apply [normed_space ℝ F] [is_scalar_tower ℝ 𝕜 F] - (fr : F →L[ℝ] ℝ) (x : F) : +lemma extend_to_𝕜'_apply (fr : F →L[ℝ] ℝ) (x : F) : fr.extend_to_𝕜' x = (fr x : 𝕜) - (I : 𝕜) * fr ((I : 𝕜) • x) := rfl +@[simp] lemma norm_extend_to_𝕜' (fr : F →L[ℝ] ℝ) : ‖(fr.extend_to_𝕜' : F →L[𝕜] 𝕜)‖ = ‖fr‖ := +le_antisymm (linear_map.mk_continuous_norm_le _ (norm_nonneg _) _) $ + op_norm_le_bound _ (norm_nonneg _) $ λ x, + calc ‖fr x‖ = ‖re (fr.extend_to_𝕜' x : 𝕜)‖ : congr_arg norm (fr.extend_to_𝕜'_apply_re x).symm + ... ≤ ‖(fr.extend_to_𝕜' x : 𝕜)‖ : (abs_re_le_abs _).trans_eq (norm_eq_abs _).symm + ... ≤ ‖(fr.extend_to_𝕜' : F →L[𝕜] 𝕜)‖ * ‖x‖ : le_op_norm _ _ + +end continuous_linear_map + /-- Extend `fr : restrict_scalars ℝ 𝕜 F →ₗ[ℝ] ℝ` to `F →ₗ[𝕜] 𝕜`. -/ noncomputable def linear_map.extend_to_𝕜 (fr : (restrict_scalars ℝ 𝕜 F) →ₗ[ℝ] ℝ) : F →ₗ[𝕜] 𝕜 := fr.extend_to_𝕜' @@ -142,3 +141,7 @@ fr.extend_to_𝕜' lemma continuous_linear_map.extend_to_𝕜_apply (fr : (restrict_scalars ℝ 𝕜 F) →L[ℝ] ℝ) (x : F) : fr.extend_to_𝕜 x = (fr x : 𝕜) - (I : 𝕜) * fr ((I : 𝕜) • x : _) := rfl + +@[simp] lemma continuous_linear_map.norm_extend_to_𝕜 (fr : (restrict_scalars ℝ 𝕜 F) →L[ℝ] ℝ) : + ‖fr.extend_to_𝕜‖ = ‖fr‖ := +fr.norm_extend_to_𝕜' diff --git a/src/analysis/normed_space/hahn_banach/extension.lean b/src/analysis/normed_space/hahn_banach/extension.lean index 74898d0c531ca..80ab1610e970d 100644 --- a/src/analysis/normed_space/hahn_banach/extension.lean +++ b/src/analysis/normed_space/hahn_banach/extension.lean @@ -92,7 +92,7 @@ begin -- And we derive the equality of the norms by bounding on both sides. refine ⟨h, le_antisymm _ _⟩, { calc ‖g.extend_to_𝕜‖ - ≤ ‖g‖ : g.extend_to_𝕜.op_norm_le_bound g.op_norm_nonneg (norm_bound _) + = ‖g‖ : g.norm_extend_to_𝕜 ... = ‖fr‖ : hnormeq ... ≤ ‖re_clm‖ * ‖f‖ : continuous_linear_map.op_norm_comp_le _ _ ... = ‖f‖ : by rw [re_clm_norm, one_mul] }, From fe8d0ff42c3c24d789f491dc2622b6cac3d61564 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 4 May 2023 07:52:13 +0000 Subject: [PATCH 08/17] chore(*): add mathlib4 synchronization comments (#18923) Regenerated from the [port status wiki page](https://github.com/leanprover-community/mathlib/wiki/mathlib4-port-status). Relates to the following files: * `algebra.continued_fractions.basic` * `analysis.convex.complex` * `analysis.special_functions.trigonometric.chebyshev` * `category_theory.category.Groupoid` * `category_theory.functor.left_derived` * `category_theory.monoidal.free.basic` * `category_theory.monoidal.tor` * `category_theory.sites.left_exact` * `data.complex.determinant` * `data.complex.module` * `data.matrix.rank` * `linear_algebra.affine_space.finite_dimensional` * `linear_algebra.affine_space.matrix` * `linear_algebra.determinant` * `linear_algebra.free_module.determinant` * `measure_theory.measure.outer_measure` * `ring_theory.localization.inv_submonoid` * `topology.algebra.module.determinant` --- src/algebra/continued_fractions/basic.lean | 3 +++ src/analysis/convex/complex.lean | 3 +++ src/analysis/special_functions/trigonometric/chebyshev.lean | 3 +++ src/category_theory/category/Groupoid.lean | 3 +++ src/category_theory/functor/left_derived.lean | 3 +++ src/category_theory/monoidal/free/basic.lean | 3 +++ src/category_theory/monoidal/tor.lean | 3 +++ src/category_theory/sites/left_exact.lean | 3 +++ src/data/complex/determinant.lean | 3 +++ src/data/complex/module.lean | 3 +++ src/data/matrix/rank.lean | 3 +++ src/linear_algebra/affine_space/finite_dimensional.lean | 3 +++ src/linear_algebra/affine_space/matrix.lean | 3 +++ src/linear_algebra/determinant.lean | 3 +++ src/linear_algebra/free_module/determinant.lean | 3 +++ src/measure_theory/measure/outer_measure.lean | 3 +++ src/ring_theory/localization/inv_submonoid.lean | 3 +++ src/topology/algebra/module/determinant.lean | 3 +++ 18 files changed, 54 insertions(+) diff --git a/src/algebra/continued_fractions/basic.lean b/src/algebra/continued_fractions/basic.lean index dfb55dd60930f..8c04dd961e079 100644 --- a/src/algebra/continued_fractions/basic.lean +++ b/src/algebra/continued_fractions/basic.lean @@ -8,6 +8,9 @@ import algebra.field.defs /-! # Basic Definitions/Theorems for Continued Fractions +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + ## Summary We define generalised, simple, and regular continued fractions and functions to evaluate their diff --git a/src/analysis/convex/complex.lean b/src/analysis/convex/complex.lean index d22d1c1b96700..58d32f143c96d 100644 --- a/src/analysis/convex/complex.lean +++ b/src/analysis/convex/complex.lean @@ -9,6 +9,9 @@ import data.complex.module /-! # Convexity of half spaces in ℂ +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + The open and closed half-spaces in ℂ given by an inequality on either the real or imaginary part are all convex over ℝ. -/ diff --git a/src/analysis/special_functions/trigonometric/chebyshev.lean b/src/analysis/special_functions/trigonometric/chebyshev.lean index ea96d6f5337d2..f35d08a9a9f50 100644 --- a/src/analysis/special_functions/trigonometric/chebyshev.lean +++ b/src/analysis/special_functions/trigonometric/chebyshev.lean @@ -11,6 +11,9 @@ import ring_theory.polynomial.chebyshev /-! # Multiple angle formulas in terms of Chebyshev polynomials +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + This file gives the trigonometric characterizations of Chebyshev polynomials, for both the real (`real.cos`) and complex (`complex.cos`) cosine. -/ diff --git a/src/category_theory/category/Groupoid.lean b/src/category_theory/category/Groupoid.lean index 2d6b843ef1af2..cac379bf9cb22 100644 --- a/src/category_theory/category/Groupoid.lean +++ b/src/category_theory/category/Groupoid.lean @@ -11,6 +11,9 @@ import category_theory.limits.is_limit /-! # Category of groupoids +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + This file contains the definition of the category `Groupoid` of all groupoids. In this category objects are groupoids and morphisms are functors between these groupoids. diff --git a/src/category_theory/functor/left_derived.lean b/src/category_theory/functor/left_derived.lean index b8df704a33603..8f8f9baf18c76 100644 --- a/src/category_theory/functor/left_derived.lean +++ b/src/category_theory/functor/left_derived.lean @@ -8,6 +8,9 @@ import category_theory.preadditive.projective_resolution /-! # Left-derived functors +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + We define the left-derived functors `F.left_derived n : C ⥤ D` for any additive functor `F` out of a category with projective resolutions. diff --git a/src/category_theory/monoidal/free/basic.lean b/src/category_theory/monoidal/free/basic.lean index dd133c7f02b1b..e3f694775af00 100644 --- a/src/category_theory/monoidal/free/basic.lean +++ b/src/category_theory/monoidal/free/basic.lean @@ -8,6 +8,9 @@ import category_theory.monoidal.functor /-! # The free monoidal category over a type +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + Given a type `C`, the free monoidal category over `C` has as objects formal expressions built from (formal) tensor products of terms of `C` and a formal unit. Its morphisms are compositions and tensor products of identities, unitors and associators. diff --git a/src/category_theory/monoidal/tor.lean b/src/category_theory/monoidal/tor.lean index 446ae7890eff0..9ea38314c8550 100644 --- a/src/category_theory/monoidal/tor.lean +++ b/src/category_theory/monoidal/tor.lean @@ -9,6 +9,9 @@ import category_theory.monoidal.preadditive /-! # Tor, the left-derived functor of tensor product +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + We define `Tor C n : C ⥤ C ⥤ C`, by left-deriving in the second factor of `(X, Y) ↦ X ⊗ Y`. For now we have almost nothing to say about it! diff --git a/src/category_theory/sites/left_exact.lean b/src/category_theory/sites/left_exact.lean index 74b59a7f4d69a..7288d49ba3824 100644 --- a/src/category_theory/sites/left_exact.lean +++ b/src/category_theory/sites/left_exact.lean @@ -10,6 +10,9 @@ import category_theory.limits.filtered_colimit_commutes_finite_limit /-! # Left exactness of sheafification + +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. In this file we show that sheafification commutes with finite limits. -/ diff --git a/src/data/complex/determinant.lean b/src/data/complex/determinant.lean index 931e201d17f4f..331fdff1eb76b 100644 --- a/src/data/complex/determinant.lean +++ b/src/data/complex/determinant.lean @@ -9,6 +9,9 @@ import linear_algebra.determinant /-! # Determinants of maps in the complex numbers as a vector space over `ℝ` +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + This file provides results about the determinants of maps in the complex numbers as a vector space over `ℝ`. diff --git a/src/data/complex/module.lean b/src/data/complex/module.lean index b6a04214d576e..cac447e5921fc 100644 --- a/src/data/complex/module.lean +++ b/src/data/complex/module.lean @@ -12,6 +12,9 @@ import algebra.char_p.invertible /-! # Complex number as a vector space over `ℝ` +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + This file contains the following instances: * Any `•`-structure (`has_smul`, `mul_action`, `distrib_mul_action`, `module`, `algebra`) on `ℝ` imbues a corresponding structure on `ℂ`. This includes the statement that `ℂ` is an `ℝ` diff --git a/src/data/matrix/rank.lean b/src/data/matrix/rank.lean index 2caf7ce437817..abf18493118dc 100644 --- a/src/data/matrix/rank.lean +++ b/src/data/matrix/rank.lean @@ -13,6 +13,9 @@ import data.complex.module /-! # Rank of matrices +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + The rank of a matrix `A` is defined to be the rank of range of the linear map corresponding to `A`. This definition does not depend on the choice of basis, see `matrix.rank_eq_finrank_range_to_lin`. diff --git a/src/linear_algebra/affine_space/finite_dimensional.lean b/src/linear_algebra/affine_space/finite_dimensional.lean index 4b009c060e9c8..07ff73f8731ca 100644 --- a/src/linear_algebra/affine_space/finite_dimensional.lean +++ b/src/linear_algebra/affine_space/finite_dimensional.lean @@ -9,6 +9,9 @@ import linear_algebra.finite_dimensional /-! # Finite-dimensional subspaces of affine spaces. +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + This file provides a few results relating to finite-dimensional subspaces of affine spaces. diff --git a/src/linear_algebra/affine_space/matrix.lean b/src/linear_algebra/affine_space/matrix.lean index 799e8203837cc..fd7eb1c686749 100644 --- a/src/linear_algebra/affine_space/matrix.lean +++ b/src/linear_algebra/affine_space/matrix.lean @@ -9,6 +9,9 @@ import linear_algebra.determinant /-! # Matrix results for barycentric co-ordinates +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + Results about the matrix of barycentric co-ordinates for a family of points in an affine space, with respect to some affine basis. -/ diff --git a/src/linear_algebra/determinant.lean b/src/linear_algebra/determinant.lean index c70296ec4e78e..c7a57875c72af 100644 --- a/src/linear_algebra/determinant.lean +++ b/src/linear_algebra/determinant.lean @@ -13,6 +13,9 @@ import linear_algebra.matrix.basis /-! # Determinant of families of vectors +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + This file defines the determinant of an endomorphism, and of a family of vectors with respect to some basis. For the determinant of a matrix, see the file `linear_algebra.matrix.determinant`. diff --git a/src/linear_algebra/free_module/determinant.lean b/src/linear_algebra/free_module/determinant.lean index 326f70dbf3d04..a9bc68de15a2d 100644 --- a/src/linear_algebra/free_module/determinant.lean +++ b/src/linear_algebra/free_module/determinant.lean @@ -10,6 +10,9 @@ import linear_algebra.free_module.finite.basic /-! # Determinants in free (finite) modules +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + Quite a lot of our results on determinants (that you might know in vector spaces) will work for all free (finite) modules over any commutative ring. diff --git a/src/measure_theory/measure/outer_measure.lean b/src/measure_theory/measure/outer_measure.lean index 28fbdf03a3618..e49e132c70227 100644 --- a/src/measure_theory/measure/outer_measure.lean +++ b/src/measure_theory/measure/outer_measure.lean @@ -11,6 +11,9 @@ import data.fin.vec_notation /-! # Outer Measures +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + An outer measure is a function `μ : set α → ℝ≥0∞`, from the powerset of a type to the extended nonnegative real numbers that satisfies the following conditions: 1. `μ ∅ = 0`; diff --git a/src/ring_theory/localization/inv_submonoid.lean b/src/ring_theory/localization/inv_submonoid.lean index d1c056efbe04e..51092aebf7fd4 100644 --- a/src/ring_theory/localization/inv_submonoid.lean +++ b/src/ring_theory/localization/inv_submonoid.lean @@ -11,6 +11,9 @@ import tactic.ring_exp /-! # Submonoid of inverses +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. + ## Main definitions * `is_localization.inv_submonoid M S` is the submonoid of `S = M⁻¹R` consisting of inverses of diff --git a/src/topology/algebra/module/determinant.lean b/src/topology/algebra/module/determinant.lean index e57201fa2bb0c..4613a6f35a2c7 100644 --- a/src/topology/algebra/module/determinant.lean +++ b/src/topology/algebra/module/determinant.lean @@ -9,6 +9,9 @@ import linear_algebra.determinant /-! # The determinant of a continuous linear map. + +> THIS FILE IS SYNCHRONIZED WITH MATHLIB4. +> Any changes to this file require a corresponding PR to mathlib4. -/ namespace continuous_linear_map From 4e529b03dd62b7b7d13806c3fb974d9d4848910e Mon Sep 17 00:00:00 2001 From: Chris Hughes Date: Thu, 4 May 2023 09:41:23 +0000 Subject: [PATCH 09/17] feat(field_theory/ax_grothendieck): Ax-Grothendieck for algebraic extensions of finite fields (#18479) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Chris Hughes <33847686+ChrisHughes24@users.noreply.github.com> Co-authored-by: Yaël Dillies --- src/data/mv_polynomial/basic.lean | 38 +++++++++++++ src/field_theory/ax_grothendieck.lean | 77 +++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 src/field_theory/ax_grothendieck.lean diff --git a/src/data/mv_polynomial/basic.lean b/src/data/mv_polynomial/basic.lean index 1be5b486ae32f..269d6e8156387 100644 --- a/src/data/mv_polynomial/basic.lean +++ b/src/data/mv_polynomial/basic.lean @@ -1297,6 +1297,44 @@ by { ext, simp only [aeval_X, aeval_tower_X] } end aeval_tower +section eval_mem + +variables {S subS : Type*} [comm_semiring S] [set_like subS S] [subsemiring_class subS S] + +theorem eval₂_mem {f : R →+* S} + {p : mv_polynomial σ R} {s : subS} + (hs : ∀ i ∈ p.support, f (p.coeff i) ∈ s) {v : σ → S} (hv : ∀ i, v i ∈ s) : + mv_polynomial.eval₂ f v p ∈ s := +begin + classical, + replace hs : ∀ i, f (p.coeff i) ∈ s, + { intro i, + by_cases hi : i ∈ p.support, + { exact hs i hi }, + { rw [mv_polynomial.not_mem_support_iff.1 hi, f.map_zero], + exact zero_mem s } }, + induction p using mv_polynomial.induction_on''' with a a b f ha hb0 ih generalizing hs, + { simpa using hs 0 }, + rw [eval₂_add, eval₂_monomial], + refine add_mem (mul_mem _ $ prod_mem $ λ i hi, pow_mem (hv _) _) (ih $ λ i, _), + { simpa only [coeff_add, coeff_monomial, if_pos rfl, + mv_polynomial.not_mem_support_iff.1 ha, add_zero] using hs a }, + have := hs i, + rw [coeff_add, coeff_monomial] at this, + split_ifs at this with h h, + { subst h, + rw [mv_polynomial.not_mem_support_iff.1 ha, map_zero], + exact zero_mem _ }, + { rwa zero_add at this } +end + +theorem eval_mem {p : mv_polynomial σ S} {s : subS} + (hs : ∀ i ∈ p.support, p.coeff i ∈ s) {v : σ → S} (hv : ∀ i, v i ∈ s) : + mv_polynomial.eval v p ∈ s := +eval₂_mem hs hv + +end eval_mem + end comm_semiring end mv_polynomial diff --git a/src/field_theory/ax_grothendieck.lean b/src/field_theory/ax_grothendieck.lean new file mode 100644 index 0000000000000..7cec7336d2e9f --- /dev/null +++ b/src/field_theory/ax_grothendieck.lean @@ -0,0 +1,77 @@ +/- +Copyright (c) 2023 Chris Hughes. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Chris Hughes +-/ +import data.mv_polynomial.basic +import ring_theory.algebraic +import data.fintype.card + +/-! +# Ax-Grothendieck for algebraic extensions of `zmod p` + +This file proves that if `R` is an algebraic extension of a finite field, +then any injective polynomial map `R^n -> R^n` is also surjective. + +This proof is required for the true Ax-Grothendieck theorem, which proves the same result +for any algebraically closed field of characteristic zero. + +## TODO + +The proof of the theorem for characteristic zero is not in mathlib, but it is at +https://github.com/Jlh18/ModelTheoryInLean8 +-/ + +noncomputable theory + +open mv_polynomial finset function + +/-- Any injective polynomial map over an algebraic extension of a finite field is surjective. -/ +lemma ax_grothendieck_of_locally_finite {ι K R : Type*} [field K] [finite K] [comm_ring R] + [finite ι] [algebra K R] (alg : algebra.is_algebraic K R) + (ps : ι → mv_polynomial ι R) + (hinj : injective (λ v i, eval v (ps i))) : + surjective (λ v i, eval v (ps i)) := +begin + have is_int : ∀ x : R, is_integral K x, + from λ x, is_algebraic_iff_is_integral.1 (alg x), + classical, + intros v, + casesI nonempty_fintype ι, + /- `s` is the set of all coefficients of the polynomial, as well as all of + the coordinates of `v`, the point I am trying to find the preimage of. -/ + let s : finset R := finset.bUnion (univ : finset ι) + (λ i, (ps i).support.image (λ x, coeff x (ps i))) + ∪ (univ : finset ι).image v, + have hv : ∀ i, v i ∈ algebra.adjoin K (s : set R), + from λ j, algebra.subset_adjoin + (mem_union_right _ + (mem_image.2 ⟨j, mem_univ _, rfl⟩)), + have hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ (ps i).support → + coeff k (ps i) ∈ algebra.adjoin K (s : set R), + from λ i k hk, algebra.subset_adjoin + (mem_union_left _ (mem_bUnion.2 + ⟨i, mem_univ _, mem_image_of_mem _ hk⟩)), + have hs : ∀ i, mv_polynomial.eval v (ps i) ∈ algebra.adjoin K (s : set R), + from λ i, eval_mem (hs₁ _) hv, + letI := is_noetherian_adjoin_finset s (λ x _, is_int x), + letI := module.is_noetherian.finite K (algebra.adjoin K (s : set R)), + letI : finite (algebra.adjoin K (s : set R)) := + finite_dimensional.finite_of_finite + K (algebra.adjoin K (s : set R)), + /- The restriction of the polynomial map, `ps`, to the subalgebra generated by `s` -/ + let res : (ι → algebra.adjoin K (s : set R)) → + (ι → algebra.adjoin K (s : set R)) := + λ x i, ⟨eval (λ j : ι, (x j : R)) (ps i), + eval_mem (hs₁ _) (λ i, (x i).2)⟩, + have hres_inj : injective res, + { intros x y hxy, + ext i, + simp only [res, subtype.ext_iff, funext_iff] at hxy, + exact congr_fun (hinj (funext hxy)) i }, + have hres_surj : surjective res, + from finite.injective_iff_surjective.1 hres_inj, + cases hres_surj (λ i, ⟨v i, hv i⟩) with w hw, + use λ i, w i, + simpa only [res, subtype.ext_iff, funext_iff] using hw, +end From 07992a1d1f7a4176c6d3f160209608be4e198566 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Thu, 4 May 2023 09:41:24 +0000 Subject: [PATCH 10/17] chore(analysis/inner_product_space/basic): golf the proof of Cauchy-Schwarz (#18938) ## API changes - Add `inner_product_space.to_core`. - Make `inner_product_space.core` extend `has_inner`. - Rename namespace from `inner_product_space.of_core` to `inner_product_space.core`. - Rename `inner_product_space.of_core.inner_norm_sq_eq_inner_self` to `inner_product_space.core.coe_norm_sq_eq_inner_self`. - Add `inner_product_space.core.norm_inner_symm`. - Add `inner_product_space.core.cauchy_schwarz_aux`, use it to golf the proof of the Cauchy-Schwarz inequality and its versions. - Use norm instead of `is_R_or_C.abs` here and there, the rest will migrate in #18919. - Rename `inner_product_space.of_core.abs_inner_le_norm` to `inner_product_space.core.norm_inner_le_norm`, use norm. - Add `norm_inner_eq_norm_tfae` and `inner_eq_norm_mul_iff_div`. - Rename `abs_inner_div_norm_mul_norm_eq_one_iff` to `norm_inner_div_norm_mul_norm_eq_one_iff`, use norm. - Rename `inner_eq_norm_mul_iff_of_norm_one` to `inner_eq_one_iff_of_norm_one`. Co-authored-by: Johan Commelin --- docs/undergrad.yaml | 2 +- src/analysis/inner_product_space/basic.lean | 423 ++++++++------------ src/analysis/quaternion.lean | 4 +- src/geometry/manifold/instances/sphere.lean | 6 +- src/linear_algebra/matrix/pos_def.lean | 8 +- 5 files changed, 175 insertions(+), 268 deletions(-) diff --git a/docs/undergrad.yaml b/docs/undergrad.yaml index 2b45ce944747e..3008a9394dd97 100644 --- a/docs/undergrad.yaml +++ b/docs/undergrad.yaml @@ -216,7 +216,7 @@ Bilinear and Quadratic Forms Over a Vector Space: dual isomorphism in the euclidean case: 'inner_product_space.to_dual' orthogonal complement: 'submodule.orthogonal' Cauchy-Schwarz inequality: 'inner_mul_inner_self_le' - norm: 'inner_product_space.of_core.to_has_norm' + norm: 'inner_product_space.core.to_has_norm' orthonormal bases: 'maximal_orthonormal_iff_basis_of_finite_dimensional' Endomorphisms: orthogonal group: 'matrix.orthogonal_group' diff --git a/src/analysis/inner_product_space/basic.lean b/src/analysis/inner_product_space/basic.lean index 0c771833488a5..3ef38143a2648 100644 --- a/src/analysis/inner_product_space/basic.lean +++ b/src/analysis/inner_product_space/basic.lean @@ -122,10 +122,8 @@ instance defined on it, otherwise this will create a second non-defeq norm insta /-- A structure requiring that a scalar product is positive definite and symmetric, from which one can construct an `inner_product_space` instance in `inner_product_space.of_core`. -/ @[nolint has_nonempty_instance] -structure inner_product_space.core - (𝕜 : Type*) (F : Type*) - [is_R_or_C 𝕜] [add_comm_group F] [module 𝕜 F] := -(inner : F → F → 𝕜) +structure inner_product_space.core (𝕜 : Type*) (F : Type*) + [is_R_or_C 𝕜] [add_comm_group F] [module 𝕜 F] extends has_inner 𝕜 F := (conj_symm : ∀ x y, conj (inner y x) = inner x y) (nonneg_re : ∀ x, 0 ≤ re (inner x x)) (definite : ∀ x, inner x x = 0 → x = 0) @@ -137,7 +135,18 @@ of the normed space structure that it produces. However, all the instances we wi local to this proof. -/ attribute [class] inner_product_space.core -namespace inner_product_space.of_core +/-- Define `inner_product_space.core` from `inner_product_space`. Defined to reuse lemmas about +`inner_product_space.core` for `inner_product_space`s. Note that the `has_norm` instance provided by +`inner_product_space.core.has_norm` is propositionally but not definitionally equal to the original +norm. -/ +def inner_product_space.to_core [normed_add_comm_group E] [c : inner_product_space 𝕜 E] : + inner_product_space.core 𝕜 E := +{ nonneg_re := λ x, by { rw [← inner_product_space.norm_sq_eq_inner], apply sq_nonneg }, + definite := λ x hx, norm_eq_zero.1 $ pow_eq_zero $ + by rw [inner_product_space.norm_sq_eq_inner x, hx, map_zero], + .. c } + +namespace inner_product_space.core variables [add_comm_group F] [module 𝕜 F] [c : inner_product_space.core 𝕜 F] include c @@ -149,9 +158,11 @@ local notation `absK` := @is_R_or_C.abs 𝕜 _ local notation `ext_iff` := @is_R_or_C.ext_iff 𝕜 _ local postfix `†`:90 := star_ring_end _ -/-- Inner product defined by the `inner_product_space.core` structure. -/ -def to_has_inner : has_inner 𝕜 F := { inner := c.inner } -local attribute [instance] to_has_inner +/-- Inner product defined by the `inner_product_space.core` structure. We can't reuse +`inner_product_space.core.to_has_inner` because it takes `inner_product_space.core` as an explicit +argument. -/ +def to_has_inner' : has_inner 𝕜 F := c.to_has_inner +local attribute [instance] to_has_inner' /-- The norm squared function for `inner_product_space.core` structure. -/ def norm_sq (x : F) := reK ⟪x, x⟫ @@ -171,7 +182,7 @@ c.add_left _ _ _ lemma inner_add_right (x y z : F) : ⟪x, y + z⟫ = ⟪x, y⟫ + ⟪x, z⟫ := by rw [←inner_conj_symm, inner_add_left, ring_hom.map_add]; simp only [inner_conj_symm] -lemma inner_norm_sq_eq_inner_self (x : F) : (norm_sqF x : 𝕜) = ⟪x, x⟫ := +lemma coe_norm_sq_eq_inner_self (x : F) : (norm_sqF x : 𝕜) = ⟪x, x⟫ := begin rw ext_iff, exact ⟨by simp only [of_real_re]; refl, by simp only [inner_self_im, of_real_im]⟩ @@ -211,6 +222,9 @@ by norm_num [ext_iff, inner_self_im] lemma abs_inner_symm (x y : F) : abs ⟪x, y⟫ = abs ⟪y, x⟫ := by rw [←inner_conj_symm, abs_conj] +lemma norm_inner_symm (x y : F) : ‖⟪x, y⟫‖ = ‖⟪y, x⟫‖ := +by rw [is_R_or_C.norm_eq_abs, is_R_or_C.norm_eq_abs, abs_inner_symm] + lemma inner_neg_left (x y : F) : ⟪-x, y⟫ = -⟪x, y⟫ := by { rw [← neg_one_smul 𝕜 x, inner_smul_left], simp } @@ -234,58 +248,36 @@ by simp only [inner_add_left, inner_add_right]; ring lemma inner_sub_sub_self (x y : F) : ⟪x - y, x - y⟫ = ⟪x, x⟫ - ⟪x, y⟫ - ⟪y, x⟫ + ⟪y, y⟫ := by simp only [inner_sub_left, inner_sub_right]; ring +/-- An auxiliary equality useful to prove the **Cauchy–Schwarz inequality**: the square of the norm +of `⟪x, y⟫ • x - ⟪x, x⟫ • y` is equal to `‖x‖ ^ 2 * (‖x‖ ^ 2 * ‖y‖ ^ 2 - ‖⟪x, y⟫‖ ^ 2)`. We use +`inner_product_space.of_core.norm_sq x` etc (defeq to `is_R_or_C.re ⟪x, x⟫`) instead of `‖x‖ ^ 2` +etc to avoid extra rewrites when applying it to an `inner_product_space`. -/ +theorem cauchy_schwarz_aux (x y : F) : + norm_sqF (⟪x, y⟫ • x - ⟪x, x⟫ • y) = + norm_sqF x * (norm_sqF x * norm_sqF y - ‖⟪x, y⟫‖ ^ 2) := +begin + rw [← @of_real_inj 𝕜, coe_norm_sq_eq_inner_self], + simp only [inner_sub_sub_self, inner_smul_left, inner_smul_right, conj_of_real, mul_sub, + ← coe_norm_sq_eq_inner_self x, ← coe_norm_sq_eq_inner_self y], + rw [← mul_assoc, mul_conj, is_R_or_C.conj_mul_eq_norm_sq_left, norm_sq_eq_def', + mul_left_comm, ← inner_conj_symm y, mul_conj, norm_sq_eq_def'], + push_cast, + ring +end + /-- -**Cauchy–Schwarz inequality**. This proof follows "Proof 2" on Wikipedia. +**Cauchy–Schwarz inequality**. We need this for the `core` structure to prove the triangle inequality below when showing the core is a normed group. -/ -lemma inner_mul_inner_self_le (x y : F) : abs ⟪x, y⟫ * abs ⟪y, x⟫ ≤ re ⟪x, x⟫ * re ⟪y, y⟫ := +lemma inner_mul_inner_self_le (x y : F) : ‖⟪x, y⟫‖ * ‖⟪y, x⟫‖ ≤ re ⟪x, x⟫ * re ⟪y, y⟫ := begin - by_cases hy : y = 0, - { rw [hy], simp only [is_R_or_C.abs_zero, inner_zero_left, mul_zero, add_monoid_hom.map_zero] }, - { change y ≠ 0 at hy, - have hy' : ⟪y, y⟫ ≠ 0 := inner_self_ne_zero.mpr hy, - set T := ⟪y, x⟫ / ⟪y, y⟫ with hT, - have h₁ : re ⟪y, x⟫ = re ⟪x, y⟫ := inner_re_symm _ _, - have h₂ : im ⟪y, x⟫ = -im ⟪x, y⟫ := inner_im_symm _ _, - have h₃ : ⟪y, x⟫ * ⟪x, y⟫ * ⟪y, y⟫ / (⟪y, y⟫ * ⟪y, y⟫) = ⟪y, x⟫ * ⟪x, y⟫ / ⟪y, y⟫, - { rw [mul_div_assoc], - have : ⟪y, y⟫ / (⟪y, y⟫ * ⟪y, y⟫) = 1 / ⟪y, y⟫ := - by rw [div_mul_eq_div_mul_one_div, div_self hy', one_mul], - rw [this, div_eq_mul_inv, one_mul, ←div_eq_mul_inv] }, - have h₄ : ⟪y, y⟫ = re ⟪y, y⟫ := by simp only [inner_self_re_to_K], - have h₅ : re ⟪y, y⟫ > 0, - { refine lt_of_le_of_ne inner_self_nonneg _, - intro H, - apply hy', - rw ext_iff, - exact ⟨by simp only [H, zero_re'], - by simp only [inner_self_im, add_monoid_hom.map_zero]⟩ }, - have h₆ : re ⟪y, y⟫ ≠ 0 := ne_of_gt h₅, - have hmain := calc - 0 ≤ re ⟪x - T • y, x - T • y⟫ - : inner_self_nonneg - ... = re ⟪x, x⟫ - re ⟪T • y, x⟫ - re ⟪x, T • y⟫ + re ⟪T • y, T • y⟫ - : by simp only [inner_sub_sub_self, inner_smul_left, inner_smul_right, h₁, h₂, - neg_mul, add_monoid_hom.map_add, mul_re, - conj_im, add_monoid_hom.map_sub, mul_neg, conj_re, neg_neg] - ... = re ⟪x, x⟫ - re (T† * ⟪y, x⟫) - re (T * ⟪x, y⟫) + re (T * T† * ⟪y, y⟫) - : by simp only [inner_smul_left, inner_smul_right, mul_assoc] - ... = re ⟪x, x⟫ - re (⟪x, y⟫ / ⟪y, y⟫ * ⟪y, x⟫) - : by field_simp [-mul_re, inner_conj_symm, hT, map_div₀, h₁, h₃] - ... = re ⟪x, x⟫ - re (⟪x, y⟫ * ⟪y, x⟫ / ⟪y, y⟫) - : by rw ←mul_div_right_comm - ... = re ⟪x, x⟫ - re (⟪x, y⟫ * ⟪y, x⟫ / re ⟪y, y⟫) - : by conv_lhs { rw [h₄] } - ... = re ⟪x, x⟫ - re (⟪x, y⟫ * ⟪y, x⟫) / re ⟪y, y⟫ - : by rw [div_re_of_real] - ... = re ⟪x, x⟫ - abs (⟪x, y⟫ * ⟪y, x⟫) / re ⟪y, y⟫ - : by rw [inner_mul_conj_re_abs] - ... = re ⟪x, x⟫ - abs ⟪x, y⟫ * abs ⟪y, x⟫ / re ⟪y, y⟫ - : by rw is_R_or_C.abs_mul, - have hmain' : abs ⟪x, y⟫ * abs ⟪y, x⟫ / re ⟪y, y⟫ ≤ re ⟪x, x⟫ := by linarith, - have := (mul_le_mul_right h₅).mpr hmain', - rwa [div_mul_cancel (abs ⟪x, y⟫ * abs ⟪y, x⟫) h₆] at this } + rcases eq_or_ne x 0 with (rfl | hx), + { simp only [inner_zero_left, map_zero, zero_mul, norm_zero] }, + { have hx' : 0 < norm_sqF x := inner_self_nonneg.lt_of_ne' (mt norm_sq_eq_zero.1 hx), + rw [← sub_nonneg, ← mul_nonneg_iff_right_nonneg_of_pos hx', ← norm_sq, ← norm_sq, + norm_inner_symm y, ← sq, ← cauchy_schwarz_aux], + exact inner_self_nonneg } end /-- Norm constructed from a `inner_product_space.core` structure, defined to be the square root @@ -304,18 +296,11 @@ by rw [norm_eq_sqrt_inner, ←sqrt_mul inner_self_nonneg (re ⟪x, x⟫), lemma sqrt_norm_sq_eq_norm (x : F) : sqrt (norm_sqF x) = ‖x‖ := rfl /-- Cauchy–Schwarz inequality with norm -/ -lemma abs_inner_le_norm (x y : F) : abs ⟪x, y⟫ ≤ ‖x‖ * ‖y‖ := -nonneg_le_nonneg_of_sq_le_sq (mul_nonneg (sqrt_nonneg _) (sqrt_nonneg _)) -begin - have H : ‖x‖ * ‖y‖ * (‖x‖ * ‖y‖) = re ⟪y, y⟫ * re ⟪x, x⟫, - { simp only [inner_self_eq_norm_mul_norm], ring, }, - rw H, - conv - begin - to_lhs, congr, rw [abs_inner_symm], - end, - exact inner_mul_inner_self_le y x, -end +lemma norm_inner_le_norm (x y : F) : ‖⟪x, y⟫‖ ≤ ‖x‖ * ‖y‖ := +nonneg_le_nonneg_of_sq_le_sq (mul_nonneg (sqrt_nonneg _) (sqrt_nonneg _)) $ + calc ‖⟪x, y⟫‖ * ‖⟪x, y⟫‖ = ‖⟪x, y⟫‖ * ‖⟪y, x⟫‖ : by rw [norm_inner_symm] + ... ≤ re ⟪x, x⟫ * re ⟪y, y⟫ : inner_mul_inner_self_le x y + ... = ‖x‖ * ‖y‖ * (‖x‖ * ‖y‖) : by simp only [inner_self_eq_norm_mul_norm]; ring /-- Normed group structure constructed from an `inner_product_space.core` structure -/ def to_normed_add_comm_group : normed_add_comm_group F := @@ -324,9 +309,9 @@ add_group_norm.to_normed_add_comm_group map_zero' := by simp only [sqrt_zero, inner_zero_right, map_zero], neg' := λ x, by simp only [inner_neg_left, neg_neg, inner_neg_right], add_le' := λ x y, begin - have h₁ : abs ⟪x, y⟫ ≤ ‖x‖ * ‖y‖ := abs_inner_le_norm _ _, - have h₂ : re ⟪x, y⟫ ≤ abs ⟪x, y⟫ := re_le_abs _, - have h₃ : re ⟪x, y⟫ ≤ ‖x‖ * ‖y‖ := by linarith, + have h₁ : ‖⟪x, y⟫‖ ≤ ‖x‖ * ‖y‖ := norm_inner_le_norm _ _, + have h₂ : re ⟪x, y⟫ ≤ ‖⟪x, y⟫‖ := (re_le_abs _).trans_eq (is_R_or_C.norm_eq_abs _).symm, + have h₃ : re ⟪x, y⟫ ≤ ‖x‖ * ‖y‖ := h₂.trans h₁, have h₄ : re ⟪y, x⟫ ≤ ‖x‖ * ‖y‖ := by rwa [←inner_conj_symm, conj_re], have : ‖x + y‖ * ‖x + y‖ ≤ (‖x‖ + ‖y‖) * (‖x‖ + ‖y‖), { simp only [←inner_self_eq_norm_mul_norm, inner_add_add_self, mul_add, mul_comm, map_add], @@ -342,16 +327,16 @@ def to_normed_space : normed_space 𝕜 F := { norm_smul_le := assume r x, begin rw [norm_eq_sqrt_inner, inner_smul_left, inner_smul_right, ←mul_assoc], - rw [conj_mul_eq_norm_sq_left, of_real_mul_re, sqrt_mul, ←inner_norm_sq_eq_inner_self, - of_real_re], + rw [is_R_or_C.conj_mul_eq_norm_sq_left, of_real_mul_re, sqrt_mul, ← coe_norm_sq_eq_inner_self, + of_real_re], { simp [sqrt_norm_sq_eq_norm, is_R_or_C.sqrt_norm_sq_eq_norm] }, { exact norm_sq_nonneg r } end } -end inner_product_space.of_core +end inner_product_space.core section -local attribute [instance] inner_product_space.of_core.to_normed_add_comm_group +local attribute [instance] inner_product_space.core.to_normed_add_comm_group /-- Given a `inner_product_space.core` structure on a space, one can use it to turn the space into an inner product space. The `normed_add_comm_group` structure is expected @@ -359,11 +344,11 @@ to already be defined with `inner_product_space.of_core.to_normed_add_comm_group def inner_product_space.of_core [add_comm_group F] [module 𝕜 F] (c : inner_product_space.core 𝕜 F) : inner_product_space 𝕜 F := begin - letI : normed_space 𝕜 F := @inner_product_space.of_core.to_normed_space 𝕜 F _ _ _ c, + letI : normed_space 𝕜 F := @inner_product_space.core.to_normed_space 𝕜 F _ _ _ c, exact { norm_sq_eq_inner := λ x, begin have h₁ : ‖x‖^2 = (sqrt (re (c.inner x x))) ^ 2 := rfl, - have h₂ : 0 ≤ re (c.inner x x) := inner_product_space.of_core.inner_self_nonneg, + have h₂ : 0 ≤ re (c.inner x x) := inner_product_space.core.inner_self_nonneg, simp [h₁, sq_sqrt, h₂], end, ..c } @@ -390,7 +375,7 @@ section basic_properties lemma real_inner_comm (x y : F) : ⟪y, x⟫_ℝ = ⟪x, y⟫_ℝ := @inner_conj_symm ℝ _ _ _ _ x y lemma inner_eq_zero_symm {x y : E} : ⟪x, y⟫ = 0 ↔ ⟪y, x⟫ = 0 := -⟨λ h, by simp [←inner_conj_symm, h], λ h, by simp [←inner_conj_symm, h]⟩ +by { rw [← inner_conj_symm], exact star_eq_zero } @[simp] lemma inner_self_im (x : E) : im ⟪x, x⟫ = 0 := by rw [← @of_real_inj 𝕜, im_eq_conj_sub]; simp @@ -489,7 +474,8 @@ lemma inner_re_zero_right (x : E) : re ⟪x, 0⟫ = 0 := by simp only [inner_zero_right, add_monoid_hom.map_zero] lemma inner_self_nonneg {x : E} : 0 ≤ re ⟪x, x⟫ := -by rw [←norm_sq_eq_inner]; exact pow_nonneg (norm_nonneg x) 2 +inner_product_space.to_core.nonneg_re x + lemma real_inner_self_nonneg {x : F} : 0 ≤ ⟪x, x⟫_ℝ := @inner_self_nonneg ℝ F _ _ _ x @[simp] lemma inner_self_re_to_K (x : E) : (re ⟪x, x⟫ : 𝕜) = ⟪x, x⟫ := @@ -587,60 +573,17 @@ lemma parallelogram_law {x y : E} : ⟪x + y, x + y⟫ + ⟪x - y, x - y⟫ = 2 * (⟪x, x⟫ + ⟪y, y⟫) := by simp [inner_add_add_self, inner_sub_sub_self, two_mul, sub_eq_add_neg, add_comm, add_left_comm] -/-- Cauchy–Schwarz inequality. This proof follows "Proof 2" on Wikipedia. -/ -lemma inner_mul_inner_self_le (x y : E) : abs ⟪x, y⟫ * abs ⟪y, x⟫ ≤ re ⟪x, x⟫ * re ⟪y, y⟫ := +/-- **Cauchy–Schwarz inequality**. -/ +lemma inner_mul_inner_self_le (x y : E) : ‖⟪x, y⟫‖ * ‖⟪y, x⟫‖ ≤ re ⟪x, x⟫ * re ⟪y, y⟫ := begin - by_cases hy : y = 0, - { rw [hy], simp only [is_R_or_C.abs_zero, inner_zero_left, mul_zero, add_monoid_hom.map_zero] }, - { have hy' : ⟪y, y⟫ ≠ 0 := inner_self_eq_zero.not.2 hy, - set T := ⟪y, x⟫ / ⟪y, y⟫ with hT, - have h₁ : re ⟪y, x⟫ = re ⟪x, y⟫ := inner_re_symm _ _, - have h₂ : im ⟪y, x⟫ = -im ⟪x, y⟫ := inner_im_symm _ _, - have h₃ : ⟪y, x⟫ * ⟪x, y⟫ * ⟪y, y⟫ / (⟪y, y⟫ * ⟪y, y⟫) = ⟪y, x⟫ * ⟪x, y⟫ / ⟪y, y⟫, - { rw [mul_div_assoc], - have : ⟪y, y⟫ / (⟪y, y⟫ * ⟪y, y⟫) = 1 / ⟪y, y⟫ := - by rw [div_mul_eq_div_mul_one_div, div_self hy', one_mul], - rw [this, div_eq_mul_inv, one_mul, ←div_eq_mul_inv] }, - have h₄ : ⟪y, y⟫ = re ⟪y, y⟫ := (inner_self_re_to_K _).symm, - have h₅ : re ⟪y, y⟫ > 0, - { refine lt_of_le_of_ne inner_self_nonneg _, - intro H, - apply hy', - rw is_R_or_C.ext_iff, - exact ⟨by simp only [H, zero_re'], - by simp only [inner_self_im, add_monoid_hom.map_zero]⟩ }, - have h₆ : re ⟪y, y⟫ ≠ 0 := ne_of_gt h₅, - have hmain := calc - 0 ≤ re ⟪x - T • y, x - T • y⟫ - : inner_self_nonneg - ... = re ⟪x, x⟫ - re ⟪T • y, x⟫ - re ⟪x, T • y⟫ + re ⟪T • y, T • y⟫ - : by simp only [inner_sub_sub_self, inner_smul_left, inner_smul_right, h₁, h₂, - neg_mul, add_monoid_hom.map_add, conj_im, - add_monoid_hom.map_sub, mul_neg, conj_re, neg_neg, mul_re] - ... = re ⟪x, x⟫ - re (T† * ⟪y, x⟫) - re (T * ⟪x, y⟫) + re (T * T† * ⟪y, y⟫) - : by simp only [inner_smul_left, inner_smul_right, mul_assoc] - ... = re ⟪x, x⟫ - re (⟪x, y⟫ / ⟪y, y⟫ * ⟪y, x⟫) - : by simp only [map_div₀, h₃, inner_conj_symm, sub_add_cancel] - with field_simps {discharger := tactic.field_simp.ne_zero} - ... = re ⟪x, x⟫ - re (⟪x, y⟫ * ⟪y, x⟫ / ⟪y, y⟫) - : by rw ←mul_div_right_comm - ... = re ⟪x, x⟫ - re (⟪x, y⟫ * ⟪y, x⟫ / re ⟪y, y⟫) - : by conv_lhs { rw [h₄] } - ... = re ⟪x, x⟫ - re (⟪x, y⟫ * ⟪y, x⟫) / re ⟪y, y⟫ - : by rw [div_re_of_real] - ... = re ⟪x, x⟫ - abs (⟪x, y⟫ * ⟪y, x⟫) / re ⟪y, y⟫ - : by rw [inner_mul_conj_re_abs] - ... = re ⟪x, x⟫ - abs ⟪x, y⟫ * abs ⟪y, x⟫ / re ⟪y, y⟫ - : by rw is_R_or_C.abs_mul, - have hmain' : abs ⟪x, y⟫ * abs ⟪y, x⟫ / re ⟪y, y⟫ ≤ re ⟪x, x⟫ := by linarith, - have := (mul_le_mul_right h₅).mpr hmain', - rwa [div_mul_cancel (abs ⟪x, y⟫ * abs ⟪y, x⟫) h₆] at this } + letI c : inner_product_space.core 𝕜 E := inner_product_space.to_core, + exact inner_product_space.core.inner_mul_inner_self_le x y end /-- Cauchy–Schwarz inequality for real inner products. -/ lemma real_inner_mul_inner_self_le (x y : F) : ⟪x, y⟫_ℝ * ⟪x, y⟫_ℝ ≤ ⟪x, x⟫_ℝ * ⟪y, y⟫_ℝ := -calc ⟪x, y⟫_ℝ * ⟪x, y⟫_ℝ ≤ is_R_or_C.abs ⟪x, y⟫_ℝ * is_R_or_C.abs ⟪y, x⟫_ℝ : - by { rw [real_inner_comm y, ← is_R_or_C.abs_mul, ← is_R_or_C.norm_eq_abs], exact le_abs_self _ } +calc ⟪x, y⟫_ℝ * ⟪x, y⟫_ℝ ≤ ‖⟪x, y⟫_ℝ‖ * ‖⟪y, x⟫_ℝ‖ : + by { rw [real_inner_comm y, ← norm_mul], exact le_abs_self _ } ... ≤ ⟪x, x⟫_ℝ * ⟪y, y⟫_ℝ : @inner_mul_inner_self_le ℝ _ _ _ _ x y /-- A family of vectors is linearly independent if they are nonzero @@ -927,7 +870,7 @@ calc ‖x‖ = sqrt (‖x‖ ^ 2) : (sqrt_sq (norm_nonneg _)).symm ... = sqrt (re ⟪x, x⟫) : congr_arg _ (norm_sq_eq_inner _) lemma norm_eq_sqrt_real_inner (x : F) : ‖x‖ = sqrt ⟪x, x⟫_ℝ := -by { have h := @norm_eq_sqrt_inner ℝ F _ _ _ x, simpa using h } +@norm_eq_sqrt_inner ℝ _ _ _ _ x lemma inner_self_eq_norm_mul_norm (x : E) : re ⟪x, x⟫ = ‖x‖ * ‖x‖ := by rw [@norm_eq_sqrt_inner 𝕜, ←sqrt_mul inner_self_nonneg (re ⟪x, x⟫), @@ -990,18 +933,15 @@ lemma norm_sub_mul_self_real (x y : F) : ‖x - y‖ * ‖x - y‖ = ‖x‖ * by { have h := @norm_sub_mul_self ℝ _ _ _ _ x y, simpa using h } /-- Cauchy–Schwarz inequality with norm -/ -lemma abs_inner_le_norm (x y : E) : abs ⟪x, y⟫ ≤ ‖x‖ * ‖y‖ := -nonneg_le_nonneg_of_sq_le_sq (mul_nonneg (norm_nonneg _) (norm_nonneg _)) +lemma norm_inner_le_norm (x y : E) : ‖⟪x, y⟫‖ ≤ ‖x‖ * ‖y‖ := begin - have : ‖x‖ * ‖y‖ * (‖x‖ * ‖y‖) = (re ⟪x, x⟫) * (re ⟪y, y⟫), - simp only [inner_self_eq_norm_mul_norm], ring, - rw this, - conv_lhs { congr, skip, rw [abs_inner_symm] }, - exact inner_mul_inner_self_le _ _ + rw [norm_eq_sqrt_inner x, norm_eq_sqrt_inner y], + letI : inner_product_space.core 𝕜 E := inner_product_space.to_core, + exact inner_product_space.core.norm_inner_le_norm x y end -lemma norm_inner_le_norm (x y : E) : ‖⟪x, y⟫‖ ≤ ‖x‖ * ‖y‖ := -(is_R_or_C.norm_eq_abs _).le.trans (abs_inner_le_norm x y) +lemma abs_inner_le_norm (x y : E) : abs ⟪x, y⟫ ≤ ‖x‖ * ‖y‖ := +(norm_eq_abs ⟪x, y⟫).symm.trans_le (norm_inner_le_norm _ _) lemma nnnorm_inner_le_nnnorm (x y : E) : ‖⟪x, y⟫‖₊ ≤ ‖x‖₊ * ‖y‖₊ := norm_inner_le_norm x y @@ -1010,8 +950,8 @@ lemma re_inner_le_norm (x y : E) : re ⟪x, y⟫ ≤ ‖x‖ * ‖y‖ := le_trans (re_le_abs (inner x y)) (abs_inner_le_norm x y) /-- Cauchy–Schwarz inequality with norm -/ -lemma abs_real_inner_le_norm (x y : F) : absR ⟪x, y⟫_ℝ ≤ ‖x‖ * ‖y‖ := -by { have h := @abs_inner_le_norm ℝ F _ _ _ x y, simpa using h } +lemma abs_real_inner_le_norm (x y : F) : |⟪x, y⟫_ℝ| ≤ ‖x‖ * ‖y‖ := +(real.norm_eq_abs _).ge.trans (norm_inner_le_norm x y) /-- Cauchy–Schwarz inequality with norm -/ lemma real_inner_le_norm (x y : F) : ⟪x, y⟫_ℝ ≤ ‖x‖ * ‖y‖ := @@ -1437,64 +1377,63 @@ itself, divided by the product of their norms, has value -1. -/ lemma real_inner_div_norm_mul_norm_eq_neg_one_of_ne_zero_of_neg_mul {x : F} {r : ℝ} (hx : x ≠ 0) (hr : r < 0) : ⟪x, r • x⟫_ℝ / (‖x‖ * ‖r • x‖) = -1 := begin - rw [real_inner_smul_self_right, norm_smul, real.norm_eq_abs, ←mul_assoc ‖x‖, mul_comm _ (absR r), + rw [real_inner_smul_self_right, norm_smul, real.norm_eq_abs, ←mul_assoc ‖x‖, mul_comm _ (|r|), mul_assoc, abs_of_neg hr, neg_mul, div_neg_eq_neg_div, div_self], - exact mul_ne_zero (ne_of_lt hr) - (λ h, hx (norm_eq_zero.1 (eq_zero_of_mul_self_eq_zero h))) + exact mul_ne_zero hr.ne (mul_self_ne_zero.2 (norm_ne_zero_iff.2 hx)) +end + +lemma norm_inner_eq_norm_tfae (x y : E) : + tfae [‖⟪x, y⟫‖ = ‖x‖ * ‖y‖, + x = 0 ∨ y = (⟪x, y⟫ / ⟪x, x⟫) • x, + x = 0 ∨ ∃ r : 𝕜, y = r • x, + x = 0 ∨ y ∈ 𝕜 ∙ x] := +begin + tfae_have : 1 → 2, + { refine λ h, or_iff_not_imp_left.2 (λ hx₀, _), + have : ‖x‖ ^ 2 ≠ 0 := pow_ne_zero _ (norm_ne_zero_iff.2 hx₀), + rw [← sq_eq_sq (norm_nonneg _) (mul_nonneg (norm_nonneg _) (norm_nonneg _)), + mul_pow, ← mul_right_inj' this, eq_comm, ← sub_eq_zero, ← mul_sub] at h, + simp only [@norm_sq_eq_inner 𝕜] at h, + letI : inner_product_space.core 𝕜 E := inner_product_space.to_core, + erw [← inner_product_space.core.cauchy_schwarz_aux, + inner_product_space.core.norm_sq_eq_zero, sub_eq_zero] at h, + rw [div_eq_inv_mul, mul_smul, h, inv_smul_smul₀], + rwa [inner_self_ne_zero] }, + tfae_have : 2 → 3, from λ h, h.imp_right (λ h', ⟨_, h'⟩), + tfae_have : 3 → 1, + { rintro (rfl | ⟨r, rfl⟩); simp [inner_smul_right, norm_smul, inner_self_eq_norm_sq_to_K, + inner_self_eq_norm_mul_norm, sq, mul_left_comm] }, + tfae_have : 3 ↔ 4, by simp only [submodule.mem_span_singleton, eq_comm], + tfae_finish end +/-- +If the inner product of two vectors is equal to the product of their norms, then the two vectors +are multiples of each other. One form of the equality case for Cauchy-Schwarz. +Compare `inner_eq_norm_mul_iff`, which takes the stronger hypothesis `⟪x, y⟫ = ‖x‖ * ‖y‖`. -/ +lemma norm_inner_eq_norm_iff {x y : E} (hx₀ : x ≠ 0) (hy₀ : y ≠ 0) : + ‖⟪x, y⟫‖ = ‖x‖ * ‖y‖ ↔ ∃ (r : 𝕜), r ≠ 0 ∧ y = r • x := +calc ‖⟪x, y⟫‖ = ‖x‖ * ‖y‖ ↔ x = 0 ∨ ∃ r : 𝕜, y = r • x : + (@norm_inner_eq_norm_tfae 𝕜 _ _ _ _ x y).out 0 2 +... ↔ ∃ r : 𝕜, y = r • x : or_iff_right hx₀ +... ↔ ∃ r : 𝕜, r ≠ 0 ∧ y = r • x : + ⟨λ ⟨r, h⟩, ⟨r, λ hr₀, hy₀ $ h.symm ▸ smul_eq_zero.2 $ or.inl hr₀, h⟩, λ ⟨r, hr₀, h⟩, ⟨r, h⟩⟩ + /-- The inner product of two vectors, divided by the product of their norms, has absolute value 1 if and only if they are nonzero and one is a multiple of the other. One form of equality case for Cauchy-Schwarz. -/ -lemma abs_inner_div_norm_mul_norm_eq_one_iff (x y : E) : - abs (⟪x, y⟫ / (‖x‖ * ‖y‖)) = 1 ↔ (x ≠ 0 ∧ ∃ (r : 𝕜), r ≠ 0 ∧ y = r • x) := +lemma norm_inner_div_norm_mul_norm_eq_one_iff (x y : E) : + ‖(⟪x, y⟫ / (‖x‖ * ‖y‖))‖ = 1 ↔ (x ≠ 0 ∧ ∃ (r : 𝕜), r ≠ 0 ∧ y = r • x) := begin split, { intro h, - have hx0 : x ≠ 0, - { intro hx0, - rw [hx0, inner_zero_left, zero_div] at h, - norm_num at h, }, - refine and.intro hx0 _, - set r := ⟪x, y⟫ / (‖x‖ * ‖x‖) with hr, - use r, - set t := y - r • x with ht, - have ht0 : ⟪x, t⟫ = 0, - { rw [ht, inner_sub_right, inner_smul_right, hr], - norm_cast, - rw [←@inner_self_eq_norm_mul_norm 𝕜, inner_self_re_to_K, - div_mul_cancel _ (λ h, hx0 ((@inner_self_eq_zero 𝕜 _ _ _ _ _).1 h)), sub_self] }, - replace h : ‖r • x‖ / ‖t + r • x‖ = 1, - { rw [←sub_add_cancel y (r • x), ←ht, inner_add_right, ht0, zero_add, inner_smul_right, - is_R_or_C.abs_div, is_R_or_C.abs_mul, ←inner_self_re_abs, - inner_self_eq_norm_mul_norm] at h, - norm_cast at h, - rwa [_root_.abs_mul, abs_norm, abs_norm, ←mul_assoc, mul_comm, - mul_div_mul_left _ _ (λ h, hx0 (norm_eq_zero.1 h)), ←is_R_or_C.norm_eq_abs, - ←norm_smul] at h }, - have hr0 : r ≠ 0, - { intro hr0, - rw [hr0, zero_smul, norm_zero, zero_div] at h, - norm_num at h }, - refine and.intro hr0 _, - have h2 : ‖r • x‖ ^ 2 = ‖t + r • x‖ ^ 2, - { rw [eq_of_div_eq_one h] }, - replace h2 : ⟪r • x, r • x⟫ = ⟪t, t⟫ + ⟪t, r • x⟫ + ⟪r • x, t⟫ + ⟪r • x, r • x⟫, - { rw [sq, sq, ←@inner_self_eq_norm_mul_norm 𝕜, ←@inner_self_eq_norm_mul_norm 𝕜] at h2, - have h2' := congr_arg (λ z : ℝ, (z : 𝕜)) h2, - simp_rw [inner_self_re_to_K, inner_add_add_self] at h2', - exact h2' }, - conv at h2 in ⟪r • x, t⟫ { rw [inner_smul_left, ht0, mul_zero] }, - symmetry' at h2, - have h₁ : ⟪t, r • x⟫ = 0 := by { rw [inner_smul_right, ←inner_conj_symm, ht0], simp }, - rw [add_zero, h₁, add_left_eq_self, add_zero, inner_self_eq_zero] at h2, - rw h2 at ht, - exact eq_of_sub_eq_zero ht.symm }, - { intro h, - rcases h with ⟨hx, ⟨r, ⟨hr, hy⟩⟩⟩, - rw [hy, is_R_or_C.abs_div], - norm_cast, - rw [_root_.abs_mul, abs_norm, abs_norm], + have hx₀ : x ≠ 0 := λ h₀, by simpa [h₀] using h, + have hy₀ : y ≠ 0 := λ h₀, by simpa [h₀] using h, + refine ⟨hx₀, (norm_inner_eq_norm_iff hx₀ hy₀).1 $ eq_of_div_eq_one _⟩, + simpa using h }, + { rintro ⟨hx, ⟨r, ⟨hr, rfl⟩⟩⟩, + simp only [is_R_or_C.abs_div, is_R_or_C.abs_mul, is_R_or_C.abs_of_real, is_R_or_C.norm_eq_abs, + abs_norm], exact abs_inner_div_norm_mul_norm_eq_one_of_ne_zero_of_ne_zero_mul hx hr } end @@ -1502,27 +1441,43 @@ end norms, has absolute value 1 if and only if they are nonzero and one is a multiple of the other. One form of equality case for Cauchy-Schwarz. -/ lemma abs_real_inner_div_norm_mul_norm_eq_one_iff (x y : F) : - absR (⟪x, y⟫_ℝ / (‖x‖ * ‖y‖)) = 1 ↔ (x ≠ 0 ∧ ∃ (r : ℝ), r ≠ 0 ∧ y = r • x) := + |⟪x, y⟫_ℝ / (‖x‖ * ‖y‖)| = 1 ↔ (x ≠ 0 ∧ ∃ (r : ℝ), r ≠ 0 ∧ y = r • x) := +@norm_inner_div_norm_mul_norm_eq_one_iff ℝ F _ _ _ x y + +lemma inner_eq_norm_mul_iff_div {x y : E} (h₀ : x ≠ 0) : + ⟪x, y⟫ = (‖x‖ : 𝕜) * ‖y‖ ↔ (‖y‖ / ‖x‖ : 𝕜) • x = y := begin - have := @abs_inner_div_norm_mul_norm_eq_one_iff ℝ F _ _ _ x y, - simpa [coe_real_eq_id] using this, + have h₀' := h₀, + rw [← norm_ne_zero_iff, ne.def, ← @of_real_eq_zero 𝕜] at h₀', + split; intro h, + { have : x = 0 ∨ y = (⟪x, y⟫ / ⟪x, x⟫ : 𝕜) • x := + ((@norm_inner_eq_norm_tfae 𝕜 _ _ _ _ x y).out 0 1).1 (by simp [h]), + rw [this.resolve_left h₀, h], + simp [norm_smul, is_R_or_C.norm_eq_abs, inner_self_abs_to_K, h₀'] }, + { conv_lhs { rw [← h, inner_smul_right, inner_self_eq_norm_sq_to_K] }, + field_simp [sq, mul_left_comm] } end -/-- -If the inner product of two vectors is equal to the product of their norms, then the two vectors -are multiples of each other. One form of the equality case for Cauchy-Schwarz. -Compare `inner_eq_norm_mul_iff`, which takes the stronger hypothesis `⟪x, y⟫ = ‖x‖ * ‖y‖`. -/ -lemma abs_inner_eq_norm_iff (x y : E) (hx0 : x ≠ 0) (hy0 : y ≠ 0): - abs ⟪x, y⟫ = ‖x‖ * ‖y‖ ↔ ∃ (r : 𝕜), r ≠ 0 ∧ y = r • x := +/-- If the inner product of two vectors is equal to the product of their norms (i.e., +`⟪x, y⟫ = ‖x‖ * ‖y‖`), then the two vectors are nonnegative real multiples of each other. One form +of the equality case for Cauchy-Schwarz. +Compare `norm_inner_eq_norm_iff`, which takes the weaker hypothesis `abs ⟪x, y⟫ = ‖x‖ * ‖y‖`. -/ +lemma inner_eq_norm_mul_iff {x y : E} : + ⟪x, y⟫ = (‖x‖ : 𝕜) * ‖y‖ ↔ (‖y‖ : 𝕜) • x = (‖x‖ : 𝕜) • y := begin - have hxy0 : ‖x‖ * ‖y‖ ≠ 0 := mul_ne_zero (norm_eq_zero.not.2 hx0) (norm_eq_zero.not.2 hy0), - have h₁ : abs ⟪x, y⟫ = ‖x‖ * ‖y‖ ↔ abs (⟪x, y⟫ / (‖x‖ * ‖y‖)) = 1, - { rw [←algebra_map.coe_mul, is_R_or_C.abs_div, is_R_or_C.abs_of_nonneg, div_eq_one_iff_eq hxy0], - positivity }, - rw [h₁, abs_inner_div_norm_mul_norm_eq_one_iff x y], - exact and_iff_right hx0, + rcases eq_or_ne x 0 with (rfl | h₀), + { simp }, + { rw [inner_eq_norm_mul_iff_div h₀, div_eq_inv_mul, mul_smul, inv_smul_eq_iff₀], + rwa [ne.def, of_real_eq_zero, norm_eq_zero] }, end +/-- If the inner product of two vectors is equal to the product of their norms (i.e., +`⟪x, y⟫ = ‖x‖ * ‖y‖`), then the two vectors are nonnegative real multiples of each other. One form +of the equality case for Cauchy-Schwarz. +Compare `norm_inner_eq_norm_iff`, which takes the weaker hypothesis `abs ⟪x, y⟫ = ‖x‖ * ‖y‖`. -/ +lemma inner_eq_norm_mul_iff_real {x y : F} : ⟪x, y⟫_ℝ = ‖x‖ * ‖y‖ ↔ ‖y‖ • x = ‖x‖ • y := +inner_eq_norm_mul_iff + /-- The inner product of two vectors, divided by the product of their norms, has value 1 if and only if they are nonzero and one is a positive multiple of the other. -/ @@ -1531,20 +1486,11 @@ lemma real_inner_div_norm_mul_norm_eq_one_iff (x y : F) : begin split, { intro h, - have ha := h, - apply_fun absR at ha, - norm_num at ha, - rcases (abs_real_inner_div_norm_mul_norm_eq_one_iff x y).1 ha with ⟨hx, ⟨r, ⟨hr, hy⟩⟩⟩, - use [hx, r], - refine and.intro _ hy, - by_contradiction hrneg, - rw hy at h, - rw real_inner_div_norm_mul_norm_eq_neg_one_of_ne_zero_of_neg_mul hx - (lt_of_le_of_ne (le_of_not_lt hrneg) hr) at h, - norm_num at h }, - { intro h, - rcases h with ⟨hx, ⟨r, ⟨hr, hy⟩⟩⟩, - rw hy, + have hx₀ : x ≠ 0 := λ h₀, by simpa [h₀] using h, + have hy₀ : y ≠ 0 := λ h₀, by simpa [h₀] using h, + refine ⟨hx₀, ‖y‖ / ‖x‖, div_pos (norm_pos_iff.2 hy₀) (norm_pos_iff.2 hx₀), _⟩, + exact ((inner_eq_norm_mul_iff_div hx₀).1 (eq_of_div_eq_one h)).symm }, + { rintro ⟨hx, ⟨r, ⟨hr, rfl⟩⟩⟩, exact real_inner_div_norm_mul_norm_eq_one_of_ne_zero_of_pos_mul hx hr } end @@ -1560,48 +1506,9 @@ begin rw [neg_pos, neg_smul, neg_inj] end -/-- If the inner product of two vectors is equal to the product of their norms (i.e., -`⟪x, y⟫ = ‖x‖ * ‖y‖`), then the two vectors are nonnegative real multiples of each other. One form -of the equality case for Cauchy-Schwarz. -Compare `abs_inner_eq_norm_iff`, which takes the weaker hypothesis `abs ⟪x, y⟫ = ‖x‖ * ‖y‖`. -/ -lemma inner_eq_norm_mul_iff {x y : E} : - ⟪x, y⟫ = (‖x‖ : 𝕜) * ‖y‖ ↔ (‖y‖ : 𝕜) • x = (‖x‖ : 𝕜) • y := -begin - by_cases h : (x = 0 ∨ y = 0), -- WLOG `x` and `y` are nonzero - { cases h; simp [h] }, - calc ⟪x, y⟫ = (‖x‖ : 𝕜) * ‖y‖ ↔ ‖x‖ * ‖y‖ = re ⟪x, y⟫ : - begin - norm_cast, - split, - { intros h', - simp [h'] }, - { have cauchy_schwarz := abs_inner_le_norm x y, - intros h', - rw h' at ⊢ cauchy_schwarz, - rwa re_eq_self_of_le } - end - ... ↔ 2 * ‖x‖ * ‖y‖ * (‖x‖ * ‖y‖ - re ⟪x, y⟫) = 0 : - by simp [h, show (2:ℝ) ≠ 0, by norm_num, sub_eq_zero] - ... ↔ ‖(‖y‖:𝕜) • x - (‖x‖:𝕜) • y‖ * ‖(‖y‖:𝕜) • x - (‖x‖:𝕜) • y‖ = 0 : - begin - simp only [@norm_sub_mul_self 𝕜, inner_smul_left, inner_smul_right, norm_smul, conj_of_real, - is_R_or_C.norm_eq_abs, abs_of_real, of_real_im, of_real_re, mul_re, abs_norm], - refine eq.congr _ rfl, - ring - end - ... ↔ (‖y‖ : 𝕜) • x = (‖x‖ : 𝕜) • y : by simp [norm_sub_eq_zero_iff] -end - -/-- If the inner product of two vectors is equal to the product of their norms (i.e., -`⟪x, y⟫ = ‖x‖ * ‖y‖`), then the two vectors are nonnegative real multiples of each other. One form -of the equality case for Cauchy-Schwarz. -Compare `abs_inner_eq_norm_iff`, which takes the weaker hypothesis `abs ⟪x, y⟫ = ‖x‖ * ‖y‖`. -/ -lemma inner_eq_norm_mul_iff_real {x y : F} : ⟪x, y⟫_ℝ = ‖x‖ * ‖y‖ ↔ ‖y‖ • x = ‖x‖ • y := -inner_eq_norm_mul_iff - /-- If the inner product of two unit vectors is `1`, then the two vectors are equal. One form of the equality case for Cauchy-Schwarz. -/ -lemma inner_eq_norm_mul_iff_of_norm_one {x y : E} (hx : ‖x‖ = 1) (hy : ‖y‖ = 1) : +lemma inner_eq_one_iff_of_norm_one {x y : E} (hx : ‖x‖ = 1) (hy : ‖y‖ = 1) : ⟪x, y⟫ = 1 ↔ x = y := by { convert inner_eq_norm_mul_iff using 2; simp [hx, hy] } diff --git a/src/analysis/quaternion.lean b/src/analysis/quaternion.lean index 35bf8ff9e3bd3..f00c116fe91f6 100644 --- a/src/analysis/quaternion.lean +++ b/src/analysis/quaternion.lean @@ -42,8 +42,8 @@ lemma inner_self (a : ℍ) : ⟪a, a⟫ = norm_sq a := rfl lemma inner_def (a b : ℍ) : ⟪a, b⟫ = (a * star b).re := rfl noncomputable instance : normed_add_comm_group ℍ := -@inner_product_space.of_core.to_normed_add_comm_group ℝ ℍ _ _ _ -{ inner := has_inner.inner, +@inner_product_space.core.to_normed_add_comm_group ℝ ℍ _ _ _ +{ to_has_inner := infer_instance, conj_symm := λ x y, by simp [inner_def, mul_comm], nonneg_re := λ x, norm_sq_nonneg, definite := λ x, norm_sq_eq_zero.1, diff --git a/src/geometry/manifold/instances/sphere.lean b/src/geometry/manifold/instances/sphere.lean index c8ad586833bae..6ab30af5703da 100644 --- a/src/geometry/manifold/instances/sphere.lean +++ b/src/geometry/manifold/instances/sphere.lean @@ -283,7 +283,7 @@ def stereographic (hv : ‖v‖ = 1) : local_homeomorph (sphere (0:E) 1) (ℝ open_source := is_open_compl_singleton, open_target := is_open_univ, continuous_to_fun := continuous_on_stereo_to_fun.comp continuous_subtype_coe.continuous_on - (λ w h, h ∘ subtype.ext ∘ eq.symm ∘ (inner_eq_norm_mul_iff_of_norm_one hv (by simp)).mp), + (λ w h, h ∘ subtype.ext ∘ eq.symm ∘ (inner_eq_one_iff_of_norm_one hv (by simp)).mp), continuous_inv_fun := (continuous_stereo_inv_fun hv).continuous_on } lemma stereographic_apply (hv : ‖v‖ = 1) (x : sphere (0 : E) 1) : @@ -363,7 +363,7 @@ section smooth_manifold lemma sphere_ext_iff (u v : sphere (0:E) 1) : u = v ↔ ⟪(u:E), v⟫_ℝ = 1 := -by simp [subtype.ext_iff, inner_eq_norm_mul_iff_of_norm_one] +by simp [subtype.ext_iff, inner_eq_one_iff_of_norm_one] lemma stereographic'_symm_apply {n : ℕ} [fact (finrank ℝ E = n + 1)] (v : sphere (0:E) 1) (x : euclidean_space ℝ (fin n)) : @@ -448,7 +448,7 @@ begin ext x, have hfxv : f x = -↑v ↔ ⟪f x, -↑v⟫_ℝ = 1, { have hfx : ‖f x‖ = 1 := by simpa using hf' x, - rw inner_eq_norm_mul_iff_of_norm_one hfx, + rw inner_eq_one_iff_of_norm_one hfx, exact norm_eq_of_mem_sphere (-v) }, dsimp [chart_at], simp [not_iff_not, subtype.ext_iff, hfxv, real_inner_comm] diff --git a/src/linear_algebra/matrix/pos_def.lean b/src/linear_algebra/matrix/pos_def.lean index c814a4996c235..6e224830d8571 100644 --- a/src/linear_algebra/matrix/pos_def.lean +++ b/src/linear_algebra/matrix/pos_def.lean @@ -143,9 +143,9 @@ variables {𝕜 : Type*} [is_R_or_C 𝕜] {n : Type*} [fintype n] @[reducible] noncomputable def normed_add_comm_group.of_matrix {M : matrix n n 𝕜} (hM : M.pos_def) : normed_add_comm_group (n → 𝕜) := -@inner_product_space.of_core.to_normed_add_comm_group _ _ _ _ _ +@inner_product_space.core.to_normed_add_comm_group _ _ _ _ _ { inner := λ x y, dot_product (star x) (M.mul_vec y), - conj_symm := λ x y, by + conj_symm := λ x y, by dsimp only [has_inner.inner]; rw [star_dot_product, star_ring_end_apply, star_star, star_mul_vec, dot_product_mul_vec, hM.is_hermitian.eq], nonneg_re := λ x, @@ -154,10 +154,10 @@ noncomputable def normed_add_comm_group.of_matrix {M : matrix n n 𝕜} (hM : M. { simp [h] }, { exact le_of_lt (hM.2 x h) } end, - definite := λ x hx, + definite := λ x (hx : dot_product _ _ = 0), begin by_contra' h, - simpa [hx, lt_self_iff_false] using hM.2 x h, + simpa [hx, lt_irrefl] using hM.2 x h, end, add_left := by simp only [star_add, add_dot_product, eq_self_iff_true, forall_const], smul_left := λ x y r, by rw [← smul_eq_mul, ←smul_dot_product, star_ring_end_apply, ← star_smul] } From 698c80e908b68f7cd37f07e0bf4669b41cfe13ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= Date: Thu, 4 May 2023 11:37:56 +0000 Subject: [PATCH 11/17] chore(probability/kernel/composition): swap the order of the arguments of prod_mk_left (#18929) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since `prod_mk_left γ κ` creates a `kernel (γ × α) β` from `κ : kernel α β`, it makes more sense to put the `γ` argument to the left. --- src/probability/kernel/composition.lean | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/probability/kernel/composition.lean b/src/probability/kernel/composition.lean index 75b1c1930c9cb..569398e57c89b 100644 --- a/src/probability/kernel/composition.lean +++ b/src/probability/kernel/composition.lean @@ -462,7 +462,7 @@ open_locale probability_theory section fst_snd /-- Define a `kernel (γ × α) β` from a `kernel α β` by taking the comap of the projection. -/ -def prod_mk_left (κ : kernel α β) (γ : Type*) [measurable_space γ] : kernel (γ × α) β := +def prod_mk_left (γ : Type*) [measurable_space γ] (κ : kernel α β) : kernel (γ × α) β := comap κ prod.snd measurable_snd variables {γ : Type*} {mγ : measurable_space γ} {f : β → γ} {g : γ → α} @@ -470,24 +470,24 @@ variables {γ : Type*} {mγ : measurable_space γ} {f : β → γ} {g : γ → include mγ lemma prod_mk_left_apply (κ : kernel α β) (ca : γ × α) : - prod_mk_left κ γ ca = κ ca.snd := rfl + prod_mk_left γ κ ca = κ ca.snd := rfl lemma prod_mk_left_apply' (κ : kernel α β) (ca : γ × α) (s : set β) : - prod_mk_left κ γ ca s = κ ca.snd s := rfl + prod_mk_left γ κ ca s = κ ca.snd s := rfl lemma lintegral_prod_mk_left (κ : kernel α β) (ca : γ × α) (g : β → ℝ≥0∞) : - ∫⁻ b, g b ∂(prod_mk_left κ γ ca) = ∫⁻ b, g b ∂(κ ca.snd) := rfl + ∫⁻ b, g b ∂(prod_mk_left γ κ ca) = ∫⁻ b, g b ∂(κ ca.snd) := rfl instance is_markov_kernel.prod_mk_left (κ : kernel α β) [is_markov_kernel κ] : - is_markov_kernel (prod_mk_left κ γ) := + is_markov_kernel (prod_mk_left γ κ) := by { rw prod_mk_left, apply_instance, } instance is_finite_kernel.prod_mk_left (κ : kernel α β) [is_finite_kernel κ] : - is_finite_kernel (prod_mk_left κ γ) := + is_finite_kernel (prod_mk_left γ κ) := by { rw prod_mk_left, apply_instance, } instance is_s_finite_kernel.prod_mk_left (κ : kernel α β) [is_s_finite_kernel κ] : - is_s_finite_kernel (prod_mk_left κ γ) := + is_s_finite_kernel (prod_mk_left γ κ) := by { rw prod_mk_left, apply_instance, } /-- Define a `kernel (β × α) γ` from a `kernel (α × β) γ` by taking the comap of `prod.swap`. -/ @@ -613,7 +613,7 @@ include mγ noncomputable def comp (η : kernel β γ) [is_s_finite_kernel η] (κ : kernel α β) [is_s_finite_kernel κ] : kernel α γ := -snd (κ ⊗ₖ prod_mk_left η α) +snd (κ ⊗ₖ prod_mk_left α η) localized "infix (name := kernel.comp) ` ∘ₖ `:100 := probability_theory.kernel.comp" in probability_theory @@ -632,7 +632,7 @@ lemma lintegral_comp (η : kernel β γ) [is_s_finite_kernel η] (κ : kernel α ∫⁻ c, g c ∂((η ∘ₖ κ) a) = ∫⁻ b, ∫⁻ c, g c ∂(η b) ∂(κ a) := begin rw [comp, lintegral_snd _ _ hg], - change ∫⁻ bc, (λ a b, g b) bc.fst bc.snd ∂((κ ⊗ₖ prod_mk_left η α) a) + change ∫⁻ bc, (λ a b, g b) bc.fst bc.snd ∂((κ ⊗ₖ prod_mk_left α η) a) = ∫⁻ b, ∫⁻ c, g c ∂(η b) ∂(κ a), exact lintegral_comp_prod _ _ _ (hg.comp measurable_snd), end @@ -691,7 +691,7 @@ include mγ noncomputable def prod (κ : kernel α β) [is_s_finite_kernel κ] (η : kernel α γ) [is_s_finite_kernel η] : kernel α (β × γ) := -κ ⊗ₖ (swap_left (prod_mk_left η β)) +κ ⊗ₖ (swap_left (prod_mk_left β η)) localized "infix (name := kernel.prod) ` ×ₖ `:100 := probability_theory.kernel.prod" in probability_theory From caf83ba4dfbf4e2f28e1ae6a0780cbafc3d19d6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= Date: Thu, 4 May 2023 11:37:57 +0000 Subject: [PATCH 12/17] chore(probability/kernel/basic): make the function argument of kernel.deterministic explicit (#18930) If that argument is implicit, the infoview often shows only `deterministic _`, which does not allow to see which function is used. Making it explicit fixes that problem. --- src/probability/kernel/basic.lean | 10 +++++----- src/probability/kernel/composition.lean | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/probability/kernel/basic.lean b/src/probability/kernel/basic.lean index 6ebb39aace833..a3163ffd2284f 100644 --- a/src/probability/kernel/basic.lean +++ b/src/probability/kernel/basic.lean @@ -28,7 +28,7 @@ Classes of kernels: * `is_s_finite_kernel κ`: a kernel is called s-finite if it is a countable sum of finite kernels. Particular kernels: -* `deterministic {f : α → β} (hf : measurable f)`: kernel `a ↦ measure.dirac (f a)`. +* `deterministic (f : α → β) (hf : measurable f)`: kernel `a ↦ measure.dirac (f a)`. * `const α (μβ : measure β)`: constant kernel `a ↦ μβ`. * `kernel.restrict κ (hs : measurable_set s)`: kernel for which the image of `a : α` is `(κ a).restrict s`. @@ -317,7 +317,7 @@ section deterministic /-- Kernel which to `a` associates the dirac measure at `f a`. This is a Markov kernel. -/ noncomputable -def deterministic {f : α → β} (hf : measurable f) : +def deterministic (f : α → β) (hf : measurable f) : kernel α β := { val := λ a, measure.dirac (f a), property := @@ -328,11 +328,11 @@ def deterministic {f : α → β} (hf : measurable f) : end, } lemma deterministic_apply {f : α → β} (hf : measurable f) (a : α) : - deterministic hf a = measure.dirac (f a) := rfl + deterministic f hf a = measure.dirac (f a) := rfl lemma deterministic_apply' {f : α → β} (hf : measurable f) (a : α) {s : set β} (hs : measurable_set s) : - deterministic hf a s = s.indicator (λ _, 1) (f a) := + deterministic f hf a s = s.indicator (λ _, 1) (f a) := begin rw [deterministic], change measure.dirac (f a) s = s.indicator 1 (f a), @@ -340,7 +340,7 @@ begin end instance is_markov_kernel_deterministic {f : α → β} (hf : measurable f) : - is_markov_kernel (deterministic hf) := + is_markov_kernel (deterministic f hf) := ⟨λ a, by { rw deterministic_apply hf, apply_instance, }⟩ end deterministic diff --git a/src/probability/kernel/composition.lean b/src/probability/kernel/composition.lean index 569398e57c89b..011bc48df906c 100644 --- a/src/probability/kernel/composition.lean +++ b/src/probability/kernel/composition.lean @@ -662,7 +662,7 @@ begin end lemma deterministic_comp_eq_map (hf : measurable f) (κ : kernel α β) [is_s_finite_kernel κ] : - (deterministic hf ∘ₖ κ) = map κ f hf := + (deterministic f hf ∘ₖ κ) = map κ f hf := begin ext a s hs : 2, simp_rw [map_apply' _ _ _ hs, comp_apply _ _ _ hs, deterministic_apply' hf _ hs, @@ -670,7 +670,7 @@ begin end lemma comp_deterministic_eq_comap (κ : kernel α β) [is_s_finite_kernel κ] (hg : measurable g) : - (κ ∘ₖ deterministic hg) = comap κ g hg := + (κ ∘ₖ deterministic g hg) = comap κ g hg := begin ext a s hs : 2, simp_rw [comap_apply' _ _ _ s, comp_apply _ _ _ hs, deterministic_apply hg a, From 338fe44f54751b9f7deaca47ffca3509f53140ae Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Thu, 4 May 2023 11:37:58 +0000 Subject: [PATCH 13/17] feat(data/is_R_or_C/basic): drop 2 fields, golf (#18931) * Drop fields `inv_def_ax` and `div_I_ax` in `is_R_or_C`, deduce them instead. * Use lemmas about `ring_hom`s to prove properties of coercion, `is_R_or_C.re` etc. * Drop `is_R_or_C.of_real_hom` and `is_R_or_C.coe_hom`. * Drop `is_R_or_C.inv_zero` and `is_R_or_C.mul_inv_cancel`. * Move some lemmas to more appropriate sections. --- src/analysis/complex/basic.lean | 5 +- src/data/is_R_or_C/basic.lean | 193 ++++++++++++-------------------- 2 files changed, 73 insertions(+), 125 deletions(-) diff --git a/src/analysis/complex/basic.lean b/src/analysis/complex/basic.lean index 455d27e524793..4a046d4ec7e65 100644 --- a/src/analysis/complex/basic.lean +++ b/src/analysis/complex/basic.lean @@ -312,10 +312,7 @@ noncomputable instance : is_R_or_C ℂ := conj_I_ax := by simp only [complex.conj_I, ring_hom.coe_mk], norm_sq_eq_def_ax := λ z, by simp only [←complex.norm_sq_eq_abs, ←complex.norm_sq_apply, add_monoid_hom.coe_mk, complex.norm_eq_abs], - mul_im_I_ax := λ z, by simp only [mul_one, add_monoid_hom.coe_mk, complex.I_im], - inv_def_ax := λ z, by simp only [complex.inv_def, complex.norm_sq_eq_abs, complex.coe_algebra_map, - complex.of_real_eq_coe, complex.norm_eq_abs], - div_I_ax := complex.div_I } + mul_im_I_ax := λ z, by simp only [mul_one, add_monoid_hom.coe_mk, complex.I_im] } lemma _root_.is_R_or_C.re_eq_complex_re : ⇑(is_R_or_C.re : ℂ →+ ℝ) = complex.re := rfl lemma _root_.is_R_or_C.im_eq_complex_im : ⇑(is_R_or_C.im : ℂ →+ ℝ) = complex.im := rfl diff --git a/src/data/is_R_or_C/basic.lean b/src/data/is_R_or_C/basic.lean index dd036822025a4..c4c1b2924aa12 100644 --- a/src/data/is_R_or_C/basic.lean +++ b/src/data/is_R_or_C/basic.lean @@ -64,8 +64,6 @@ class is_R_or_C (K : Type*) (conj_I_ax : conj I = -I) (norm_sq_eq_def_ax : ∀ (z : K), ‖z‖^2 = (re z) * (re z) + (im z) * (im z)) (mul_im_I_ax : ∀ (z : K), (im z) * im I = im z) -(inv_def_ax : ∀ (z : K), z⁻¹ = conj z * 𝓚 ((‖z‖^2)⁻¹)) -(div_I_ax : ∀ (z : K), z / I = -(z * I)) end @@ -85,7 +83,7 @@ lemma of_real_alg (x : ℝ) : (x : K) = x • (1 : K) := algebra.algebra_map_eq_smul_one x lemma real_smul_eq_coe_mul (r : ℝ) (z : K) : r • z = (r : K) * z := -by rw [is_R_or_C.of_real_alg, ←smul_eq_mul, smul_assoc, smul_eq_mul, one_mul] +algebra.smul_def r z lemma real_smul_eq_coe_smul [add_comm_group E] [module K E] [module ℝ E] [is_scalar_tower ℝ K E] (r : ℝ) (x : E) : r • x = (r : K) • x := @@ -104,62 +102,77 @@ is_R_or_C.mul_re_ax @[simp, is_R_or_C_simps] lemma mul_im : ∀ z w : K, im (z * w) = re z * im w + im z * re w := is_R_or_C.mul_im_ax -theorem inv_def (z : K) : z⁻¹ = conj z * ((‖z‖^2)⁻¹:ℝ) := -is_R_or_C.inv_def_ax z - -theorem ext_iff : ∀ {z w : K}, z = w ↔ re z = re w ∧ im z = im w := -λ z w, { mp := by { rintro rfl, cc }, - mpr := by { rintro ⟨h₁,h₂⟩, rw [←re_add_im z, ←re_add_im w, h₁, h₂] } } - -theorem ext : ∀ {z w : K}, re z = re w → im z = im w → z = w := -by { simp_rw ext_iff, cc } +theorem ext_iff {z w : K} : z = w ↔ re z = re w ∧ im z = im w := +⟨λ h, h ▸ ⟨rfl, rfl⟩, λ ⟨h₁, h₂⟩, re_add_im z ▸ re_add_im w ▸ h₁ ▸ h₂ ▸ rfl⟩ +theorem ext {z w : K} (hre : re z = re w) (him : im z = im w) : z = w := +ext_iff.2 ⟨hre, him⟩ @[norm_cast] lemma of_real_zero : ((0 : ℝ) : K) = 0 := by rw [of_real_alg, zero_smul] @[simp, is_R_or_C_simps] lemma zero_re' : re (0 : K) = (0 : ℝ) := re.map_zero -@[norm_cast] lemma of_real_one : ((1 : ℝ) : K) = 1 := -by rw [of_real_alg, one_smul] -@[simp, is_R_or_C_simps] lemma one_re : re (1 : K) = 1 := by rw [←of_real_one, of_real_re] -@[simp, is_R_or_C_simps] lemma one_im : im (1 : K) = 0 := by rw [←of_real_one, of_real_im] +@[norm_cast] lemma of_real_one : ((1 : ℝ) : K) = 1 := map_one (algebra_map ℝ K) +@[simp, is_R_or_C_simps] lemma one_re : re (1 : K) = 1 := by rw [← of_real_one, of_real_re] +@[simp, is_R_or_C_simps] lemma one_im : im (1 : K) = 0 := by rw [← of_real_one, of_real_im] + +theorem of_real_injective : function.injective (coe : ℝ → K) := (algebra_map ℝ K).injective @[norm_cast] theorem of_real_inj {z w : ℝ} : (z : K) = (w : K) ↔ z = w := -{ mp := λ h, by { convert congr_arg re h; simp only [of_real_re] }, - mpr := λ h, by rw h } +algebra_map.coe_inj -@[simp, is_R_or_C_simps] lemma bit0_re (z : K) : re (bit0 z) = bit0 (re z) := -by simp only [bit0, map_add] +@[simp, is_R_or_C_simps] lemma bit0_re (z : K) : re (bit0 z) = bit0 (re z) := map_bit0 _ _ @[simp, is_R_or_C_simps] lemma bit1_re (z : K) : re (bit1 z) = bit1 (re z) := -by simp only [bit1, add_monoid_hom.map_add, bit0_re, add_right_inj, one_re] -@[simp, is_R_or_C_simps] lemma bit0_im (z : K) : im (bit0 z) = bit0 (im z) := -by simp only [bit0, map_add] +by simp only [bit1, map_add, bit0_re, one_re] +@[simp, is_R_or_C_simps] lemma bit0_im (z : K) : im (bit0 z) = bit0 (im z) := map_bit0 _ _ @[simp, is_R_or_C_simps] lemma bit1_im (z : K) : im (bit1 z) = bit0 (im z) := -by simp only [bit1, add_right_eq_self, add_monoid_hom.map_add, bit0_im, one_im] +by simp only [bit1, map_add, bit0_im, one_im, add_zero] -theorem of_real_eq_zero {z : ℝ} : (z : K) = 0 ↔ z = 0 := -by rw [←of_real_zero]; exact of_real_inj - -theorem of_real_ne_zero {z : ℝ} : (z : K) ≠ 0 ↔ z ≠ 0 := of_real_eq_zero.not +theorem of_real_eq_zero {x : ℝ} : (x : K) = 0 ↔ x = 0 := algebra_map.lift_map_eq_zero_iff x +theorem of_real_ne_zero {x : ℝ} : (x : K) ≠ 0 ↔ x ≠ 0 := of_real_eq_zero.not @[simp, is_R_or_C_simps, norm_cast, priority 900] -lemma of_real_add ⦃r s : ℝ⦄ : ((r + s : ℝ) : K) = r + s := -by { apply (@is_R_or_C.ext_iff K _ ((r + s : ℝ) : K) (r + s)).mpr, simp } +lemma of_real_add (r s : ℝ) : ((r + s : ℝ) : K) = r + s := algebra_map.coe_add _ _ @[simp, is_R_or_C_simps, norm_cast, priority 900] -lemma of_real_bit0 (r : ℝ) : ((bit0 r : ℝ) : K) = bit0 (r : K) := -ext_iff.2 $ by simp [bit0] +lemma of_real_bit0 (r : ℝ) : ((bit0 r : ℝ) : K) = bit0 (r : K) := of_real_add _ _ @[simp, is_R_or_C_simps, norm_cast, priority 900] lemma of_real_bit1 (r : ℝ) : ((bit1 r : ℝ) : K) = bit1 (r : K) := -ext_iff.2 $ by simp [bit1] +map_bit1 (algebra_map ℝ K) r + +@[simp, norm_cast, is_R_or_C_simps, priority 900] +lemma of_real_neg (r : ℝ) : ((-r : ℝ) : K) = -r := algebra_map.coe_neg r + +@[simp, norm_cast, is_R_or_C_simps, priority 900] +lemma of_real_sub (r s : ℝ) : ((r - s : ℝ) : K) = r - s := map_sub (algebra_map ℝ K) r s + +@[simp, is_R_or_C_simps, norm_cast, priority 900] +lemma of_real_sum {α : Type*} (s : finset α) (f : α → ℝ) : + ((∑ i in s, f i : ℝ) : K) = ∑ i in s, (f i : K) := +map_sum (algebra_map ℝ K) _ _ + +@[simp, is_R_or_C_simps, norm_cast] lemma of_real_finsupp_sum + {α M : Type*} [has_zero M] (f : α →₀ M) (g : α → M → ℝ) : + ((f.sum (λ a b, g a b) : ℝ) : K) = f.sum (λ a b, ((g a b) : K)) := +map_finsupp_sum (algebra_map ℝ K) f g @[simp, norm_cast, is_R_or_C_simps, priority 900] -lemma of_real_neg (r : ℝ) : ((-r : ℝ) : K) = -r := ext_iff.2 $ by simp +lemma of_real_mul (r s : ℝ) : ((r * s : ℝ) : K) = r * s := algebra_map.coe_mul _ _ @[simp, norm_cast, is_R_or_C_simps, priority 900] -lemma of_real_mul (r s : ℝ) : ((r * s : ℝ) : K) = r * s := ext_iff.2 $ by simp with is_R_or_C_simps +lemma of_real_pow (r : ℝ) (n : ℕ) : ((r ^ n : ℝ) : K) = r ^ n := map_pow (algebra_map ℝ K) r n + +@[simp, is_R_or_C_simps, norm_cast, priority 900] +lemma of_real_prod {α : Type*} (s : finset α) (f : α → ℝ) : + ((∏ i in s, f i : ℝ) : K) = ∏ i in s, (f i : K) := +ring_hom.map_prod _ _ _ + +@[simp, is_R_or_C_simps, norm_cast] lemma of_real_finsupp_prod + {α M : Type*} [has_zero M] (f : α →₀ M) (g : α → M → ℝ) : + ((f.prod (λ a b, g a b) : ℝ) : K) = f.prod (λ a b, ((g a b) : K)) := +ring_hom.map_finsupp_prod _ f g @[simp, norm_cast, is_R_or_C_simps] lemma of_real_smul (r x : ℝ) : r • (x : K) = (r : K) * (x : K) := @@ -201,14 +214,11 @@ lemma I_mul_I : (I : K) = 0 ∨ (I : K) * I = -1 := I_mul_I_ax by { rw ext_iff, simp only [of_real_im, conj_im, eq_self_iff_true, conj_re, and_self, neg_zero] } -@[simp, is_R_or_C_simps] lemma conj_bit0 (z : K) : conj (bit0 z) = bit0 (conj z) := -by simp only [bit0, ring_hom.map_add, eq_self_iff_true] -@[simp, is_R_or_C_simps] lemma conj_bit1 (z : K) : conj (bit1 z) = bit1 (conj z) := -by simp only [bit0, ext_iff, bit1_re, conj_im, eq_self_iff_true, conj_re, neg_add_rev, - and_self, bit1_im] +@[simp, is_R_or_C_simps] lemma conj_bit0 (z : K) : conj (bit0 z) = bit0 (conj z) := map_bit0 _ _ +@[simp, is_R_or_C_simps] lemma conj_bit1 (z : K) : conj (bit1 z) = bit1 (conj z) := map_bit1 _ _ @[simp, is_R_or_C_simps] lemma conj_neg_I : conj (-I) = (I : K) := -by simp only [conj_I, ring_hom.map_neg, eq_self_iff_true, neg_neg] +by rw [map_neg, conj_I, neg_neg] lemma conj_eq_re_sub_im (z : K) : conj z = re z - (im z) * I := by { rw ext_iff, simp only [add_zero, I_re, of_real_im, I_im, zero_sub, zero_mul, conj_im, @@ -305,24 +315,6 @@ theorem add_conj (z : K) : z + conj z = 2 * (re z) := by simp only [ext_iff, two_mul, map_add, add_zero, of_real_im, conj_im, of_real_re, eq_self_iff_true, add_right_neg, conj_re, and_self] -/-- The pseudo-coercion `of_real` as a `ring_hom`. -/ -noncomputable def of_real_hom : ℝ →+* K := algebra_map ℝ K - -/-- The coercion from reals as a `ring_hom`. -/ -noncomputable def coe_hom : ℝ →+* K := ⟨coe, of_real_one, of_real_mul, of_real_zero, of_real_add⟩ - -@[simp, norm_cast, is_R_or_C_simps, priority 900] lemma of_real_sub (r s : ℝ) : - ((r - s : ℝ) : K) = r - s := -ext_iff.2 $ by simp only [of_real_im, of_real_re, eq_self_iff_true, sub_zero, and_self, map_sub] - -@[simp, norm_cast, is_R_or_C_simps, priority 900] lemma of_real_pow (r : ℝ) (n : ℕ) : - ((r ^ n : ℝ) : K) = r ^ n := -begin - induction n, - { simp only [of_real_one, pow_zero]}, - { simp only [*, of_real_mul, pow_succ]} -end - theorem sub_conj (z : K) : z - conj z = (2 * im z) * I := by simp only [ext_iff, two_mul, sub_eq_add_neg, add_mul, map_add, add_zero, add_left_inj, zero_mul, map_add_neg, eq_self_iff_true, add_right_neg, and_self, neg_neg, mul_zero, neg_zero] @@ -333,42 +325,32 @@ by simp only [norm_sq_add, sub_eq_add_neg, ring_equiv.map_neg, mul_neg, norm_sq_neg, map_neg] lemma sqrt_norm_sq_eq_norm {z : K} : real.sqrt (norm_sq z) = ‖z‖ := -begin - have h₂ : ‖z‖ = real.sqrt (‖z‖^2) := (real.sqrt_sq (norm_nonneg z)).symm, - rw [h₂], - exact congr_arg real.sqrt (norm_sq_eq_def' z) -end +by rw [norm_sq_eq_def', real.sqrt_sq (norm_nonneg _)] /-! ### Inversion -/ -@[simp, is_R_or_C_simps] lemma inv_re (z : K) : re (z⁻¹) = re z / norm_sq z := -by simp only [inv_def, norm_sq_eq_def, norm_sq, division_def, - monoid_with_zero_hom.coe_mk, sub_zero, mul_zero] with is_R_or_C_simps -@[simp, is_R_or_C_simps] lemma inv_im (z : K) : im (z⁻¹) = im (-z) / norm_sq z := -by simp only [inv_def, norm_sq_eq_def, norm_sq, division_def, of_real_im, - monoid_with_zero_hom.coe_mk, of_real_re, zero_add, map_neg, mul_zero] - with is_R_or_C_simps - @[simp, norm_cast, is_R_or_C_simps, priority 900] -lemma of_real_inv (r : ℝ) : ((r⁻¹ : ℝ) : K) = r⁻¹ := +lemma of_real_inv (r : ℝ) : ((r⁻¹ : ℝ) : K) = r⁻¹ := map_inv₀ (algebra_map ℝ K) r + +theorem inv_def (z : K) : z⁻¹ = conj z * ((‖z‖^2)⁻¹:ℝ) := begin - rw ext_iff, - by_cases r = 0, - { simp only [h, of_real_zero, inv_zero, and_self, map_zero]}, - { simp only with is_R_or_C_simps, - field_simp [h, norm_sq] } + rcases eq_or_ne z 0 with (rfl | h₀), + { simp }, + { apply inv_eq_of_mul_eq_one_right, + rw [← mul_assoc, mul_conj, of_real_inv, ← norm_sq_eq_def', mul_inv_cancel], + rwa [of_real_ne_zero, ne.def, norm_sq_eq_zero] } end -protected lemma inv_zero : (0⁻¹ : K) = 0 := -by rw [← of_real_zero, ← of_real_inv, inv_zero] +@[simp, is_R_or_C_simps] lemma inv_re (z : K) : re (z⁻¹) = re z / norm_sq z := +by rw [inv_def, norm_sq_eq_def', mul_comm, of_real_mul_re, conj_re, div_eq_inv_mul] -protected theorem mul_inv_cancel {z : K} (h : z ≠ 0) : z * z⁻¹ = 1 := -by rw [inv_def, ←mul_assoc, mul_conj, ←of_real_mul, ←norm_sq_eq_def', - mul_inv_cancel (mt norm_sq_eq_zero.1 h), of_real_one] +@[simp, is_R_or_C_simps] lemma inv_im (z : K) : im (z⁻¹) = -im z / norm_sq z := +by rw [inv_def, norm_sq_eq_def', mul_comm, of_real_mul_im, conj_im, div_eq_inv_mul] lemma div_re (z w : K) : re (z / w) = re z * re w / norm_sq w + im z * im w / norm_sq w := by simp only [div_eq_mul_inv, mul_assoc, sub_eq_add_neg, neg_mul, mul_neg, neg_neg, map_neg] with is_R_or_C_simps + lemma div_im (z w : K) : im (z / w) = im z * re w / norm_sq w - re z * im w / norm_sq w := by simp only [div_eq_mul_inv, mul_assoc, sub_eq_add_neg, add_comm, neg_mul, mul_neg, map_neg] with is_R_or_C_simps @@ -378,23 +360,16 @@ lemma conj_inv (x : K) : conj (x⁻¹) = (conj x)⁻¹ := star_inv' _ @[simp, norm_cast, is_R_or_C_simps, priority 900] lemma of_real_div (r s : ℝ) : ((r / s : ℝ) : K) = r / s := -map_div₀ (@is_R_or_C.coe_hom K _) r s +map_div₀ (algebra_map ℝ K) r s lemma div_re_of_real {z : K} {r : ℝ} : re (z / r) = re z / r := -begin - by_cases h : r = 0, - { simp only [h, of_real_zero, div_zero, zero_re']}, - { change r ≠ 0 at h, - rw [div_eq_mul_inv, ←of_real_inv, div_eq_mul_inv], - simp only [one_div, of_real_im, of_real_re, sub_zero, mul_re, mul_zero]} -end +by rw [div_eq_inv_mul, div_eq_inv_mul, ← of_real_inv, of_real_mul_re] @[simp, norm_cast, is_R_or_C_simps, priority 900] lemma of_real_zpow (r : ℝ) (n : ℤ) : ((r ^ n : ℝ) : K) = r ^ n := -map_zpow₀ (@is_R_or_C.coe_hom K _) r n +map_zpow₀ (algebra_map ℝ K) r n -lemma I_mul_I_of_nonzero : (I : K) ≠ 0 → (I : K) * I = -1 := -by { have := I_mul_I_ax, tauto } +lemma I_mul_I_of_nonzero : (I : K) ≠ 0 → (I : K) * I = -1 := I_mul_I_ax.resolve_left @[simp, is_R_or_C_simps] lemma div_I (z : K) : z / I = -(z * I) := begin @@ -422,7 +397,7 @@ by simp only [←sqrt_norm_sq_eq_norm, norm_sq_conj] @[simp, is_R_or_C_simps, norm_cast, priority 900] theorem of_real_nat_cast (n : ℕ) : ((n : ℝ) : K) = n := -map_nat_cast (@of_real_hom K _) n +map_nat_cast (algebra_map ℝ K) n @[simp, is_R_or_C_simps, norm_cast] lemma nat_cast_re (n : ℕ) : re (n : K) = n := by rw [← of_real_nat_cast, of_real_re] @@ -431,7 +406,7 @@ by rw [← of_real_nat_cast, of_real_re] by rw [← of_real_nat_cast, of_real_im] @[simp, is_R_or_C_simps, norm_cast, priority 900] -lemma of_real_int_cast (n : ℤ) : ((n : ℝ) : K) = n := map_int_cast (@of_real_hom K _) n +lemma of_real_int_cast (n : ℤ) : ((n : ℝ) : K) = n := map_int_cast (algebra_map ℝ K) n @[simp, is_R_or_C_simps, norm_cast] lemma int_cast_re (n : ℤ) : re (n : K) = n := by rw [← of_real_int_cast, of_real_re] @@ -441,7 +416,7 @@ by rw [← of_real_int_cast, of_real_im] @[simp, is_R_or_C_simps, norm_cast, priority 900] theorem of_real_rat_cast (n : ℚ) : ((n : ℝ) : K) = n := -map_rat_cast (@is_R_or_C.of_real_hom K _) n +map_rat_cast (algebra_map ℝ K) n @[simp, is_R_or_C_simps, norm_cast] lemma rat_cast_re (q : ℚ) : re (q : K) = q := by rw [← of_real_rat_cast, of_real_re] @@ -646,26 +621,6 @@ lemma is_cau_seq_abs {f : ℕ → K} (hf : is_cau_seq abs f) : λ ε ε0, let ⟨i, hi⟩ := hf ε ε0 in ⟨i, λ j hj, lt_of_le_of_lt (abs_abs_sub_le_abs_sub _ _) (hi j hj)⟩ -@[simp, is_R_or_C_simps, norm_cast, priority 900] -lemma of_real_prod {α : Type*} (s : finset α) (f : α → ℝ) : - ((∏ i in s, f i : ℝ) : K) = ∏ i in s, (f i : K) := -ring_hom.map_prod _ _ _ - -@[simp, is_R_or_C_simps, norm_cast, priority 900] -lemma of_real_sum {α : Type*} (s : finset α) (f : α → ℝ) : - ((∑ i in s, f i : ℝ) : K) = ∑ i in s, (f i : K) := -ring_hom.map_sum _ _ _ - -@[simp, is_R_or_C_simps, norm_cast] lemma of_real_finsupp_sum - {α M : Type*} [has_zero M] (f : α →₀ M) (g : α → M → ℝ) : - ((f.sum (λ a b, g a b) : ℝ) : K) = f.sum (λ a b, ((g a b) : K)) := -ring_hom.map_finsupp_sum _ f g - -@[simp, is_R_or_C_simps, norm_cast] lemma of_real_finsupp_prod - {α M : Type*} [has_zero M] (f : α →₀ M) (g : α → M → ℝ) : - ((f.prod (λ a b, g a b) : ℝ) : K) = f.prod (λ a b, ((g a b) : K)) := -ring_hom.map_finsupp_prod _ f g - end is_R_or_C @@ -690,10 +645,6 @@ noncomputable instance real.is_R_or_C : is_R_or_C ℝ := norm_sq_eq_def_ax := λ z, by simp only [sq, real.norm_eq_abs, ←abs_mul, abs_mul_self z, add_zero, mul_zero, add_monoid_hom.zero_apply, add_monoid_hom.id_apply], mul_im_I_ax := λ z, by simp only [mul_zero, add_monoid_hom.zero_apply], - inv_def_ax := λ z, by simp only [star_ring_end_apply, star, sq, real.norm_eq_abs, - abs_mul_abs_self, ←div_eq_mul_inv, algebra.id.map_eq_id, id.def, ring_hom.id_apply, - div_self_mul_self'], - div_I_ax := λ z, by simp only [div_zero, mul_zero, neg_zero], .. real.densely_normed_field, .. real.metric_space } end instances From 2f39bcbc98f8255490f8d4562762c9467694c809 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Thu, 4 May 2023 11:38:00 +0000 Subject: [PATCH 14/17] chore(ring_theory/ideal/quotient): add missing smul compatibility instances (#18934) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The low priority is needed to avoid a timeout in what will be `ring_theory/kaehler.lean`. These instances are more general cases of the instances implied by `algebra α c.quotient` and `algebra α (R ⧸ I)`, which work for cases like `α = units R`. --- src/ring_theory/congruence.lean | 17 +++++++++++++++++ src/ring_theory/ideal/quotient.lean | 14 ++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/ring_theory/congruence.lean b/src/ring_theory/congruence.lean index f0c339ea28545..865204133e71c 100644 --- a/src/ring_theory/congruence.lean +++ b/src/ring_theory/congruence.lean @@ -247,6 +247,23 @@ function.surjective.comm_ring _ quotient.surjective_quotient_mk' rfl rfl (λ _ _, rfl) (λ _ _, rfl) (λ _, rfl) (λ _ _, rfl) (λ _ _, rfl) (λ _ _, rfl) (λ _ _, rfl) (λ _, rfl) (λ _, rfl) +instance is_scalar_tower_right [has_add R] [mul_one_class R] [has_smul α R] [is_scalar_tower α R R] + (c : ring_con R) : + is_scalar_tower α c.quotient c.quotient := +{ smul_assoc := λ a, quotient.ind₂' $ by exact λ m₁ m₂, + congr_arg quotient.mk' $ smul_mul_assoc _ _ _ } + +instance smul_comm_class [has_add R] [mul_one_class R] [has_smul α R] + [is_scalar_tower α R R] [smul_comm_class α R R] (c : ring_con R) : + smul_comm_class α c.quotient c.quotient := +{ smul_comm := λ a, quotient.ind₂' $ by exact λ m₁ m₂, + congr_arg quotient.mk' $ (mul_smul_comm _ _ _).symm } + +instance smul_comm_class' [has_add R] [mul_one_class R] [has_smul α R] + [is_scalar_tower α R R] [smul_comm_class R α R] (c : ring_con R) : + smul_comm_class c.quotient α c.quotient := +by haveI := smul_comm_class.symm R α R; exact smul_comm_class.symm _ _ _ + instance [monoid α] [non_assoc_semiring R] [distrib_mul_action α R] [is_scalar_tower α R R] (c : ring_con R) : distrib_mul_action α c.quotient := diff --git a/src/ring_theory/ideal/quotient.lean b/src/ring_theory/ideal/quotient.lean index cda8ece37d175..4cefd306702b4 100644 --- a/src/ring_theory/ideal/quotient.lean +++ b/src/ring_theory/ideal/quotient.lean @@ -72,6 +72,20 @@ instance comm_ring (I : ideal R) : comm_ring (R ⧸ I) := { ..submodule.quotient.add_comm_group I, -- to help with unification ..(quotient.ring_con I)^.quotient.comm_ring } +-- this instance is harder to find than the one via `algebra α (R ⧸ I)`, so use a lower priority +@[priority 100] +instance is_scalar_tower_right {α} [has_smul α R] [is_scalar_tower α R R] : + is_scalar_tower α (R ⧸ I) (R ⧸ I) := +(quotient.ring_con I)^.is_scalar_tower_right + +instance smul_comm_class {α} [has_smul α R] [is_scalar_tower α R R] [smul_comm_class α R R] : + smul_comm_class α (R ⧸ I) (R ⧸ I) := +(quotient.ring_con I)^.smul_comm_class + +instance smul_comm_class' {α} [has_smul α R] [is_scalar_tower α R R] [smul_comm_class R α R] : + smul_comm_class (R ⧸ I) α (R ⧸ I) := +(quotient.ring_con I)^.smul_comm_class' + /-- The ring homomorphism from a ring `R` to a quotient ring `R/I`. -/ def mk (I : ideal R) : R →+* (R ⧸ I) := ⟨λ a, submodule.quotient.mk a, rfl, λ _ _, rfl, rfl, λ _ _, rfl⟩ From 26ae6f6771ba2d8c76ac47efb84ef2908f178630 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Thu, 4 May 2023 11:38:01 +0000 Subject: [PATCH 15/17] chore(ring_theory/derivation): generalize tower instance (#18937) --- src/ring_theory/derivation.lean | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ring_theory/derivation.lean b/src/ring_theory/derivation.lean index 5d70b42f02def..8816fcedc40de 100644 --- a/src/ring_theory/derivation.lean +++ b/src/ring_theory/derivation.lean @@ -159,8 +159,9 @@ instance : inhabited (derivation R A M) := ⟨0⟩ section scalar -variables {S : Type*} [monoid S] [distrib_mul_action S M] [smul_comm_class R S M] - [smul_comm_class S A M] +variables {S T : Type*} +variables [monoid S] [distrib_mul_action S M] [smul_comm_class R S M] [smul_comm_class S A M] +variables [monoid T] [distrib_mul_action T M] [smul_comm_class R T M] [smul_comm_class T A M] @[priority 100] instance : has_smul S (derivation R A M) := @@ -190,6 +191,12 @@ instance [distrib_mul_action Sᵐᵒᵖ M] [is_central_scalar S M] : is_central_scalar S (derivation R A M) := { op_smul_eq_smul := λ _ _, ext $ λ _, op_smul_eq_smul _ _} +instance [has_smul S T] [is_scalar_tower S T M] : is_scalar_tower S T (derivation R A M) := +⟨λ x y z, ext $ λ a, smul_assoc _ _ _⟩ + +instance [smul_comm_class S T M] : smul_comm_class S T (derivation R A M) := +⟨λ x y z, ext $ λ a, smul_comm _ _ _⟩ + end scalar @[priority 100] @@ -197,9 +204,6 @@ instance {S : Type*} [semiring S] [module S M] [smul_comm_class R S M] [smul_com module S (derivation R A M) := function.injective.module S coe_fn_add_monoid_hom coe_injective coe_smul -instance [is_scalar_tower R A M] : is_scalar_tower R A (derivation R A M) := -⟨λ x y z, ext (λ a, smul_assoc _ _ _)⟩ - section push_forward variables {N : Type*} [add_comm_monoid N] [module A N] [module R N] [is_scalar_tower R A M] From 570e9f4877079b3a923135b3027ac3be8695ab8c Mon Sep 17 00:00:00 2001 From: "Filippo A. E. Nuccio" Date: Thu, 4 May 2023 13:44:28 +0000 Subject: [PATCH 16/17] feat(ring_theory/localization/away) : Add `num_denom` section (#18830) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added a section `num_denom`: the main result is the lemma `exists_reduced_fraction` that shows that every non-zero element `b` in a `localization.away x` of a UFM can be written in a unique way as `b=x^n * a` with `n : ℤ` and `a` not divisible by `x`. Co-authored-by: Vierkantor --- src/ring_theory/localization/away.lean | 142 ++++++++++++++++++ .../unique_factorization_domain.lean | 28 +++- 2 files changed, 162 insertions(+), 8 deletions(-) diff --git a/src/ring_theory/localization/away.lean b/src/ring_theory/localization/away.lean index 39d04cb19893d..0ea25713791eb 100644 --- a/src/ring_theory/localization/away.lean +++ b/src/ring_theory/localization/away.lean @@ -13,6 +13,8 @@ import ring_theory.localization.basic * `is_localization.away (x : R) S` expresses that `S` is a localization away from `x`, as an abbreviation of `is_localization (submonoid.powers x) S` + * `exists_reduced_fraction (hb : b ≠ 0)` produces a reduced fraction of the form `b = a * x^n` for + some `n : ℤ` and some `a : R` that is not divisible by `x`. ## Implementation notes @@ -194,3 +196,143 @@ lemma is_localization.away.finite_presentation (r : R) {S} [comm_ring S] [algebr [is_localization.away r S] : algebra.finite_presentation R S := (adjoin_root.finite_presentation _).equiv $ (localization.away_equiv_adjoin r).symm.trans $ is_localization.alg_equiv (submonoid.powers r) _ _ + +section num_denom + +open multiplicity unique_factorization_monoid is_localization + +variable (x : R) + +variables (B : Type*) [comm_ring B] [algebra R B] [is_localization.away x B] + +/-- `self_zpow x (m : ℤ)` is `x ^ m` as an element of the localization away from `x`. -/ +noncomputable def self_zpow (m : ℤ) : B := +if hm : 0 ≤ m +then algebra_map _ _ x ^ m.nat_abs +else mk' _ (1 : R) (submonoid.pow x m.nat_abs) + +lemma self_zpow_of_nonneg {n : ℤ} (hn : 0 ≤ n) : self_zpow x B n = + algebra_map R B x ^ n.nat_abs := +dif_pos hn + +@[simp] lemma self_zpow_coe_nat (d : ℕ) : self_zpow x B d = (algebra_map R B x)^d := +self_zpow_of_nonneg _ _ (int.coe_nat_nonneg d) + +@[simp] lemma self_zpow_zero : self_zpow x B 0 = 1 := +by simp [self_zpow_of_nonneg _ _ le_rfl] + +lemma self_zpow_of_neg {n : ℤ} (hn : n < 0) : + self_zpow x B n = mk' _ (1 : R) (submonoid.pow x n.nat_abs) := +dif_neg hn.not_le + +lemma self_zpow_of_nonpos {n : ℤ} (hn : n ≤ 0) : + self_zpow x B n = mk' _ (1 : R) (submonoid.pow x n.nat_abs) := +begin + by_cases hn0 : n = 0, + { simp [hn0, self_zpow_zero, submonoid.pow_apply] }, + { simp [self_zpow_of_neg _ _ (lt_of_le_of_ne hn hn0)] } +end + +@[simp] lemma self_zpow_neg_coe_nat (d : ℕ) : + self_zpow x B (-d) = mk' _ (1 : R) (submonoid.pow x d) := +by simp [self_zpow_of_nonpos _ _ (neg_nonpos.mpr (int.coe_nat_nonneg d))] + +@[simp] lemma self_zpow_sub_cast_nat {n m : ℕ} : + self_zpow x B (n - m) = mk' _ (x ^ n) (submonoid.pow x m) := +begin + by_cases h : m ≤ n, + { rw [is_localization.eq_mk'_iff_mul_eq, submonoid.pow_apply, subtype.coe_mk, + ← int.coe_nat_sub h, self_zpow_coe_nat, ← map_pow, ← map_mul, ← pow_add, + nat.sub_add_cancel h] }, + { rw [← neg_sub, ← int.coe_nat_sub (le_of_not_le h), self_zpow_neg_coe_nat, + is_localization.mk'_eq_iff_eq], + simp [submonoid.pow_apply, ← pow_add, nat.sub_add_cancel (le_of_not_le h)] } +end + +@[simp] lemma self_zpow_add {n m : ℤ} : + self_zpow x B (n + m) = self_zpow x B n * self_zpow x B m := +begin + cases le_or_lt 0 n with hn hn; cases le_or_lt 0 m with hm hm, + { rw [self_zpow_of_nonneg _ _ hn, self_zpow_of_nonneg _ _ hm, + self_zpow_of_nonneg _ _ (add_nonneg hn hm), int.nat_abs_add_nonneg hn hm, pow_add] }, + { have : n + m = n.nat_abs - m.nat_abs, + { rw [int.nat_abs_of_nonneg hn, int.of_nat_nat_abs_of_nonpos hm.le, sub_neg_eq_add] }, + rw [self_zpow_of_nonneg _ _ hn, self_zpow_of_neg _ _ hm, + this, self_zpow_sub_cast_nat, is_localization.mk'_eq_mul_mk'_one, map_pow] }, + { have : n + m = m.nat_abs - n.nat_abs, + { rw [int.nat_abs_of_nonneg hm, int.of_nat_nat_abs_of_nonpos hn.le, sub_neg_eq_add, add_comm] }, + rw [self_zpow_of_nonneg _ _ hm, self_zpow_of_neg _ _ hn, + this, self_zpow_sub_cast_nat, is_localization.mk'_eq_mul_mk'_one, map_pow, mul_comm] }, + { rw [self_zpow_of_neg _ _ hn, self_zpow_of_neg _ _ hm, self_zpow_of_neg _ _ (add_neg hn hm), + int.nat_abs_add_neg hn hm, ← mk'_mul, one_mul], + congr, + ext, + simp [pow_add] }, +end + +lemma self_zpow_mul_neg (d : ℤ) : self_zpow x B d * self_zpow x B (-d) = 1 := +begin + by_cases hd : d ≤ 0, + { erw [self_zpow_of_nonpos x B hd, self_zpow_of_nonneg, ← map_pow, int.nat_abs_neg, + is_localization.mk'_spec, map_one], + apply nonneg_of_neg_nonpos, + rwa [neg_neg]}, + { erw [self_zpow_of_nonneg x B (le_of_not_le hd), self_zpow_of_nonpos, ← map_pow, int.nat_abs_neg, + @is_localization.mk'_spec' R _ (submonoid.powers x) B _ _ _ 1 (submonoid.pow x d.nat_abs), + map_one], + refine nonpos_of_neg_nonneg (le_of_lt _), + rwa [neg_neg, ← not_le] }, +end + +lemma self_zpow_neg_mul (d : ℤ) : self_zpow x B (-d) * self_zpow x B d = 1 := +by rw [mul_comm, self_zpow_mul_neg x B d] + + +lemma self_zpow_pow_sub (a : R) (b : B) (m d : ℤ) : + (self_zpow x B (m - d)) * mk' B a (1 : submonoid.powers x) = b ↔ + (self_zpow x B m) * mk' B a (1 : submonoid.powers x) = (self_zpow x B d) * b := +begin + rw [sub_eq_add_neg, self_zpow_add, mul_assoc, mul_comm _ (mk' B a 1), ← mul_assoc], + split, + { intro h, + have := congr_arg (λ s : B, s * self_zpow x B d) h, + simp only at this, + rwa [mul_assoc, mul_assoc, self_zpow_neg_mul, mul_one, mul_comm b _] at this}, + { intro h, + have := congr_arg (λ s : B, s * self_zpow x B (-d)) h, + simp only at this, + rwa [mul_comm _ b, mul_assoc b _ _, self_zpow_mul_neg, mul_one] at this} +end + + +variables [is_domain R] [normalization_monoid R] [unique_factorization_monoid R] + + +theorem exists_reduced_fraction' {b : B} (hb : b ≠ 0) (hx : irreducible x) : + ∃ (a : R) (n : ℤ), ¬ x ∣ a ∧ + self_zpow x B n * algebra_map R B a = b := +begin + classical, + obtain ⟨⟨a₀, y⟩, H⟩ := surj (submonoid.powers x) b, + obtain ⟨d, hy⟩ := (submonoid.mem_powers_iff y.1 x).mp y.2, + have ha₀ : a₀ ≠ 0, + { haveI := @is_domain_of_le_non_zero_divisors B _ R _ _ _ (submonoid.powers x) _ + (powers_le_non_zero_divisors_of_no_zero_divisors hx.ne_zero), + simp only [map_zero, ← subtype.val_eq_coe, ← hy, map_pow] at H, + apply ((injective_iff_map_eq_zero' (algebra_map R B)).mp _ a₀).mpr.mt, + rw ← H, + apply mul_ne_zero hb (pow_ne_zero _ _), + exact is_localization.to_map_ne_zero_of_mem_non_zero_divisors B + (powers_le_non_zero_divisors_of_no_zero_divisors (hx.ne_zero)) + (mem_non_zero_divisors_iff_ne_zero.mpr hx.ne_zero), + exact is_localization.injective B (powers_le_non_zero_divisors_of_no_zero_divisors + (hx.ne_zero)) }, + simp only [← subtype.val_eq_coe, ← hy] at H, + obtain ⟨m, a, hyp1, hyp2⟩ := max_power_factor ha₀ hx, + refine ⟨a, m-d, _⟩, + rw [← mk'_one B, self_zpow_pow_sub, self_zpow_coe_nat, self_zpow_coe_nat, ← map_pow _ _ d, + mul_comm _ b, H, hyp2, map_mul, map_pow _ _ m], + exact ⟨hyp1, (congr_arg _ (is_localization.mk'_one _ _))⟩, +end + +end num_denom diff --git a/src/ring_theory/unique_factorization_domain.lean b/src/ring_theory/unique_factorization_domain.lean index 471af7ef520d2..d4c443fe63a91 100644 --- a/src/ring_theory/unique_factorization_domain.lean +++ b/src/ring_theory/unique_factorization_domain.lean @@ -863,12 +863,12 @@ lemma pow_eq_pow_iff {a : R} (ha0 : a ≠ 0) (ha1 : ¬ is_unit a) {i j : ℕ} : (pow_right_injective ha0 ha1).eq_iff section multiplicity -variables [nontrivial R] [normalization_monoid R] [decidable_eq R] +variables [nontrivial R] [normalization_monoid R] variables [dec_dvd : decidable_rel (has_dvd.dvd : R → R → Prop)] open multiplicity multiset include dec_dvd -lemma le_multiplicity_iff_replicate_le_normalized_factors {a b : R} {n : ℕ} +lemma le_multiplicity_iff_replicate_le_normalized_factors [decidable_eq R] {a b : R} {n : ℕ} (ha : irreducible a) (hb : b ≠ 0) : ↑n ≤ multiplicity a b ↔ replicate n (normalize a) ≤ normalized_factors b := begin @@ -894,8 +894,8 @@ the normalized factor occurs in the `normalized_factors`. See also `count_normalized_factors_eq` which expands the definition of `multiplicity` to produce a specification for `count (normalized_factors _) _`.. -/ -lemma multiplicity_eq_count_normalized_factors {a b : R} (ha : irreducible a) (hb : b ≠ 0) : - multiplicity a b = (normalized_factors b).count (normalize a) := +lemma multiplicity_eq_count_normalized_factors [decidable_eq R] {a b : R} (ha : irreducible a) + (hb : b ≠ 0) : multiplicity a b = (normalized_factors b).count (normalize a) := begin apply le_antisymm, { apply part_enat.le_of_lt_add_one, @@ -912,8 +912,8 @@ the number of times it divides `x`. See also `multiplicity_eq_count_normalized_factors` if `n` is given by `multiplicity p x`. -/ -lemma count_normalized_factors_eq {p x : R} (hp : irreducible p) (hnorm : normalize p = p) {n : ℕ} - (hle : p^n ∣ x) (hlt : ¬ (p^(n+1) ∣ x)) : +lemma count_normalized_factors_eq [decidable_eq R] {p x : R} (hp : irreducible p) + (hnorm : normalize p = p) {n : ℕ} (hle : p^n ∣ x) (hlt : ¬ (p^(n+1) ∣ x)) : (normalized_factors x).count p = n := begin letI : decidable_rel ((∣) : R → R → Prop) := λ _ _, classical.prop_decidable _, @@ -931,8 +931,8 @@ the number of times it divides `x`. This is a slightly more general version of See also `multiplicity_eq_count_normalized_factors` if `n` is given by `multiplicity p x`. -/ -lemma count_normalized_factors_eq' {p x : R} (hp : p = 0 ∨ irreducible p) (hnorm : normalize p = p) - {n : ℕ} (hle : p^n ∣ x) (hlt : ¬ (p^(n+1) ∣ x)) : +lemma count_normalized_factors_eq' [decidable_eq R] {p x : R} (hp : p = 0 ∨ irreducible p) + (hnorm : normalize p = p) {n : ℕ} (hle : p^n ∣ x) (hlt : ¬ (p^(n+1) ∣ x)) : (normalized_factors x).count p = n := begin rcases hp with rfl|hp, @@ -943,6 +943,18 @@ begin { exact count_normalized_factors_eq hp hnorm hle hlt } end +lemma max_power_factor {a₀ : R} {x : R} (h : a₀ ≠ 0) (hx : irreducible x) : + ∃ n : ℕ, ∃ a : R, ¬ x ∣ a ∧ a₀ = x ^ n * a := +begin + classical, + let n := (normalized_factors a₀).count (normalize x), + obtain ⟨a, ha1, ha2⟩ := (@exists_eq_pow_mul_and_not_dvd R _ _ x a₀ + (ne_top_iff_finite.mp (part_enat.ne_top_iff.mpr _))), + simp_rw [← (multiplicity_eq_count_normalized_factors hx h).symm] at ha1, + use [n, a, ha2, ha1], + use [n, (multiplicity_eq_count_normalized_factors hx h)], +end + end multiplicity section multiplicative From 738054fa93d43512da144ec45ce799d18fd44248 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Thu, 4 May 2023 20:00:45 +0000 Subject: [PATCH 17/17] chore(number_theory/modular_forms/slash_invariant_forms): golf and rename (#18933) In the `slash_action` namespace, this renames: * `right_action` to `slash_mul` (and reverses the direction), to match `slash_one` * `add_action` to `add_slash`, to match `zero_slash` * `smul_action` to `smul_slash`, to match `zero_slash` --- .../modular_forms/slash_actions.lean | 30 +++++++++---------- .../modular_forms/slash_invariant_forms.lean | 10 +++---- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/number_theory/modular_forms/slash_actions.lean b/src/number_theory/modular_forms/slash_actions.lean index e03cf93f4925d..9c980afa75e78 100644 --- a/src/number_theory/modular_forms/slash_actions.lean +++ b/src/number_theory/modular_forms/slash_actions.lean @@ -39,9 +39,9 @@ class slash_action (β G α γ : Type*) [group G] [add_monoid α] [has_smul γ (map : β → G → α → α) (zero_slash : ∀ (k : β) (g : G), map k g 0 = 0) (slash_one : ∀ (k : β) (a : α) , map k 1 a = a) -(right_action : ∀ (k : β) (g h : G) (a : α), map k h (map k g a) = map k (g * h) a ) -(smul_action : ∀ (k : β) (g : G) (a : α) (z : γ), map k g (z • a) = z • (map k g a)) -(add_action : ∀ (k : β) (g : G) (a b : α), map k g (a + b) = map k g a + map k g b) +(slash_mul : ∀ (k : β) (g h : G) (a : α), map k (g * h) a =map k h (map k g a)) +(smul_slash : ∀ (k : β) (g : G) (a : α) (z : γ), map k g (z • a) = z • (map k g a)) +(add_slash : ∀ (k : β) (g : G) (a b : α), map k g (a + b) = map k g a + map k g b) localized "notation (name := modular_form.slash) f ` ∣[`:100 k `;` γ `] `:0 a :100 := slash_action.map γ k a f" in modular_form @@ -52,18 +52,18 @@ localized "notation (name := modular_form.slash_complex) f ` ∣[`:100 k `] `:0 @[simp] lemma slash_action.neg_slash {β G α γ : Type*} [group G] [add_group α] [has_smul γ α] [slash_action β G α γ] (k : β) (g : G) (a : α) : (-a) ∣[k;γ] g = - (a ∣[k;γ] g) := -eq_neg_of_add_eq_zero_left $ by rw [←slash_action.add_action, add_left_neg, slash_action.zero_slash] +eq_neg_of_add_eq_zero_left $ by rw [←slash_action.add_slash, add_left_neg, slash_action.zero_slash] @[simp] lemma slash_action.smul_slash_of_tower {R β G α : Type*} (γ : Type*) [group G] [add_group α] [monoid γ] [mul_action γ α] [has_smul R γ] [has_smul R α] [is_scalar_tower R γ α] [slash_action β G α γ] (k : β) (g : G) (a : α) (r : R) : (r • a) ∣[k;γ] g = r • (a ∣[k;γ] g) := -by rw [←smul_one_smul γ r a, slash_action.smul_action, smul_one_smul] +by rw [←smul_one_smul γ r a, slash_action.smul_slash, smul_one_smul] attribute [simp] slash_action.zero_slash slash_action.slash_one - slash_action.smul_action slash_action.add_action + slash_action.smul_slash slash_action.add_slash /--Slash_action induced by a monoid homomorphism.-/ def monoid_hom_slash_action {β G H α γ : Type*} [group G] [add_monoid α] [has_smul γ α] @@ -71,9 +71,9 @@ def monoid_hom_slash_action {β G H α γ : Type*} [group G] [add_monoid α] [ha { map := λ k g, slash_action.map γ k (h g), zero_slash := λ k g, slash_action.zero_slash k (h g), slash_one := λ k a, by simp only [map_one, slash_action.slash_one], - right_action := λ k g gg a, by simp only [map_mul, slash_action.right_action], - smul_action := λ _ _, slash_action.smul_action _ _, - add_action := λ _ g _ _, slash_action.add_action _ (h g) _ _,} + slash_mul := λ k g gg a, by simp only [map_mul, slash_action.slash_mul], + smul_slash := λ _ _, slash_action.smul_slash _ _, + add_slash := λ _ g _ _, slash_action.add_slash _ (h g) _ _,} namespace modular_form @@ -90,8 +90,8 @@ section -- temporary notation until the instance is built local notation f ` ∣[`:100 k `]`:0 γ :100 := modular_form.slash k γ f -private lemma slash_right_action (k : ℤ) (A B : GL(2, ℝ)⁺) (f : ℍ → ℂ) : - (f ∣[k] A) ∣[k] B = f ∣[k] (A * B) := +private lemma slash_mul (k : ℤ) (A B : GL(2, ℝ)⁺) (f : ℍ → ℂ) : + f ∣[k] (A * B) = (f ∣[k] A) ∣[k] B := begin ext1, simp_rw [slash,(upper_half_plane.denom_cocycle A B x)], @@ -109,7 +109,7 @@ begin simp_rw [this, ← mul_assoc, ←mul_zpow], end -private lemma slash_add (k : ℤ) (A : GL(2, ℝ)⁺) (f g : ℍ → ℂ) : +private lemma add_slash (k : ℤ) (A : GL(2, ℝ)⁺) (f g : ℍ → ℂ) : (f + g) ∣[k] A = (f ∣[k] A) + (g ∣[k] A) := begin ext1, @@ -140,9 +140,9 @@ instance : slash_action ℤ GL(2, ℝ)⁺ (ℍ → ℂ) ℂ := { map := slash, zero_slash := zero_slash, slash_one := slash_one, - right_action := slash_right_action, - smul_action := smul_slash, - add_action := slash_add } + slash_mul := slash_mul, + smul_slash := smul_slash, + add_slash := add_slash } end diff --git a/src/number_theory/modular_forms/slash_invariant_forms.lean b/src/number_theory/modular_forms/slash_invariant_forms.lean index 7ed80a3f81de8..98b6074ce71ee 100644 --- a/src/number_theory/modular_forms/slash_invariant_forms.lean +++ b/src/number_theory/modular_forms/slash_invariant_forms.lean @@ -85,7 +85,7 @@ instance slash_invariant_form_class.coe_to_fun [slash_invariant_form_class F Γ has_coe_to_fun F (λ _, ℍ → ℂ) := fun_like.has_coe_to_fun @[simp] lemma slash_action_eqn [slash_invariant_form_class F Γ k] (f : F) (γ : Γ) : - slash_action.map ℂ k γ ⇑f = ⇑f := slash_invariant_form_class.slash_action_eq f γ + ⇑f ∣[k] γ = ⇑f := slash_invariant_form_class.slash_action_eq f γ lemma slash_action_eqn' (k : ℤ) (Γ : subgroup SL(2, ℤ)) [slash_invariant_form_class F Γ k] (f : F) (γ : Γ) (z : ℍ) : f (γ • z) = ((↑ₘ[ℤ]γ 1 0 : ℂ) * z +(↑ₘ[ℤ]γ 1 1 : ℂ))^k * f z := @@ -103,7 +103,7 @@ instance [slash_invariant_form_class F Γ k] : has_coe_t F (slash_invariant_form instance has_add : has_add (slash_invariant_form Γ k) := ⟨ λ f g, { to_fun := f + g, - slash_action_eq' := λ γ, by convert slash_action.add_action k γ (f : ℍ → ℂ) g; simp } ⟩ + slash_action_eq' := λ γ, by rw [slash_action.add_slash, slash_action_eqn, slash_action_eqn] }⟩ @[simp] lemma coe_add (f g : slash_invariant_form Γ k) : ⇑(f + g) = f + g := rfl @[simp] lemma add_apply (f g : slash_invariant_form Γ k) (z : ℍ) : (f + g) z = f z + g z := rfl @@ -120,8 +120,7 @@ variables {α : Type*} [has_smul α ℂ] [is_scalar_tower α ℂ ℂ] instance has_smul : has_smul α (slash_invariant_form Γ k) := ⟨ λ c f, { to_fun := c • f, - slash_action_eq' := λ γ, by rw [←smul_one_smul ℂ c ⇑f, slash_action.smul_action k γ ⇑f, - slash_action_eqn] }⟩ + slash_action_eq' := λ γ, by rw [slash_action.smul_slash_of_tower, slash_action_eqn] }⟩ @[simp] lemma coe_smul (f : slash_invariant_form Γ k) (n : α) : ⇑(n • f) = n • f := rfl @[simp] lemma smul_apply (f : slash_invariant_form Γ k) (n : α) (z : ℍ) : @@ -132,8 +131,7 @@ end instance has_neg : has_neg (slash_invariant_form Γ k) := ⟨ λ f, { to_fun := -f, - slash_action_eq' := λ γ, by simpa [modular_form.subgroup_slash, - slash_action.neg_slash] using f.slash_action_eq' γ } ⟩ + slash_action_eq' := λ γ, by rw [slash_action.neg_slash, slash_action_eqn] } ⟩ @[simp] lemma coe_neg (f : slash_invariant_form Γ k) : ⇑(-f) = -f := rfl @[simp] lemma neg_apply (f : slash_invariant_form Γ k) (z : ℍ) : (-f) z = - (f z) := rfl