@@ -61,14 +61,12 @@ HB.mixin Record Choice_isMonomialDef V of Choice V := {
6161 unitm : forall x y, mul x y = one -> x = one /\ y = one
6262}.
6363
64+ #[short(type="monomType")]
6465HB.structure Definition MonomialDef :=
6566 { V of Choice V & Choice_isMonomialDef V }.
6667
67- Module MonomialDefExports.
6868Bind Scope monom_scope with MonomialDef.sort.
69- Notation monomType := MonomialDef.type.
70- End MonomialDefExports.
71- Export MonomialDefExports.
69+ Bind Scope type_scope with monomType.
7270
7371(* -------------------------------------------------------------------- *)
7472Notation mone := one.
@@ -83,14 +81,50 @@ HB.mixin Record MonomialDef_isConomialDef V of MonomialDef V := {
8381 mulmC : commutative (@mul V)
8482}.
8583
84+ #[short(type="conomType")]
8685HB.structure Definition ConomialDef :=
8786 { V of MonomialDef V & MonomialDef_isConomialDef V }.
8887
89- Module ConomialDefExports.
9088Bind Scope monom_scope with ConomialDef.sort.
91- Notation conomType := ConomialDef.type.
92- End ConomialDefExports.
93- Export ConomialDefExports.
89+ Bind Scope type_scope with conomType.
90+
91+ (* -------------------------------------------------------------------- *)
92+ Section ProdMonom.
93+
94+ Context (K1 K2 : monomType).
95+
96+ Let one : K1 * K2 := (1, 1)%M.
97+ Let mul (m1 m2 : K1 * K2) := (m1.1 * m2.1, m1.2 * m2.2)%M.
98+
99+ Fact mulpA : associative mul.
100+ Proof . by move=> ? ? ?; rewrite /mul !mulmA. Qed .
101+
102+ Fact mul1p : left_id one mul.
103+ Proof . by move=> [? ?]; rewrite /mul !mul1m. Qed .
104+
105+ Fact mulp1 : right_id one mul.
106+ Proof . by move=> [? ?]; rewrite /mul !mulm1. Qed .
107+
108+ Fact unitp m1 m2 : mul m1 m2 = one -> m1 = one /\ m2 = one.
109+ Proof . by case: m1 m2 => [? ?] [? ?] [/unitm[-> ->] /unitm[-> ->]]. Qed .
110+
111+ HB.instance Definition _ :=
112+ Choice_isMonomialDef.Build (K1 * K2)%type mulpA mul1p mulp1 unitp.
113+
114+ End ProdMonom.
115+
116+ (* -------------------------------------------------------------------- *)
117+ Section ProdConom.
118+
119+ Context (K1 K2 : conomType).
120+
121+ Fact mulpC : @commutative (K1 * K2) _ mul.
122+ Proof . move=> ? ?; congr pair; apply: mulmC. Qed .
123+
124+ HB.instance Definition _ :=
125+ MonomialDef_isConomialDef.Build (K1 * K2)%type mulpC.
126+
127+ End ProdConom.
94128
95129(* -------------------------------------------------------------------- *)
96130Section Monomial.
@@ -170,7 +204,7 @@ HB.instance Definition _ := [Choice of malg by <:].
170204
171205End MalgDef.
172206
173- (* -------------------------------------------------------------------- *)
207+ Arguments malg K%_type_scope G%_type_scope.
174208Bind Scope ring_scope with malg.
175209
176210Notation "{ 'malg' G [ K ] }" := (@malg K G) : type_scope.
@@ -369,8 +403,104 @@ apply/fsubsetP=> k; rewrite -!mcoeff_neq0 mcoeffMn.
369403by apply/contra_neq => ->; rewrite mul0rn.
370404Qed .
371405
406+ Lemma msupp_eq0 (g : {malg G[K]}) : (msupp g == fset0) = (g == 0).
407+ Proof .
408+ apply/eqP/eqP=> [/fsetP z_g|->]; last exact: msupp0.
409+ by apply/malgP=> i; rewrite mcoeff0 mcoeff_outdom // z_g.
410+ Qed .
411+
372412End MalgNmodTheory.
373413
414+ (* -------------------------------------------------------------------- *)
415+ Section MalgProdNmodTheory.
416+
417+ Context {K1 K2 : choiceType} {G : nmodType}.
418+
419+ Definition mcurry (g : {malg G[K1 * K2]}) : {malg {malg G[K2]}[K1]} :=
420+ \sum_(k <- msupp g) << << g@_k *g k.2 >> *g k.1 >>.
421+
422+ Definition muncurry (g : {malg {malg G[K2]}[K1]}) : {malg G[K1 * K2]} :=
423+ \sum_(x <- msupp g) \sum_(y <- msupp g@_x) << g@_x@_y *g (x, y) >>.
424+
425+ Lemma mcurryE (g : {malg G[K1 * K2]}) (k1 : K1) (k2 : K2) :
426+ (mcurry g)@_k1@_k2 = g@_(k1, k2).
427+ Proof .
428+ rewrite !raddf_sum/=; case: msuppP => kg; last first.
429+ apply: big1_fset => /= -[k1' k2'] kg' _; rewrite mcoeffU raddfMn/= mcoeffU.
430+ by move: kg' kg; do 2 case: eqP; move=> // -> -> ->.
431+ rewrite (big_fsetD1 _ kg)/= !mcoeffUU big1_fset ?addr0// => k.
432+ rewrite in_fsetD1 negb_and/= => /andP[+ _] _.
433+ by rewrite mcoeffU raddfMn/= mcoeffU; do 2 case: eqP.
434+ Qed .
435+
436+ Lemma msupp_curryl (g : {malg G[K1 * K2]}) : msupp (mcurry g) = fst @` msupp g.
437+ Proof .
438+ apply/fsetP => k1; rewrite -mcoeff_neq0 -msupp_eq0; apply/fset0Pn/idP.
439+ case=> k2; rewrite -mcoeff_neq0 mcurryE mcoeff_neq0 => kg.
440+ by apply/imfsetP; exists (k1, k2).
441+ move/imfsetP => [[_ k2]/= /[swap] <-] kg; exists k2.
442+ by rewrite -mcoeff_neq0 mcurryE mcoeff_neq0.
443+ Qed .
444+
445+ Lemma msupp_curryr (g : {malg G[K1 * K2]}) (k1 : K1) :
446+ msupp (mcurry g)@_k1 = [fset k.2 | k in msupp g & k.1 == k1].
447+ Proof .
448+ apply/fsetP => k2; rewrite -mcoeff_neq0 mcurryE.
449+ apply/idP/imfsetP => /=[gk_neq0|[[k1' k2']/=]].
450+ by exists (k1, k2); rewrite // inE /= -mcoeff_neq0 gk_neq0 eqxx.
451+ by rewrite inE -mcoeff_neq0 => /= /andP[+ /eqP <-] ->.
452+ Qed .
453+
454+ Lemma muncurryE (g : {malg {malg G[K2]}[K1]}) (k : K1 * K2) :
455+ (muncurry g)@_k = g@_k.1@_k.2.
456+ Proof .
457+ rewrite raddf_sum/=; under eq_bigr => x _.
458+ rewrite raddf_sum/=; under eq_bigr => y _ do rewrite mcoeffU /eq_op/=.
459+ over.
460+ case: (msuppP g) => k1g; last first.
461+ rewrite raddf0; apply: big1_fset => x xg _.
462+ by apply: big1_fset => y _ _; case: eqP xg k1g => //= -> ->.
463+ rewrite (big_fsetD1 _ k1g)/= [s in _ + s]big1_fset; last first.
464+ move=> k1; rewrite !inE => /andP[k1neq _] _.
465+ by apply: big1_fset => k2 _ _; rewrite (negPf k1neq).
466+ rewrite eqxx/= addr0; case: (msuppP g@_k.1) => k2g; last first.
467+ by apply: big1_fset=> y yg _; case: eqP yg k2g => // -> ->.
468+ rewrite (big_fsetD1 _ k2g)/= eqxx/= big1_fset ?addr0 //.
469+ by move=> k2; rewrite !inE => /andP[] /negPf->.
470+ Qed .
471+
472+ Lemma mcurryK : cancel mcurry muncurry.
473+ Proof . by move=> g; apply/malgP => -[k1 k2]; rewrite muncurryE mcurryE. Qed .
474+
475+ Lemma muncurryK : cancel muncurry mcurry.
476+ Proof .
477+ by move=> g; apply/malgP => k1; apply/malgP => k2; rewrite mcurryE muncurryE.
478+ Qed .
479+
480+ Fact mcurry_is_semi_additive : semi_additive mcurry.
481+ Proof .
482+ split => [|g1 g2]; apply/malgP => k1; apply/malgP => k2.
483+ by rewrite mcurryE !mcoeff0.
484+ by rewrite !(mcurryE, mcoeffD).
485+ Qed .
486+
487+ HB.instance Definition _ :=
488+ GRing.isSemiAdditive.Build {malg G[K1 * K2]} {malg {malg G[K2]}[K1]} mcurry
489+ mcurry_is_semi_additive.
490+
491+ Fact muncurry_is_semi_additive : semi_additive muncurry.
492+ Proof .
493+ split => [|g1 g2]; apply/malgP => k.
494+ by rewrite muncurryE !mcoeff0.
495+ by rewrite !(muncurryE, mcoeffD).
496+ Qed .
497+
498+ HB.instance Definition _ :=
499+ GRing.isSemiAdditive.Build {malg {malg G[K2]}[K1]} {malg G[K1 * K2]} muncurry
500+ muncurry_is_semi_additive.
501+
502+ End MalgProdNmodTheory.
503+
374504(* -------------------------------------------------------------------- *)
375505Section MalgZmodTheory.
376506
@@ -522,12 +652,6 @@ Proof. exact: can_inj malgCK. Qed.
522652Lemma malgC_eq (c1 c2 : G) : (c1%:MP == c2%:MP :> {malg G[K]}) = (c1 == c2).
523653Proof . by apply/eqP/eqP => [/malgC_inj|->//]. Qed .
524654
525- Lemma msupp_eq0 (g : {malg G[K]}) : (msupp g == fset0) = (g == 0).
526- Proof .
527- apply/eqP/eqP=> [/fsetP z_g|->]; last exact: msupp0.
528- by apply/malgP=> i; rewrite mcoeff0 mcoeff_outdom // z_g.
529- Qed .
530-
531655End MalgMonomTheory.
532656
533657(* -------------------------------------------------------------------- *)
@@ -785,6 +909,46 @@ HB.instance Definition _ :=
785909
786910End MalgSemiRingTheory.
787911
912+ (* -------------------------------------------------------------------- *)
913+ Section MalgProdMonomSemiRingTheory.
914+
915+ Context {K1 K2 : monomType} {G : pzSemiRingType}.
916+
917+ Fact mcurry_is_multiplicative : multiplicative (@mcurry K1 K2 G).
918+ Proof .
919+ split => /=[g1 g2|]; apply/malgP => k1; apply/malgP => k2; last first.
920+ rewrite mcurryE !mcoeff1 -pair_eqE/=.
921+ by case: eqP => //=; rewrite (mcoeff1, mcoeff0).
922+ rewrite mcurryE !mcoeffMl raddf_sum/=.
923+ rewrite (partition_big_imfset _ fst)/= msupp_curryl; apply/eq_bigr => k1l _.
924+ rewrite exchange_big (partition_big_imfset _ fst) raddf_sum msupp_curryl/=.
925+ apply/eq_bigr => k1r _; rewrite exchange_big raddfMn/= mcoeffMl -sumrMnl.
926+ rewrite (* SLOW *)msupp_curryr big_imfset/=; last first.
927+ by move=> [? ?] [? ?] /andP[/= _ /eqP ->] /andP[/= _ /eqP ->] ->.
928+ rewrite big_filter; apply/eq_bigr => -[_ k2l]/= /eqP ->.
929+ rewrite -sumrMnl msupp_curryr big_imfset/=; last first.
930+ by move=> [? ?] [? ?] /andP[/= _ /eqP ->] /andP[/= _ /eqP ->] ->.
931+ rewrite big_filter; apply/eq_bigr => -[_ k2r]/= /eqP ->.
932+ by rewrite !mcurryE -mulrnA mulnb andbC.
933+ Qed .
934+
935+ HB.instance Definition _ :=
936+ GRing.isMultiplicative.Build {malg G[K1 * K2]} {malg {malg G[K2]}[K1]}
937+ (@mcurry K1 K2 G) mcurry_is_multiplicative.
938+
939+ Fact muncurry_is_multiplicative : multiplicative (@muncurry K1 K2 G).
940+ Proof .
941+ split => /=[g1 g2|]; apply/eqP; rewrite (can2_eq muncurryK mcurryK); apply/eqP.
942+ by rewrite rmorphM/= !muncurryK.
943+ by rewrite rmorph1.
944+ Qed .
945+
946+ HB.instance Definition _ :=
947+ GRing.isMultiplicative.Build {malg {malg G[K2]}[K1]} {malg G[K1 * K2]}
948+ (@muncurry K1 K2 G) muncurry_is_multiplicative.
949+
950+ End MalgProdMonomSemiRingTheory.
951+
788952(* -------------------------------------------------------------------- *)
789953Section MalgNzSemiRingTheory.
790954
0 commit comments