Skip to content
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

feat: more PGame.identical PGame.memₗ PGame.memᵣ APIs #5901

Open
wants to merge 58 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
3cc4bd5
feat: add lemmas about `Relator.LeftTotal` `Relator.RightTotal` `Rela…
FR-vdash-bot Jul 14, 2023
088ac08
feat: define `pgame.identical` `pgame.memₗ` `pgame.memᵣ`
FR-vdash-bot Jul 14, 2023
e6c9820
Merge branch 'master' into FR_game_identical
FR-vdash-bot Jul 31, 2023
e9e6636
Merge branch 'master' into FR_game_identical
FR-vdash-bot Sep 10, 2023
3dba08d
diffs
FR-vdash-bot Sep 10, 2023
a6bec11
inherit_doc
FR-vdash-bot Sep 14, 2023
1bc0b50
missing lemma
FR-vdash-bot Sep 14, 2023
c66a20e
fix
FR-vdash-bot Sep 14, 2023
1fa2e1f
simp
FR-vdash-bot Sep 14, 2023
c1d9143
missing lemmas
FR-vdash-bot Sep 14, 2023
35c10e7
lemmas
FR-vdash-bot Sep 16, 2023
69b7f4a
golf
FR-vdash-bot Sep 16, 2023
32fb3f1
Merge branch 'master' into FR_game_identical
FR-vdash-bot Sep 17, 2023
af2a948
golf
FR-vdash-bot Sep 18, 2023
70f52f5
golf
FR-vdash-bot Sep 18, 2023
d9c0632
golf
FR-vdash-bot Sep 18, 2023
5734b28
golf
FR-vdash-bot Sep 18, 2023
2815373
fix name
FR-vdash-bot Sep 18, 2023
b1201aa
reduce diffs
FR-vdash-bot Sep 18, 2023
52d35c2
reduce diffs
FR-vdash-bot Sep 18, 2023
c3e983f
reorder
FR-vdash-bot Sep 19, 2023
a3c5bb1
fix
FR-vdash-bot Sep 19, 2023
7a45fcb
missing `#align`
FR-vdash-bot Sep 19, 2023
cd4b649
Merge branch 'master' into FR_game_identical
FR-vdash-bot Jan 24, 2024
f3a25a3
Merge branch 'master' into FR_game_identical
FR-vdash-bot Jun 3, 2024
646abcf
Merge branch 'master' into FR_game_identical
FR-vdash-bot Jul 14, 2024
d93c384
Merge branch 'master' into FR_game_identical
FR-vdash-bot Jul 14, 2024
1fb6bfa
fix
FR-vdash-bot Jul 14, 2024
9cfe585
Update style-exceptions.txt
FR-vdash-bot Jul 14, 2024
4214c48
fix
FR-vdash-bot Jul 14, 2024
f2787cd
more
FR-vdash-bot Jul 15, 2024
2c6625d
Merge branch 'master' into FR_game_identical
hwatheod Jul 20, 2024
3b64d0c
Merge branch 'master' into FR_game_identical
hwatheod Jul 20, 2024
1c82554
refine' -> refine
hwatheod Jul 20, 2024
51997dc
Merge branch 'master' into FR_game_identical
FR-vdash-bot Jul 24, 2024
02857f7
Update PGame.lean
FR-vdash-bot Jul 24, 2024
9faebf8
Update PGame.lean
FR-vdash-bot Jul 24, 2024
4890303
remove `Equiv.ext''`
FR-vdash-bot Jul 24, 2024
ea5291f
docs, golf
FR-vdash-bot Jul 24, 2024
fc1fb21
docs
FR-vdash-bot Jul 24, 2024
34f0137
docs
FR-vdash-bot Jul 27, 2024
f39a50b
Update Basic.lean
FR-vdash-bot Jul 28, 2024
db63470
Merge branch 'master' into FR_game_identical
FR-vdash-bot Aug 3, 2024
e34173e
Merge branch 'master' into FR_game_identical
vihdzp Aug 14, 2024
b1c0c26
Merge branch 'master' into FR_game_identical
FR-vdash-bot Aug 27, 2024
9707644
suggestions
FR-vdash-bot Aug 27, 2024
dc6c71a
more
FR-vdash-bot Aug 27, 2024
18cfc87
more
FR-vdash-bot Aug 27, 2024
5189561
fix
FR-vdash-bot Aug 27, 2024
b3f6aa3
Update PGame.lean
FR-vdash-bot Aug 27, 2024
a47f30e
Update Impartial.lean
FR-vdash-bot Aug 27, 2024
bf0d644
more reduce diffs
FR-vdash-bot Aug 27, 2024
4ff819f
more
FR-vdash-bot Aug 27, 2024
fa76689
Merge branch 'master' into FR_game_identical
FR-vdash-bot Sep 25, 2024
4659495
reduce diffs
FR-vdash-bot Sep 25, 2024
784a1e7
Update PGame.lean
FR-vdash-bot Sep 25, 2024
58c1635
suggestion
FR-vdash-bot Sep 25, 2024
317d91f
lint
FR-vdash-bot Sep 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 127 additions & 11 deletions Mathlib/SetTheory/Game/Basic.lean
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/-
Copyright (c) 2019 Mario Carneiro. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Reid Barton, Mario Carneiro, Isabel Longbottom, Scott Morrison, Apurva Nakade
Authors: Reid Barton, Mario Carneiro, Isabel Longbottom, Scott Morrison, Apurva Nakade, Yuyang Zhao
-/
import Mathlib.SetTheory.Game.PGame
import Mathlib.Tactic.Abel
Expand All @@ -28,8 +28,6 @@ namespace SetTheory

open Function PGame

open PGame

universe u

-- Porting note: moved the setoid instance to PGame.lean
Expand Down Expand Up @@ -222,8 +220,8 @@ theorem quot_sub (a b : PGame) : ⟦a - b⟧ = (⟦a⟧ : Game) - ⟦b⟧ :=
theorem quot_eq_of_mk'_quot_eq {x y : PGame} (L : x.LeftMoves ≃ y.LeftMoves)
(R : x.RightMoves ≃ y.RightMoves) (hl : ∀ i, (⟦x.moveLeft i⟧ : Game) = ⟦y.moveLeft (L i)⟧)
(hr : ∀ j, (⟦x.moveRight j⟧ : Game) = ⟦y.moveRight (R j)⟧) : (⟦x⟧ : Game) = ⟦y⟧ := by
exact Quot.sound (equiv_of_mk_equiv L R (fun _ => Game.PGame.equiv_iff_game_eq.2 (hl _))
(fun _ => Game.PGame.equiv_iff_game_eq.2 (hr _)))
exact Quot.sound (.of_equiv L R (fun _ => Game.PGame.equiv_iff_game_eq.2 (hl _))
(fun _ => Game.PGame.equiv_iff_game_eq.2 (hr _)))
#align pgame.quot_eq_of_mk_quot_eq SetTheory.PGame.quot_eq_of_mk'_quot_eq

/-! Multiplicative operations can be defined at the level of pre-games,
Expand All @@ -232,7 +230,7 @@ Hence we define them here. -/


/-- The product of `x = {xL | xR}` and `y = {yL | yR}` is
`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, x*yL + xR*y - xR*yL }`. -/
`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, xR*y + x*yL - xR*yL}`. -/
instance : Mul PGame.{u} :=
⟨fun x y => by
induction' x with xl xr _ _ IHxl IHxr generalizing y
Expand Down Expand Up @@ -338,28 +336,28 @@ theorem mul_moveRight_inr {x y : PGame} {i j} :
rfl
#align pgame.mul_move_right_inr SetTheory.PGame.mul_moveRight_inr

-- @[simp] -- Porting note: simpNF linter complains
@[nolint simpNF, simp] -- Porting note: simpNF linter complains, but this is a useful dsimp lemma
FR-vdash-bot marked this conversation as resolved.
Show resolved Hide resolved
theorem neg_mk_mul_moveLeft_inl {xl xr yl yr} {xL xR yL yR} {i j} :
(-(mk xl xr xL xR * mk yl yr yL yR)).moveLeft (Sum.inl (i, j)) =
-(xL i * mk yl yr yL yR + mk xl xr xL xR * yR j - xL i * yR j) :=
rfl
#align pgame.neg_mk_mul_move_left_inl SetTheory.PGame.neg_mk_mul_moveLeft_inl

-- @[simp] -- Porting note: simpNF linter complains
@[nolint simpNF, simp] -- Porting note: simpNF linter complains, but this is a useful dsimp lemma
theorem neg_mk_mul_moveLeft_inr {xl xr yl yr} {xL xR yL yR} {i j} :
(-(mk xl xr xL xR * mk yl yr yL yR)).moveLeft (Sum.inr (i, j)) =
-(xR i * mk yl yr yL yR + mk xl xr xL xR * yL j - xR i * yL j) :=
rfl
#align pgame.neg_mk_mul_move_left_inr SetTheory.PGame.neg_mk_mul_moveLeft_inr

-- @[simp] -- Porting note: simpNF linter complains
@[nolint simpNF, simp] -- Porting note: simpNF linter complains, but this is a useful dsimp lemma
theorem neg_mk_mul_moveRight_inl {xl xr yl yr} {xL xR yL yR} {i j} :
(-(mk xl xr xL xR * mk yl yr yL yR)).moveRight (Sum.inl (i, j)) =
-(xL i * mk yl yr yL yR + mk xl xr xL xR * yL j - xL i * yL j) :=
rfl
#align pgame.neg_mk_mul_move_right_inl SetTheory.PGame.neg_mk_mul_moveRight_inl

-- @[simp] -- Porting note: simpNF linter complains
@[nolint simpNF, simp] -- Porting note: simpNF linter complains, but this is a useful dsimp lemma
theorem neg_mk_mul_moveRight_inr {xl xr yl yr} {xL xR yL yR} {i j} :
(-(mk xl xr xL xR * mk yl yr yL yR)).moveRight (Sum.inr (i, j)) =
-(xR i * mk yl yr yL yR + mk xl xr xL xR * yR j - xR i * yR j) :=
Expand All @@ -384,6 +382,51 @@ theorem rightMoves_mul_cases {x y : PGame} (k) {P : (x * y).RightMoves → Prop}
· apply hr
#align pgame.right_moves_mul_cases SetTheory.PGame.rightMoves_mul_cases

lemma LeftMovesMul.exists {x y : PGame} {p : (x * y).LeftMoves → Prop} :
FR-vdash-bot marked this conversation as resolved.
Show resolved Hide resolved
(∃ i, p i) ↔
(∃ i j, p (toLeftMovesMul (.inl (i, j)))) ∨ (∃ i j, p (toLeftMovesMul (.inr (i, j)))) := by
cases' x with xl xr xL xR
cases' y with yl yr yL yR
constructor
· rintro ⟨(⟨i, j⟩ | ⟨i, j⟩), hi⟩
exacts [.inl ⟨i, j, hi⟩, .inr ⟨i, j, hi⟩]
· rintro (⟨i, j, h⟩ | ⟨i, j, h⟩)
exacts [⟨_, h⟩, ⟨_, h⟩]

lemma RightMovesMul.exists {x y : PGame} {p : (x * y).RightMoves → Prop} :
(∃ i, p i) ↔
(∃ i j, p (toRightMovesMul (.inl (i, j)))) ∨ (∃ i j, p (toRightMovesMul (.inr (i, j)))) := by
cases' x with xl xr xL xR
cases' y with yl yr yL yR
constructor
· rintro ⟨(⟨i, j⟩ | ⟨i, j⟩), hi⟩
exacts [.inl ⟨i, j, hi⟩, .inr ⟨i, j, hi⟩]
· rintro (⟨i, j, h⟩ | ⟨i, j, h⟩)
exacts [⟨_, h⟩, ⟨_, h⟩]

lemma memₗ_mul_iff : ∀ {x y₁ y₂ : PGame},
FR-vdash-bot marked this conversation as resolved.
Show resolved Hide resolved
x ∈ₗ y₁ * y₂ ↔
(∃ i j, x ≡ y₁.moveLeft i * y₂ + y₁ * y₂.moveLeft j - y₁.moveLeft i * y₂.moveLeft j) ∨
(∃ i j, x ≡ y₁.moveRight i * y₂ + y₁ * y₂.moveRight j - y₁.moveRight i * y₂.moveRight j)
| mk _ _ _ _, mk _ _ _ _, mk _ _ _ _ => LeftMovesMul.exists

lemma memᵣ_mul_iff : ∀ {x y₁ y₂ : PGame},
x ∈ᵣ y₁ * y₂ ↔
(∃ i j, x ≡ y₁.moveLeft i * y₂ + y₁ * y₂.moveRight j - y₁.moveLeft i * y₂.moveRight j) ∨
(∃ i j, x ≡ y₁.moveRight i * y₂ + y₁ * y₂.moveLeft j - y₁.moveRight i * y₂.moveLeft j)
| mk _ _ _ _, mk _ _ _ _, mk _ _ _ _ => RightMovesMul.exists

/-- `x * y` and `y * x` have the same moves. -/
protected lemma mul_comm (x y : PGame) : x * y ≡ y * x :=
match x, y with
| ⟨xl, xr, xL, xR⟩, ⟨yl, yr, yL, yR⟩ => by
refine Identical.of_equiv ((Equiv.prodComm _ _).sumCongr (Equiv.prodComm _ _))
((Equiv.sumComm _ _).trans ((Equiv.prodComm _ _).sumCongr (Equiv.prodComm _ _))) ?_ ?_ <;>
· rintro (⟨_, _⟩ | ⟨_, _⟩) <;>
exact ((((PGame.mul_comm _ (mk _ _ _ _)).add (PGame.mul_comm (mk _ _ _ _) _)).trans
(PGame.add_comm _ _)).sub (PGame.mul_comm _ _))
termination_by _ => (x, y)

/-- `x * y` and `y * x` have the same moves. -/
def mulCommRelabelling (x y : PGame.{u}) : x * y ≡r y * x :=
match x, y with
Expand Down Expand Up @@ -429,6 +472,9 @@ instance isEmpty_zero_mul_rightMoves (x : PGame.{u}) : IsEmpty (0 * x).RightMove
apply instIsEmptySum
#align pgame.is_empty_zero_mul_right_moves SetTheory.PGame.isEmpty_zero_mul_rightMoves

/-- `x * 0` has exactly the same moves as `0`. -/
protected lemma mul_zero (x : PGame) : x * 0 ≡ 0 := identical_zero _

/-- `x * 0` has exactly the same moves as `0`. -/
def mulZeroRelabelling (x : PGame) : x * 0 ≡r 0 :=
Relabelling.isEmpty _
Expand All @@ -444,6 +490,9 @@ theorem quot_mul_zero (x : PGame) : (⟦x * 0⟧ : Game) = ⟦0⟧ :=
@Quotient.sound _ _ (x * 0) _ x.mul_zero_equiv
#align pgame.quot_mul_zero SetTheory.PGame.quot_mul_zero

/-- `0 * x` has exactly the same moves as `0`. -/
protected lemma zero_mul (x : PGame) : 0 * x ≡ 0 := identical_zero _

/-- `0 * x` has exactly the same moves as `0`. -/
def zeroMulRelabelling (x : PGame) : 0 * x ≡r 0 :=
Relabelling.isEmpty _
Expand Down Expand Up @@ -480,6 +529,39 @@ def negMulRelabelling (x y : PGame.{u}) : -x * y ≡r -(x * y) :=
decreasing_by pgame_wf_tac
#align pgame.neg_mul_relabelling SetTheory.PGame.negMulRelabelling

/-- `x * -y` and `-(x * y)` have the same moves. -/
lemma mul_neg (x y : PGame) : x * -y = -(x * y) :=
FR-vdash-bot marked this conversation as resolved.
Show resolved Hide resolved
match x, y with
| mk xl xr xL xR, mk yl yr yL yR => by
refine ext rfl rfl ?_ ?_
· rintro (⟨i, j⟩ | ⟨i, j⟩) _ ⟨rfl⟩
· refine (@mul_moveLeft_inl (mk xl xr xL xR) (-mk yl yr yL yR) i j).trans ?_
dsimp [toLeftMovesNeg]
rw [PGame.neg_sub', PGame.neg_add]
congr
exacts [mul_neg _ (mk _ _ _ _), mul_neg _ _, mul_neg _ _]
· refine (@mul_moveLeft_inr (mk xl xr xL xR) (-mk yl yr yL yR) i j).trans ?_
dsimp [toLeftMovesNeg]
rw [PGame.neg_sub', PGame.neg_add]
congr
exacts [mul_neg _ (mk _ _ _ _), mul_neg _ _, mul_neg _ _]
· rintro (⟨i, j⟩ | ⟨i, j⟩) _ ⟨rfl⟩
· refine (@mul_moveRight_inl (mk xl xr xL xR) (-mk yl yr yL yR) i j).trans ?_
dsimp [toLeftMovesNeg]
rw [PGame.neg_sub', PGame.neg_add]
congr
exacts [mul_neg _ (mk _ _ _ _), mul_neg _ _, mul_neg _ _]
· refine (@mul_moveRight_inr (mk xl xr xL xR) (-mk yl yr yL yR) i j).trans ?_
dsimp [toLeftMovesNeg]
rw [PGame.neg_sub', PGame.neg_add]
congr
exacts [mul_neg _ (mk _ _ _ _), mul_neg _ _, mul_neg _ _]
termination_by _ => (x, y)

/-- `-x * y` and `-(x * y)` have the same moves. -/
lemma neg_mul (x y : PGame) : -x * y ≡ -(x * y) :=
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have the equality in this case too?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. (-x * y).LeftMoves = xr × yl ⊕ xl × yr, (-(x * y)).LeftMoves = xl × yr ⊕ xr × yl

((PGame.mul_comm _ _).trans (of_eq (mul_neg _ _))).trans (PGame.mul_comm _ _).neg

@[simp]
theorem quot_neg_mul (x y : PGame) : (⟦-x * y⟧ : Game) = -⟦x * y⟧ :=
Quot.sound (negMulRelabelling x y).equiv
Expand Down Expand Up @@ -637,11 +719,23 @@ def mulOneRelabelling : ∀ x : PGame.{u}, x * 1 ≡r x
{ (try intro i)
dsimp
apply (Relabelling.subCongr (Relabelling.refl _) (mulZeroRelabelling _)).trans
rw [sub_zero]
rw [sub_zero_eq_add_zero]
exact (addZeroRelabelling _).trans <|
(((mulOneRelabelling _).addCongr (mulZeroRelabelling _)).trans <| addZeroRelabelling _) }
#align pgame.mul_one_relabelling SetTheory.PGame.mulOneRelabelling

/-- `1 * x` has the same moves as `x`. -/
protected lemma one_mul : ∀ (x : PGame), 1 * x ≡ x
| ⟨xl, xr, xL, xR⟩ => by
refine Identical.of_equiv ((Equiv.sumEmpty _ _).trans (Equiv.punitProd _))
((Equiv.sumEmpty _ _).trans (Equiv.punitProd _)) ?_ ?_ <;>
· rintro (⟨⟨⟩, _⟩ | ⟨⟨⟩, _⟩)
exact ((((PGame.zero_mul (mk _ _ _ _)).add (PGame.one_mul _)).trans (PGame.zero_add _)).sub
(PGame.zero_mul _)).trans (PGame.sub_zero _)

/-- `x * 1` has the same moves as `x`. -/
lemma mul_one (x : PGame) : x * 1 ≡ x := (x.mul_comm _).trans x.one_mul

@[simp]
theorem quot_mul_one (x : PGame) : (⟦x * 1⟧ : Game) = ⟦x⟧ :=
Quot.sound <| PGame.Relabelling.equiv <| mulOneRelabelling x
Expand Down Expand Up @@ -890,6 +984,13 @@ theorem zero_lf_inv' : ∀ x : PGame, 0 ⧏ inv' x
rfl
#align pgame.zero_lf_inv' SetTheory.PGame.zero_lf_inv'

/-- `inv' 0` has exactly the same moves as `1`. -/
lemma inv'_zero : inv' 0 ≡ (1 : PGame) := by
FR-vdash-bot marked this conversation as resolved.
Show resolved Hide resolved
refine ⟨?_, ?_⟩ <;> dsimp [Relator.BiTotal, Relator.LeftTotal, Relator.RightTotal]
· simp_rw [Unique.forall_iff, Unique.exists_iff, and_self, PGame.invVal_isEmpty]
exact identical_zero _
· simp_rw [IsEmpty.forall_iff]

/-- `inv' 0` has exactly the same moves as `1`. -/
def inv'Zero : inv' 0 ≡r 1 := by
change mk _ _ _ _ ≡r 1
Expand All @@ -906,6 +1007,16 @@ theorem inv'_zero_equiv : inv' 0 ≈ 1 :=
inv'Zero.equiv
#align pgame.inv'_zero_equiv SetTheory.PGame.inv'_zero_equiv

/-- `inv' 1` has exactly the same moves as `1`. -/
lemma inv'_one : inv'.{u} 1 ≡ 1 := by
have : IsEmpty {_i : PUnit.{u+1} // (0 : PGame.{u}) < 0} := by
rw [lt_self_iff_false]
infer_instance
refine ⟨?_, ?_⟩ <;> dsimp [Relator.BiTotal, Relator.LeftTotal, Relator.RightTotal]
· simp_rw [Unique.forall_iff, Unique.exists_iff, PGame.invVal_isEmpty, and_self]
exact identical_zero _
· simp_rw [IsEmpty.forall_iff]

/-- `inv' 1` has exactly the same moves as `1`. -/
def inv'One : inv' 1 ≡r (1 : PGame.{u}) := by
change Relabelling (mk _ _ _ _) 1
Expand Down Expand Up @@ -947,6 +1058,11 @@ theorem inv_eq_of_lf_zero {x : PGame} (h : x ⧏ 0) : x⁻¹ = -inv' (-x) := by
classical exact (if_neg h.not_equiv).trans (if_neg h.not_gt)
#align pgame.inv_eq_of_lf_zero SetTheory.PGame.inv_eq_of_lf_zero

/-- `1⁻¹` has exactly the same moves as `1`. -/
lemma inv_one : 1⁻¹ ≡ 1 := by
rw [inv_eq_of_pos PGame.zero_lt_one]
exact inv'_one

/-- `1⁻¹` has exactly the same moves as `1`. -/
def invOne : 1⁻¹ ≡r 1 := by
rw [inv_eq_of_pos PGame.zero_lt_one]
Expand Down
Loading