11From HB Require Import structures.
2- From mathcomp Require Import all_ssreflect function_spaces boolp ssralg functions.
2+ From mathcomp Require Import all_ssreflect boolp ssralg functions.
33Import Order.OrdinalOrder Order.POrderTheory GRing.Theory.
44Local Open Scope order_scope.
55Local Open Scope nat_scope.
@@ -330,15 +330,56 @@ HB.instance Definition _ := GRing.Nmodule.on dirichlet.
330330HB.instance Definition _ := GRing.Nmodule_isComNzSemiRing.Build dirichlet
331331 dirichlet_mulA dirichlet_mulC dirichlet_mul1f dirichlet_mulDl dirichlet_mul0f dirichlet_mul10.
332332
333+ Lemma dirichlet_mulE_dvdn (f g : dirichlet) (n : nat) : 0 < n ->
334+ (f * g) n = \sum_(1 <= d < n.+1 | d %| n) f d * g (n %/ d).
335+ Proof .
336+ move=> n0.
337+ rewrite [LHS]big_nat_recr//= addrC big_pred0; last first.
338+ move=> d.
339+ apply/eqP => /esym nd.
340+ have: n.+1 %| n by apply/dvdnP; exists d; rewrite mulnC.
341+ by move=> /dvdn_leq-/(_ n0); rewrite ltnn.
342+ rewrite add0r big_ltn// big_pred0//; last first.
343+ by move=> d; rewrite mul0n eq_sym eqn0Ngt n0.
344+ rewrite add0r [RHS]big_mkcond [LHS]big_nat [RHS]big_nat.
345+ apply: eq_bigr => d /andP[] d0 dn.
346+ case: ifPn => dn'; last first.
347+ rewrite big_pred0// => d1.
348+ apply/negP/negP; move: dn'; apply: contra => /eqP/esym dn'.
349+ by apply/dvdnP; exists d1; rewrite mulnC.
350+ under eq_bigl do rewrite eq_sym mulnC eqn_mul// eq_sym.
351+ rewrite big_nat1_eq/= ltnS.
352+ suff ->: (n %/ d <= n.+1) by [].
353+ exact: (leq_trans (leq_div _ _)).
354+ Qed .
355+
356+ Definition multiplicative (f : nat -> R) :=
357+ forall n m, coprime n m -> f (n * m) = f n * f m.
358+
359+ Lemma dirichlet_mul_multiplicative (f g : dirichlet) :
360+ multiplicative f -> multiplicative g -> multiplicative (f * g).
361+ Proof .
362+ move=> fm gm [|n] m.
363+ rewrite /coprime gcd0n => /eqP ->.
364+ rewrite mul0r.
365+ STOP.
366+ Search gcdn 0%N.
367+ m nm.
368+ rewrite !dirichlet_mulE_dvdn.
369+
333370End Dirichlet.
334371
335372HB.instance Definition _ (R : comRingType) := GRing.Zmodule.on (dirichlet R).
336373
337374Section DirichletUnit.
338- Variable (R : comUnitRingType).
375+ (* TODO weaken to rings with decidable divisibility. *)
376+ Variable (R : fieldType).
339377
340378Notation dirichlet := (dirichlet R).
341379
380+ (* N.B. This definition is compatible with the weakening to comUnitRingType but
381+ the actual second hypothesis should be (f 0 + f 1 %| f 0) in a ring with
382+ decidable divisibility. *)
342383Definition dirichlet_unit (f : dirichlet) :=
343384 (f 1 \is a GRing.unit) && (f 0 + f 1 \is a GRing.unit).
344385
@@ -349,7 +390,7 @@ Fixpoint dirichlet_inv_subdef (f : dirichlet) (s : seq R) n :=
349390 let s := dirichlet_inv_subdef f s n in
350391 match n with
351392 | 0 => (f 1)^-1
352- | n.+1 => - ((((fun k => s`_(n - k)) : dirichlet) * f) n.+1 ) / f 1
393+ | n.+1 => - ((((fun k => (k <= n.+1)%:R * s`_(n.+1 - k)) : dirichlet) * f) n.+2 ) / f 1
353394 end :: s
354395 end.
355396
@@ -359,16 +400,141 @@ Definition dirichlet_inv (f : dirichlet) (n : nat) :=
359400Lemma dirichlet_mulVx :
360401 {in dirichlet_unit, left_inverse 1 dirichlet_inv (@GRing.mul dirichlet)}.
361402Proof.
362- move=> f funit; apply: funext => n.
403+ move=> f funit.
404+ have subproof n k : k <= n ->
405+ (dirichlet_inv_subdef f [::] n)`_(n - k) = (dirichlet_inv_subdef f [::] k)`_0.
406+ elim: n k => [|n IHn] k; first by rewrite leqn0 sub0n => /eqP ->.
407+ rewrite [in LHS]/dirichlet_inv_subdef.
408+ case: n IHn => [_|n IHn].
409+ by rewrite leq_eqVlt ltnS leqn0 => /orP[] /eqP ->.
410+ rewrite leq_eqVlt => /orP[/eqP ->|].
411+ by rewrite subnn/=.
412+ by rewrite ltnS => kn; rewrite subSn//= IHn.
413+ have dvdnF d n k : n.+1 < k -> (k * d)%N == n.+1 = false.
414+ move=> nk; rewrite mulnC; apply/negP => /eqP /esym nE.
415+ suff /dvdn_leq-/(_ erefl)/(leq_trans nk): (k %| n.+1) by rewrite ltnn.
416+ by apply/dvdnP; exists d.
417+ apply: funext => -[|n].
418+ rewrite [LHS]big_nat_recr//= !big_nat_recr//= big_geq//=.
419+ rewrite big_geq//=.
420+ under eq_bigl do rewrite mul1n.
421+ rewrite big_nat1_eq/= !add0r /dirichlet_inv/= funit/=.
422+ move: funit => /andP[] f1 f01.
423+ rewrite -mulrDr invrM// mulrCA mulrC !mulrA divrr// mul1r.
424+ by rewrite mulrC mulrN addNr.
363425rewrite /dirichlet_inv.
364426under [X in X * _]funext do rewrite funit.
365- case: (ubnP n) => k.
366- elim: k n => // n IHn k.
367- rewrite ltnS leq_eqVlt => /orP[/eqP -> {k}|/IHn//].
427+ move: funit => /andP[] f1 f01.
428+ rewrite [LHS]big_nat_recr//= addrC.
429+ under eq_bigl do rewrite dvdnF//.
430+ rewrite big_pred0// add0r.
431+ rewrite big_nat_recr//= addrC.
432+ under eq_bigl do rewrite mulnC -eqn_div// divnn/=.
433+ rewrite big_nat1_eq/= [X in X * _]/nth/=.
434+ case: n => [|n] /=.
435+ rewrite mulVr// big_nat1.
436+ by rewrite big_pred0// addr0.
437+ rewrite -mulrA mulVr// mulr1.
438+ under [X in - X]eq_bigr => d _.
439+ set G := bigop _ _ _.
440+ have -> : G = if d <= n.+1 then G else 0.
441+ case: (leqP d n.+1) => //; rewrite ltnNge => /negPf dn.
442+ rewrite /G.
443+ under eq_bigr do rewrite dn mul0r mul0r.
444+ by rewrite big1.
445+ rewrite -ltnS /G.
446+ over.
447+ rewrite -big_mkcond/= -(big_nat_widen _ _ _ xpredT); last first.
448+ by rewrite !ltnS -addn2 leq_addr.
449+ rewrite big_nat.
450+ under eq_bigr => d/= dn.
451+ under eq_bigr => d0 _.
452+ rewrite ltnS in dn.
453+ rewrite dn mul1r [X in X * _]subproof//.
454+ over.
455+ over.
456+ rewrite -big_nat -sumrN -big_split/=.
457+ under eq_bigr => d _.
458+ rewrite -sumrN -big_split/=.
459+ under eq_bigr do rewrite addNr.
460+ rewrite big1//.
461+ over.
462+ rewrite big1//.
463+ Qed .
368464
465+ Lemma dirichlet_unitPl (f g : dirichlet) : g * f = 1 -> dirichlet_unit f.
466+ Proof .
467+ rewrite funeqE => gf.
468+ have: (f 1 \in GRing.unit) /\ (g 1 \in GRing.unit).
469+ move: (gf 1).
470+ rewrite [LHS]big_nat_recr//= !big_nat_recr//= big_geq//=.
471+ under eq_bigl do rewrite mul0n.
472+ rewrite big_pred0//.
473+ under eq_bigl do rewrite mul1n.
474+ rewrite big_nat1_eq/=.
475+ under eq_bigl => d.
476+ have -> : (2 * d)%N == 1 = false.
477+ apply/negP => /eqP /esym d2.
478+ suff: (2 %| 1)%N by [].
479+ by apply/dvdnP; exists d; rewrite mulnC.
480+ over.
481+ rewrite big1// !add0r addr0 => gf1.
482+ split; apply/unitrPr; last by exists (f 1).
483+ by exists (g 1); rewrite mulrC.
484+ move=> [] f1 g1; apply/andP; split=> //.
485+ (* TODO: This is where we need to change the definition of `unit` to generalise
486+ to rings with decidable divisibility *)
487+ rewrite unitfE; apply/eqP => f01.
488+ move: (gf 0).
489+ rewrite [LHS]big_nat_recr//= big_nat1.
490+ under [X in _ + X]eq_bigl do rewrite mul1n.
491+ rewrite big_nat1_eq/= big_nat_recr//= big_nat1.
492+ rewrite -mulrDr f01 mulr0 add0r => /eqP.
493+ rewrite mulf_eq0.
494+ move: g1; rewrite unitfE => /negPf -> /= /eqP f0.
495+ move: f01; rewrite f0 add0r => f10.
496+ by move: f1; rewrite f10 unitfE eqxx.
497+ Qed .
369498
370- mulVx : {in unit, left_inverse 1 inv *%R};
371- unitPl : forall x y, y * x = 1 -> unit x;
372- invr_out : {in [predC unit], inv =1 id}
499+ Lemma dirichlet_invr_out : {in [predC dirichlet_unit], dirichlet_inv =1 id}.
500+ Proof .
501+ move=> f; rewrite inE => /negPf f1.
502+ rewrite /dirichlet_inv.
503+ by under [LHS]funext do rewrite f1.
504+ Qed .
505+
506+ HB.instance Definition _ := GRing.ComNzRing_hasMulInverse.Build dirichlet
507+ dirichlet_mulVx dirichlet_unitPl dirichlet_invr_out.
508+
509+ Lemma dirichletVcst1E n : ((fun n => (n != 0)%:R) : dirichlet)^-1 n =
510+ match primes n with
511+ | [::] => (n == 1)%:R
512+ | [:: p] => (-1) ^+ (logn p n)
513+ | _ => 0
514+ end .
515+ Proof .
516+ have f1: ((fun n0 : nat => (n0 != 0)%:R) : dirichlet.dirichlet R) \in GRing.unit.
517+ apply/andP/andP; rewrite eqxx add0r andbb oner_neq0.
518+ exact: unitr1.
519+ move: n; rewrite -/(_ =1 _) -funeqE.
520+ apply/esym/(mulrI f1); rewrite divrr//.
521+ apply: funext => n.
522+ rewrite [LHS]big_nat_recl//.
523+ under eq_bigr do rewrite mul0r.
524+ rewrite big1// add0r.
525+ under eq_bigr do under eq_bigr do rewrite mul1r.
526+ case: n => [|n].
527+ rewrite big_nat1.
528+ under eq_bigl do rewrite mul1n.
529+ by rewrite big_nat1_eq.
530+
531+ rewrite /injective.
532+ Set Printing All.
533+ apply.
534+ Search GRing.inv GRing.mul.
535+ case pn: (primes n).
536+ move: pn => /eqP; rewrite primes_eq0.
537+ rewrite ltnS leq_eqVlt ltnS leqn0 => /orP[] /eqP ->.
538+ Search primes nil.
373539
374540End DirichletUnit.
0 commit comments