Documentation

CombinatorialGames.Nimber.SimplestExtension.Polynomial

Nimber polynomials #

This file contains multiple auxiliary results and definitions for working with nimber polynomials:

For Mathlib #

theorem Polynomial.degree_pos_of_mem_roots {R : Type u_2} [CommRing R] [IsDomain R] {p : Polynomial R} {r : R} (h : r ∈ p.roots) :
0 < p.degree
theorem Polynomial.monomial_induction {R : Type u_1} [Semiring R] {motive : Polynomial R → Prop} (zero : motive 0) (add : ∀ (a : R) (n : ℕ) (q : Polynomial R), q.degree < ↑n → motive q → motive (C a * X ^ n + q)) (p : Polynomial R) :
motive p
theorem Polynomial.eq_add_C_mul_X_pow_of_degree_le {R : Type u_1} [Semiring R] {p : Polynomial R} {n : ℕ} (h : p.degree ≤ ↑n) :
∃ (a : R) (q : Polynomial R), p = q + C a * X ^ n ∧ q.degree < ↑n
theorem WithBot.le_zero_iff {α : Type u_1} [AddZeroClass α] [PartialOrder α] [CanonicallyOrderedAdd α] {x : WithBot α} :
x ≤ 0 ↔ x = ⊥ ∨ x = 0
theorem WithBot.coe_add_one (n : ℕ) :
↑(n + 1) = ↑n + 1
@[simp]
theorem WithBot.natCast_eq_coe (n : ℕ) :
↑n = ↑n
@[simp]
theorem WithBot.lt_add_one {x : WithBot ℕ} (n : ℕ) :
x < ↑n + 1 ↔ x ≤ ↑n
theorem WithBot.add_pos_of_pos_of_nonneg {α : Type u_1} [AddZeroClass α] [Preorder α] [AddLeftMono α] {a b : WithBot α} (ha : 0 < a) (hb : 0 ≤ b) :
0 < a + b
@[simp]
theorem WithTop.untop_eq {α : Type u_1} {x : WithTop α} {y : α} (h : x = ↑y) :
x.untop ⋯ = y
theorem WithTop.eq_untop {α : Type u_1} {x : WithTop α} {y : α} (h : ↑y = x) :
y = x.untop ⋯

Basic results #

theorem Nimber.polynomial_eq_zero_of_le_one {x : Nimber} {p : Polynomial Nimber} (hx₁ : x ≤ 1) (h : ∀ (k : ℕ), p.coeff k < x) :
p = 0
theorem Nimber.IsRing.eval_lt {x y : Nimber} (h : x.IsRing) {p : Polynomial Nimber} (hp : ∀ (k : ℕ), p.coeff k < x) (hy : y < x) :
theorem Nimber.coeff_X_pow_lt {x : Nimber} (n : ℕ) (h : 1 < x) (k : ℕ) :
theorem Nimber.coeff_X_lt {x : Nimber} (h : 1 < x) (k : ℕ) :
theorem Nimber.IsGroup.coeff_add_lt {x : Nimber} {p q : Polynomial Nimber} (h : x.IsGroup) (hp : ∀ (k : ℕ), p.coeff k < x) (hq : ∀ (k : ℕ), q.coeff k < x) (k : ℕ) :
(p + q).coeff k < x
theorem Nimber.IsGroup.coeff_sum_lt {x : Nimber} {ι : Type u_2} {f : ι → Polynomial Nimber} {s : Finset ι} (h : x.IsGroup) (hs : ∀ y ∈ s, ∀ (k : ℕ), (f y).coeff k < x) (k : ℕ) :
(s.sum f).coeff k < x
theorem Nimber.coeff_zero_lt {x : Nimber} (h : x ≠ 0) (k : ℕ) :
theorem Nimber.IsRing.coeff_mul_lt {x : Nimber} {p q : Polynomial Nimber} (h : x.IsRing) (hp : ∀ (k : ℕ), p.coeff k < x) (hq : ∀ (k : ℕ), q.coeff k < x) (k : ℕ) :
(p * q).coeff k < x
theorem Nimber.IsRing.coeff_prod_lt {x : Nimber} {ι : Type u_2} {f : ι → Polynomial Nimber} {s : Finset ι} (h : x.IsRing) (hs : ∀ y ∈ s, ∀ (k : ℕ), (f y).coeff k < x) (k : ℕ) :
(s.prod f).coeff k < x
theorem Nimber.coeff_one_lt {x : Nimber} (h : 1 < x) (k : ℕ) :
theorem Nimber.coeff_C_lt {x y : Nimber} (h : y < x) (k : ℕ) :

Embedding in a subfield #

noncomputable def Nimber.IsField.embed {x : Nimber} (h : x.IsField) (p : Polynomial Nimber) (hp : ∀ (k : ℕ), p.coeff k < x) :

Reinterpret a polynomial in the nimbers as a polynomial in the subfield x.

We could define this under the weaker assumption IsRing, but due to proof erasure, this leads to issues where Field (h.toSubring ⋯) can't be inferred, even if h : IsField x.

Equations
Instances For
    @[simp]
    theorem Nimber.IsField.coeff_embed {x : Nimber} (h : x.IsField) {p : Polynomial Nimber} (hp : ∀ (k : ℕ), p.coeff k < x) (k : ℕ) :
    (h.embed p hp).coeff k = ⟨p.coeff k, ⋯⟩
    @[simp]
    theorem Nimber.IsField.degree_embed {x : Nimber} (h : x.IsField) {p : Polynomial Nimber} (hp : ∀ (k : ℕ), p.coeff k < x) :
    (h.embed p hp).degree = p.degree
    @[simp]
    theorem Nimber.IsField.leadingCoeff_embed {x : Nimber} (h : x.IsField) {p : Polynomial Nimber} (hp : ∀ (k : ℕ), p.coeff k < x) :
    @[simp]
    theorem Nimber.IsField.monic_embed {x : Nimber} (h : x.IsField) {p : Polynomial Nimber} (hp : ∀ (k : ℕ), p.coeff k < x) :
    (h.embed p hp).Monic ↔ p.Monic
    @[simp]
    theorem Nimber.IsField.map_embed {x : Nimber} (h : x.IsField) {p : Polynomial Nimber} (hp : ∀ (k : ℕ), p.coeff k < x) :
    @[simp]
    theorem Nimber.IsField.embed_C {x : Nimber} (h : x.IsField) {y : Nimber} {hy : ∀ (k : ℕ), (Polynomial.C y).coeff k < x} :
    @[simp]
    theorem Nimber.IsField.eval_embed {x : Nimber} (h : x.IsField) {p : Polynomial Nimber} (hp : ∀ (k : ℕ), p.coeff k < x) (y : ↥h.toSubfield) :
    Polynomial.eval y (h.embed p hp) = ⟨Polynomial.eval (↑y) p, ⋯⟩

    Lexicographic ordering on polynomials #

    @[instance_reducible]

    The colexicographic ordering on nimber polynomials.

    Equations
    • One or more equations did not get rendered due to their size.
    theorem Nimber.Lex.lt_def {p q : Polynomial Nimber} :
    p < q ↔ ∃ (n : ℕ), (∀ (k : ℕ), n < k → p.coeff k = q.coeff k) ∧ p.coeff n < q.coeff n
    @[instance_reducible]
    Equations
    @[simp]
    @[simp]
    theorem Nimber.Lex.forall_lt_C {P : Polynomial Nimber → Prop} {x : Nimber} :
    (∀ p < Polynomial.C x, P p) ↔ ∀ a < x, P (Polynomial.C a)
    @[simp]
    theorem Nimber.Lex.forall_le_C {P : Polynomial Nimber → Prop} {x : Nimber} :
    (∀ y ≤ Polynomial.C x, P y) ↔ ∀ y ≤ x, P (Polynomial.C y)
    @[simp]
    theorem Nimber.Lex.exists_lt_C {P : Polynomial Nimber → Prop} {x : Nimber} :
    (∃ y < Polynomial.C x, P y) ↔ ∃ y < x, P (Polynomial.C y)
    @[simp]
    theorem Nimber.Lex.exists_le_C {P : Polynomial Nimber → Prop} {x : Nimber} :
    (∃ y ≤ Polynomial.C x, P y) ↔ ∃ y ≤ x, P (Polynomial.C y)
    @[simp]
    @[simp]
    theorem Nimber.Lex.coe_lt_X_pow_iff {p : Polynomial Nimber} {n : ℕ} :
    ↑p < ↑Polynomial.X ^ n ↔ p.degree < ↑n
    @[simp]
    @[instance_reducible]
    Equations
    • One or more equations did not get rendered due to their size.
    @[simp]

    Evaluating nimber polynomials as ordinals #

    noncomputable def Nimber.oeval (x : Nimber) (p : Polynomial Nimber) :

    Evaluate a nimber polynomial using ordinal arithmetic.

    TODO: once the Ordinal.CNF API is more developed, use it to redefine this.

    Equations
    Instances For
      @[simp]
      theorem Nimber.oeval_zero (x : Nimber) :
      x.oeval 0 = 0
      theorem Nimber.oeval_eq_of_natDegree_le {p : Polynomial Nimber} {n : ℕ} (h : p.natDegree + 1 ≤ n) (x : Nimber) :
      x.oeval p = of (List.map (fun (k : ℕ) => val x ^ k * val (p.coeff k)) (List.range n).reverse).sum
      theorem Nimber.oeval_C_mul_X_pow_add {n : ℕ} {p : Polynomial Nimber} (hp : p.degree < ↑n) (x a : Nimber) :
      x.oeval (Polynomial.C a * Polynomial.X ^ n + p) = of (val x ^ n * val a + val (x.oeval p))
      @[simp]
      theorem Nimber.oeval_X_pow_mul (x : Nimber) (n : ℕ) (p : Polynomial Nimber) :
      x.oeval (Polynomial.X ^ n * p) = of (val x ^ n * val (x.oeval p))
      @[simp]
      theorem Nimber.oeval_mul_X_pow (x : Nimber) (n : ℕ) (p : Polynomial Nimber) :
      x.oeval (p * Polynomial.X ^ n) = of (val x ^ n * val (x.oeval p))
      @[simp]
      theorem Nimber.oeval_X_pow (x : Nimber) (n : ℕ) :
      x.oeval (Polynomial.X ^ n) = of (val x ^ n)
      @[simp]
      @[simp]
      theorem Nimber.oeval_C (x a : Nimber) :
      @[simp]
      theorem Nimber.oeval_one (x : Nimber) :
      x.oeval 1 = 1
      theorem Nimber.mul_coeff_le_oeval (x : Nimber) (p : Polynomial Nimber) (k : ℕ) :
      of (val x ^ k * val (p.coeff k)) ≤ x.oeval p
      theorem Nimber.oeval_lt_pow {x : Nimber} {p : Polynomial Nimber} {n : ℕ} (hpk : ∀ (k : ℕ), p.coeff k < x) (hn : p.degree < ↑n) :
      x.oeval p < of (val x ^ n)
      theorem Nimber.oeval_lt_pow_iff {x : Nimber} {p : Polynomial Nimber} {n : ℕ} (hpk : ∀ (k : ℕ), p.coeff k < x) :
      x.oeval p < of (val x ^ n) ↔ p.degree < ↑n
      theorem Nimber.oeval_lt_opow_omega0 {x : Nimber} {p : Polynomial Nimber} (hpk : ∀ (k : ℕ), p.coeff k < x) :
      theorem Nimber.oeval_lt_oeval {x : Nimber} {p q : Polynomial Nimber} (h : p < q) (hpk : ∀ (k : ℕ), p.coeff k < x) (hqk : ∀ (k : ℕ), q.coeff k < x) :
      x.oeval p < x.oeval q
      theorem Nimber.oeval_le_oeval {x : Nimber} {p q : Polynomial Nimber} (h : p ≤ q) (hpk : ∀ (k : ℕ), p.coeff k < x) (hqk : ∀ (k : ℕ), q.coeff k < x) :
      x.oeval p ≤ x.oeval q
      theorem Nimber.oeval_lt_oeval_iff {x : Nimber} {p q : Polynomial Nimber} (hpk : ∀ (k : ℕ), p.coeff k < x) (hqk : ∀ (k : ℕ), q.coeff k < x) :
      x.oeval p < x.oeval q ↔ p < q
      theorem Nimber.oeval_le_oeval_iff {x : Nimber} {p q : Polynomial Nimber} (hpk : ∀ (k : ℕ), p.coeff k < x) (hqk : ∀ (k : ℕ), q.coeff k < x) :
      x.oeval p ≤ x.oeval q ↔ p ≤ q
      theorem Nimber.oeval_inj {x : Nimber} {p q : Polynomial Nimber} (hpk : ∀ (k : ℕ), p.coeff k < x) (hqk : ∀ (k : ℕ), q.coeff k < x) :
      x.oeval p = x.oeval q ↔ p = q
      theorem Nimber.oeval_eq_zero_iff {x : Nimber} {p : Polynomial Nimber} (hx : x ≠ 0) :
      x.oeval p = 0 ↔ p = 0
      theorem Nimber.eq_oeval_of_lt_pow' {x y : Ordinal.{u_1}} {n : ℕ} (hx₀ : x ≠ 0) (h : y < x ^ n) :
      ∃ (p : Polynomial Nimber), p.degree < ↑n ∧ (∀ (k : ℕ), val (p.coeff k) < x) ∧ val ((of x).oeval p) = y

      A version of eq_oeval_of_lt_pow stated in terms of Ordinal.

      theorem Nimber.eq_oeval_of_lt_pow {x y : Nimber} {n : ℕ} (hx₀ : x ≠ 0) (h : y < of (val x ^ n)) :
      ∃ (p : Polynomial Nimber), p.degree < ↑n ∧ (∀ (k : ℕ), p.coeff k < x) ∧ x.oeval p = y
      theorem Nimber.eq_oeval_of_lt_opow_omega0 {x y : Nimber} (h : y < of (val x ^ Ordinal.omega0)) :
      ∃ (p : Polynomial Nimber), (∀ (k : ℕ), p.coeff k < x) ∧ x.oeval p = y
      theorem Nimber.eq_oeval_of_lt_oeval {x y : Nimber} {p : Polynomial Nimber} (hx₀ : x ≠ 0) (hpk : ∀ (k : ℕ), p.coeff k < x) (h : y < x.oeval p) :
      ∃ q < p, (∀ (k : ℕ), q.coeff k < x) ∧ x.oeval q = y
      theorem Nimber.forall_lt_oeval_iff {x : Nimber} {P : Nimber → Prop} {p : Polynomial Nimber} (hpk : ∀ (k : ℕ), p.coeff k < x) :
      (∀ y < x.oeval p, P y) ↔ ∀ q < p, (∀ (k : ℕ), q.coeff k < x) → P (x.oeval q)

      Least irreducible polynomial #

      Returns the lexicographically earliest non-constant polynomial, all of whose coefficients are less than x, without any roots less than x. If none exists, returns ⊤.

      This function takes values on WithTop (Nimber[X]), which is a well-ordered complete lattice (the order on Nimber[X] is the lexicographic order).

      Equations
      Instances For
        theorem Nimber.leastNoRoots_le_of_not_isRoot {x : Nimber} {p : Polynomial Nimber} (hp₀ : 0 < p.degree) (hpk : ∀ (k : ℕ), p.coeff k < x) (hr : ∀ r < x, ¬p.IsRoot r) :
        theorem Nimber.exists_root_of_lt_leastNoRoots {x : Nimber} {p : Polynomial Nimber} (hp₀ : p.degree ≠ 0) (hpk : ∀ (k : ℕ), p.coeff k < x) (hpn : ↑p < x.leastNoRoots) :
        ∃ r < x, p.IsRoot r
        theorem Nimber.le_leastNoRoots_of_exists_isRoot {x : Nimber} {p : Polynomial Nimber} (hp : ∀ c < p, 0 < c.degree → (∀ (k : ℕ), c.coeff k < x) → ∃ r < x, c.IsRoot r) :
        theorem Nimber.IsField.exists_root_subfield {x : Nimber} (h : x.IsField) {p : Polynomial ↥h.toSubfield} (hp₀ : p.degree ≠ 0) (hpn : ↑(Polynomial.map h.toSubfield.subtype p) < x.leastNoRoots) :
        ∃ (r : ↥h.toSubfield), p.IsRoot r
        theorem Nimber.IsField.roots_eq_map {x : Nimber} (h : x.IsField) {p : Polynomial Nimber} (hpn : ↑p < x.leastNoRoots) (hpk : ∀ (k : ℕ), p.coeff k < x) :
        theorem Nimber.IsField.root_lt {x r : Nimber} (h : x.IsField) {p : Polynomial Nimber} (hpn : ↑p < x.leastNoRoots) (hpk : ∀ (k : ℕ), p.coeff k < x) (hr : r ∈ p.roots) :
        r < x
        theorem Polynomial.exists_gt_of_forall_coeff_gt {s : Set Nimber} {p : Polynomial Nimber} (h : ∀ (k : ℕ), ∃ a ∈ s, p.coeff k < a) :
        ∃ a ∈ s, ∀ (k : ℕ), p.coeff k < a
        theorem Nimber.le_leastNoRoots_iSup {ι : Sort u_1} {f : ι → Nimber} {p : WithTop (Polynomial Nimber)} (H : ∀ (i : ι), p ≤ (f i).leastNoRoots) :
        p ≤ (⨆ (i : ι), f i).leastNoRoots