Skip to content

Commit 468a7cc

Browse files
authored
Merge pull request #112 from math-comp/mcurry
Isomorphism between `{malg G[K1 * K2]}` and `{malg {malg G[K2]}[K1]}`
2 parents 60cb527 + 98096ed commit 468a7cc

File tree

1 file changed

+179
-15
lines changed

1 file changed

+179
-15
lines changed

src/monalg.v

Lines changed: 179 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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")]
6465
HB.structure Definition MonomialDef :=
6566
{ V of Choice V & Choice_isMonomialDef V }.
6667

67-
Module MonomialDefExports.
6868
Bind 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
(* -------------------------------------------------------------------- *)
7472
Notation 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")]
8685
HB.structure Definition ConomialDef :=
8786
{ V of MonomialDef V & MonomialDef_isConomialDef V }.
8887

89-
Module ConomialDefExports.
9088
Bind 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
(* -------------------------------------------------------------------- *)
96130
Section Monomial.
@@ -170,7 +204,7 @@ HB.instance Definition _ := [Choice of malg by <:].
170204

171205
End MalgDef.
172206

173-
(* -------------------------------------------------------------------- *)
207+
Arguments malg K%_type_scope G%_type_scope.
174208
Bind Scope ring_scope with malg.
175209

176210
Notation "{ 'malg' G [ K ] }" := (@malg K G) : type_scope.
@@ -369,8 +403,104 @@ apply/fsubsetP=> k; rewrite -!mcoeff_neq0 mcoeffMn.
369403
by apply/contra_neq => ->; rewrite mul0rn.
370404
Qed.
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+
372412
End 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
(* -------------------------------------------------------------------- *)
375505
Section MalgZmodTheory.
376506

@@ -522,12 +652,6 @@ Proof. exact: can_inj malgCK. Qed.
522652
Lemma malgC_eq (c1 c2 : G) : (c1%:MP == c2%:MP :> {malg G[K]}) = (c1 == c2).
523653
Proof. 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-
531655
End MalgMonomTheory.
532656

533657
(* -------------------------------------------------------------------- *)
@@ -785,6 +909,46 @@ HB.instance Definition _ :=
785909

786910
End 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
(* -------------------------------------------------------------------- *)
789953
Section MalgNzSemiRingTheory.
790954

0 commit comments

Comments
 (0)