Library CatSem.CAT.rmonad
Require Export CatSem.CAT.functor.
Require Export CatSem.CAT.NT.
Require Export CatSem.CAT.product.
Require Export CatSem.CAT.initial_terminal.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Transparent Obligations.
Unset Automatic Introduction.
Section rmonad_def.
Variables obC obD : Type.
Variable morC : obC -> obC -> Type.
Variable morD : obD -> obD -> Type.
Variable C : Cat_struct morC.
Variable D : Cat_struct morD.
Variable F : Functor C D.
Class RMonad_struct (T : obC -> obD) := {
rweta: forall c: obC, morD (F c) (T c);
rkleisli: forall a b: obC, morD (F a) (T b) -> morD (T a) (T b);
rkleisli_oid:> forall a b,
Proper (equiv ==> equiv) (rkleisli (a:=a) (b:=b));
reta_kl : forall a b: obC, forall f : morD (F a) (T b),
rweta a ;; rkleisli f == f;
rkl_eta : forall a, rkleisli (rweta a) == id _;
rdist: forall a b c (f:morD (F a) (T b)) (g: morD (F b) (T c)),
rkleisli f ;; rkleisli g == rkleisli (f ;; rkleisli g)
}.
Record RMonad := {
FR :> obC -> obD ;
rmonad_struct :> RMonad_struct FR
}.
Existing Instance rmonad_struct.
Section trivial_lemmata.
Variable FF : obC -> obD.
Variable FM : RMonad_struct FF.
Lemma rkl_eq a b (f g : morD (F a) (FF b)) :
f == g -> rkleisli f == rkleisli g.
Proof.
intros a b f g H;
apply (rkleisli_oid H).
Qed.
Lemma retakl a b (f:morD (F a) (FF b)) : rweta a ;; rkleisli f == f.
Proof.
intros;
apply FM.
Qed.
Lemma rkleta a : rkleisli (rweta a) == id _ .
Proof.
intros;
apply FM.
Qed.
Lemma rkleta_eq a f : f == rweta a -> rkleisli f == id _ .
Proof.
intros a f H.
rewrite H.
apply rkleta.
Qed.
Lemma rklkl a b c (f:morD (F a) (FF b)) (g: morD (F b) (FF c)) :
rkleisli f ;; rkleisli g == rkleisli (f ;; rkleisli g).
Proof.
intros;
apply FM.
Qed.
End trivial_lemmata.
Hint Rewrite retakl rkleta rklkl : rmonad.
Hint Rewrite assoc idl idr FId FComp : rmonad.
Hint Resolve idl idr hom_refl hom_sym : rmonad.
Ltac rmonad := intros; autorewrite with rmonad; auto with rmonad.
Require Export CatSem.CAT.NT.
Require Export CatSem.CAT.product.
Require Export CatSem.CAT.initial_terminal.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Transparent Obligations.
Unset Automatic Introduction.
Section rmonad_def.
Variables obC obD : Type.
Variable morC : obC -> obC -> Type.
Variable morD : obD -> obD -> Type.
Variable C : Cat_struct morC.
Variable D : Cat_struct morD.
Variable F : Functor C D.
Class RMonad_struct (T : obC -> obD) := {
rweta: forall c: obC, morD (F c) (T c);
rkleisli: forall a b: obC, morD (F a) (T b) -> morD (T a) (T b);
rkleisli_oid:> forall a b,
Proper (equiv ==> equiv) (rkleisli (a:=a) (b:=b));
reta_kl : forall a b: obC, forall f : morD (F a) (T b),
rweta a ;; rkleisli f == f;
rkl_eta : forall a, rkleisli (rweta a) == id _;
rdist: forall a b c (f:morD (F a) (T b)) (g: morD (F b) (T c)),
rkleisli f ;; rkleisli g == rkleisli (f ;; rkleisli g)
}.
Record RMonad := {
FR :> obC -> obD ;
rmonad_struct :> RMonad_struct FR
}.
Existing Instance rmonad_struct.
Section trivial_lemmata.
Variable FF : obC -> obD.
Variable FM : RMonad_struct FF.
Lemma rkl_eq a b (f g : morD (F a) (FF b)) :
f == g -> rkleisli f == rkleisli g.
Proof.
intros a b f g H;
apply (rkleisli_oid H).
Qed.
Lemma retakl a b (f:morD (F a) (FF b)) : rweta a ;; rkleisli f == f.
Proof.
intros;
apply FM.
Qed.
Lemma rkleta a : rkleisli (rweta a) == id _ .
Proof.
intros;
apply FM.
Qed.
Lemma rkleta_eq a f : f == rweta a -> rkleisli f == id _ .
Proof.
intros a f H.
rewrite H.
apply rkleta.
Qed.
Lemma rklkl a b c (f:morD (F a) (FF b)) (g: morD (F b) (FF c)) :
rkleisli f ;; rkleisli g == rkleisli (f ;; rkleisli g).
Proof.
intros;
apply FM.
Qed.
End trivial_lemmata.
Hint Rewrite retakl rkleta rklkl : rmonad.
Hint Rewrite assoc idl idr FId FComp : rmonad.
Hint Resolve idl idr hom_refl hom_sym : rmonad.
Ltac rmonad := intros; autorewrite with rmonad; auto with rmonad.
- definition of join, lift
- fusion laws
Section Defs_and_Facts.
Variable M : RMonad.
Definition rlift : forall a b (f: morC a b), morD (M a) (M b) :=
fun a b f => rkleisli (#F f ;; rweta b).
Lemma rlift_eq a b (f g : morC a b) : f == g -> rlift f == rlift g.
Proof.
intros a b f g H.
unfold rlift.
rewrite H.
cat.
Qed.
Instance rlift_oid a b : Proper (equiv ==> equiv) (rlift (a:=a) (b:=b)).
Proof.
unfold rlift,Proper;
red.
apply rlift_eq.
Qed.
Lemma rlift_id c :
rlift (id c) == id (M c).
Proof.
unfold rlift; rmonad.
Qed.
Lemma rlift_eq_id a g : g == id a -> rlift g == id (M a).
Proof.
intros a g H.
rewrite H.
apply rlift_id.
Qed.
Lemma rlift_rweta c d (f:morC c d) :
rweta _ ;; rlift f == #F f ;; rweta _ .
Proof.
unfold rlift;
rmonad.
Qed.
Lemma rlift_rlift c d e (f:morC c d) (g:morC d e) :
rlift f ;; rlift g == rlift (f ;; g).
Proof.
unfold rlift;
rmonad.
Qed.
Lemma rlift_rkleisli c d e (f:morC c d) (g: morD (F d) (M e)) :
rlift f ;; rkleisli g == rkleisli (#F f ;; g).
Proof.
unfold rlift;
rmonad.
Qed.
Lemma rkleisli_rlift c d e (f:morD (F c) (M d)) (g: morC d e) :
rkleisli f ;; rlift g == rkleisli (f ;; rlift g).
Proof.
unfold rlift;
rmonad.
Qed.
Hint Rewrite rlift_id rlift_rweta rlift_rlift
rlift_rkleisli rkleisli_rlift : rmonad.
Obligation Tactic := rmonad.
Program Instance RMFunc_struct : Functor_struct (Fobj:= M)
(@rlift ).
Canonical Structure RMFunc := Build_Functor RMFunc_struct.
End Defs_and_Facts.
Section RModule.
Variable P : RMonad.
Section RModule_E.
Variable obE : Type.
Variable morE : obE -> obE -> Type.
Variable E : Cat_struct morE.
Class RModule_struct (M : obC -> obE) := {
rmkleisli: forall c d (f:morD (F c) (P d)), morE (M c) (M d);
rmkleisli_oid :> forall c d, Proper (equiv ==> equiv)
(rmkleisli (c:=c)(d:=d));
rmkl_rmkl: forall c d e (f: morD (F c) (P d)) (g:morD (F d) (P e)),
rmkleisli f ;; rmkleisli g == rmkleisli (f ;; rkleisli g);
rmkl_rweta: forall c:obC, rmkleisli (rweta c) == id (M c)
}.
Record RModule := {
rmodule :> obC -> obE ;
rmodule_struct :> RModule_struct rmodule
}.
Existing Instance rmodule_struct.
Hint Rewrite @rmkl_rweta : rmonad.
Hint Rewrite @rmkl_rmkl : rmonad.
Section RModule_Func.
Variable M : RModule.
Lemma rmkl_eq c d (f g : morD (F c) (P d)) : f == g ->
rmkleisli (RModule_struct := M) f == rmkleisli g.
Proof.
intros.
apply (@rmkleisli_oid M).
auto.
Qed.
Lemma rmkleta : forall c:obC, rmkleisli (rweta c) == id (M c).
Proof.
apply rmkl_rweta.
Qed.
Lemma rmkleta_id_eq : forall c:obC, forall f, f == rweta _ ->
rmkleisli f == id (M c).
Proof.
intros; rew_all; apply rmkleta.
Qed.
Lemma rmklmkl : forall c d e
(f: morD (F c) (P d)) (g:morD (F d) (P e)),
rmkleisli (RModule_struct := M) f ;;
rmkleisli g ==
rmkleisli (f ;; rkleisli g).
Proof.
apply rmkl_rmkl.
Qed.
Definition rmlift (c d:obC) (f:morC c d) : morE (M c) (M d) :=
rmkleisli (#F f ;; rweta d ).
Lemma rmlift_eq c d (f g : morC c d) : f == g -> rmlift f == rmlift g.
Proof.
unfold rmlift.
intros c d f g H.
rewrite H.
cat.
Qed.
Instance rmlift_oid c d : Proper (equiv ==> equiv) (@rmlift c d) :=
@rmlift_eq c d.
Obligation Tactic := unfold rmlift; rmonad.
Program Instance RModFunc_struct : Functor_struct (C:=C) (D:=E) (rmlift).
Lemma rmlift_rmkleisli c d e (f: morD (F c) (P d)) (g: morC d e) :
rmkleisli f ;; rmlift g == rmkleisli (f ;; rlift P g).
Proof.
unfold rmlift.
rmonad.
Qed.
Lemma rmkleisli_rmlift c d e (f : morC c d) (g: morD (F d) (P e)) :
rmlift f ;; rmkleisli g == rmkleisli (#F f ;; g).
Proof.
unfold rmlift;
rmonad.
Qed.
Lemma rmlift_rmlift c d e (f: morC c d) (g: morC d e) :
rmlift f ;; rmlift g == rmlift (f ;; g).
Proof.
unfold rmlift;
rmonad.
Qed.
End RModule_Func.
Section RModule_Hom.
Variables M N : RModule.
Class RModule_Hom_struct (sig : forall c : obC, morE (M c) (N c)) := {
rmod_hom_rmkl: forall c d (f: morD (F c) (P d)),
rmkleisli f ;; sig d == sig c ;; rmkleisli f
}.
Record RModule_Hom := {
rmodule_hom:> forall x, morE (M x) (N x);
rmodule_hom_struct :> RModule_Hom_struct rmodule_hom
}.
Existing Instance rmodule_hom_struct.
Section lemmata.
Variable S : RModule_Hom.
Lemma rmhom_rmkl : forall c d (f: morD (F c) (P d)),
rmkleisli f ;; S d == S c ;; rmkleisli f.
Proof.
apply rmod_hom_rmkl.
Qed.
End lemmata.
End RModule_Hom.
Existing Instance rmodule_hom_struct.
Section RMOD_id_comp.
Variable M : RModule.
Obligation Tactic := rmonad.
Program Instance RMOD_id_struct :
RModule_Hom_struct (M:=M) (N:=M) (fun _ => id _ ).
Canonical Structure RMOD_id := Build_RModule_Hom RMOD_id_struct.
Variables N K : RModule.
Variable S : RModule_Hom M N.
Variable T : RModule_Hom N K.
Program Instance RMOD_comp_struct :
RModule_Hom_struct (M:=M) (N:=K) (fun c => S c ;; T c).
Next Obligation.
Proof.
rewrite <- assoc.
rewrite <- assoc.
rewrite (rmod_hom_rmkl);
try apply S.
repeat rewrite assoc.
apply praecomp.
rewrite rmod_hom_rmkl;
try apply T.
cat.
Qed.
Canonical Structure RMOD_comp := Build_RModule_Hom RMOD_comp_struct.
End RMOD_id_comp.
Lemma RMod_eq (A B : RModule) : Equivalence (A:=RModule_Hom A B)
(fun M N => forall c, M c == N c).
Proof.
intros A B.
constructor.
unfold Reflexive.
cat.
unfold Symmetric.
intros.
apply hom_sym.
auto.
unfold Transitive.
intros x y z H H' c.
apply hom_trans with (y c);
auto.
Qed.
Instance RMod_oid A B : Setoid _ := Build_Setoid (RMod_eq A B).
Instance RMod_comp_oid :
forall a b c : RModule, Proper (equiv ==> equiv ==> equiv)
(RMOD_comp (M:=a)(N:=b)(K:=c)).
Proof.
intros R S T.
unfold Proper;
do 2 red.
simpl.
intros x y H x0 y0 H0 t .
rewrite H.
rewrite H0.
cat.
Qed.
Obligation Tactic := simpl; intros; try rewrite assoc; cat.
Program Instance RMOD_struct : Cat_struct RModule_Hom := {
id := RMOD_id ;
comp := RMOD_comp ;
mor_oid := RMod_oid
}.
Canonical Structure RMOD := Build_Cat RMOD_struct.
constant module
Section const_rmod.
Variable e : obE.
Instance const_rmod_oid c c' :
Proper (equiv ==> equiv) (fun _ : morD (F c) (P c') => id e).
Proof.
unfold Proper;
red; cat.
Qed.
Obligation Tactic := try apply const_rmod_oid; cat.
Program Instance Const_RMod_struct :
RModule_struct (fun c => e) := {
rmkleisli a b f := id _
}.
Canonical Structure Const_RMod : RMOD :=
Build_RModule Const_RMod_struct.
End const_rmod.
Section terminal.
Variable T : Terminal E.
Definition RMOD_Term : RMOD := Const_RMod Term.
Hint Resolve TermMorUnique : cat.
Program Instance RMOD_TermMor_struct (A: RMOD) :
RModule_Hom_struct (M:=A) (N:=RMOD_Term)
(fun x => TermMor (A x)) .
Canonical Structure RMOD_TermMor (A: RMOD) : A ---> RMOD_Term :=
Build_RModule_Hom (RMOD_TermMor_struct A).
Program Instance RMOD_Terminal : Terminal (RMOD) := {
Term := RMOD_Term;
TermMor A := RMOD_TermMor A
}.
End terminal.
Existing Instance RMOD_Terminal.
Section product.
Variable EP : Cat_Prod E.
Section product_prep.
Variable M N: RMOD.
Notation "a 'x' b" := (product a b) (at level 30).
Notation "a 'X' b" := (product_mor _ a b) (at level 30).
Program Instance Prod_RMod_struct:
RModule_struct (fun a => M a x N a) := {
rmkleisli c d f := (rmkleisli f) X (rmkleisli f)
}.
Next Obligation.
Proof.
unfold Proper; red.
intros z y HH.
unfold product_mor.
apply prod_mor_oid;
rewrite HH; cat.
Qed.
Next Obligation.
Proof.
rewrite <- product_mor_product_mor.
rmonad.
Qed.
Next Obligation.
Proof.
repeat rewrite rmkl_rweta.
apply product_mor_id.
Qed.
Canonical Structure Prod_RMod : RMOD := Build_RModule Prod_RMod_struct.
Program Instance RMod_prl_struct : RModule_Hom_struct
(M:=Prod_RMod)(N:=M)(fun c => prl _ _ ).
Next Obligation.
Proof.
unfold product_mor.
rewrite prod_prl.
cat.
Qed.
Canonical Structure Mod_prl : Prod_RMod ---> M :=
Build_RModule_Hom RMod_prl_struct.
Program Instance Mod_prr_struct :
RModule_Hom_struct (M:=Prod_RMod)(N:=N)
(fun c => prr _ _ ).
Next Obligation.
Proof.
unfold product_mor.
rewrite prod_prr.
cat.
Qed.
Canonical Structure Mod_prr : Prod_RMod ---> N :=
Build_RModule_Hom Mod_prr_struct.
Section Mod_prod_mor.
Variable K: RMOD.
Variables (S : K ---> M)
(T : K ---> N).
Program Instance Mod_prod_mor_struct : RModule_Hom_struct
(M:=K) (N:=Prod_RMod) (fun c => prod_mor (S c) (T c)).
Next Obligation.
Proof.
rewrite prod_mor_product_mor.
apply prod_mor_unique.
repeat rewrite assoc.
rewrite prod_prl.
rewrite prod_prr.
split;
rmonad; try apply S;
try apply T.
Qed.
Canonical Structure Mod_Prod_mor : K ---> Prod_RMod :=
Build_RModule_Hom Mod_prod_mor_struct.
End Mod_prod_mor.
End product_prep.
Program Instance RMOD_PROD : Cat_Prod (RMOD) := {
product M N := Prod_RMod M N;
prl M N := Mod_prl M N;
prr M N := Mod_prr M N;
prod_mor a c d f g := Mod_Prod_mor f g
}.
Next Obligation.
Proof.
unfold Proper; do 2 red.
unfold Mod_Prod_mor;
simpl.
intros r s H1 r' s' H' t.
rewrite H1.
rewrite H'.
cat.
Qed.
Next Obligation.
Proof.
unfold
Mod_Prod_mor in *;
simpl in *.
cat.
apply prod_mor_unique.
destruct H.
cat.
Qed.
End product.
End RModule_E.
tautological module
Existing Instance rmonad_struct.
Existing Instance rkleisli_oid.
Obligation Tactic := rmonad; try apply rkleisli_oid.
Program Instance Taut_RMod_struct : RModule_struct D (P) := {
rmkleisli := rkleisli
}.
Canonical Structure Taut_RMod := Build_RModule Taut_RMod_struct.
End RModule.
End rmonad_def.
Coercion Taut_RMod : RMonad >-> RModule.
Hint Rewrite retakl rkleta rklkl rmkleta rmklmkl rmhom_rmkl : rmonad.
Hint Rewrite assoc idl idr FId FComp : rmonad.
Hint Resolve idl idr hom_refl hom_sym : rmonad.
Ltac rmonad := simpl in *; intros;
autorewrite with rmonad; auto with rmonad.
Existing Instance rmonad_struct.
Existing Instance rmodule_struct.
Existing Instance rmodule_hom_struct.
Existing Instance RMOD_Terminal.
Existing Instance RMOD_PROD.
Implicit Arguments rmod_hom_rmkl
[obC obD morC C morD D F P obE morE E M N c d sig].