Library SSProve.Relational.Rel

From Coq Require Import ssreflect ssrfun ssrbool.
From Coq Require FunctionalExtensionality.
From SSProve.Mon Require Export Base.
From Coq Require Import Relation_Definitions Morphisms.
From SSProve.Mon Require Import SPropBase.
From SSProve.Relational Require Import Category RelativeMonads EnrichedSetting.

Set Primitive Projections.
Set Universe Polymorphism.

(* This file defines most components of the relational dependent type theory as embedded in coq *)

Section Rel.
  Notation πl := (fun xnfst (dfst x)).
  Notation πr := (fun xnsnd (dfst x)).
  Notation πw := (fun xdsnd x).
  Notation "⦑ x , y ⦒" := (dpair _ (npair x y) _).
  Notation "⦑ x , y | w ⦒" := (dpair _ (npair x y) w).
  Notation "⦑ x , y | w | Y ⦒" := (dpair (fun pπw Y (nfst p) (nsnd p)) (npair x y) w).

  (* CwF of relations *)

  (* Objects *)
  Definition Rel : Type := { AB : Type × Type nfst AB nsnd AB Type }.
  Definition mkRel (A B : Type) (R : A B Type) : Rel :=
    dpair (fun pnfst p nsnd p Type) A , B R.

  Definition Relw : R:Rel, ( _ _ _) := πw.
  Coercion Relw : Rel >-> Funclass.

  Definition points (X:Rel) : Type := { p : πl X × πr X X (nfst p) (nsnd p)}.
  Notation "⟬ X ⟭" := (points X).

  (* Universes *)
  Definition TyRel : Rel := @mkRel Type Type (fun A BA B Type).

  (* Up to size issues, we have ⟬TyRel⟭ = Rel *)

  Definition ArrRel (X Y : Rel) : Rel :=
     πl X πl Y, πr X πr Y
    | fun fl fr xl xr, X xl xr Y (fl xl) (fr xr) | TyRel .

  Notation "X R=> Y" := (ArrRel X Y) (at level 60).

  Definition arrRel X Y := X R Y.
  Notation "X R==> Y" := (arrRel X Y) (at level 60).

  Program Definition idRel X : X R==> X := id, id.

  Program Definition compRel {X Y Z : Rel}
          (f : X R==> Y) (g : Y R==> Z) : X R==> Z :=
    fun xπl g (πl f x), fun xπr g (πr f x)
    | fun xl xr xwπw g _ _ (πw f xl xr xw).

  (* Defining relational morphisms : *)
  (*      We use a syntactic trick to define relational morphisms *)
  (*      X R==> Y out of plain functions (1 R==> X) -> (1 R==> Y) *)
  (*      such that the value of the function on the left (resp. right) *)
  (*      projection is determined by the value of the argument on its *)
  (*      left (resp. right) projection. *)
  (*    *)
  Notation "[< t | Y >]" :=
    (ltac:(let tl :=
               let t := (eval cbn in (fun x y wπl (t x, y| w))) in
               match t with | fun x y w ⇒ @?P xP end
           in
           let tr :=
               let t := (eval cbn in (fun x y wπr (t x, y| w))) in
               match t with | fun x y w ⇒ @?P yP end
           in
           let tw := eval cbn in (fun x y wπw (t x, y| w)) in
           exact (dpair (fun p xl xr xw, πw Y (nfst p xl) (nsnd p xr)) tl, tr tw)))
    (only parsing).

  Definition Hi A : Rel := A, A | fun a a'True | TyRel .
  Definition Lo A : Rel := A, A | fun a a'a = a' | TyRel .

  (* Families *)
  Definition dRel (r:Rel) := r R TyRel.

  Program Definition applyRel (X Y:Rel) (f :X R==> Y) : X Y :=
    fun xπl f (πl x), πr f (πr x) | πw f (πl x) (πr x) (πw x) | Y.

  Notation "f @R x" := (applyRel f x) (at level 85).

  Definition f : Hi nat R==> (Lo nat R Lo nat) :=
    [< fun (hi : Hi nat) ⇒ [< fun lo : Lo natlo | Lo nat >] | Lo nat R Lo nat >].

  (* Notation "| x | t |" := (ltac:(let t' := constr:(fun x => t) in idtac t' ; exact 0)) (x ident). *)

  (* Notation "λ² x ∈ X | Y → t" := (< constr:(fun x : X t) | Y >) (at level 50, x ident). *)

  (* Definition g := λ² x ∈ Hi nat | Lo nat R=> Lo nat → λ² y ∈ Lo nat | Lo nat → y. *)

  Definition EmptyCtx : Rel := mkRel unit unit (fun _ _unit).
  Definition ConsCtx (Γ : Rel) (X : Rel) :=
    mkRel (πl Γ × πl X) (πr Γ × πr X) (fun γx1 γx2Γ (nfst γx1) (nfst γx2) × X (nsnd γx1) (nsnd γx2)).

  Definition extends (Γ : Rel) (A1 A2 : Type) : Rel :=
    mkRel (πl Γ × A1) (πr Γ × A2) (fun γa1 γa2Γ (nfst γa1) (nfst γa2)).

  Definition extend_point {Γ A1 A2} (γ : Γ) (a1:A1) (a2:A2)
    : extends Γ A1 A2.
  Proof. ⟨⟨πl γ, a1⟩, πr γ, a2⟩⟩. exact: πw γ. Defined.

  Definition mk_point (R : Rel) (xl : πl R) (xr : πr R) (xw : R xl xr) : R :=
    dpair _ xl, xr xw.
End Rel.

Module RelNotations.
  Notation πl := (fun xnfst (dfst x)).
  Notation πr := (fun xnsnd (dfst x)).
  Notation πw := (fun xdsnd x).
  Notation "⦑ x , y ⦒" := (dpair _ (npair x y) _).
  Notation "⦑ x , y | w ⦒" := (dpair _ (npair x y) w).
  Notation "⦑ x , y | w | Y ⦒" := (dpair (fun pπw Y (nfst p) (nsnd p)) (npair x y) w).
  Notation "⟬ X ⟭" := (points X).
  Notation "X R=> Y" := (ArrRel X Y) (at level 60).
  Notation "X R==> Y" := (arrRel X Y) (at level 60).

  Notation "[< t | Y >]" :=
    (ltac:(let tl :=
               let t := (eval cbn in (fun x y wπl (t x, y| w))) in
               match t with | fun x y w ⇒ @?P xP end
           in
           let tr :=
               let t := (eval cbn in (fun x y wπr (t x, y| w))) in
               match t with | fun x y w ⇒ @?P yP end
           in
           let tw := eval cbn in (fun x y wπw (t x, y| w)) in
           exact (dpair (fun p xl xr xw, πw Y (nfst p xl) (nsnd p xr)) tl, tr tw)))
    (only parsing).

  Notation "f @R x" := (applyRel _ _ f x) (at level 85).

  Notation " Γ ,∘ X " := (ConsCtx Γ (Hi X)) (at level 100).
  Notation " Γ ,∙ X " := (ConsCtx Γ (Lo X)) (at level 100).
End RelNotations.

Section RelCat.
  Import RelNotations.

  Program Definition RelCat :=
    mkCategory Rel arrRel (fun _ _ f1 f2f1 = f2) _ idRel
               (fun _ _ _ f gcompRel g f) _ _ _ _.

  Definition rel_one : Rel := unit, unit| fun _ _unit.
  Definition to_rel_one X : RelCatX;rel_one :=
    dpair _ fun tt, fun tt (fun _ _ _tt).

  Definition rel_prod (X Y : Rel) : Rel :=
    πl X × πl Y, πr X × πr Y |
     fun p1 p2X (nfst p1) (nfst p2) × Y (nsnd p1) (nsnd p2)|TyRel.

  Definition rel_prod_fmap {X1 X2 Y1 Y2} (f1:RelCatX1;Y1) (f2:RelCatX2;Y2)
    : RelCatrel_prod X1 X2; rel_prod Y1 Y2.
  Proof.
    cbv.
    unshelve eexists.
    split ; move⇒ [p1 p2] ; constructor.
    exact (πl f1 p1).
    exact (πl f2 p2).
    exact (πr f1 p1).
    exact (πr f2 p2).
    move⇒ [xl1 xl2] [yl1 yl2] [w1 w2] ; constructor.
    exact (πw f1 xl1 yl1 w1).
    exact (πw f2 xl2 yl2 w2).
  Defined.

End RelCat.