|
| 1 | +/- |
| 2 | +Copyright (c) 2022 Damiano Testa. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Damiano Testa |
| 5 | +-/ |
| 6 | + |
| 7 | +import data.polynomial.induction |
| 8 | +import data.polynomial.degree.definitions |
| 9 | + |
| 10 | +/-! # Interactions between `R[X]` and `Rᵐᵒᵖ[X]` |
| 11 | +
|
| 12 | +This file contains the basic API for "pushing through" the isomorphism |
| 13 | +`op_ring_equiv : R[X]ᵐᵒᵖ ≃+* Rᵐᵒᵖ[X]`. It allows going back and forth between a polynomial ring |
| 14 | +over a semiring and the polynomial ring over the opposite semiring. -/ |
| 15 | + |
| 16 | +open_locale polynomial |
| 17 | +open polynomial mul_opposite |
| 18 | + |
| 19 | +variables {R : Type*} [semiring R] {p q : R[X]} |
| 20 | + |
| 21 | +noncomputable theory |
| 22 | + |
| 23 | +namespace polynomial |
| 24 | + |
| 25 | +/-- Ring isomorphism between `R[X]ᵐᵒᵖ` and `Rᵐᵒᵖ[X]` sending each coefficient of a polynomial |
| 26 | +to the corresponding element of the opposite ring. -/ |
| 27 | +def op_ring_equiv (R : Type*) [semiring R] : R[X]ᵐᵒᵖ ≃+* Rᵐᵒᵖ[X] := |
| 28 | +((to_finsupp_iso R).op.trans add_monoid_algebra.op_ring_equiv).trans (to_finsupp_iso _).symm |
| 29 | + |
| 30 | +-- for maintenance purposes: `by simp [op_ring_equiv]` proves this lemma |
| 31 | +/-! Lemmas to get started, using `op_ring_equiv R` on the various expressions of |
| 32 | +`finsupp.single`: `monomial`, `C a`, `X`, `C a * X ^ n`. -/ |
| 33 | +@[simp] lemma op_ring_equiv_op_monomial (n : ℕ) (r : R) : |
| 34 | + op_ring_equiv R (op (monomial n r : R[X])) = monomial n (op r) := |
| 35 | +by simp only [op_ring_equiv, ring_equiv.trans_apply, ring_equiv.op_apply_apply, |
| 36 | + ring_equiv.to_add_equiv_eq_coe, add_equiv.mul_op_apply, add_equiv.to_fun_eq_coe, |
| 37 | + add_equiv.coe_trans, op_add_equiv_apply, ring_equiv.coe_to_add_equiv, op_add_equiv_symm_apply, |
| 38 | + function.comp_app, unop_op, to_finsupp_iso_apply, to_finsupp_monomial, |
| 39 | + add_monoid_algebra.op_ring_equiv_single, to_finsupp_iso_symm_apply, of_finsupp_single] |
| 40 | + |
| 41 | +@[simp] lemma op_ring_equiv_op_C (a : R) : |
| 42 | + op_ring_equiv R (op (C a)) = C (op a) := |
| 43 | +op_ring_equiv_op_monomial 0 a |
| 44 | + |
| 45 | +@[simp] lemma op_ring_equiv_op_X : |
| 46 | + op_ring_equiv R (op (X : R[X])) = X := |
| 47 | +op_ring_equiv_op_monomial 1 1 |
| 48 | + |
| 49 | +lemma op_ring_equiv_op_C_mul_X_pow (r : R) (n : ℕ) : |
| 50 | + op_ring_equiv R (op (C r * X ^ n : R[X])) = C (op r) * X ^ n := |
| 51 | +by simp only [X_pow_mul, op_mul, op_pow, map_mul, map_pow, op_ring_equiv_op_X, op_ring_equiv_op_C] |
| 52 | + |
| 53 | +/-! Lemmas to get started, using `(op_ring_equiv R).symm` on the various expressions of |
| 54 | +`finsupp.single`: `monomial`, `C a`, `X`, `C a * X ^ n`. -/ |
| 55 | +@[simp] lemma op_ring_equiv_symm_monomial (n : ℕ) (r : Rᵐᵒᵖ) : |
| 56 | + (op_ring_equiv R).symm (monomial n r) = op (monomial n (unop r)) := |
| 57 | +(op_ring_equiv R).injective (by simp) |
| 58 | + |
| 59 | +@[simp] lemma op_ring_equiv_symm_C (a : Rᵐᵒᵖ) : |
| 60 | + (op_ring_equiv R).symm (C a) = op (C (unop a)) := |
| 61 | +op_ring_equiv_symm_monomial 0 a |
| 62 | + |
| 63 | +@[simp] lemma op_ring_equiv_symm_X : |
| 64 | + (op_ring_equiv R).symm (X : Rᵐᵒᵖ[X]) = op X := |
| 65 | +op_ring_equiv_symm_monomial 1 1 |
| 66 | + |
| 67 | +lemma op_ring_equiv_symm_C_mul_X_pow (r : Rᵐᵒᵖ) (n : ℕ) : |
| 68 | + (op_ring_equiv R).symm (C r * X ^ n : Rᵐᵒᵖ[X]) = op (C (unop r) * X ^ n) := |
| 69 | +by rw [← monomial_eq_C_mul_X, op_ring_equiv_symm_monomial, monomial_eq_C_mul_X] |
| 70 | + |
| 71 | +/-! Lemmas about more global properties of polynomials and opposites. -/ |
| 72 | +@[simp] lemma coeff_op_ring_equiv (p : R[X]ᵐᵒᵖ) (n : ℕ) : |
| 73 | + (op_ring_equiv R p).coeff n = op ((unop p).coeff n) := |
| 74 | +begin |
| 75 | + induction p using mul_opposite.rec, |
| 76 | + cases p, |
| 77 | + refl |
| 78 | +end |
| 79 | + |
| 80 | +@[simp] lemma support_op_ring_equiv (p : R[X]ᵐᵒᵖ) : |
| 81 | + (op_ring_equiv R p).support = (unop p).support := |
| 82 | +begin |
| 83 | + induction p using mul_opposite.rec, |
| 84 | + cases p, |
| 85 | + exact finsupp.support_map_range_of_injective _ _ op_injective |
| 86 | +end |
| 87 | + |
| 88 | +@[simp] lemma nat_degree_op_ring_equiv (p : R[X]ᵐᵒᵖ) : |
| 89 | + (op_ring_equiv R p).nat_degree = (unop p).nat_degree := |
| 90 | +begin |
| 91 | + by_cases p0 : p = 0, |
| 92 | + { simp only [p0, _root_.map_zero, nat_degree_zero, unop_zero] }, |
| 93 | + { simp only [p0, nat_degree_eq_support_max', ne.def, add_equiv_class.map_eq_zero_iff, |
| 94 | + not_false_iff, support_op_ring_equiv, unop_eq_zero_iff] } |
| 95 | +end |
| 96 | + |
| 97 | +@[simp] lemma leading_coeff_op_ring_equiv (p : R[X]ᵐᵒᵖ) : |
| 98 | + (op_ring_equiv R p).leading_coeff = op (unop p).leading_coeff := |
| 99 | +by rw [leading_coeff, coeff_op_ring_equiv, nat_degree_op_ring_equiv, leading_coeff] |
| 100 | + |
| 101 | +end polynomial |
0 commit comments