@@ -10,7 +10,7 @@ import tactic.equiv_rw
10
10
universe u
11
11
12
12
/-!
13
- # Basic deinitions about impartial (pre-)games
13
+ # Basic definitions about impartial (pre-)games
14
14
15
15
We will define an impartial game, one in which left and right can make exactly the same moves.
16
16
Our definition differs slightly by saying that the game is always equivalent to its negative,
@@ -22,12 +22,10 @@ namespace pgame
22
22
23
23
local infix ` ≈ ` := equiv
24
24
25
- /-- The definiton for a impartial game, defined using Conway induction -/
26
- def impartial : pgame → Prop
25
+ /-- The definition for a impartial game, defined using Conway induction -/
26
+ @[class] def impartial : pgame → Prop
27
27
| G := G ≈ -G ∧ (∀ i, impartial (G.move_left i)) ∧ (∀ j, impartial (G.move_right j))
28
- using_well_founded {dec_tac := pgame_wf_tac}
29
-
30
- lemma zero_impartial : impartial 0 := by tidy
28
+ using_well_founded { dec_tac := pgame_wf_tac }
31
29
32
30
lemma impartial_def {G : pgame} :
33
31
G.impartial ↔ G ≈ -G ∧ (∀ i, impartial (G.move_left i)) ∧ (∀ j, impartial (G.move_right j)) :=
@@ -41,204 +39,166 @@ begin
41
39
exact hi }
42
40
end
43
41
44
- lemma impartial_neg_equiv_self {G : pgame} (h : G.impartial) : G ≈ -G := (impartial_def.1 h).1
42
+ namespace impartial
43
+
44
+ instance impartial_zero : impartial 0 := by tidy
45
+
46
+ lemma neg_equiv_self (G : pgame) [h : G.impartial] : G ≈ -G := (impartial_def.1 h).1
45
47
46
- lemma impartial_move_left_impartial {G : pgame} ( h : G.impartial) (i : G.left_moves) :
47
- impartial (G.move_left i) :=
48
+ instance move_left_impartial {G : pgame} [ h : G.impartial] (i : G.left_moves) :
49
+ (G.move_left i).impartial :=
48
50
(impartial_def.1 h).2 .1 i
49
51
50
- lemma impartial_move_right_impartial {G : pgame} ( h : G.impartial) (j : G.right_moves) :
51
- impartial (G.move_right j) :=
52
+ instance move_right_impartial {G : pgame} [ h : G.impartial] (j : G.right_moves) :
53
+ (G.move_right j).impartial :=
52
54
(impartial_def.1 h).2 .2 j
53
55
54
- lemma impartial_add : ∀ { G H : pgame}, G.impartial → H.impartial → (G + H).impartial
56
+ instance impartial_add : ∀ ( G H : pgame) [ G.impartial] [ H.impartial], (G + H).impartial
55
57
| G H :=
56
58
begin
57
- intros hG hH,
59
+ introsI hG hH,
58
60
rw impartial_def,
59
61
split,
60
62
{ apply equiv_trans _ (equiv_of_relabelling (neg_add_relabelling G H)).symm,
61
- apply add_congr,
62
- exact impartial_neg_equiv_self hG,
63
- exact impartial_neg_equiv_self hH },
63
+ exact add_congr (neg_equiv_self _) (neg_equiv_self _) },
64
64
split,
65
+ all_goals
65
66
{ intro i,
66
- equiv_rw pgame.left_moves_add G H at i,
67
- cases i with iG iH,
68
- { rw add_move_left_inl,
69
- exact impartial_add (impartial_move_left_impartial hG _) hH },
70
- { rw add_move_left_inr,
71
- exact impartial_add hG (impartial_move_left_impartial hH _) } },
72
- { intro j,
73
- equiv_rw pgame.right_moves_add G H at j,
74
- cases j with jG jH,
75
- { rw add_move_right_inl,
76
- exact impartial_add (impartial_move_right_impartial hG _) hH },
77
- { rw add_move_right_inr,
78
- exact impartial_add hG (impartial_move_right_impartial hH _) } }
67
+ equiv_rw pgame.left_moves_add G H at i <|> equiv_rw pgame.right_moves_add G H at i,
68
+ cases i },
69
+ all_goals
70
+ { simp only [add_move_left_inl, add_move_right_inl, add_move_left_inr, add_move_right_inr],
71
+ exact impartial_add _ _ }
79
72
end
80
- using_well_founded {dec_tac := pgame_wf_tac}
73
+ using_well_founded { dec_tac := pgame_wf_tac }
81
74
82
- lemma impartial_neg : ∀ { G : pgame}, G.impartial → (-G).impartial
75
+ instance impartial_neg : ∀ ( G : pgame) [ G.impartial], (-G).impartial
83
76
| G :=
84
77
begin
85
- intro hG,
78
+ introI hG,
86
79
rw impartial_def,
87
80
split,
88
81
{ rw neg_neg,
89
82
symmetry,
90
- exact impartial_neg_equiv_self hG },
83
+ exact neg_equiv_self G },
91
84
split,
85
+ all_goals
92
86
{ intro i,
93
- equiv_rw G.left_moves_neg at i,
94
- rw move_left_left_moves_neg_symm,
95
- exact impartial_neg (impartial_move_right_impartial hG _) },
96
- { intro j,
97
- equiv_rw G.right_moves_neg at j,
98
- rw move_right_right_moves_neg_symm,
99
- exact impartial_neg (impartial_move_left_impartial hG _) }
87
+ equiv_rw G.left_moves_neg at i <|> equiv_rw G.right_moves_neg at i,
88
+ simp only [move_left_left_moves_neg_symm, move_right_right_moves_neg_symm],
89
+ exact impartial_neg _ }
100
90
end
101
- using_well_founded {dec_tac := pgame_wf_tac}
91
+ using_well_founded { dec_tac := pgame_wf_tac }
102
92
103
- lemma impartial_winner_cases { G : pgame} (hG : G.impartial) : G.first_loses ∨ G.first_wins :=
93
+ lemma winner_cases ( G : pgame) [ G.impartial] : G.first_loses ∨ G.first_wins :=
104
94
begin
105
95
rcases G.winner_cases with hl | hr | hp | hn,
106
96
{ cases hl with hpos hnonneg,
107
97
rw ←not_lt at hnonneg,
108
- have hneg := lt_of_lt_of_equiv hpos (impartial_neg_equiv_self hG ),
98
+ have hneg := lt_of_lt_of_equiv hpos (neg_equiv_self G ),
109
99
rw [lt_iff_neg_gt, neg_neg, neg_zero] at hneg,
110
100
contradiction },
111
101
{ cases hr with hnonpos hneg,
112
102
rw ←not_lt at hnonpos,
113
- have hpos := lt_of_equiv_of_lt (impartial_neg_equiv_self hG ).symm hneg,
103
+ have hpos := lt_of_equiv_of_lt (neg_equiv_self G ).symm hneg,
114
104
rw [lt_iff_neg_gt, neg_neg, neg_zero] at hpos,
115
105
contradiction },
116
106
{ left, assumption },
117
107
{ right, assumption }
118
108
end
119
109
120
- lemma impartial_not_first_wins { G : pgame} (hG : G.impartial) : ¬G.first_wins ↔ G.first_loses :=
121
- by cases impartial_winner_cases hG ; finish using [not_first_loses_of_first_wins]
110
+ lemma not_first_wins ( G : pgame) [ G.impartial] : ¬G.first_wins ↔ G.first_loses :=
111
+ by cases winner_cases G ; finish using [not_first_loses_of_first_wins]
122
112
123
- lemma impartial_not_first_loses { G : pgame} (hG : G.impartial) : ¬G.first_loses ↔ G.first_wins :=
124
- iff.symm $ iff_not_comm.1 $ iff.symm $ impartial_not_first_wins hG
113
+ lemma not_first_loses ( G : pgame) [ G.impartial] : ¬G.first_loses ↔ G.first_wins :=
114
+ iff.symm $ iff_not_comm.1 $ iff.symm $ not_first_wins G
125
115
126
- lemma impartial_add_self { G : pgame} (hG : G.impartial) : (G + G).first_loses :=
127
- first_loses_is_zero.2 $ equiv_trans (add_congr (impartial_neg_equiv_self hG ) G.equiv_refl)
116
+ lemma add_self ( G : pgame) [ G.impartial] : (G + G).first_loses :=
117
+ first_loses_is_zero.2 $ equiv_trans (add_congr (neg_equiv_self G ) G.equiv_refl)
128
118
add_left_neg_equiv
129
119
130
- lemma equiv_iff_sum_first_loses { G H : pgame} (hG : G.impartial) (hH : H.impartial) :
120
+ lemma equiv_iff_sum_first_loses ( G H : pgame) [ G.impartial] [ H.impartial] :
131
121
G ≈ H ↔ (G + H).first_loses :=
132
122
begin
133
123
split,
134
124
{ intro heq,
135
- exact first_loses_of_equiv (add_congr (equiv_refl _) heq) (impartial_add_self hG ) },
125
+ exact first_loses_of_equiv (add_congr (equiv_refl _) heq) (add_self G ) },
136
126
{ intro hGHp,
137
127
split,
138
128
{ rw le_iff_sub_nonneg,
139
129
exact le_trans hGHp.2
140
130
(le_trans add_comm_le $ le_of_le_of_equiv (le_refl _) $ add_congr (equiv_refl _)
141
- (impartial_neg_equiv_self hG )) },
131
+ (neg_equiv_self G )) },
142
132
{ rw le_iff_sub_nonneg,
143
133
exact le_trans hGHp.2
144
- (le_of_le_of_equiv (le_refl _) $ add_congr (equiv_refl _) (impartial_neg_equiv_self hH )) } }
134
+ (le_of_le_of_equiv (le_refl _) $ add_congr (equiv_refl _) (neg_equiv_self H )) } }
145
135
end
146
136
147
- lemma impartial_first_loses_symm {G : pgame} (hG : G.impartial) : G.first_loses ↔ G ≤ 0 :=
148
- begin
149
- use and.left,
150
- { intro hneg,
151
- use hneg,
152
- exact zero_le_iff_neg_le_zero.2 (le_of_equiv_of_le (impartial_neg_equiv_self hG).symm hneg) }
153
- end
137
+ lemma le_zero_iff {G : pgame} [G.impartial] : G ≤ 0 ↔ 0 ≤ G :=
138
+ by rw [le_zero_iff_zero_le_neg, le_congr (equiv_refl 0 ) (neg_equiv_self G)]
154
139
155
- lemma impartial_first_wins_symm {G : pgame} (hG : G.impartial) : G.first_wins ↔ G < 0 :=
156
- begin
157
- use and.right,
158
- { intro hneg,
159
- split,
160
- rw lt_iff_neg_gt,
161
- rw neg_zero,
162
- exact lt_of_equiv_of_lt (impartial_neg_equiv_self hG).symm hneg,
163
- exact hneg }
164
- end
140
+ lemma lt_zero_iff {G : pgame} [G.impartial] : G < 0 ↔ 0 < G :=
141
+ by rw [lt_iff_neg_gt, neg_zero, lt_congr (equiv_refl 0 ) (neg_equiv_self G)]
165
142
166
- lemma impartial_first_loses_symm' {G : pgame} (hG : G.impartial) : G.first_loses ↔ 0 ≤ G :=
167
- begin
168
- use and.right,
169
- { intro hpos,
170
- use le_zero_iff_zero_le_neg.2 (le_of_le_of_equiv hpos $ impartial_neg_equiv_self hG),
171
- exact hpos }
172
- end
143
+ lemma first_loses_symm (G : pgame) [G.impartial] : G.first_loses ↔ G ≤ 0 :=
144
+ ⟨and.left, λ h, ⟨h, le_zero_iff.1 h⟩⟩
173
145
174
- lemma impartial_first_wins_symm' {G : pgame} (hG : G.impartial) : G.first_wins ↔ 0 < G :=
175
- begin
176
- use and.left,
177
- { intro hpos,
178
- use hpos,
179
- rw lt_iff_neg_gt,
180
- rw neg_zero,
181
- exact lt_of_lt_of_equiv hpos (impartial_neg_equiv_self hG) }
182
- end
146
+ lemma first_wins_symm (G : pgame) [G.impartial] : G.first_wins ↔ G < 0 :=
147
+ ⟨and.right, λ h, ⟨lt_zero_iff.1 h, h⟩⟩
148
+
149
+ lemma first_loses_symm' (G : pgame) [G.impartial] : G.first_loses ↔ 0 ≤ G :=
150
+ ⟨and.right, λ h, ⟨le_zero_iff.2 h, h⟩⟩
151
+
152
+ lemma first_wins_symm' (G : pgame) [G.impartial] : G.first_wins ↔ 0 < G :=
153
+ ⟨and.left, λ h, ⟨h, lt_zero_iff.2 h⟩⟩
183
154
184
- lemma no_good_left_moves_iff_first_loses { G : pgame} (hG : G.impartial) :
155
+ lemma no_good_left_moves_iff_first_loses ( G : pgame) [ G.impartial] :
185
156
(∀ (i : G.left_moves), (G.move_left i).first_wins) ↔ G.first_loses :=
186
157
begin
187
158
split,
188
159
{ intro hbad,
189
- rw [impartial_first_loses_symm hG , le_def_lt],
160
+ rw [first_loses_symm G , le_def_lt],
190
161
split,
191
162
{ intro i,
192
163
specialize hbad i,
193
164
exact hbad.2 },
194
165
{ intro j,
195
166
exact pempty.elim j } },
196
167
{ intros hp i,
197
- rw impartial_first_wins_symm (impartial_move_left_impartial hG _) ,
198
- exact (le_def_lt.1 $ (impartial_first_loses_symm hG ).1 hp).1 i }
168
+ rw first_wins_symm ,
169
+ exact (le_def_lt.1 $ (first_loses_symm G ).1 hp).1 i }
199
170
end
200
171
201
- lemma no_good_right_moves_iff_first_loses { G : pgame} (hG : G.impartial) :
172
+ lemma no_good_right_moves_iff_first_loses ( G : pgame) [ G.impartial] :
202
173
(∀ (j : G.right_moves), (G.move_right j).first_wins) ↔ G.first_loses :=
203
174
begin
204
- split,
205
- { intro hbad,
206
- rw [impartial_first_loses_symm' hG, le_def_lt],
207
- split,
208
- { intro i,
209
- exact pempty.elim i },
210
- { intro j,
211
- specialize hbad j,
212
- exact hbad.1 } },
213
- { intros hp j,
214
- rw impartial_first_wins_symm' (impartial_move_right_impartial hG _),
215
- exact ((le_def_lt.1 $ (impartial_first_loses_symm' hG).1 hp).2 j) }
175
+ rw [first_loses_of_equiv_iff (neg_equiv_self G), ←no_good_left_moves_iff_first_loses],
176
+ refine ⟨λ h i, _, λ h i, _⟩,
177
+ { simpa [first_wins_of_equiv_iff (neg_equiv_self ((-G).move_left i))]
178
+ using h (left_moves_neg _ i) },
179
+ { simpa [first_wins_of_equiv_iff (neg_equiv_self (G.move_right i))]
180
+ using h ((left_moves_neg _).symm i) }
216
181
end
217
182
218
- lemma good_left_move_iff_first_wins { G : pgame} (hG : G.impartial) :
183
+ lemma good_left_move_iff_first_wins ( G : pgame) [ G.impartial] :
219
184
(∃ (i : G.left_moves), (G.move_left i).first_loses) ↔ G.first_wins :=
220
185
begin
221
- split,
222
- { rintro ⟨ i, hi ⟩,
223
- exact (impartial_first_wins_symm' hG).2 (lt_def_le.2 $ or.inl ⟨ i, hi.2 ⟩) },
224
- { intro hn,
225
- rw [impartial_first_wins_symm' hG, lt_def_le] at hn,
226
- rcases hn with ⟨ i, hi ⟩ | ⟨ j, _ ⟩,
227
- { exact ⟨ i, (impartial_first_loses_symm' $ impartial_move_left_impartial hG _).2 hi ⟩ },
228
- { exact pempty.elim j } }
186
+ refine ⟨λ ⟨i, hi⟩, (first_wins_symm' G).2 (lt_def_le.2 $ or.inl ⟨i, hi.2 ⟩), λ hn, _⟩,
187
+ rw [first_wins_symm' G, lt_def_le] at hn,
188
+ rcases hn with ⟨i, hi⟩ | ⟨j, _⟩,
189
+ { exact ⟨i, (first_loses_symm' _).2 hi⟩ },
190
+ { exact pempty.elim j }
229
191
end
230
192
231
- lemma good_right_move_iff_first_wins { G : pgame} (hG : G.impartial) :
193
+ lemma good_right_move_iff_first_wins ( G : pgame) [ G.impartial] :
232
194
(∃ j : G.right_moves, (G.move_right j).first_loses) ↔ G.first_wins :=
233
195
begin
234
- split,
235
- { rintro ⟨ j, hj ⟩,
236
- exact (impartial_first_wins_symm hG).2 (lt_def_le.2 $ or.inr ⟨ j, hj.1 ⟩) },
237
- { intro hn,
238
- rw [impartial_first_wins_symm hG, lt_def_le] at hn,
239
- rcases hn with ⟨ i, _ ⟩ | ⟨ j, hj ⟩,
240
- { exact pempty.elim i },
241
- { exact ⟨ j, (impartial_first_loses_symm $ impartial_move_right_impartial hG _).2 hj ⟩ } }
196
+ refine ⟨λ ⟨j, hj⟩, (first_wins_symm G).2 (lt_def_le.2 $ or.inr ⟨j, hj.1 ⟩), λ hn, _⟩,
197
+ rw [first_wins_symm G, lt_def_le] at hn,
198
+ rcases hn with ⟨i, _⟩ | ⟨j, hj⟩,
199
+ { exact pempty.elim i },
200
+ { exact ⟨j, (first_loses_symm _).2 hj⟩ }
242
201
end
243
202
203
+ end impartial
244
204
end pgame
0 commit comments