@@ -1370,8 +1370,188 @@ theorem leadingCoeff_pow_X_add_C (r : R) (i : ℕ) : leadingCoeff ((X + C r) ^ i
1370
1370
nontriviality
1371
1371
rw [leadingCoeff_pow'] <;> simp
1372
1372
1373
+ variable [NoZeroDivisors R] {p q : R[X]}
1374
+
1375
+ @[simp]
1376
+ lemma degree_mul : degree (p * q) = degree p + degree q :=
1377
+ letI := Classical.decEq R
1378
+ if hp0 : p = 0 then by simp only [hp0, degree_zero, zero_mul, WithBot.bot_add]
1379
+ else
1380
+ if hq0 : q = 0 then by simp only [hq0, degree_zero, mul_zero, WithBot.add_bot]
1381
+ else degree_mul' <| mul_ne_zero (mt leadingCoeff_eq_zero.1 hp0) (mt leadingCoeff_eq_zero.1 hq0)
1382
+
1383
+ /-- `degree` as a monoid homomorphism between `R[X]` and `Multiplicative (WithBot ℕ)`.
1384
+ This is useful to prove results about multiplication and degree. -/
1385
+ def degreeMonoidHom [Nontrivial R] : R[X] →* Multiplicative (WithBot ℕ) where
1386
+ toFun := degree
1387
+ map_one' := degree_one
1388
+ map_mul' _ _ := degree_mul
1389
+
1390
+ @[simp]
1391
+ lemma degree_pow [Nontrivial R] (p : R[X]) (n : ℕ) : degree (p ^ n) = n • degree p :=
1392
+ map_pow (@degreeMonoidHom R _ _ _) _ _
1393
+
1394
+ @[simp]
1395
+ lemma leadingCoeff_mul (p q : R[X]) : leadingCoeff (p * q) = leadingCoeff p * leadingCoeff q := by
1396
+ by_cases hp : p = 0
1397
+ · simp only [hp, zero_mul, leadingCoeff_zero]
1398
+ · by_cases hq : q = 0
1399
+ · simp only [hq, mul_zero, leadingCoeff_zero]
1400
+ · rw [leadingCoeff_mul']
1401
+ exact mul_ne_zero (mt leadingCoeff_eq_zero.1 hp) (mt leadingCoeff_eq_zero.1 hq)
1402
+
1403
+ /-- `Polynomial.leadingCoeff` bundled as a `MonoidHom` when `R` has `NoZeroDivisors`, and thus
1404
+ `leadingCoeff` is multiplicative -/
1405
+ def leadingCoeffHom : R[X] →* R where
1406
+ toFun := leadingCoeff
1407
+ map_one' := by simp
1408
+ map_mul' := leadingCoeff_mul
1409
+
1410
+ @[simp]
1411
+ lemma leadingCoeffHom_apply (p : R[X]) : leadingCoeffHom p = leadingCoeff p :=
1412
+ rfl
1413
+
1414
+ @[simp]
1415
+ lemma leadingCoeff_pow (p : R[X]) (n : ℕ) : leadingCoeff (p ^ n) = leadingCoeff p ^ n :=
1416
+ (leadingCoeffHom : R[X] →* R).map_pow p n
1417
+
1418
+ lemma leadingCoeff_dvd_leadingCoeff {a p : R[X]} (hap : a ∣ p) :
1419
+ a.leadingCoeff ∣ p.leadingCoeff :=
1420
+ map_dvd leadingCoeffHom hap
1421
+
1422
+ instance : NoZeroDivisors R[X] where
1423
+ eq_zero_or_eq_zero_of_mul_eq_zero h := by
1424
+ rw [← leadingCoeff_eq_zero, ← leadingCoeff_eq_zero]
1425
+ refine eq_zero_or_eq_zero_of_mul_eq_zero ?_
1426
+ rw [← leadingCoeff_zero, ← leadingCoeff_mul, h]
1427
+ lemma natDegree_mul (hp : p ≠ 0 ) (hq : q ≠ 0 ) : (p*q).natDegree = p.natDegree + q.natDegree := by
1428
+ rw [← Nat.cast_inj (R := WithBot ℕ), ← degree_eq_natDegree (mul_ne_zero hp hq),
1429
+ Nat.cast_add, ← degree_eq_natDegree hp, ← degree_eq_natDegree hq, degree_mul]
1430
+
1431
+ @[simp]
1432
+ lemma natDegree_pow (p : R[X]) (n : ℕ) : natDegree (p ^ n) = n * natDegree p := by
1433
+ classical
1434
+ obtain rfl | hp := eq_or_ne p 0
1435
+ · obtain rfl | hn := eq_or_ne n 0 <;> simp [*]
1436
+ exact natDegree_pow' <| by
1437
+ rw [← leadingCoeff_pow, Ne, leadingCoeff_eq_zero]; exact pow_ne_zero _ hp
1438
+
1439
+ lemma degree_le_mul_left (p : R[X]) (hq : q ≠ 0 ) : degree p ≤ degree (p * q) := by
1440
+ classical
1441
+ obtain rfl | hp := eq_or_ne p 0
1442
+ · simp
1443
+ · rw [degree_mul, degree_eq_natDegree hp, degree_eq_natDegree hq]
1444
+ exact WithBot.coe_le_coe.2 (Nat.le_add_right _ _)
1445
+
1446
+ lemma natDegree_le_of_dvd (h1 : p ∣ q) (h2 : q ≠ 0 ) : p.natDegree ≤ q.natDegree := by
1447
+ obtain ⟨q, rfl⟩ := h1
1448
+ rw [mul_ne_zero_iff] at h2
1449
+ rw [natDegree_mul h2.1 h2.2 ]; exact Nat.le_add_right _ _
1450
+
1451
+ lemma degree_le_of_dvd (h1 : p ∣ q) (h2 : q ≠ 0 ) : degree p ≤ degree q := by
1452
+ rcases h1 with ⟨q, rfl⟩; rw [mul_ne_zero_iff] at h2
1453
+ exact degree_le_mul_left p h2.2
1454
+
1455
+ lemma eq_zero_of_dvd_of_degree_lt (h₁ : p ∣ q) (h₂ : degree q < degree p) : q = 0 := by
1456
+ by_contra hc
1457
+ exact (lt_iff_not_ge _ _).mp h₂ (degree_le_of_dvd h₁ hc)
1458
+
1459
+ lemma eq_zero_of_dvd_of_natDegree_lt (h₁ : p ∣ q) (h₂ : natDegree q < natDegree p) :
1460
+ q = 0 := by
1461
+ by_contra hc
1462
+ exact (lt_iff_not_ge _ _).mp h₂ (natDegree_le_of_dvd h₁ hc)
1463
+
1464
+ lemma not_dvd_of_degree_lt (h0 : q ≠ 0 ) (hl : q.degree < p.degree) : ¬p ∣ q := by
1465
+ by_contra hcontra
1466
+ exact h0 (eq_zero_of_dvd_of_degree_lt hcontra hl)
1467
+
1468
+ lemma not_dvd_of_natDegree_lt (h0 : q ≠ 0 ) (hl : q.natDegree < p.natDegree) :
1469
+ ¬p ∣ q := by
1470
+ by_contra hcontra
1471
+ exact h0 (eq_zero_of_dvd_of_natDegree_lt hcontra hl)
1472
+
1473
+ /-- This lemma is useful for working with the `intDegree` of a rational function. -/
1474
+ lemma natDegree_sub_eq_of_prod_eq {p₁ p₂ q₁ q₂ : R[X]} (hp₁ : p₁ ≠ 0 ) (hq₁ : q₁ ≠ 0 )
1475
+ (hp₂ : p₂ ≠ 0 ) (hq₂ : q₂ ≠ 0 ) (h_eq : p₁ * q₂ = p₂ * q₁) :
1476
+ (p₁.natDegree : ℤ) - q₁.natDegree = (p₂.natDegree : ℤ) - q₂.natDegree := by
1477
+ rw [sub_eq_sub_iff_add_eq_add]
1478
+ norm_cast
1479
+ rw [← natDegree_mul hp₁ hq₂, ← natDegree_mul hp₂ hq₁, h_eq]
1480
+
1481
+ lemma natDegree_eq_zero_of_isUnit (h : IsUnit p) : natDegree p = 0 := by
1482
+ nontriviality R
1483
+ obtain ⟨q, hq⟩ := h.exists_right_inv
1484
+ have := natDegree_mul (left_ne_zero_of_mul_eq_one hq) (right_ne_zero_of_mul_eq_one hq)
1485
+ rw [hq, natDegree_one, eq_comm, add_eq_zero] at this
1486
+ exact this.1
1487
+
1488
+ lemma degree_eq_zero_of_isUnit [Nontrivial R] (h : IsUnit p) : degree p = 0 :=
1489
+ (natDegree_eq_zero_iff_degree_le_zero.mp <| natDegree_eq_zero_of_isUnit h).antisymm
1490
+ (zero_le_degree_iff.mpr h.ne_zero)
1491
+
1492
+ @[simp]
1493
+ lemma degree_coe_units [Nontrivial R] (u : R[X]ˣ) : degree (u : R[X]) = 0 :=
1494
+ degree_eq_zero_of_isUnit ⟨u, rfl⟩
1495
+
1496
+ /-- Characterization of a unit of a polynomial ring over an integral domain `R`.
1497
+ See `Polynomial.isUnit_iff_coeff_isUnit_isNilpotent` when `R` is a commutative ring. -/
1498
+ lemma isUnit_iff : IsUnit p ↔ ∃ r : R, IsUnit r ∧ C r = p :=
1499
+ ⟨fun hp =>
1500
+ ⟨p.coeff 0 ,
1501
+ let h := eq_C_of_natDegree_eq_zero (natDegree_eq_zero_of_isUnit hp)
1502
+ ⟨isUnit_C.1 (h ▸ hp), h.symm⟩⟩,
1503
+ fun ⟨_, hr, hrp⟩ => hrp ▸ isUnit_C.2 hr⟩
1504
+
1505
+ lemma not_isUnit_of_degree_pos (p : R[X]) (hpl : 0 < p.degree) : ¬ IsUnit p := by
1506
+ cases subsingleton_or_nontrivial R
1507
+ · simp [Subsingleton.elim p 0 ] at hpl
1508
+ intro h
1509
+ simp [degree_eq_zero_of_isUnit h] at hpl
1510
+
1511
+ lemma not_isUnit_of_natDegree_pos (p : R[X]) (hpl : 0 < p.natDegree) : ¬ IsUnit p :=
1512
+ not_isUnit_of_degree_pos _ (natDegree_pos_iff_degree_pos.mp hpl)
1513
+
1514
+ @[simp] lemma natDegree_coe_units (u : R[X]ˣ) : natDegree (u : R[X]) = 0 := by
1515
+ nontriviality R
1516
+ exact natDegree_eq_of_degree_eq_some (degree_coe_units u)
1517
+
1518
+ theorem coeff_coe_units_zero_ne_zero [Nontrivial R] (u : R[X]ˣ) : coeff (u : R[X]) 0 ≠ 0 := by
1519
+ conv in 0 => rw [← natDegree_coe_units u]
1520
+ rw [← leadingCoeff, Ne, leadingCoeff_eq_zero]
1521
+ exact Units.ne_zero _
1522
+
1373
1523
end Semiring
1374
1524
1525
+ section CommSemiring
1526
+ variable [CommSemiring R] {a p : R[X]} (hp : p.Monic)
1527
+ include hp
1528
+
1529
+ lemma Monic.C_dvd_iff_isUnit {a : R} : C a ∣ p ↔ IsUnit a where
1530
+ mp h := isUnit_iff_dvd_one.mpr <| hp.coeff_natDegree ▸ (C_dvd_iff_dvd_coeff _ _).mp h p.natDegree
1531
+ mpr ha := (ha.map C).dvd
1532
+
1533
+ lemma Monic.natDegree_pos : 0 < natDegree p ↔ p ≠ 1 :=
1534
+ Nat.pos_iff_ne_zero.trans hp.natDegree_eq_zero.not
1535
+
1536
+ lemma Monic.degree_pos : 0 < degree p ↔ p ≠ 1 :=
1537
+ natDegree_pos_iff_degree_pos.symm.trans hp.natDegree_pos
1538
+
1539
+ lemma Monic.degree_pos_of_not_isUnit (hu : ¬IsUnit p) : 0 < degree p :=
1540
+ hp.degree_pos.mpr fun hp' ↦ (hp' ▸ hu) isUnit_one
1541
+
1542
+ lemma Monic.natDegree_pos_of_not_isUnit (hu : ¬IsUnit p) : 0 < natDegree p :=
1543
+ hp.natDegree_pos.mpr fun hp' ↦ (hp' ▸ hu) isUnit_one
1544
+
1545
+ lemma degree_pos_of_not_isUnit_of_dvd_monic (ha : ¬IsUnit a) (hap : a ∣ p) : 0 < degree a := by
1546
+ contrapose! ha with h
1547
+ rw [Polynomial.eq_C_of_degree_le_zero h] at hap ⊢
1548
+ simpa [hp.C_dvd_iff_isUnit, isUnit_C] using hap
1549
+
1550
+ lemma natDegree_pos_of_not_isUnit_of_dvd_monic (ha : ¬IsUnit a) (hap : a ∣ p) : 0 < natDegree a :=
1551
+ natDegree_pos_iff_degree_pos.mpr <| degree_pos_of_not_isUnit_of_dvd_monic hp ha hap
1552
+
1553
+ end CommSemiring
1554
+
1375
1555
section Ring
1376
1556
1377
1557
variable [Ring R]
@@ -1420,59 +1600,11 @@ theorem natDegree_X_pow_sub_C {n : ℕ} {r : R} : (X ^ n - C r).natDegree = n :=
1420
1600
theorem leadingCoeff_X_sub_C [Ring S] (r : S) : (X - C r).leadingCoeff = 1 := by
1421
1601
rw [sub_eq_add_neg, ← map_neg C r, leadingCoeff_X_add_C]
1422
1602
1423
- end Ring
1424
-
1425
- section NoZeroDivisors
1426
-
1427
- variable [Semiring R] [NoZeroDivisors R] {p q : R[X]}
1428
-
1429
- @[simp]
1430
- theorem degree_mul : degree (p * q) = degree p + degree q :=
1431
- letI := Classical.decEq R
1432
- if hp0 : p = 0 then by simp only [hp0, degree_zero, zero_mul, WithBot.bot_add]
1433
- else
1434
- if hq0 : q = 0 then by simp only [hq0, degree_zero, mul_zero, WithBot.add_bot]
1435
- else degree_mul' <| mul_ne_zero (mt leadingCoeff_eq_zero.1 hp0) (mt leadingCoeff_eq_zero.1 hq0)
1436
-
1437
- /-- `degree` as a monoid homomorphism between `R[X]` and `Multiplicative (WithBot ℕ)`.
1438
- This is useful to prove results about multiplication and degree. -/
1439
- def degreeMonoidHom [Nontrivial R] : R[X] →* Multiplicative (WithBot ℕ) where
1440
- toFun := degree
1441
- map_one' := degree_one
1442
- map_mul' _ _ := degree_mul
1603
+ variable [IsDomain R] {p q : R[X]}
1443
1604
1444
- @[simp]
1445
- theorem degree_pow [Nontrivial R] (p : R[X]) (n : ℕ) : degree (p ^ n) = n • degree p :=
1446
- map_pow (@degreeMonoidHom R _ _ _) _ _
1447
-
1448
- @[simp]
1449
- theorem leadingCoeff_mul (p q : R[X]) : leadingCoeff (p * q) = leadingCoeff p * leadingCoeff q := by
1450
- by_cases hp : p = 0
1451
- · simp only [hp, zero_mul, leadingCoeff_zero]
1452
- · by_cases hq : q = 0
1453
- · simp only [hq, mul_zero, leadingCoeff_zero]
1454
- · rw [leadingCoeff_mul']
1455
- exact mul_ne_zero (mt leadingCoeff_eq_zero.1 hp) (mt leadingCoeff_eq_zero.1 hq)
1456
-
1457
- /-- `Polynomial.leadingCoeff` bundled as a `MonoidHom` when `R` has `NoZeroDivisors`, and thus
1458
- `leadingCoeff` is multiplicative -/
1459
- def leadingCoeffHom : R[X] →* R where
1460
- toFun := leadingCoeff
1461
- map_one' := by simp
1462
- map_mul' := leadingCoeff_mul
1463
-
1464
- @[simp]
1465
- theorem leadingCoeffHom_apply (p : R[X]) : leadingCoeffHom p = leadingCoeff p :=
1466
- rfl
1467
-
1468
- @[simp]
1469
- theorem leadingCoeff_pow (p : R[X]) (n : ℕ) : leadingCoeff (p ^ n) = leadingCoeff p ^ n :=
1470
- (leadingCoeffHom : R[X] →* R).map_pow p n
1471
-
1472
- theorem leadingCoeff_dvd_leadingCoeff {a p : R[X]} (hap : a ∣ p) :
1473
- a.leadingCoeff ∣ p.leadingCoeff :=
1474
- map_dvd leadingCoeffHom hap
1475
-
1476
- end NoZeroDivisors
1605
+ instance : IsDomain R[X] := NoZeroDivisors.to_isDomain _
1477
1606
1607
+ end Ring
1478
1608
end Polynomial
1609
+
1610
+ set_option linter.style.longFile 1700
0 commit comments