Library SSProve.Relational.EnrichedSetting

From Coq Require Import ssreflect ssrfun.
From SSProve.Mon Require Export Base.
From Coq.Classes Require Import RelationClasses Morphisms.
From SSProve.Relational Require Import Category.

Set Primitive Projections.
Set Universe Polymorphism.

(* This file introduces a notion of relative monad enriched over a cartesian closed category *)
(* This development is not used yet in the POC framework *)

Section CartesianCategory.
  Reserved Notation "A ⨰ B" (at level 65).
  Reserved Notation "⟪ f | g ⟫" (at level 50).

  Program Definition functor_const {C D : category} (X : D) : functor C D :=
    mkFunctor (fun X) (fun _ _ fId X) _ _ _.
  Next Obligation. cbv ; auto with relations. Qed.
  Next Obligation. reflexivity. Qed.
  Next Obligation. rewrite cat_law1 ; reflexivity. Qed.

  Cumulative Record cartesian_category : Type :=
    mkCartesianCategory
      { cc_cat :> category
      ; cc_one : cc_cat
      ; cc_into_one : natTrans (functor_id cc_cat) (functor_const cc_one)
      ; cc_prod : functor (prod_cat cc_cat cc_cat) cc_cat
        where "A ⨰ B" := (cc_prod A,B)
      ; cc_projl : natTrans cc_prod (left_proj_functor _ _)
      ; cc_projr : natTrans cc_prod (right_proj_functor _ _)
      ; cc_prod_into : {X A B},
          cc_catX;A cc_catX;B cc_catX; AB
        where "⟪ f | g ⟫" := (cc_prod_into f g)
      ; cc_prod_into_proper : {X A B},
          Proper (@sim cc_cat X A ==> @sim _ X B ==> @sim _ X (A B)) cc_prod_into
      ; cc_law1 : {X} (f : cc_catX;cc_one), f cc_into_one X
      ; cc_law2 : {X A B} (f :cc_catX;A) (g:cc_catX;B),
          cc_projl A,B f|g f
      ; cc_law3 : {X A B} (f :cc_catX;A) (g:cc_catX;B),
          cc_projr A,B f|g g
      ; cc_law4 : {X A B} (h : cc_catX;AB), h cc_projl _h|cc_projr _ h
      }.

  Global Existing Instance cc_prod_into_proper.
End CartesianCategory.

Notation "A ⨰ B" := (cc_prod _ A, B) (at level 65).
Notation "⟪ f | g ⟫" := (cc_prod_into _ f g) (at level 50).

Definition projl {C : cartesian_category} {A B : C} : CAB;A :=
  cc_projl C A,B.
Definition projr {C : cartesian_category} {A B : C} : CAB;B :=
  cc_projr C A,B.
Definition morphism_prod {C : cartesian_category} {A1 B1 A2 B2 : C}
           (f:CA1;B1) (g:CA2;B2) : CA1A2;B1B2 :=
  fprojl|gprojr.

Notation "f ⨰r g" := (@morphism_prod _ _ _ _ _ f g) (at level 65).
Notation "!1" := (cc_into_one _ _).

Section EnrichedCat.
  Context {C : cartesian_category}.
  Reserved Notation "⟦ X ; Y ⟧".

  Definition assoc (X Y Z: C) : CX (Y Z); (X Y) Z :=
     projl|projl projr | projr projr .

  Record enriched_cat :=
    mkEnrichedCat
    { ec_Obj :> Type
    ; ec_Hom : ec_Obj ec_Obj C
      where "⟦ X ; Y ⟧" := (ec_Hom X Y)
    ; ec_id : A, Ccc_one _;A;A
    ; ec_comp : {X Y Z}, CY;ZX;Y;X;Z
    ; ec_law1 : {A B}, ec_comp Id _|ec_id _ !1 Id A;B
    ; ec_law2 : {A B}, ec_comp ec_id _ !1|Id _ Id A;B
    ; ec_law3 : {X Y Z W},
        ec_comp (Id _ r ec_comp)
                ec_comp (ec_comp r Id _) assoc Z;W Y;Z X;Y
    }.

End EnrichedCat.

Arguments enriched_cat : clear implicits.
Notation "D ⟦ X ; Y ⟧" := (ec_Hom D X Y) (at level 50).

Section EnrichedFunctor.
  Context {C:cartesian_category} {D E : enriched_cat C}.

  Cumulative Record enriched_functor : Type :=
    mkEnrichedFunctor
      { ef_mapObj :> D E
      ; ef_map : {A B}, C DA;B ; Eef_mapObj A;ef_mapObj B
      ; functor_law1 : A, ef_map ec_id D A ec_id E _
      ; functor_law2 : {X Y Z},
          ef_map @ec_comp _ D X Y Z ec_comp E (ef_map r ef_map)
      }.
End EnrichedFunctor.

Arguments enriched_functor {_} _ _.

Section EnrichedRelativeMonad.
  Context {C} {D E:enriched_cat C} (J : enriched_functor D E).

  Cumulative Record enrichedRelativeMonad : Type :=
    mkEnrichedRMon
      { ermonObj :> D E
      ; ermon_ret : A, Ccc_one _;EJ A; ermonObj A
      ; ermon_bind : {A B}, CEJ A; ermonObj B ; EermonObj A; ermonObj B
      ; ermon_law1 : {A},
          ermon_bind ermon_ret A ec_id E _
      ; ermon_law2 : {A B},
          ec_comp E ermon_bind|ermon_ret A !1 Id (EJ A; ermonObj B)
      ; ermon_law3 : {A B C},
          ec_comp E (@ermon_bind B C r @ermon_bind A B)
                  ermon_bind ec_comp E (ermon_bind r Id _)
      }.
End EnrichedRelativeMonad.