Skip to content

Commit c3f2f2d

Browse files
feat(Algebra/Polynomial/Laurent): Lifting maps to ring of Laurent polynomials (#19573)
This PR defines `LaurentPolynomial.eval₂` and provides basic API for it. This was mentioned unter "future work" in the comments. Co-authored-by: Justus Springer <50165510+justus-springer@users.noreply.github.com> Co-authored-by: Michael Rothgang <rothgang@math.uni-bonn.de>
1 parent 5dfc3a9 commit c3f2f2d

File tree

1 file changed

+76
-5
lines changed

1 file changed

+76
-5
lines changed

Mathlib/Algebra/Polynomial/Laurent.lean

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Authors: Damiano Testa
66
import Mathlib.Algebra.Polynomial.AlgebraMap
77
import Mathlib.Algebra.Polynomial.Reverse
88
import Mathlib.Algebra.Polynomial.Inductions
9-
import Mathlib.RingTheory.Localization.Defs
9+
import Mathlib.RingTheory.Localization.Away.Basic
1010

1111
/-! # Laurent polynomials
1212
@@ -49,8 +49,6 @@ Any comments or suggestions for improvements is greatly appreciated!
4949
## Future work
5050
Lots is missing!
5151
-- (Riccardo) add inclusion into Laurent series.
52-
-- (Riccardo) giving a morphism (as `R`-alg, so in the commutative case)
53-
from `R[T,T⁻¹]` to `S` is the same as choosing a unit of `S`.
5452
-- A "better" definition of `trunc` would be as an `R`-linear map. This works:
5553
-- ```
5654
-- def trunc : R[T;T⁻¹][R] R[X] :=
@@ -484,7 +482,7 @@ end Semiring
484482

485483
section CommSemiring
486484

487-
variable [CommSemiring R]
485+
variable [CommSemiring R] {S : Type*} [CommSemiring S] (f : R →+* S) (x : Sˣ)
488486

489487
instance algebraPolynomial (R : Type*) [CommSemiring R] : Algebra R[X] R[T;T⁻¹] where
490488
algebraMap := Polynomial.toLaurent
@@ -498,7 +496,7 @@ theorem algebraMap_X_pow (n : ℕ) : algebraMap R[X] R[T;T⁻¹] (X ^ n) = T n :
498496
theorem algebraMap_eq_toLaurent (f : R[X]) : algebraMap R[X] R[T;T⁻¹] f = toLaurent f :=
499497
rfl
500498

501-
theorem isLocalization : IsLocalization (Submonoid.powers (X : R[X])) R[T;T⁻¹] :=
499+
instance isLocalization : IsLocalization.Away (X : R[X]) R[T;T⁻¹] :=
502500
{ map_units' := fun ⟨t, ht⟩ => by
503501
obtain ⟨n, rfl⟩ := ht
504502
rw [algebraMap_eq_toLaurent, toLaurent_X_pow]
@@ -514,6 +512,79 @@ theorem isLocalization : IsLocalization (Submonoid.powers (X : R[X])) R[T;T⁻¹
514512
rintro rfl
515513
exact ⟨1, rfl⟩ }
516514

515+
theorem mk'_mul_T (p : R[X]) (n : ℕ) :
516+
IsLocalization.mk' R[T;T⁻¹] p (⟨X^n, n, rfl⟩ : Submonoid.powers (X : R[X])) * T n =
517+
toLaurent p := by
518+
rw [←toLaurent_X_pow, ←algebraMap_eq_toLaurent, IsLocalization.mk'_spec, algebraMap_eq_toLaurent]
519+
520+
@[simp]
521+
theorem mk'_eq (p : R[X]) (n : ℕ) : IsLocalization.mk' R[T;T⁻¹] p
522+
(⟨X^n, n, rfl⟩ : Submonoid.powers (X : R[X])) = toLaurent p * T (-n) := by
523+
rw [←IsUnit.mul_left_inj (isUnit_T n), mul_T_assoc, neg_add_cancel, T_zero, mul_one]
524+
exact mk'_mul_T p n
525+
526+
theorem mk'_one_X_pow (n : ℕ) : IsLocalization.mk' R[T;T⁻¹] 1
527+
(⟨X^n, n, rfl⟩ : Submonoid.powers (X : R[X])) = T (-n) := by
528+
rw [mk'_eq 1 n, toLaurent_one, one_mul]
529+
530+
@[simp]
531+
theorem mk'_one_X : IsLocalization.mk' R[T;T⁻¹] 1
532+
(⟨X, 1, pow_one X⟩ : Submonoid.powers (X : R[X])) = T (-1) := by
533+
convert mk'_one_X_pow 1
534+
exact (pow_one X).symm
535+
536+
/-- Given a ring homomorphism `f : R →+* S` and a unit `x` in `S`, the induced homomorphism
537+
`R[T;T⁻¹] →+* S` sending `T` to `x` and `T⁻¹` to `x⁻¹`. -/
538+
def eval₂ : R[T;T⁻¹] →+* S :=
539+
IsLocalization.lift (M := Submonoid.powers (X : R[X])) (g := Polynomial.eval₂RingHom f x) (by
540+
rintro ⟨y, n, rfl⟩
541+
simpa only [coe_eval₂RingHom, eval₂_X_pow] using IsUnit.pow n x.isUnit
542+
)
543+
544+
@[simp]
545+
theorem eval₂_toLaurent (p : R[X]) : eval₂ f x (toLaurent p) = Polynomial.eval₂ f x p := by
546+
unfold eval₂
547+
rw [←algebraMap_eq_toLaurent, IsLocalization.lift_eq]
548+
rfl
549+
550+
theorem eval₂_T_n (n : ℕ) : eval₂ f x (T n) = x ^ n := by
551+
rw [←Polynomial.toLaurent_X_pow, eval₂_toLaurent, eval₂_X_pow]
552+
553+
theorem eval₂_T_neg_n (n : ℕ) : eval₂ f x (T (-n)) = x⁻¹ ^ n := by
554+
rw [←mk'_one_X_pow]
555+
unfold eval₂
556+
rw [IsLocalization.lift_mk'_spec, map_one, coe_eval₂RingHom, eval₂_X_pow, ←mul_pow,
557+
Units.mul_inv, one_pow]
558+
559+
@[simp]
560+
theorem eval₂_T (n : ℤ) : eval₂ f x (T n) = (x ^ n).val := by
561+
by_cases hn : 0 ≤ n
562+
· lift n to ℕ using hn
563+
apply eval₂_T_n
564+
· obtain ⟨m, rfl⟩ := Int.exists_eq_neg_ofNat (Int.le_of_not_le hn)
565+
rw [eval₂_T_neg_n, zpow_neg]
566+
rfl
567+
568+
@[simp]
569+
theorem eval₂_C (r : R) : eval₂ f x (C r) = f r := by
570+
rw [← toLaurent_C, eval₂_toLaurent, Polynomial.eval₂_C]
571+
572+
theorem eval₂_C_mul_T_n (r : R) (n : ℕ) : eval₂ f x (C r * T n) = f r * x ^ n := by
573+
rw [←Polynomial.toLaurent_C_mul_T, eval₂_toLaurent, eval₂_monomial]
574+
575+
theorem eval₂_C_mul_T_neg_n (r : R) (n : ℕ) : eval₂ f x (C r * T (-n)) =
576+
f r * x⁻¹ ^ n := by rw [map_mul, eval₂_T_neg_n, eval₂_C]
577+
578+
@[simp]
579+
theorem eval₂_C_mul_T (r : R) (n : ℤ) : eval₂ f x (C r * T n) = f r * (x ^ n).val := by
580+
by_cases hn : 0 ≤ n
581+
· lift n to ℕ using hn
582+
rw [map_mul, eval₂_C, eval₂_T_n]
583+
rfl
584+
· obtain ⟨m, rfl⟩ := Int.exists_eq_neg_ofNat (Int.le_of_not_le hn)
585+
rw [map_mul, eval₂_C, eval₂_T_neg_n, zpow_neg]
586+
rfl
587+
517588
end CommSemiring
518589

519590
section Inversion

0 commit comments

Comments
 (0)