Library CatSem.CAT.ind_potype
Require Import Coq.Program.Equality.
Require Export CatSem.CAT.cat_INDEXED_TYPE.
Require Export CatSem.CAT.initial_terminal.
Require Export CatSem.CAT.orders.
Require Export CatSem.CAT.monad_haskell.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Transparent Obligations.
Unset Automatic Introduction.
Require Export CatSem.CAT.cat_INDEXED_TYPE.
Require Export CatSem.CAT.initial_terminal.
Require Export CatSem.CAT.orders.
Require Export CatSem.CAT.monad_haskell.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Transparent Obligations.
Unset Automatic Introduction.
i tried to make the following in a modular way, which means
T -> PO_obj fun A B => fun t => PO_mor (A t) (B t)
like, to be easily generalizable to T -> C for any cat C
and so on. consequence: no coercions as we'd like them
modular programming rules, but not in coq
Category of a family of preorders indexed by T
Class ipo_obj_struct (A : T -> Type) := {
IRel : forall t, relation (A t);
IPOprf :> forall t, PreOrder (@IRel t)
}.
Notation "y <<< z" := (IRel y z) (at level 60).
Record ipo_obj := {
ipo_obj_carrier :> T -> Type ;
ipo_obj_s :> ipo_obj_struct ipo_obj_carrier
}.
Existing Instance ipo_obj_s.
Instance IRel_Trans (A : ipo_obj) t : Transitive (IRel (A:=A) (t:=t)).
Proof.
intros;
apply IPOprf.
Qed.
Lemma IRel_refl (V : ipo_obj) t (x : V t) : x <<< x.
Proof.
reflexivity.
Qed.
Lemma IRel_eq (V : ipo_obj) t (x y : V t) : x = y -> x <<< y.
Proof.
intros;
subst;
apply IRel_refl.
Qed.
Lemma IRel_eq_r (V : ipo_obj) t (x y z : V t) :
x <<< y -> y = z -> x <<< z.
Proof.
intros;
subst;
auto.
Qed.
Lemma IRel_eq_l (V : ipo_obj) t (x y z : V t) :
x <<< z -> x = y -> y <<< z.
Proof.
intros; subst; auto.
Qed.
Lemma IRel_trans (V : ipo_obj) t (x y z : V t) :
x <<< y -> y <<< z -> x <<< z.
Proof.
intros;
etransitivity;
eauto.
Qed.
Lemma IRel_trans_2 (V : ipo_obj) t (x y z : V t) :
x <<< z -> y <<< x -> y <<< z.
Proof.
intros;
etransitivity;
eauto.
Qed.
Program Instance ipo_proj_struct (A:ipo_obj) (t:T) :
PO_obj_struct (A t) := {
Rel := IRel (t:=t)
}.
Definition ipo_proj A t := Build_PO_obj (ipo_proj_struct A t).
Lemma proj_rel (A : ipo_obj) (t : T) (x y : A t) :
x <<< y -> x << y.
Proof.
auto.
Qed.
Lemma rel_proj (A : ipo_obj) (t : T) (x y : A t) :
x << y -> x <<< y.
Proof.
auto.
Qed.
Notation "'OB'" := ipo_obj (at level 70).
Existing Instance ipo_obj_s.
Class ipo_mor_struct (a b: OB) (f: forall t, a t -> b t) := {
ind_po_struct :> forall t, Proper (IRel (t:=t) ==> IRel (t:=t)) (f t)
}.
Record ipo_mor (a b: OB) := {
ipo_mor_carrier :> forall t, a t -> b t;
ipo_mor_s :> ipo_mor_struct ipo_mor_carrier
}.
Notation "'MOR'" := ipo_mor (at level 70).
Lemma IPO_mor_monotone (a b : ipo_obj)(f : ipo_mor a b):
forall t x y, x <<< y -> f t x <<< f t y.
Proof.
intros a b f t x y;
apply f.
Qed.
Hint Resolve IPO_mor_monotone.
Program Instance ipo_comp_s (a b c: OB) (f: MOR a b)
(g: MOR b c) : ipo_mor_struct (fun t z => g t (f t z)).
Next Obligation.
Proof.
unfold Proper; red;
intros; auto.
Qed.
Definition ipo_comp a b c f g := Build_ipo_mor (ipo_comp_s a b c f g).
Program Definition ind_po_id (a : OB) : MOR a a :=
Build_ipo_mor (ipo_mor_carrier :=
fun t z => z) _ .
Next Obligation.
Proof.
constructor; intros;
unfold Proper; red;
auto.
Qed.
Lemma eq_ind_setoid (a b: OB) :
Equivalence (fun f g: MOR a b => forall t z, f t z = g t z).
Proof.
intros; constructor;
unfold Reflexive,
Symmetric,
Transitive;
intros;
try etransitivity; auto.
Qed.
Definition ind_po_oid (a b: OB) :=
Build_Setoid (eq_ind_setoid a b).
Obligation Tactic := cat;
try (match goal with | [ |- Proper _ _ ] =>
unfold Proper; do 2 red end) ;
cat; repeat rew_hyp_2; cat.
Program Instance IPO_struct : Cat_struct ipo_mor := {
mor_oid := ind_po_oid;
comp := ipo_comp;
id := ind_po_id
}.
Canonical Structure IPO := Build_Cat IPO_struct.
Inductive smallest_irel (V : ITYPE T) : forall t, relation (V t) :=
| t_eq : forall t (x : V t), smallest_irel x x.
Program Instance sm_ipo_struct (V : ITYPE T) : ipo_obj_struct V := {
IRel := smallest_irel (V:=V)
}.
Next Obligation.
Proof.
constructor;
intros; simpl;
unfold Transitive;
intros;
try (match goal with [ H : smallest_irel _ _ |- _ ] =>
destruct H end);
try constructor;
auto.
Qed.
Canonical Structure sm_ipo (V : ITYPE T) : IPO :=
Build_ipo_obj (sm_ipo_struct V).
Ltac elim_sm := match goal with
| [ H : @IRel (ipo_obj_carrier (sm_ipo _))
(ipo_obj_s (sm_ipo _)) _ _ _ |- _ ] => destruct H end.
Lemma sm_irel_eq (V : ITYPE T) t (x y : sm_ipo V t) :
x <<< y -> x = y.
Proof.
intros;
elim_sm;
auto.
Qed.
Section sm_ipo_mor.
Variables V W : ITYPE T.
Variable f : V ---> W.
Obligation Tactic := intros;
unfold Proper; red; intros; elim_sm; constructor.
Program Instance sm_ipo_mor_s :
ipo_mor_struct (a:=sm_ipo V) (b:=sm_ipo W) f.
Canonical Structure sm_ipo_mor : sm_ipo V ---> sm_ipo W :=
Build_ipo_mor sm_ipo_mor_s.
End sm_ipo_mor.
Obligation Tactic := cat;
try (match goal with | [ |- Proper _ _ ] =>
unfold Proper; red end) ;
cat; repeat rew_hyp_2; cat.
Program Instance SM_ipo_s : Functor_struct sm_ipo_mor.
Definition IDelta := Build_Functor SM_ipo_s.
Section SM_ind.
Variable V : ITYPE T.
Variable W : IPO.
Variable f : forall t, V t -> W t.
Obligation Tactic := idtac.
Program Instance SM_ind_s : ipo_mor_struct
(a:=IDelta V) (b:=W) f.
Next Obligation.
Proof.
intros;
try (match goal with | [ |- Proper _ _ ] =>
unfold Proper; red end);
intros;
match goal with [H : IRel _ _|- _ ] => destruct H end;
reflexivity.
Qed.
Canonical Structure SM_ind := Build_ipo_mor SM_ind_s.
End SM_ind.
Notation "'IP'":= IPO.
Section proj.
Section hom.
Variable t: T.
Variables a b : OB.
Variable f : MOR a b.
Program Definition ipo_mor_proj :=
Build_PO_mor (a:=ipo_proj a t) (b:=ipo_proj b t)
(PO_fun := f t) _ .
Next Obligation.
Proof.
constructor.
unfold Proper; red.
simpl.
intros; apply f.
auto.
Qed.
End hom.
Program Instance IP_proj_Func (t:T) :
Functor_struct (C:=IP) (D:=Ord)
(ipo_mor_proj t).
Canonical Structure IP_proj t := Build_Functor (IP_proj_Func t).
End proj.
Forgetful functor (T -> PO) -> (T -> Set)
if i give Fobj as implicit argument, i will have a BAD
eta expansion which breaks the NT in po_monads
Program Instance OIP_struct : Functor_struct (C:=IPO) (D:= ITYPE T)
(fun V W => fun f => f).
Definition OIP := Build_Functor OIP_struct.
End forget.
Category IP has initial and terminal object
Section IND_PO_init_term.
Program Instance IP_term_struct : ipo_obj_struct (fun t => unit) := {
IRel t := fun _ _ => True
}.
Next Obligation.
Proof.
constructor;
auto.
Qed.
Definition IP_term := Build_ipo_obj IP_term_struct.
Program Instance IP_term_mor_struct (a: OB) :
ipo_mor_struct (a:=a)(b:=IP_term)(fun _ _ => tt).
Definition IP_term_mor (a:OB) := Build_ipo_mor (IP_term_mor_struct a).
Hint Extern 3 (?a = ?b) => try destruct a.
Program Instance IP_Terminal : Terminal IP := {
Term := IP_term;
TermMor := IP_term_mor
}.
Program Instance IP_init_struct : ipo_obj_struct (fun t => TEMPTY) := {
IRel t := fun _ _ => True
}.
Next Obligation.
Proof.
constructor;
auto.
Qed.
Definition IP_init := Build_ipo_obj IP_init_struct.
Obligation Tactic := intros;
unfold Proper; red; cat;
repeat (match goal with
[ H : TEMPTY |- _ ] => elim H end); cat.
Program Instance IP_init_mor_struct (a : OB) :
ipo_mor_struct
(a:=IP_init)
(b:=a)
(fun t => InitMor (C:=TYPE) (a t)).
Definition IP_init_mor (a:OB) := Build_ipo_mor (IP_init_mor_struct a).
Program Instance IP_Initial : Initial IP := {
Init := IP_init;
InitMor := IP_init_mor
}.
End IND_PO_init_term.
Adding a distinct element of type (T u)
to a family of preorders A
Inductive optrelT (u:T) (V: IP) :
forall t,relation (opt u V t):=
| optrelTP_none : optrelT (none u V) (none u V)
| optrelTP_some : forall t (y z:V t), y <<< z ->
optrelT (some u y) (some u z).
Program Instance opt_TP_preorder (u:T)(A:IP):
ipo_obj_struct (opt u A) := {
IRel := @optrelT u A
}.
Next Obligation.
Proof.
intros;
constructor;
unfold Reflexive, Transitive.
intro z; induction z;
constructor. apply IPOprf.
intros r y z H. generalize dependent z.
elim H.
intros z Hz.
dependent induction Hz.
constructor.
intros t0 x0 y0 H0 z H1.
generalize dependent x0.
dependent destruction H1. intros.
constructor.
transitivity y0; auto.
Qed.
Canonical Structure opt_TP u A := Build_ipo_obj (opt_TP_preorder u A).
Notation "V *" := (opt_TP _ V) (at level 5).
injection Some_TP is a morphism of preorders
Obligation Tactic := unfold Proper; red;
constructor; auto.
Program Instance Some_TP_POs (u:T) (A:IP) :
ipo_mor_struct (a:=A)(b:=A*)
(@some _ u _ ).
Canonical Structure Some_TP_PO (u:T) (A:IP): A ---> A* :=
Build_ipo_mor (Some_TP_POs u A).
constructor; auto.
Program Instance Some_TP_POs (u:T) (A:IP) :
ipo_mor_struct (a:=A)(b:=A*)
(@some _ u _ ).
Canonical Structure Some_TP_PO (u:T) (A:IP): A ---> A* :=
Build_ipo_mor (Some_TP_POs u A).
opt_TP is a monad
- return := Some_TP
- bind f := default f None_TP
Program Definition opt_TP_weta (u:T)(V:IP) : V ---> V* :=
Build_ipo_mor (ipo_mor_carrier := @some _ u V) _.
Obligation Tactic := idtac.
Program Definition opt_TP_kl (u:T) (V W : OB)
(f: V ---> W*) : V* ---> W* :=
Build_ipo_mor (ipo_mor_carrier := @opt_kl _ u V W f) _.
Next Obligation.
Proof.
constructor.
unfold Proper;
repeat red; intros.
induction H; simpl.
constructor.
apply f; auto.
Qed.
Canonical Structure opt_TP_kl.
Obligation Tactic := repeat red; cat; elim_opt.
Program Instance opt_TP_monad_struct (u:T) :
Monad_struct (fun V => opt_TP u V) := {
weta V := opt_TP_weta u V;
kleisli V W f := opt_TP_kl (u:=u) f
}.
Canonical Structure opt_TP_monad (u:T):=
Build_Monad (opt_TP_monad_struct u).
Section opt_TP_opt_T.
Lemma TP_T_kl: forall u (V W:IP) (f:V ---> W*) (t:T) z,
kleisli (Monad_struct:= (opt_TP_monad u)) f z =
kleisli (Monad_struct:= (opt_monad u)) f z.
Proof.
intros; simpl; auto.
Qed.
Lemma TP_T_weta: forall u (V:IP) (t:T) (z:V t),
weta (Monad_struct:= (opt_TP_monad u)) V t z =
(weta (Monad_struct:= (opt_monad u))) V t z.
Proof.
intros; simpl; auto.
Qed.
End opt_TP_opt_T.
Derived Module
default
Program Definition opt_TP_default (u:T) (V W : IP)
(f: V ---> W) (w:W u): V* ---> W :=
Build_ipo_mor (ipo_mor_carrier := @opt_default _ u V W f w) _ .
Next Obligation.
Proof.
constructor.
unfold Proper; red.
intros t q y H;
induction H; simpl.
apply IPOprf.
apply f.
auto.
Qed.
Canonical Structure opt_TP_default.
Monad P, we define
- var_inj V : V ---> P V*
- def_var_inj (f: V ---> P W) -> V* ---> P W*
Variable P : Monad IPO.
Existing Instance IPO_struct.
Definition opt_TP_def_varinj (u:T) (V W: IP) (f:V ---> P W) :
opt_TP u V ---> P (opt_TP u W):=
(opt_TP_default (u:=u) (V:=V) (W:=P (opt_TP u W))
(f ;; lift (weta (Monad_struct := (opt_TP_monad u)) W))
(weta (Monad_struct := P) (opt_TP u W) u (none u W))).
needed for module property of the derivative
Ltac t := simpl; intros; elim_opt; rew (lift_weta P).
Lemma opt_TP_def_varinj_weta (u:T)(V:IP) :
opt_TP_def_varinj u (weta V) == weta _.
Proof. t.
Qed.
Lemma opt_TP_def_varinj_weta_f (u:T) (V V':IP) (f: V' ---> V) :
opt_TP_def_varinj u (f ;; weta V) ==
lift (M :=opt_TP_monad u) f ;; weta _ .
Proof. t.
Qed.
End PostComp_w_Monad.
Section substitution.
Variable R: Monad IP.
Section subst_kleisli_arg.
Variable V: IP.
Variable r: T.
Variable W : R V r.
Definition IPsubst_map := opt_TP_default (weta (Monad_struct:=R) _ ) W.
End subst_kleisli_arg.
Definition IPsubstar (r:T) (V:IP) (W:R V r) := kleisli (IPsubst_map W).
End substitution.
End ind_po_cat.
Notation "x <<< y" := (IRel x y) (at level 60).
Existing Instance IP_Initial.
Existing Instance IP_Terminal.
Existing Instance IPO_struct.
Existing Instance ipo_obj_s.
Existing Instance ipo_mor_s.
Existing Instance IPOprf.