-
Notifications
You must be signed in to change notification settings - Fork 14
feat: ordinal powers of a field form a basis for nimbers #348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
vihdzp
wants to merge
13
commits into
master
Choose a base branch
from
addmonoidalg
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
d68bdbf
there goes
vihdzp f125b3a
there
vihdzp 9e57269
finish
vihdzp 9cc119e
is this going to work now
vihdzp 306f1cd
tweak
vihdzp 8d20d0e
fix
vihdzp fd0cbb8
fix?
vihdzp b72aaf2
fix names
vihdzp ca284b7
golf
vihdzp 86bebb8
Update CombinatorialGames/Nimber/Finsupp.lean
vihdzp f218c41
Update CombinatorialGames/Nimber/Finsupp.lean
vihdzp 805479c
Merge branch 'master' into addmonoidalg
vihdzp 4eaa9b8
more theorems
vihdzp File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,193 @@ | ||
| /- | ||
| Copyright (c) 2026 Violeta Hernández Palacios. All rights reserved. | ||
| Released under Apache 2.0 license as described in the file LICENSE. | ||
| Authors: Violeta Hernández Palacios | ||
| -/ | ||
| module | ||
|
|
||
| public import CombinatorialGames.Nimber.SimplestExtension.Basic | ||
| public import Mathlib.LinearAlgebra.Basis.Defs | ||
|
|
||
| import Mathlib.SetTheory.Ordinal.CantorNormalForm | ||
|
|
||
| /-! | ||
| # Nimbers as finitely supported functions | ||
|
|
||
| We prove that if `b` is a field, then the base-`b` Cantor normal form of a nimber respects addition, | ||
| when viewed as a formal sum of powers of `b`. | ||
| -/ | ||
|
|
||
| universe u | ||
|
|
||
| /-! ### For Mathlib -/ | ||
|
|
||
| namespace Ordinal.CNF | ||
|
|
||
| theorem coeff_lt {b : Ordinal} (hb : 1 < b) (o e : Ordinal) : coeff b o e < b := by | ||
| by_cases he : e ∈ (CNF b o).map Prod.fst | ||
| · rw [List.mem_map, Prod.exists] at he | ||
| obtain ⟨c, _, hc, rfl⟩ := he | ||
| rw [coeff_of_mem_CNF hc] | ||
| exact snd_lt hb hc | ||
| · rw [coeff_of_notMem_CNF he] | ||
| exact hb.pos | ||
|
|
||
| theorem support_coeff_subset {b o x : Ordinal} (hx : x < b ^ o) : | ||
| SetLike.coe (coeff b x).support ⊆ Set.Iio o := by | ||
| obtain rfl | hb := eq_zero_or_pos b | ||
| · have := hx.trans_le (zero_opow_le _) | ||
| simp_all | ||
| intro e | ||
| rw [SetLike.mem_coe, Finsupp.mem_support_iff, Set.mem_Iio] | ||
| contrapose! | ||
| exact fun he ↦ coeff_eq_zero_of_lt (hx.trans_le (opow_le_opow_right hb he)) | ||
|
|
||
| end Ordinal.CNF | ||
|
|
||
| namespace Finsupp | ||
| variable {M N α : Type*} [AddZeroClass M] [AddZeroClass N] | ||
|
|
||
| theorem mapRange_single_add {f : M → N} {g : α →₀ M} {hf : f 0 = 0} {a : α} {b : M} | ||
| (hg : a ∉ g.support) : mapRange f hf (single a b + g) = single a (f b) + mapRange f hf g := by | ||
| ext e | ||
| obtain rfl | he := eq_or_ne e a | ||
| · rw [notMem_support_iff] at hg | ||
| simp_all | ||
| · simp [he] | ||
|
|
||
| end Finsupp | ||
|
|
||
| public noncomputable section | ||
|
|
||
| namespace Nimber | ||
| variable (b : Nimber) (hb : IsField b) | ||
|
|
||
| open Finsupp Ordinal Set | ||
|
|
||
| /-- `toFinsupp b hb x e` returns the coefficient of `b ^ e` in `x`. This is a specialization of | ||
| `Ordinal.CNF.coeff`. -/ | ||
| @[pp_nodot] | ||
| def toFinsupp (x : Nimber) : Ordinal →₀ hb.toSubfield := | ||
| (CNF.coeff b.val x.val).mapRange | ||
| (fun z ↦ if h : z < b.val then ⟨z, h⟩ else 0) (dif_pos hb.pos) | ||
|
|
||
| @[simp] | ||
| private theorem toFinsupp_apply (x : Nimber) (e : Ordinal) : | ||
| toFinsupp b hb x e = ⟨∗(CNF.coeff b.val x.val e), CNF.coeff_lt hb.one_lt _ e⟩ := | ||
| dif_pos .. | ||
|
|
||
| @[simp] | ||
| theorem toFinsupp_zero : toFinsupp b hb 0 = 0 := by | ||
| ext; simp | ||
|
|
||
| theorem support_toFinsupp_subset {o : Ordinal} {x : Nimber} (hx : x < ∗(b.val ^ o)) : | ||
| SetLike.coe (toFinsupp b hb x).support ⊆ Iio o := | ||
| (SetLike.coe_subset_coe.2 (support_mapRange ..)).trans (CNF.support_coeff_subset hx) | ||
|
|
||
| /-- Add a linear combination of ordinal powers of `b` to create a nimber. This is a specialization | ||
| of `Ordinal.CNF.eval`. -/ | ||
| @[pp_nodot] | ||
| def ofFinsupp (x : Ordinal →₀ hb.toSubfield) : Nimber := | ||
| ∗(CNF.eval b.val (x.mapRange (fun e ↦ e.1.val) rfl)) | ||
|
|
||
| @[simp] | ||
| theorem ofFinsupp_zero : ofFinsupp b hb 0 = 0 := by | ||
| simp [ofFinsupp] | ||
|
|
||
| theorem ofFinsupp_lt {o : Ordinal} {x : Ordinal →₀ hb.toSubfield} | ||
| (hf : SetLike.coe x.support ⊆ Iio o) : ofFinsupp b hb x < ∗(b.val ^ o) := by | ||
| apply CNF.eval_lt | ||
| · simp | ||
| · aesop | ||
|
|
||
| @[simp] | ||
| theorem toFinsupp_ofFinsupp (x) : toFinsupp b hb (ofFinsupp b hb x) = x := by | ||
| ext e | ||
| simp only [ofFinsupp, toFinsupp_apply, val_of] | ||
| rw [CNF.coeff_eval (b := b.val) hb.one_lt] <;> simp | ||
|
|
||
| @[simp] | ||
| theorem ofFinsupp_toFinsupp (x) : ofFinsupp b hb (toFinsupp b hb x) = x := by | ||
| rw [ofFinsupp, of_eq_iff] | ||
| convert CNF.eval_coeff .. | ||
| ext | ||
| simp | ||
|
|
||
| theorem toFinsupp_injective : Function.Injective (toFinsupp b hb) := | ||
| Function.LeftInverse.injective (ofFinsupp_toFinsupp b hb) | ||
|
|
||
| theorem ofFinsupp_injective : Function.Injective (ofFinsupp b hb) := | ||
| Function.LeftInverse.injective (toFinsupp_ofFinsupp b hb) | ||
|
|
||
| @[simp] | ||
| theorem toFinsupp_inj {x y} : toFinsupp b hb x = toFinsupp b hb y ↔ x = y := | ||
| (toFinsupp_injective b hb).eq_iff | ||
|
|
||
| @[simp] | ||
| theorem ofFinsupp_inj {x y} : ofFinsupp b hb x = ofFinsupp b hb y ↔ x = y := | ||
| (ofFinsupp_injective b hb).eq_iff | ||
|
|
||
| theorem ofFinsupp_def (x) : | ||
| ofFinsupp b hb x = x.linearCombination hb.toSubfield fun o ↦ ∗(val b ^ o) := by | ||
| induction x using induction_on_max with | ||
| | zero => simp | ||
| | single_add o x f hf hx IH => | ||
| rw [ofFinsupp, mapRange_single_add (by contrapose! hf; use o), | ||
| CNF.eval_single_add', (hb.opow o).mul_add_eq_of_lt', hb.opow_mul_eq_of_lt] | ||
| · dsimp [linearCombination, lsum, Subfield.smul_def] at IH ⊢ | ||
| rw [sum_add_index' (by simp) (by simp [add_mul]), ← IH, sum_single_index (by simp), mul_comm] | ||
| rfl | ||
| · simp | ||
| · apply CNF.eval_lt | ||
| · simp | ||
| · simpa using hf | ||
| · simpa using hf | ||
|
|
||
| @[simp] | ||
| theorem ofFinsupp_single (x y) : ofFinsupp b hb (single x y) = y * ∗(b.val ^ x) := by | ||
| simp [ofFinsupp_def, Subfield.smul_def] | ||
|
|
||
| @[simp] | ||
| theorem toFinsupp_opow_mul (o : Ordinal) {x : Nimber} (hx : x < b) : | ||
| toFinsupp b hb (x * ∗(b.val ^ o)) = single o ⟨x, hx⟩ := by | ||
| simp [← ofFinsupp_inj] | ||
|
|
||
| @[simp] | ||
| theorem toFinsupp_opow (o : Ordinal) : toFinsupp b hb (∗(b.val ^ o)) = single o 1 := by | ||
| simpa using toFinsupp_opow_mul b hb o hb.one_lt | ||
|
|
||
| @[simp] | ||
| theorem toFinsupp_one : toFinsupp b hb 1 = single 0 1 := by | ||
| simpa using toFinsupp_opow b hb 0 | ||
|
|
||
| /-- `toFinsupp` as a `LinearEquiv`. -/ | ||
| @[expose, simps!] | ||
| def toFinsuppIso : Nimber ≃ₗ[hb.toSubfield] (Ordinal →₀ hb.toSubfield) := | ||
| .symm { | ||
| toFun := ofFinsupp b hb | ||
| invFun := toFinsupp b hb | ||
| left_inv := toFinsupp_ofFinsupp b hb | ||
| right_inv := ofFinsupp_toFinsupp b hb | ||
| map_add' x y := by | ||
| simp_rw [ofFinsupp_def] | ||
| apply sum_add_index' | ||
| · simp | ||
| · simp [add_mul, Subfield.smul_def] | ||
| map_smul' := by simp [ofFinsupp_def] | ||
| } | ||
|
|
||
| @[simp] | ||
| theorem toFinsupp_add (x y) : toFinsupp b hb (x + y) = toFinsupp b hb x + toFinsupp b hb y := | ||
| (toFinsuppIso b hb).map_add x y | ||
|
|
||
| @[simp] | ||
| theorem ofFinsupp_add (x y) : ofFinsupp b hb (x + y) = ofFinsupp b hb x + ofFinsupp b hb y := | ||
| (toFinsuppIso b hb).symm.map_add x y | ||
|
|
||
| /-- Ordinal powers of `b` form a basis for `Nimber`. -/ | ||
|
vihdzp marked this conversation as resolved.
|
||
| @[expose, simps!] | ||
| def IsField.opow_basis : Module.Basis Ordinal.{u} hb.toSubfield Nimber where | ||
| repr := toFinsuppIso b hb | ||
|
|
||
| end Nimber | ||
| end | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to only expose the bundled
LinearEquiv? I can't think of a scenario in which having aLinearEquivinstead of a plain function would be bad.