From Coq Require Import FunctionalExtensionality ProofIrrelevance. From mathcomp Require Import all_ssreflect ssralg. Require Import isomorphism. Open Scope R. Import GRing.Theory. Section WeilAlgebras. Variables (R : comRingType). Record WeilData : Type := { Domain : finType; Mul : {ffun Domain -> R^o} -> {ffun Domain -> R^o} -> {ffun Domain -> R^o}; Lin : forall a, linear (Mul a); Assoc : associative Mul; Comm : commutative Mul; Nilpotent : exists T : finType, forall (x : {ffun Domain -> R}) (xs : T -> {ffun Domain -> R}), \big[Mul/x]_(i : T) (xs i) = 0 }. Section WeilImpls. Variables (W : WeilData). Definition weil : Type := R * {ffun (Domain W) -> R^o}. Definition wrap (w : R * {ffun Domain W -> R}) : weil := w. Definition unwrap (w : weil) : R * {ffun Domain W -> R} := w. Lemma wrap_unwrap : cancel wrap unwrap. move=> w. by rewrite /wrap /unwrap. Qed. Canonical weil_eq : eqType := EqType weil (CanEqMixin wrap_unwrap). Canonical weil_choice : choiceType := ChoiceType weil (CanChoiceMixin wrap_unwrap). Canonical weil_zmodType : zmodType := ZmodType weil (ZmodMixin (@addrA _) (@addrC _) (@add0r _) (@addNr _)). Definition weil_mul (x y : weil) : weil := ( fst x * fst y , fst x *: snd y + fst y *: snd x + Mul W (snd x) (snd y) ). Definition weil_one : weil := ( 1 , [ffun=> 0]). Fact weil_mulA : associative weil_mul. Admitted. Fact weil_mulC : commutative weil_mul. Admitted. Fact weil_mul_1l : left_id weil_one weil_mul. Admitted. Fact weil_mul_1r : right_id weil_one weil_mul. Admitted. Fact weil_mul_addl : left_distributive weil_mul +%R. Admitted. Fact weil_mul_addr : right_distributive weil_mul +%R. Admitted. Fact weil1_nonzero : weil_one != 0. Admitted. Canonical weil_ringType : ringType := RingType weil (RingMixin weil_mulA weil_mul_1l weil_mul_1r weil_mul_addl weil_mul_addr weil1_nonzero). Canonical weil_comRingType : comRingType := ComRingType weil weil_mulC. Definition weil_scale (k : R) (w : weil) : weil := (k * fst w, [ffun a => k *: snd w a]). Fact weil_scaleA k1 k2 f : weil_scale k1 (weil_scale k2 f) = weil_scale (k1 * k2) f. Admitted. Fact weil_scale1 : left_id 1 weil_scale. Admitted. Fact weil_scale_addr k : {morph (weil_scale k) : x y / x + y}. Admitted. Fact weil_scale_addl u : {morph (weil_scale)^~ u : k1 k2 / k1 + k2}. Admitted. Canonical weil_lmodType : lmodType R := LmodType R weil (LmodMixin weil_scaleA weil_scale1 weil_scale_addr weil_scale_addl). Fact weil_scaleAl (a : R) (u v : weil) : a *: (u * v) = (a *: u) * v. Admitted. Fact weil_scaleAr (a : R) (u v : weil) : a *: (u * v) = u * (a *: v). Admitted. Canonical weil_lalgType : lalgType R := LalgType R weil weil_scaleAl. Canonical weil_algType : algType R := AlgType R weil weil_scaleAr. Canonical weil_comAlgType : comAlgType R := [comAlgType R of weil]. End WeilImpls. End WeilAlgebras. Definition Weil {R} W := weil_comAlgType R W. Definition WeilMorph {R} (W : WeilData R) (A : algType R) : Type := {f : {ffun (Domain R W) -> A} | {morph (fun (x : {ffun _ -> R^o}) => \sum_(i : Domain R W) (x i *: f i)) : x y / Mul R W x y >-> x * y }}. Module Export IsoImpl. (* The proofs below are a mess, but they work. *) Section reify. Context {R} {W : WeilData R} {A : algType R} (m : WeilMorph W A). Definition reify : Weil W -> A := let '(exist dom_f morph) := m in fun '(x, dx) => x%:A + (\sum_i dx i *: dom_f i). Fact reify_is_additive : additive reify. Proof. rewrite /reify; move: m => [dom_f morph]. move=> [x dx] [y dy]. simpl. rewrite scalerDl -addrA -addrA; f_equal. rewrite opprD addrA [_ - y%:A]addrC -addrA scaleNr; f_equal. rewrite -sumrB. apply: eq_bigr => i _. rewrite -scaleNr -scalerDl; f_equal. by rewrite {1}/+%R {1}/-%R; simpl; rewrite /ffun_add /ffun_opp ffunE ffunE. Qed. Canonical reify_additive := Additive reify_is_additive. Fact reify_is_multiplicative : multiplicative reify. Proof. rewrite /reify; move: m => [dom_f morph]. split. - move=> [x dx] [y dy]. simpl. rewrite mulrDr mulrDl mulrDl. rewrite -morph. rewrite -[x%:A*_+_+_]addrA -scalerAl -scalerAr scalerA mulr1; f_equal. rewrite mulr_suml mulr_sumr -big_split -big_split; simpl. apply: eq_bigr => i _. rewrite -scalerAr mulr1 scalerA. rewrite -scalerAl mul1r scalerA. rewrite -scalerDl -scalerDl addrA; f_equal. rewrite {1 2}/+%R {1 2}/*:%R; simpl; rewrite /ffun_add /ffun_scale. do 4 rewrite ffunE; f_equal. by rewrite addrC /*:%R; simpl. - simpl. rewrite big1. + by rewrite addr0 scale1r. + by move=> i _; rewrite ffunE scale0r. Qed. Canonical reify_multiplicative := AddRMorphism reify_is_multiplicative. Fact reify_is_scalable : scalable reify. Proof. rewrite /reify; move: m => [dom_f morph]. move=> k [x dx]. simpl. rewrite scalerDr scalerA; f_equal. rewrite scaler_sumr. apply: eq_bigr => i _. by rewrite ffunE scalerA. Qed. Canonical reify_linear := AddLinear reify_is_scalable. Definition LR_of_WeilMorph : {lrmorphism (Weil W) -> A} := [lrmorphism of reify]. End reify. Definition unreify {R} {W : WeilData R} {A : algType R} (f : {lrmorphism (Weil W) -> A}) : {ffun Domain R W -> A} := [ffun i => f (0, [ffun j => if i == j then 1 else 0])]. Lemma unreify_morph {R} {W : WeilData R} {A : algType R} (f : {lrmorphism (Weil W) -> A}) : { morph (fun x : {ffun Domain R W -> R^o} => \sum_i x i *: (unreify f) i) : x y / Mul R W x y >-> x * y }. Proof. move=> x y. have: forall (g : Domain R W -> R^o), (\sum_i g i *: (unreify f) i) = f (0, [ffun i => g i]). { move=> g. have: \sum_i g i *: (unreify f) i = \sum_i f (0, [ffun j => if i == j then g i else 0]). { apply: eq_bigr => i _. rewrite /(unreify f) ffunE -linearZ_LR. rewrite /*:%R; simpl; rewrite /weil_scale; simpl. rewrite mulr0; f_equal; f_equal. apply: eq_ffun => j. rewrite ffunE. case: (i == j). + by rewrite /*:%R; simpl; rewrite mulr1. + by rewrite scaler0. } move=>->. rewrite -linear_sum. apply: f_equal. have: \sum_i (0, [ffun j => if i == j then g i else 0]) = (0, \sum_i [ffun j => if i == j then g i else 0]). { move=> t. elim/big_rec2 : _ => // [i da [b db] _ ->]. rewrite /+%R; simpl; rewrite /add_pair /ffun_add; simpl. rewrite addr0. done. } move=>->. f_equal. rewrite -ffunP => i. rewrite ffunE sum_ffunE. have: \sum_k [ffun j => if k == j then g k else 0] i = \sum_k if k == i then g k else 0 by apply: eq_bigr => k _; rewrite ffunE. move=>->. rewrite -big_mkcond; simpl. by rewrite big_pred1_eq. } move=> lemma; rewrite lemma lemma lemma; clear lemma. rewrite -rmorphM. rewrite /*%R; simpl; rewrite /weil_mul; simpl. rewrite mul0r scale0r scale0r add0r add0r. f_equal; f_equal. have: forall (g : {ffun Domain R W -> R^o}), [ffun i => g i] = g. { move=> g. apply ffunP => i. by rewrite ffunE. } by move=> lemma; rewrite lemma lemma lemma; clear lemma. Qed. Definition WeilMorph_of_LR {R} {W : WeilData R} {A : algType R} (f : {lrmorphism (Weil W) -> A}) : WeilMorph W A := exist _ (unreify f) (unreify_morph f). Theorem LR_W_LR {R} {W : WeilData R} {A : algType R} : cancel WeilMorph_of_LR (@LR_of_WeilMorph R W A). move=> m. have: forall w, LR_of_WeilMorph (WeilMorph_of_LR m) w = m w. { move=> [x dx]. simpl. rewrite /unreify. have: \sum_i dx i *: [ffun i0 => m (0, [ffun j => if i0 == j then 1 else 0])] i = \sum_i m (0, dx i *: [ffun j => if i == j then 1 else 0]). { apply: eq_bigr => i _; rewrite ffunE -linearZ_LR. rewrite {3}/*:%R; simpl; rewrite /weil_scale; simpl. rewrite mulr0. f_equal; f_equal. } move=>->. rewrite -linear_sum. have: \sum_i (0, dx i *: [ffun j => if i == j then 1 : R^o else 0]) = (0, \sum_i dx i *: [ffun j => if i == j then 1 : R^o else 0]). { move=> t. elim/big_rec2 : _ => // [i da [b db] _ ->]. rewrite /+%R; simpl; rewrite /add_pair /ffun_add; simpl. rewrite addr0. done. } move=>->. have: x%:A = m (x%:A) by rewrite linearZ_LR rmorph1. move=>->. rewrite -linearD. rewrite {3}/*:%R; simpl; rewrite /weil_scale; simpl. apply: f_equal. rewrite pair_equal_spec; split; simpl. - by rewrite addr0 mulr1. - rewrite -ffunP => i. rewrite ffunE ffunE ffunE. rewrite scaler0 add0r sum_ffunE. have: \sum_k (dx k *: [ffun j => if k == j then 1 : R^o else 0]) i = \sum_k (if k == i then dx k else 0). { apply: eq_bigr => k _. rewrite /*:%R; simpl; rewrite /ffun_scale ffunE ffunE. rewrite /*:%R; simpl. case: (k == i). - by rewrite mulr1. - by rewrite mulr0. } move=>->. rewrite -big_mkcond; simpl. by rewrite big_pred1_eq. } move /functional_extensionality. case: (LR_of_WeilMorph (WeilMorph_of_LR m)) => f1 pf1. case: m => f2 pf2. simpl. move=> eq; move: eq pf1 pf2 => -> pf1 pf2. by move: (proof_irrelevance _ pf1 pf2) => ->. Qed. Theorem W_LR_W {R} {W : WeilData R} {A : algType R} : cancel (@LR_of_WeilMorph R W A) WeilMorph_of_LR. move=> [dom_f morph]. apply: eq_sig; simpl. { rewrite /unreify; simpl. rewrite -ffunP => i. rewrite ffunE. rewrite scale0r add0r . have: \sum_k [ffun j => if i == j then 1 else 0] k *: dom_f k = \sum_k if k == i then dom_f k else 0. { apply: eq_bigr => k _. rewrite ffunE. rewrite eq_sym. case: (k == i). - by rewrite scale1r. - by rewrite scale0r. } move=>->. rewrite -big_mkcond; simpl. by rewrite big_pred1_eq. } move=> H. apply proof_irrelevance. Qed. Definition reifyIso {R} {W : WeilData R} {A : algType R} : WeilMorph W A <--> {lrmorphism Weil W -> A} := {| Forward := LR_of_WeilMorph; Backward := WeilMorph_of_LR; BF := W_LR_W; FB := LR_W_LR; |}. End IsoImpl.