@@ -6,7 +6,12 @@ Authors: Johannes Hölzl, Johan Commelin, Mario Carneiro
6
6
7
7
import data.mv_polynomial.rename
8
8
import data.polynomial.algebra_map
9
+ import data.polynomial.lifts
10
+ import data.mv_polynomial.variables
11
+ import data.finsupp.fin
9
12
import logic.equiv.fin
13
+ import algebra.big_operators.fin
14
+
10
15
11
16
/-!
12
17
# Equivalences between polynomial rings
@@ -47,7 +52,7 @@ universes u v w x
47
52
variables {R : Type u} {S₁ : Type v} {S₂ : Type w} {S₃ : Type x}
48
53
49
54
namespace mv_polynomial
50
- variables {σ : Type *} {a a' a₁ a₂ : R} {e : ℕ} {n m : σ} { s : σ →₀ ℕ}
55
+ variables {σ : Type *} {a a' a₁ a₂ : R} {e : ℕ} {s : σ →₀ ℕ}
51
56
52
57
section equiv
53
58
@@ -274,19 +279,30 @@ def option_equiv_right : mv_polynomial (option S₁) R ≃ₐ[R] mv_polynomial S
274
279
alg_equiv.of_alg_hom
275
280
(mv_polynomial.aeval (λ o, o.elim (C polynomial.X) X))
276
281
(mv_polynomial.aeval_tower (polynomial.aeval (X none)) (λ i, X (option.some i)))
277
- (by ext : 2 ; simp [mv_polynomial.algebra_map_eq])
278
- (by ext i : 2 ; cases i; simp)
282
+ begin
283
+ ext : 2 ;
284
+ simp only [mv_polynomial.algebra_map_eq, option.elim, alg_hom.coe_comp, alg_hom.id_comp,
285
+ is_scalar_tower.coe_to_alg_hom', comp_app, aeval_tower_C, polynomial.aeval_X, aeval_X,
286
+ option.elim, aeval_tower_X, alg_hom.coe_id, id.def, eq_self_iff_true, implies_true_iff],
287
+ end
288
+ begin
289
+ ext ⟨i⟩ : 2 ;
290
+ simp only [option.elim, alg_hom.coe_comp, comp_app, aeval_X, aeval_tower_C,
291
+ polynomial.aeval_X, alg_hom.coe_id, id.def, aeval_tower_X],
292
+ end
293
+
294
+ variables (n : ℕ)
279
295
280
296
/--
281
297
The algebra isomorphism between multivariable polynomials in `fin (n + 1)` and
282
298
polynomials over multivariable polynomials in `fin n`.
283
299
-/
284
- def fin_succ_equiv (n : ℕ) :
300
+ def fin_succ_equiv :
285
301
mv_polynomial (fin (n + 1 )) R ≃ₐ[R] polynomial (mv_polynomial (fin n) R) :=
286
302
(rename_equiv R (fin_succ_equiv n)).trans
287
303
(option_equiv_left R (fin n))
288
304
289
- lemma fin_succ_equiv_eq (n : ℕ) :
305
+ lemma fin_succ_equiv_eq :
290
306
(fin_succ_equiv R n : mv_polynomial (fin (n + 1 )) R →+* polynomial (mv_polynomial (fin n) R)) =
291
307
eval₂_hom (polynomial.C.comp (C : R →+* mv_polynomial (fin n) R))
292
308
(λ i : fin (n+1 ), fin.cases polynomial.X (λ k, polynomial.C (X k)) i) :=
@@ -301,7 +317,7 @@ begin
301
317
simp [fin_succ_equiv] }
302
318
end
303
319
304
- @[simp] lemma fin_succ_equiv_apply (n : ℕ) ( p : mv_polynomial (fin (n + 1 )) R) :
320
+ @[simp] lemma fin_succ_equiv_apply (p : mv_polynomial (fin (n + 1 )) R) :
305
321
fin_succ_equiv R n p =
306
322
eval₂_hom (polynomial.C.comp (C : R →+* mv_polynomial (fin n) R))
307
323
(λ i : fin (n+1 ), fin.cases polynomial.X (λ k, polynomial.C (X k)) i) p :=
@@ -319,6 +335,153 @@ begin
319
335
simp only [mv_polynomial.fin_succ_equiv_apply, mv_polynomial.eval₂_hom_C],
320
336
end
321
337
338
+ variables {n} {R}
339
+
340
+ lemma fin_succ_equiv_X_zero :
341
+ fin_succ_equiv R n (X 0 ) = polynomial.X := by simp
342
+
343
+ lemma fin_succ_equiv_X_succ {j : fin n} :
344
+ fin_succ_equiv R n (X j.succ) = polynomial.C (X j) := by simp
345
+
346
+ /-- The coefficient of `m` in the `i`-th coefficient of `fin_succ_equiv R n f` equals the
347
+ coefficient of `finsupp.cons i m` in `f`. -/
348
+ lemma fin_succ_equiv_coeff_coeff (m : fin n →₀ ℕ)
349
+ (f : mv_polynomial (fin (n + 1 )) R) (i : ℕ) :
350
+ coeff m (polynomial.coeff (fin_succ_equiv R n f) i) = coeff (m.cons i) f :=
351
+ begin
352
+ induction f using mv_polynomial.induction_on' with j r p q hp hq generalizing i m,
353
+ swap,
354
+ { simp only [(fin_succ_equiv R n).map_add, polynomial.coeff_add, coeff_add, hp, hq] },
355
+ simp only [fin_succ_equiv_apply, coe_eval₂_hom, eval₂_monomial, ring_hom.coe_comp, prod_pow,
356
+ polynomial.coeff_C_mul, coeff_C_mul, coeff_monomial,
357
+ fin.prod_univ_succ, fin.cases_zero, fin.cases_succ, ← ring_hom.map_prod, ← ring_hom.map_pow],
358
+ rw [← mul_boole, mul_comm (polynomial.X ^ j 0 ), polynomial.coeff_C_mul_X_pow], congr' 1 ,
359
+ obtain rfl | hjmi := eq_or_ne j (m.cons i),
360
+ { simpa only [cons_zero, cons_succ, if_pos rfl, monomial_eq, C_1, one_mul, prod_pow]
361
+ using coeff_monomial m m (1 :R), },
362
+ { simp only [hjmi, if_false],
363
+ obtain hij | rfl := ne_or_eq i (j 0 ),
364
+ { simp only [hij, if_false, coeff_zero] },
365
+ simp only [eq_self_iff_true, if_true],
366
+ have hmj : m ≠ j.tail, { rintro rfl, rw [cons_tail] at hjmi, contradiction },
367
+ simpa only [monomial_eq, C_1, one_mul, prod_pow, finsupp.tail_apply, if_neg hmj.symm]
368
+ using coeff_monomial m j.tail (1 :R), }
369
+ end
370
+
371
+ lemma eval_eq_eval_mv_eval' (s : fin n → R) (y : R) (f : mv_polynomial (fin (n + 1 )) R) :
372
+ eval (fin.cons y s : fin (n + 1 ) → R) f =
373
+ polynomial.eval y (polynomial.map (eval s) (fin_succ_equiv R n f)) :=
374
+ begin
375
+ -- turn this into a def `polynomial.map_alg_hom`
376
+ let φ : (mv_polynomial (fin n) R)[X] →ₐ[R] R[X] :=
377
+ { commutes' := λ r, by { convert polynomial.map_C _, exact (eval_C _).symm },
378
+ .. polynomial.map_ring_hom (eval s) },
379
+ show aeval (fin.cons y s : fin (n + 1 ) → R) f =
380
+ (polynomial.aeval y).comp (φ.comp (fin_succ_equiv R n).to_alg_hom) f,
381
+ congr' 2 ,
382
+ apply mv_polynomial.alg_hom_ext,
383
+ rw fin.forall_fin_succ,
384
+ simp only [aeval_X, fin.cons_zero, alg_equiv.to_alg_hom_eq_coe, alg_hom.coe_comp,
385
+ polynomial.coe_aeval_eq_eval, polynomial.map_C, alg_hom.coe_mk, ring_hom.to_fun_eq_coe,
386
+ polynomial.coe_map_ring_hom, alg_equiv.coe_alg_hom, comp_app, fin_succ_equiv_apply,
387
+ eval₂_hom_X', fin.cases_zero, polynomial.map_X, polynomial.eval_X, eq_self_iff_true,
388
+ fin.cons_succ, fin.cases_succ, eval_X, polynomial.eval_C, implies_true_iff, and_self],
389
+ end
390
+
391
+ lemma coeff_eval_eq_eval_coeff (s' : fin n → R) (f : polynomial (mv_polynomial (fin n) R))
392
+ (i : ℕ) : polynomial.coeff (polynomial.map (eval s') f) i = eval s' (polynomial.coeff f i) :=
393
+ by simp only [polynomial.coeff_map]
394
+
395
+ lemma support_coeff_fin_succ_equiv {f : mv_polynomial (fin (n + 1 )) R} {i : ℕ}
396
+ {m : fin n →₀ ℕ } : m ∈ (polynomial.coeff ((fin_succ_equiv R n) f) i).support
397
+ ↔ (finsupp.cons i m) ∈ f.support :=
398
+ begin
399
+ apply iff.intro,
400
+ { intro h,
401
+ simpa [←fin_succ_equiv_coeff_coeff] using h },
402
+ { intro h,
403
+ simpa [mem_support_iff, ←fin_succ_equiv_coeff_coeff m f i] using h },
404
+ end
405
+
406
+ lemma fin_succ_equiv_support (f : mv_polynomial (fin (n + 1 )) R) :
407
+ (fin_succ_equiv R n f).support = finset.image (λ m : fin (n + 1 )→₀ ℕ, m 0 ) f.support :=
408
+ begin
409
+ ext i,
410
+ rw [polynomial.mem_support_iff, finset.mem_image, nonzero_iff_exists],
411
+ split,
412
+ { rintro ⟨m, hm⟩,
413
+ refine ⟨cons i m, _, cons_zero _ _⟩,
414
+ rw ← support_coeff_fin_succ_equiv,
415
+ simpa using hm, },
416
+ { rintro ⟨m, h, rfl⟩,
417
+ refine ⟨tail m, _⟩,
418
+ rwa [← coeff, ← mem_support_iff, support_coeff_fin_succ_equiv, cons_tail] },
419
+ end
420
+
421
+ lemma fin_succ_equiv_support' {f : mv_polynomial (fin (n + 1 )) R} {i : ℕ} :
422
+ finset.image (finsupp.cons i) (polynomial.coeff ((fin_succ_equiv R n) f) i).support
423
+ = f.support.filter(λ m, m 0 = i) :=
424
+ begin
425
+ ext m,
426
+ rw [finset.mem_filter, finset.mem_image, mem_support_iff],
427
+ conv_lhs
428
+ { congr,
429
+ funext,
430
+ rw [mem_support_iff, fin_succ_equiv_coeff_coeff, ne.def] },
431
+ split,
432
+ { rintros ⟨m',⟨h, hm'⟩⟩,
433
+ simp only [←hm'],
434
+ exact ⟨h, by rw cons_zero⟩ },
435
+ { intro h,
436
+ use tail m,
437
+ rw [← h.2 , cons_tail],
438
+ simp [h.1 ] }
439
+ end
440
+
441
+ lemma support_fin_succ_equiv_nonempty {f : mv_polynomial (fin (n + 1 )) R} (h : f ≠ 0 ) :
442
+ (fin_succ_equiv R n f).support.nonempty :=
443
+ begin
444
+ by_contradiction c,
445
+ simp only [finset.not_nonempty_iff_eq_empty, polynomial.support_eq_empty] at c,
446
+ have t'' : (fin_succ_equiv R n f) ≠ 0 ,
447
+ { let ii := (fin_succ_equiv R n).symm,
448
+ have h' : f = 0 :=
449
+ calc f = ii (fin_succ_equiv R n f) : by simpa only [ii, ←alg_equiv.inv_fun_eq_symm]
450
+ using ((fin_succ_equiv R n).left_inv f).symm
451
+ ... = ii 0 : by rw c
452
+ ... = 0 : by simp,
453
+ simpa [h'] using h },
454
+ simpa [c] using h,
455
+ end
456
+
457
+ lemma degree_fin_succ_equiv {f : mv_polynomial (fin (n + 1 )) R} (h : f ≠ 0 ) :
458
+ (fin_succ_equiv R n f).degree = degree_of 0 f :=
459
+ begin
460
+ have h' : (fin_succ_equiv R n f).support.sup (λ x , x) = degree_of 0 f,
461
+ { rw [degree_of_eq_sup, fin_succ_equiv_support f, finset.sup_image] },
462
+ rw [polynomial.degree, ← h', finset.coe_sup_of_nonempty (support_fin_succ_equiv_nonempty h)],
463
+ congr,
464
+ end
465
+
466
+ lemma nat_degree_fin_succ_equiv (f : mv_polynomial (fin (n + 1 )) R) :
467
+ (fin_succ_equiv R n f).nat_degree = degree_of 0 f :=
468
+ begin
469
+ by_cases c : f = 0 ,
470
+ { rw [c, (fin_succ_equiv R n).map_zero, polynomial.nat_degree_zero, degree_of_zero] },
471
+ { rw [polynomial.nat_degree, degree_fin_succ_equiv (by simpa only [ne.def]) ],
472
+ simp },
473
+ end
474
+
475
+ lemma degree_of_coeff_fin_succ_equiv (p : mv_polynomial (fin (n + 1 )) R) (j : fin n)
476
+ (i : ℕ) : degree_of j (polynomial.coeff (fin_succ_equiv R n p) i) ≤ degree_of j.succ p :=
477
+ begin
478
+ rw [degree_of_eq_sup, degree_of_eq_sup, finset.sup_le_iff],
479
+ intros m hm,
480
+ rw ← finsupp.cons_succ j i m,
481
+ convert finset.le_sup (support_coeff_fin_succ_equiv.1 hm),
482
+ refl,
483
+ end
484
+
322
485
end
323
486
324
487
end equiv
0 commit comments