@@ -96,28 +96,69 @@ begin
96
96
exact funext (λ i, IH _ (typein_lt_self i))
97
97
end
98
98
99
- instance nim_impartial : ∀ (O : ordinal), impartial (nim O)
100
- | O :=
99
+ lemma left_moves_nim (O : ordinal) : (nim O).left_moves = O.out.α :=
100
+ by { rw nim_def, refl }
101
+ lemma right_moves_nim (O : ordinal) : (nim O).right_moves = O.out.α :=
102
+ by { rw nim_def, refl }
103
+
104
+ lemma move_left_nim_heq (O : ordinal) : (nim O).move_left == λ i : O.out.α, nim (typein (<) i) :=
105
+ by { rw nim_def, refl }
106
+ lemma move_right_nim_heq (O : ordinal) : (nim O).move_right == λ i : O.out.α, nim (typein (<) i) :=
107
+ by { rw nim_def, refl }
108
+
109
+ /-- Turns an ordinal less than `O` into a left move for `nim O` and viceversa. -/
110
+ noncomputable def to_left_moves_nim {O : ordinal} : {O' // O' < O} ≃ (nim O).left_moves :=
111
+ (out_equiv_lt O).trans (equiv.cast (left_moves_nim O).symm)
112
+
113
+ /-- Turns an ordinal less than `O` into a right move for `nim O` and viceversa. -/
114
+ noncomputable def to_right_moves_nim {O : ordinal} : {O' // O' < O} ≃ (nim O).right_moves :=
115
+ (out_equiv_lt O).trans (equiv.cast (right_moves_nim O).symm)
116
+
117
+ @[simp] theorem to_left_moves_nim_symm_lt {O : ordinal} (i : (nim O).left_moves) :
118
+ ↑(to_left_moves_nim.symm i) < O :=
119
+ (to_left_moves_nim.symm i).prop
120
+
121
+ @[simp] theorem to_right_moves_nim_symm_lt {O : ordinal} (i : (nim O).right_moves) :
122
+ ↑(to_right_moves_nim.symm i) < O :=
123
+ (to_right_moves_nim.symm i).prop
124
+
125
+ @[simp] lemma move_left_nim' {O : ordinal.{u}} (i) :
126
+ (nim O).move_left i = nim (to_left_moves_nim.symm i).val :=
127
+ (congr_heq (move_left_nim_heq O).symm (cast_heq _ i)).symm
128
+
129
+ lemma move_left_nim {O : ordinal} (i) :
130
+ (nim O).move_left (to_left_moves_nim i) = nim i :=
131
+ by simp
132
+
133
+ @[simp] lemma move_right_nim' {O : ordinal} (i) :
134
+ (nim O).move_right i = nim (to_right_moves_nim.symm i).val :=
135
+ (congr_heq (move_right_nim_heq O).symm (cast_heq _ i)).symm
136
+
137
+ lemma move_right_nim {O : ordinal} (i) :
138
+ (nim O).move_right (to_right_moves_nim i) = nim i :=
139
+ by simp
140
+
141
+ @[simp] lemma neg_nim (O : ordinal) : -nim O = nim O :=
101
142
begin
102
- rw [impartial_def, nim_def, neg_def],
103
- split, split;
104
- rw pgame.le_def,
105
- all_goals { refine ⟨λ i, let hwf := ordinal.typein_lt_self i in _,
106
- λ j, let hwf := ordinal.typein_lt_self j in _⟩ },
107
- { exact or.inl ⟨i, (@impartial.neg_equiv_self _ $ nim_impartial $ typein (<) i).1 ⟩ },
108
- { exact or.inr ⟨j, (@impartial.neg_equiv_self _ $ nim_impartial $ typein (<) j).1 ⟩ },
109
- { exact or.inl ⟨i, (@impartial.neg_equiv_self _ $ nim_impartial $ typein (<) i).2 ⟩ },
110
- { exact or.inr ⟨j, (@impartial.neg_equiv_self _ $ nim_impartial $ typein (<) j).2 ⟩ },
111
- { exact nim_impartial (typein (<) i) },
112
- { exact nim_impartial (typein (<) j) }
143
+ induction O using ordinal.induction with O IH,
144
+ rw nim_def, dsimp; congr;
145
+ funext i;
146
+ exact IH _ (ordinal.typein_lt_self i)
147
+ end
148
+
149
+ instance nim_impartial (O : ordinal) : impartial (nim O) :=
150
+ begin
151
+ induction O using ordinal.induction with O IH,
152
+ rw [impartial_def, neg_nim],
153
+ refine ⟨equiv_refl _, λ i, _, λ i, _⟩;
154
+ simpa using IH _ (typein_lt_self _)
113
155
end
114
- using_well_founded { dec_tac := tactic.assumption }
115
156
116
- lemma exists_ordinal_move_left_eq ( O : ordinal) : ∀ i, ∃ O' < O, (nim O).move_left i = nim O' :=
117
- by { rw nim_def, exact λ i, ⟨_, ⟨ordinal. typein_lt_self i, rfl⟩⟩ }
157
+ lemma exists_ordinal_move_left_eq { O : ordinal} (i ) : ∃ O' < O, (nim O).move_left i = nim O' :=
158
+ ⟨_, typein_lt_self _, move_left_nim' i⟩
118
159
119
- lemma exists_move_left_eq {O : ordinal} : ∀ O' < O, ∃ i, (nim O).move_left i = nim O' :=
120
- by { rw nim_def, exact λ _ h, ⟨(ordinal.principal_seg_out h).top, by simp⟩ }
160
+ lemma exists_move_left_eq {O O' : ordinal} (h : O' < O) : ∃ i, (nim O).move_left i = nim O' :=
161
+ ⟨to_left_moves_nim ⟨O', h⟩, by simp⟩
121
162
122
163
@[simp] lemma zero_first_loses : (nim (0 : ordinal)).first_loses :=
123
164
begin
@@ -254,7 +295,7 @@ begin
254
295
255
296
all_goals
256
297
{ -- One of the piles is reduced to `k` stones, with `k < n` or `k < m`.
257
- obtain ⟨ok, ⟨ hk, hk'⟩⟩ := nim.exists_ordinal_move_left_eq _ a,
298
+ obtain ⟨ok, hk, hk'⟩ := nim.exists_ordinal_move_left_eq a,
258
299
obtain ⟨k, rfl⟩ := ordinal.lt_omega.1 (lt_trans hk (ordinal.nat_lt_omega _)),
259
300
replace hk := ordinal.nat_cast_lt.1 hk,
260
301
@@ -288,11 +329,11 @@ begin
288
329
289
330
-- Therefore, we can play the corresponding move, and by the inductive hypothesis the new state
290
331
-- is `(u xor m) xor m = u` or `n xor (u xor n) = u` as required.
291
- { obtain ⟨i, hi⟩ := nim.exists_move_left_eq _ (ordinal.nat_cast_lt.2 h),
332
+ { obtain ⟨i, hi⟩ := nim.exists_move_left_eq (ordinal.nat_cast_lt.2 h),
292
333
refine ⟨(left_moves_add _ _).symm (sum.inl i), _⟩,
293
334
simp only [hi, add_move_left_inl],
294
335
rw [hn _ h, nat.lxor_assoc, nat.lxor_self, nat.lxor_zero] },
295
- { obtain ⟨i, hi⟩ := nim.exists_move_left_eq _ (ordinal.nat_cast_lt.2 h),
336
+ { obtain ⟨i, hi⟩ := nim.exists_move_left_eq (ordinal.nat_cast_lt.2 h),
296
337
refine ⟨(left_moves_add _ _).symm (sum.inr i), _⟩,
297
338
simp only [hi, add_move_left_inr],
298
339
rw [hm _ h, nat.lxor_comm, nat.lxor_assoc, nat.lxor_self, nat.lxor_zero] } },
0 commit comments