@@ -3,6 +3,7 @@ Copyright (c) 2018 Chris Hughes. All rights reserved.
33Released under Apache 2.0 license as described in the file LICENSE.
44Authors: Chris Hughes
55-/
6+ import algebra.char_p.algebra
67import field_theory.intermediate_field
78import ring_theory.adjoin.field
89
@@ -109,46 +110,234 @@ namespace splitting_field_aux
109110theorem succ (n : ℕ) (f : K[X]) :
110111 splitting_field_aux (n+1 ) f = splitting_field_aux n f.remove_factor := rfl
111112
112- instance field (n : ℕ) : Π {K : Type u} [field K], by exactI
113- Π {f : K[X]}, field (splitting_field_aux n f) :=
114- nat.rec_on n (λ K _ _, ‹field K›) $ λ n ih K _ f, ih
113+ section lift_instances
115114
116- instance inhabited {n : ℕ} {f : K[X]} :
117- inhabited (splitting_field_aux n f) := ⟨37 ⟩
115+ /-! ### Instances on `splitting_field_aux`
118116
119- /-
120- Note that the recursive nature of this definition and `splitting_field_aux.field` creates
121- non-definitionally-equal diamonds in the `ℕ`- and `ℤ`- actions.
122- ```lean
123- example (n : ℕ) {K : Type u} [field K] {f : K[X]} (hfn : f.nat_degree = n) :
124- (add_comm_monoid.nat_module : module ℕ (splitting_field_aux n f hfn)) =
125- @algebra.to_module _ _ _ _ (splitting_field_aux.algebra n _ hfn) :=
126- rfl -- fails
127- ```
128- It's not immediately clear whether this _can_ be fixed; the failure is much the same as the reason
129- that the following fails:
130- ```lean
131- def cases_twice {α} (a₀ aₙ : α) : ℕ → α × α
132- | 0 := (a₀, a₀)
133- | (n + 1) := (aₙ, aₙ)
134-
135- example (x : ℕ) {α} (a₀ aₙ : α) : (cases_twice a₀ aₙ x).1 = (cases_twice a₀ aₙ x).2 := rfl -- fails
136- ```
137- We don't really care at this point because this is an implementation detail (which is why this is
138- not a docstring), but we do in `splitting_field.algebra'` below. -/
139- instance algebra (n : ℕ) : Π (R : Type *) {K : Type u} [comm_semiring R] [field K],
140- by exactI Π [algebra R K] {f : K[X]},
141- algebra R (splitting_field_aux n f) :=
142- nat.rec_on n (λ R K _ _ _ _, by exactI ‹algebra R K›) $
143- λ n ih R K _ _ _ f, by exactI ih R
117+ In order to avoid diamond issues, we have to be careful to define each data field of algebraic
118+ instances on `splitting_field_aux` by recursion, rather than defining the whole structure by
119+ recursion at once.
120+
121+ The important detail is that the `smul` instances can be lifted _before_ we create the algebraic
122+ instances; if we do not do this, this creates a mutual dependence on both on each other, and it
123+ is impossible to untangle this mess. In order to do this, we need that these `smul` instances
124+ are distributive in the sense of `distrib_smul`, which is weak enough to be guaranteed at this
125+ stage. This is sufficient to lift an action to `adjoin_root f` (remember that this is a quotient,
126+ so these conditions are equivalent to well-definedness), which is all we need.
127+ -/
128+
129+ /-- Splitting fields have a zero. -/
130+ protected def zero (n : ℕ) : Π {K : Type u} [field K], by exactI Π {f : K[X]},
131+ splitting_field_aux n f :=
132+ nat.rec_on n (λ K fK f, by exactI @has_zero.zero K _) (λ n ih K fK f, ih)
133+
134+ /-- Splitting fields have an addition. -/
135+ protected def add (n : ℕ) : Π {K : Type u} [field K], by exactI Π {f : K[X]},
136+ splitting_field_aux n f → splitting_field_aux n f → splitting_field_aux n f :=
137+ nat.rec_on n (λ K fK f, by exactI @has_add.add K _) (λ n ih K fK f, ih)
138+
139+ /-- Splitting fields inherit scalar multiplication. -/
140+ protected def smul (n : ℕ) : Π (α : Type *) {K : Type u} [field K],
141+ by exactI Π [distrib_smul α K],
142+ by exactI Π [is_scalar_tower α K K] {f : K[X]},
143+ α → splitting_field_aux n f → splitting_field_aux n f :=
144+ nat.rec_on n
145+ (λ α K fK ds ist f, by exactI @has_smul.smul _ K _)
146+ (λ n ih α K fK ds ist f, by exactI ih α)
147+
148+ instance has_smul (α : Type *) (n : ℕ) {K : Type u} [field K] [distrib_smul α K]
149+ [is_scalar_tower α K K] {f : K[X]} :
150+ has_smul α (splitting_field_aux n f) :=
151+ ⟨splitting_field_aux.smul n α⟩
144152
145153instance is_scalar_tower (n : ℕ) : Π (R₁ R₂ : Type *) {K : Type u}
146- [comm_semiring R₁] [comm_semiring R₂] [has_smul R₁ R₂] [field K],
147- by exactI Π [algebra R₁ K] [algebra R₂ K],
148- by exactI Π [is_scalar_tower R₁ R₂ K] {f : K[X]},
149- is_scalar_tower R₁ R₂ (splitting_field_aux n f) :=
150- nat.rec_on n (λ R₁ R₂ K _ _ _ _ _ _ _ _, by exactI ‹is_scalar_tower R₁ R₂ K›) $
151- λ n ih R₁ R₂ K _ _ _ _ _ _ _ f, by exactI ih R₁ R₂
154+ [has_smul R₁ R₂] [field K],
155+ by exactI Π [distrib_smul R₂ K] [distrib_smul R₁ K],
156+ by exactI Π [is_scalar_tower R₁ K K] [is_scalar_tower R₂ K K] [is_scalar_tower R₁ R₂ K]
157+ {f : K[X]}, by exactI is_scalar_tower R₁ R₂ (splitting_field_aux n f) :=
158+ nat.rec_on n (λ R₁ R₂ K _ _ hs₂ hs₁ _ _ h f,
159+ begin
160+ rcases hs₁ with @⟨@⟨⟨hs₁⟩,_⟩,_⟩,
161+ rcases hs₂ with @⟨@⟨⟨hs₂⟩,_⟩,_⟩,
162+ exact h,
163+ end ) $ λ n ih R₁ R₂ K _ _ _ _ _ _ _ f, by exactI ih R₁ R₂
164+
165+ /-- Splitting fields have a negation. -/
166+ protected def neg (n : ℕ) : Π {K : Type u} [field K], by exactI Π {f : K[X]},
167+ splitting_field_aux n f → splitting_field_aux n f :=
168+ nat.rec_on n (λ K fK f, by exactI @has_neg.neg K _) (λ n ih K fK f, ih)
169+
170+ /-- Splitting fields have subtraction. -/
171+ protected def sub (n : ℕ) : Π {K : Type u} [field K], by exactI Π {f : K[X]},
172+ splitting_field_aux n f → splitting_field_aux n f → splitting_field_aux n f :=
173+ nat.rec_on n (λ K fK f, by exactI @has_sub.sub K _) (λ n ih K fK f, ih)
174+
175+ /-- Splitting fields have a one. -/
176+ protected def one (n : ℕ) : Π {K : Type u} [field K], by exactI Π {f : K[X]},
177+ splitting_field_aux n f :=
178+ nat.rec_on n (λ K fK f, by exactI @has_one.one K _) (λ n ih K fK f, ih)
179+
180+ /-- Splitting fields have a multiplication. -/
181+ protected def mul (n : ℕ) : Π {K : Type u} [field K], by exactI Π {f : K[X]},
182+ splitting_field_aux n f → splitting_field_aux n f → splitting_field_aux n f :=
183+ nat.rec_on n (λ K fK f, by exactI @has_mul.mul K _) (λ n ih K fK f, ih)
184+
185+ /-- Splitting fields have a power operation. -/
186+ protected def npow (n : ℕ) : Π {K : Type u} [field K], by exactI Π {f : K[X]},
187+ ℕ → splitting_field_aux n f → splitting_field_aux n f :=
188+ nat.rec_on n (λ K fK f n x, by exactI @has_pow.pow K _ _ x n) (λ n ih K fK f, ih)
189+
190+ /-- Splitting fields have an injection from the base field. -/
191+ protected def mk (n : ℕ) : Π {K : Type u} [field K],
192+ by exactI Π {f : K[X]}, K → splitting_field_aux n f :=
193+ nat.rec_on n (λ K fK f, id) (λ n ih K fK f, by exactI ih ∘ coe)
194+ -- note that `coe` goes from `K → adjoin_root f`, and then `ih` lifts to the full splitting field
195+ -- (as we generalise over all fields in this recursion!)
196+
197+ /-- Splitting fields have an inverse. -/
198+ protected def inv (n : ℕ) : Π {K : Type u} [field K], by exactI Π {f : K[X]},
199+ splitting_field_aux n f → splitting_field_aux n f :=
200+ nat.rec_on n (λ K fK f, by exactI @has_inv.inv K _) (λ n ih K fK f, ih)
201+
202+ /-- Splitting fields have a division. -/
203+ protected def div (n : ℕ) : Π {K : Type u} [field K], by exactI Π {f : K[X]},
204+ splitting_field_aux n f → splitting_field_aux n f → splitting_field_aux n f :=
205+ nat.rec_on n (λ K fK f, by exactI @has_div.div K _) (λ n ih K fK f, ih)
206+
207+ /-- Splitting fields have powers by integers. -/
208+ protected def zpow (n : ℕ) : Π {K : Type u} [field K], by exactI Π {f : K[X]},
209+ ℤ → splitting_field_aux n f → splitting_field_aux n f :=
210+ nat.rec_on n (λ K fK f n x, by exactI @has_pow.pow K _ _ x n) (λ n ih K fK f, ih)
211+
212+ -- I'm not sure why these two lemmas break, but inlining them seems to not work.
213+ private lemma nsmul_zero (n : ℕ) : Π {K : Type u} [field K], by exactI Π {f : K[X]}
214+ (x : splitting_field_aux n f), (0 : ℕ) • x = splitting_field_aux.zero n :=
215+ nat.rec_on n (λ K fK f, by exactI zero_nsmul) (λ n ih K fK f, by exactI ih)
216+
217+ private lemma nsmul_succ (n : ℕ) : Π {K : Type u} [field K], by exactI Π {f : K[X]}
218+ (k : ℕ) (x : splitting_field_aux n f),
219+ (k + 1 ) • x = splitting_field_aux.add n x (k • x) :=
220+ nat.rec_on n (λ K fK f n x, by exactI succ_nsmul x n) (λ n ih K fK f, by exactI ih)
221+
222+ instance field (n : ℕ) {K : Type u} [field K] {f : K[X]} :
223+ field (splitting_field_aux n f) :=
224+ begin
225+ refine
226+ { zero := splitting_field_aux.zero n,
227+ one := splitting_field_aux.one n,
228+ add := splitting_field_aux.add n,
229+ zero_add := have h : _ := @zero_add, _,
230+ add_zero := have h : _ := @add_zero, _,
231+ add_assoc := have h : _ := @add_assoc, _,
232+ add_comm := have h : _ := @add_comm, _,
233+ neg := splitting_field_aux.neg n,
234+ add_left_neg := have h : _ := @add_left_neg, _,
235+ sub := splitting_field_aux.sub n,
236+ sub_eq_add_neg := have h : _ := @sub_eq_add_neg, _,
237+ mul := splitting_field_aux.mul n,
238+ one_mul := have h : _ := @one_mul, _,
239+ mul_one := have h : _ := @mul_one, _,
240+ mul_assoc := have h : _ := @mul_assoc, _,
241+ left_distrib := have h : _ := @left_distrib, _,
242+ right_distrib := have h : _ := @right_distrib, _,
243+ mul_comm := have h : _ := @mul_comm, _,
244+ inv := splitting_field_aux.inv n,
245+ inv_zero := have h : _ := @inv_zero, _,
246+ div := splitting_field_aux.div n,
247+ div_eq_mul_inv := have h : _ := @div_eq_mul_inv, _,
248+ mul_inv_cancel := have h : _ := @mul_inv_cancel, _,
249+ exists_pair_ne := have h : _ := @exists_pair_ne, _,
250+ nat_cast := splitting_field_aux.mk n ∘ (coe : ℕ → K),
251+ nat_cast_zero := have h : _ := @comm_ring.nat_cast_zero, _,
252+ nat_cast_succ := have h : _ := @comm_ring.nat_cast_succ, _,
253+ nsmul := (•),
254+ nsmul_zero' := nsmul_zero n,
255+ nsmul_succ' := nsmul_succ n,
256+ int_cast := splitting_field_aux.mk n ∘ (coe : ℤ → K),
257+ int_cast_of_nat := have h : _ := @comm_ring.int_cast_of_nat, _,
258+ int_cast_neg_succ_of_nat := have h : _ := @comm_ring.int_cast_neg_succ_of_nat, _,
259+ zsmul := (•),
260+ zsmul_zero' := have h : _ := @subtraction_comm_monoid.zsmul_zero', _,
261+ zsmul_succ' := have h : _ := @subtraction_comm_monoid.zsmul_succ', _,
262+ zsmul_neg' := have h : _ := @subtraction_comm_monoid.zsmul_neg', _,
263+ rat_cast := splitting_field_aux.mk n ∘ (coe : ℚ → K),
264+ rat_cast_mk := have h : _ := @field.rat_cast_mk, _,
265+ qsmul := (•),
266+ qsmul_eq_mul' := have h : _ := @field.qsmul_eq_mul', _,
267+ npow := splitting_field_aux.npow n,
268+ npow_zero' := have h : _ := @comm_ring.npow_zero', _,
269+ npow_succ' := have h : _ := @comm_ring.npow_succ', _,
270+ zpow := splitting_field_aux.zpow n,
271+ zpow_zero' := have h : _ := @field.zpow_zero', _,
272+ zpow_succ' := have h : _ := @field.zpow_succ', _,
273+ zpow_neg' := have h : _ := @field.zpow_neg', _},
274+ all_goals {
275+ unfreezingI { induction n with n ih generalizing K },
276+ { apply @h K },
277+ { exact @ih _ _ _ } },
278+ end
279+
280+ instance inhabited {n : ℕ} {f : K[X]} :
281+ inhabited (splitting_field_aux n f) := ⟨37 ⟩
282+
283+ /-- The injection from the base field as a ring homomorphism. -/
284+ @[simps] protected def mk_hom (n : ℕ) {K : Type u} [field K] {f : K[X]} :
285+ K →+* splitting_field_aux n f :=
286+ { to_fun := splitting_field_aux.mk n,
287+ map_one' :=
288+ begin
289+ unfreezingI { induction n with k hk generalizing K },
290+ { simp [splitting_field_aux.mk] },
291+ exact hk
292+ end ,
293+ map_mul' :=
294+ begin
295+ unfreezingI { induction n with k hk generalizing K },
296+ { simp [splitting_field_aux.mk] },
297+ intros x y,
298+ change (splitting_field_aux.mk k) ((adjoin_root.of f.factor) _) = _,
299+ rw [map_mul],
300+ exact hk _ _
301+ end ,
302+ map_zero' :=
303+ begin
304+ unfreezingI { induction n with k hk generalizing K },
305+ { simp [splitting_field_aux.mk] },
306+ change (splitting_field_aux.mk k) ((adjoin_root.of f.factor) 0 ) = _,
307+ rw [map_zero, hk],
308+ end ,
309+ map_add' :=
310+ begin
311+ unfreezingI { induction n with k hk generalizing K },
312+ { simp [splitting_field_aux.mk] },
313+ intros x y,
314+ change (splitting_field_aux.mk k) ((adjoin_root.of f.factor) _) = _,
315+ rw [map_add],
316+ exact hk _ _
317+ end }
318+
319+ instance algebra (n : ℕ) (R : Type *) {K : Type u} [comm_semiring R] [field K]
320+ [algebra R K] {f : K[X]} : algebra R (splitting_field_aux n f) :=
321+ { to_fun := (splitting_field_aux.mk_hom n).comp (algebra_map R K),
322+ smul := (•),
323+ smul_def' :=
324+ begin
325+ unfreezingI { induction n with k hk generalizing K },
326+ { exact algebra.smul_def },
327+ exact hk
328+ end ,
329+ commutes' := λ a b, mul_comm _ _,
330+ .. (splitting_field_aux.mk_hom n).comp (algebra_map R K) }
331+
332+ /-- Because `splitting_field_aux` is defined by recursion, we have to make sure all instances
333+ on `splitting_field_aux` are defined by recursion within the fields. Otherwise, there will be
334+ instance diamonds such as the following: -/
335+ example (n : ℕ) {K : Type u} [field K] {f : K[X]} :
336+ (add_comm_monoid.nat_module : module ℕ (splitting_field_aux n f)) =
337+ @algebra.to_module _ _ _ _ (splitting_field_aux.algebra n _) :=
338+ rfl
339+
340+ end lift_instances
152341
153342instance algebra''' {n : ℕ} {f : K[X]} :
154343 algebra (adjoin_root f.factor)
@@ -248,36 +437,32 @@ splitting_field_aux.field _
248437
249438instance inhabited : inhabited (splitting_field f) := ⟨37 ⟩
250439
251- /-- This should be an instance globally, but it creates diamonds with the `ℕ`, `ℤ`, and `ℚ` algebras
252- (via their `smul` and `to_fun` fields):
440+ instance algebra' {R} [comm_semiring R] [algebra R K] : algebra R (splitting_field f) :=
441+ splitting_field_aux.algebra _ _
253442
254- ```lean
255- example :
256- (algebra_nat : algebra ℕ (splitting_field f)) = splitting_field.algebra' f :=
257- rfl -- fails
443+ instance : algebra K (splitting_field f) :=
444+ splitting_field_aux.algebra _ _
258445
259- example :
260- (algebra_int _ : algebra ℤ (splitting_field f)) = splitting_field.algebra' f :=
261- rfl -- fails
446+ instance [char_zero K] : char_zero (splitting_field f) :=
447+ char_zero_of_injective_algebra_map ((algebra_map K _).injective)
262448
263- example [char_zero K] [char_zero (splitting_field f)] :
264- (algebra_rat : algebra ℚ (splitting_field f)) = splitting_field.algebra' f :=
265- rfl -- fails
266- ```
449+ -- The algebra instance deriving from `K` should be definitionally equal to that
450+ -- deriving from the field structure on `splitting_field f`.
451+ example : (add_comm_monoid.nat_module : module ℕ (splitting_field f)) =
452+ @algebra.to_module _ _ _ _ (splitting_field.algebra' f) :=
453+ rfl
267454
268- Until we resolve these diamonds, it's more convenient to only turn this instance on with
269- `local attribute [instance]` in places where the benefit of having the instance outweighs the cost.
455+ example : (add_comm_group.int_module _ : module ℤ (splitting_field f)) =
456+ @algebra.to_module _ _ _ _ (splitting_field.algebra' f) :=
457+ rfl
270458
271- In the meantime, the `splitting_field.algebra` instance below is immune to these particular diamonds
272- since `K = ℕ` and `K = ℤ` are not possible due to the `field K` assumption. Diamonds in
273- `algebra ℚ (splitting_field f)` instances are still possible via this instance unfortunately, but
274- these are less common as they require suitable `char_zero` instances to be present.
275- -/
276- instance algebra' {R} [comm_semiring R] [algebra R K] : algebra R (splitting_field f) :=
277- splitting_field_aux.algebra _ _
459+ example [char_zero K] : (splitting_field.algebra' f) = algebra_rat :=
460+ rfl
278461
279- instance : algebra K (splitting_field f) :=
280- splitting_field_aux.algebra _ _
462+ example [char_zero K] : (splitting_field.algebra' f) = algebra_rat :=
463+ rfl
464+
465+ example {q : ℚ[X]} : algebra_int (splitting_field q) = splitting_field.algebra' q := rfl
281466
282467protected theorem splits : splits (algebra_map K (splitting_field f)) f :=
283468splitting_field_aux.splits _ _ rfl
0 commit comments