New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Merged by Bors] - feat(ring_theory/localization): Localizations of integral extensions #3942
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks 🎉
theorem is_integral_of_is_integral_mul_unit {x y : A} {r : R} (hr : (algebra_map R A r) * y = 1) | ||
(hx : is_integral R (x * y)) : (is_integral R x) := | ||
begin | ||
by_cases triv : (1 : R) = 0, | ||
{ exact ⟨0, ⟨trans leading_coeff_zero triv.symm, eval₂_zero _ _⟩⟩ }, | ||
haveI : nontrivial R := nontrivial_of_ne 1 0 triv, | ||
obtain ⟨p, ⟨p_monic, hp⟩⟩ := hx, | ||
let p' : polynomial R := ∑ (i : ℕ) in p.support, monomial i ((p.coeff i) * r ^ (p.nat_degree - i)), | ||
have hp' : p'.nat_degree = p.nat_degree, | ||
{ refine finset_sum_monomial_degree (λ h, triv _), | ||
rw [nat.sub_self, pow_zero r, mul_one] at h, | ||
exact p_monic ▸ h }, | ||
refine ⟨p', ⟨_, _⟩⟩, | ||
{ rwa [monic, leading_coeff, hp', finset_sum_monomial_coeff, nat.sub_self, pow_zero, mul_one] }, | ||
-- TODO: A lot of this is just basic algebra, but `ring` can't solve it because only some elements are invertible | ||
{ have : is_unit (y ^ p.nat_degree) := is_unit_iff_exists_inv.2 | ||
⟨(algebra_map R A r) ^ p.nat_degree, by rw [← mul_pow, mul_comm, hr, one_pow]⟩, | ||
rw [aeval_def, eval₂, sum_over_range] at hp, | ||
rw [← (is_unit.mul_right_eq_zero this), aeval_def, eval₂, sum_over_range, finset.mul_sum, ← hp], | ||
refine finset.sum_congr (by rw hp') (λ n hn, _), | ||
simp only [finset_sum_monomial_coeff, ring_hom.map_pow, ring_hom.map_mul], | ||
rw [← mul_assoc (y ^ p.nat_degree), mul_comm (y ^ p.nat_degree), mul_comm x y, mul_pow y x n, | ||
← mul_assoc _ (y ^ n) (x ^ n), mul_assoc _ _ (y ^ p.nat_degree)], | ||
congr, | ||
have : is_unit ((algebra_map R A r) ^ n) := is_unit_iff_exists_inv.2 | ||
⟨y ^ n, by rw [← mul_pow, hr, one_pow]⟩, | ||
rw [← (is_unit.mul_left_inj this), ← mul_pow y _ n, mul_comm y, hr, mul_comm, ← mul_assoc, | ||
← pow_add, nat.add_sub_cancel' (nat.le_of_lt_succ (finset.mem_range.1 hn)), | ||
← mul_pow, hr, one_pow, one_pow], | ||
all_goals {simp [add_mul]} }, | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can shorten the proof dramatically if you use scale_roots p (r⁻¹)
defined in ring_theory.polynomial.rational_root
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very helpful as that is essentially the exact same polynomial as I tried to use here. The only issue is that if I try and import it, I end up with a cyclic dependency, rational_root → localization → integral_closure → rational_root
, and I can't just move this theorem to rational_root
since the additions to localization
depend on it. I could maybe move these new theorems into rational_root
, or create a new file like localization_integral
. Not sure what's the best practice here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the best way would be to move the whole section scale_roots
from the rational_root
file to a new file ring_theory/polynomial/scale_roots.lean
(or add it to ring_theory/basic
, but that's getting long by itself already) (or even move it to data/polynomial/scale_roots.lean
. I'm not sure what qualifies as data/polynomial
and what as ring_theory/polynomial
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've pulled out scale_roots
into its own file, but to completely resolve the dependencies I also had to move non_zero_divisors
into its own file, since scale_roots
depends on it (I managed to remove le_non_zero_divisors
from some scale_roots
lemmas that didn't actually need to rely on it, but some do still actually need it`).
For now these are both in two new independent files, but perhaps non_zero_divisors
could go somewhere else, maybe integral_domain
or some other place that already deals with zero divisors. I also kept scale roots in ring_theory
rather than data
because of the reliance on non_zero_divisors
for some lemmas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha, I recall being annoyed before that non_zero_divisors
is so far down the import hierarchy. Thank you for fixing that 🎉
As for the location of non_zero_divisors
, maybe we should generalize all the way to monoid_with_zero
and put it somewhere in algebra/group_with_zero.lean
(I can't think of any non-ring
monoid_with_zero
where we would care about zero divisors, but the highest possible generality is what we really care about in mathlib :P)
I don't have any time right now for a full review, but tomorrow morning (in about 9 hours) I will check it out 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the definition to the more generic monoid with zero, but most of the useful lemmas require more structure to prove, so as of now they still rely on either comm_ring
or integral_domain
. I didn't move it to location outside ring_theory
either, since basically everything but the definition still relies on comm_ring
Co-authored-by: Vierkantor <Vierkantor@users.noreply.github.com>
…n_zero_divisors in many of the proofs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we're almost finished. I found a few small points to improve and then it's good for me.
Co-authored-by: Vierkantor <Vierkantor@users.noreply.github.com>
Co-authored-by: Vierkantor <Vierkantor@users.noreply.github.com>
Co-authored-by: Vierkantor <Vierkantor@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all the work you've done! I think that some parts can still be optimized a bit.
⟨λ hm hz, zero_ne_one (hm 1 $ by rw [hz, one_mul]).symm, | ||
λ hnx z, eq_zero_of_ne_zero_of_mul_eq_zero hnx⟩ | ||
|
||
lemma map_ne_zero_of_mem_non_zero_divisors {B : Type*} [ring B] {g : A →+* B} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does A
really need to be an integral domain for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like all it really needs is that A
is nontrivial. I think whoever originally wrote these was just concerned about properties of fraction_map
, and integral_domain
was fine for these in that context. I'll go through and try and generalize some more of these lemmas as well.
(hg : function.injective g) {x : non_zero_divisors A} : g x ≠ 0 := | ||
λ h0, mem_non_zero_divisors_iff_ne_zero.1 x.2 $ g.injective_iff.1 hg x h0 | ||
|
||
lemma map_mem_non_zero_divisors {B : Type*} [integral_domain B] {g : A →+* B} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please figure out the minimal assumptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that to drop the integral_domain
assumption we'd need to instead assume that g
is surjective, since I think g z * x = 0
isn't strong enough, we need to get g z * g x' = 0
to prove this is true. On the other hand I can't find any uses of this lemma anywhere in mathlib, so I'm not even sure it needs to exist in the first place.
…on set doesn't contain zero divisors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks 🎉
bors merge
…3942) The main definition is the algebra induced by localization at an algebra. Given an algebra `R → S` and a submonoid `M` of `R`, as well as localization maps `f : R → Rₘ` and `g : S → Sₘ`, there is a natural algebra `Rₘ → Sₘ` that makes the entire square commute, and this is defined as `localization_algebra`. The two main theorems are similar but distinct statements about integral elements and localizations: * `is_integral_localization_at_leading_coeff` says that if an element `x` is algebraic over `algebra R S`, then if we localize to a submonoid containing the leading coefficient the image of `x` will be integral. * `is_integral_localization` says that if `R → S` is an integral extension, then the algebra induced by localizing at any particular submonoid will be an integral extension. Co-authored-by: Devon Tuma <dtumad@gmail.com>
Pull request successfully merged into master. Build succeeded: |
…3942) The main definition is the algebra induced by localization at an algebra. Given an algebra `R → S` and a submonoid `M` of `R`, as well as localization maps `f : R → Rₘ` and `g : S → Sₘ`, there is a natural algebra `Rₘ → Sₘ` that makes the entire square commute, and this is defined as `localization_algebra`. The two main theorems are similar but distinct statements about integral elements and localizations: * `is_integral_localization_at_leading_coeff` says that if an element `x` is algebraic over `algebra R S`, then if we localize to a submonoid containing the leading coefficient the image of `x` will be integral. * `is_integral_localization` says that if `R → S` is an integral extension, then the algebra induced by localizing at any particular submonoid will be an integral extension. Co-authored-by: Devon Tuma <dtumad@gmail.com>
The main definition is the algebra induced by localization at an algebra. Given an algebra
R → S
and a submonoidM
ofR
, as well as localization mapsf : R → Rₘ
andg : S → Sₘ
, there is a natural algebraRₘ → Sₘ
that makes the entire square commute, and this is defined aslocalization_algebra
.The two main theorems are similar but distinct statements about integral elements and localizations:
is_integral_localization_at_leading_coeff
says that if an elementx
is algebraic overalgebra R S
, then if we localize to a submonoid containing the leading coefficient the image ofx
will be integral.is_integral_localization
says that ifR → S
is an integral extension, then the algebra induced by localizing at any particular submonoid will be an integral extension.Both of the proofs of these statements are very simple to explain in words, but fiddling with the polynomial evaluations makes the proofs much larger. I pulled out a lot of lemmas to shorten them, but there is still a decent amount of the proofs that's just manipulating ring elements, and
ring
doesn't seem quite strong enough to figure it out.