Documentation

CombinatorialGames.Nimber.SimplestExtension.Polynomial

Nimber polynomials #

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

For Mathlib #

theorem List.le_sum_of_mem' {M : Type u_1} [AddMonoid M] [PartialOrder M] [OrderBot M] [AddLeftMono M] [AddRightMono M] (hm : = 0) {xs : List M} {x : M} (h₁ : x xs) :
x xs.sum
theorem Polynomial.monomial_induction {R : Type u_1} [Semiring R] {motive : Polynomial RProp} (zero : motive 0) (add : ∀ (a : R) (n : ) (q : Polynomial R), q.degree < nmotive qmotive (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
@[simp]
theorem WithTop.forall_lt_coe {α : Type u_1} {P : WithTop αProp} [Preorder α] {x : α} :
(∀ y < x, P y) y < x, P y
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

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.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) (hx₀ : x 0) (hs : ys, ∀ (k : ), (f y).coeff k < x) (k : ) :
(s.sum f).coeff k < x
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) (hx₁ : 1 < x) (hs : ys, ∀ (k : ), (f y).coeff k < x) (k : ) :
(s.prod f).coeff k < x

Embedding in a subfield #

def Nimber.IsField.embed {x : Nimber} (h : x.IsField) (hx₁ : 1 < x) (p : Polynomial Nimber) (hp : ∀ (k : ), p.coeff k < x) :
Polynomial (h.toSubfield hx₁)

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) (hx₁ : 1 < x) {p : Polynomial Nimber} (hp : ∀ (k : ), p.coeff k < x) (k : ) :
    (h.embed hx₁ p hp).coeff k = p.coeff k,
    @[simp]
    theorem Nimber.IsField.degree_embed {x : Nimber} (h : x.IsField) (hx₁ : 1 < x) {p : Polynomial Nimber} (hp : ∀ (k : ), p.coeff k < x) :
    (h.embed hx₁ p hp).degree = p.degree
    @[simp]
    theorem Nimber.IsField.leadingCoeff_embed {x : Nimber} (h : x.IsField) (hx₁ : 1 < x) {p : Polynomial Nimber} (hp : ∀ (k : ), p.coeff k < x) :
    (h.embed hx₁ p hp).leadingCoeff = p.leadingCoeff,
    @[simp]
    theorem Nimber.IsField.map_embed {x : Nimber} (h : x.IsField) (hx₁ : 1 < x) {p : Polynomial Nimber} (hp : ∀ (k : ), p.coeff k < x) :
    Polynomial.map (h.toSubfield hx₁).subtype (h.embed hx₁ p hp) = p
    @[simp]
    theorem Nimber.IsField.embed_C {x : Nimber} (h : x.IsField) (hx₁ : 1 < x) {y : Nimber} {hy : ∀ (k : ), (Polynomial.C y).coeff k < x} :
    h.embed hx₁ (Polynomial.C y) hy = Polynomial.C y,
    @[simp]
    theorem Nimber.IsField.eval_embed {x : Nimber} (h : x.IsField) (hx₁ : 1 < x) {p : Polynomial Nimber} (hp : ∀ (k : ), p.coeff k < x) (y : (h.toSubfield hx₁)) :
    Polynomial.eval y (h.embed hx₁ p hp) = Polynomial.eval (↑y) p,

    Lexicographic ordering on polynomials #

    The colexicographic ordering on nimber polynomials.

    TODO: Use Colex to define the ordering instead of Lex once it's available.

    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 < kp.coeff k = q.coeff k) p.coeff n < q.coeff n
    @[simp]
    @[simp]
    theorem Nimber.Lex.forall_lt_C {P : Polynomial NimberProp} {x : Nimber} :
    (∀ p < Polynomial.C x, P p) a < x, P (Polynomial.C a)
    @[simp]
    theorem Nimber.Lex.forall_le_C {P : Polynomial NimberProp} {x : Nimber} :
    (∀ yPolynomial.C x, P y) yx, P (Polynomial.C y)
    @[simp]
    theorem Nimber.Lex.exists_lt_C {P : Polynomial NimberProp} {x : Nimber} :
    (∃ y < Polynomial.C x, P y) y < x, P (Polynomial.C y)
    @[simp]
    theorem Nimber.Lex.exists_le_C {P : Polynomial NimberProp} {x : Nimber} :
    (∃ yPolynomial.C x, P y) yx, 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]
    Equations
    • One or more equations did not get rendered due to their size.
    @[simp]

    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_opow {x : Nimber} {p : Polynomial Nimber} {n : } (hpk : ∀ (k : ), p.coeff k < x) (hn : p.degree < n) :
      val (x.oeval p) < of (val x ^ n)
      theorem Nimber.oeval_lt_opow_iff {x : Nimber} {p : Polynomial Nimber} {n : } (hpk : ∀ (k : ), p.coeff k < x) :
      val (x.oeval p) < of (val x ^ n) p.degree < n
      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.eq_oeval_of_lt_opow' {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_opow stated in terms of Ordinal.

      theorem Nimber.eq_oeval_of_lt_opow {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_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} (hx₁ : 1 < x) {P : Ordinal.{u_1}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.has_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.IsField.has_root_subfield {x : Nimber} (h : x.IsField) (hx₁ : 1 < x) {p : Polynomial (h.toSubfield hx₁)} (hp₀ : p.degree 0) (hpn : (Polynomial.map (h.toSubfield hx₁).subtype p) < x.leastNoRoots) :
        ∃ (r : (h.toSubfield hx₁)), p.IsRoot r
        theorem Nimber.IsField.splits_subfield {x : Nimber} (h : x.IsField) (hx₁ : 1 < x) {p : Polynomial (h.toSubfield hx₁)} (hpn : (Polynomial.map (h.toSubfield hx₁).subtype p) < x.leastNoRoots) :
        theorem Nimber.IsField.roots_eq_map {x : Nimber} (h : x.IsField) (hx₁ : 1 < x) {p : Polynomial Nimber} (hpn : p < x.leastNoRoots) (hpk : ∀ (k : ), p.coeff k < x) :
        p.roots = Multiset.map (⇑(h.toSubfield hx₁).subtype) (h.embed hx₁ p hpk).roots
        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