Library CatSem.STS.STS_arities
Require Export Coq.Lists.List.
Require Export CatSem.CAT.monad_h_module.
Require Export CatSem.CAT.cat_INDEXED_TYPE.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Transparent Obligations.
Unset Automatic Introduction.
Ltac app_any := match goal with [H:_|-_] => app H end.
Section arities.
Notation "[ T ]" := (list T) (at level 5).
Ltac opt := simpl in *; intros;
autorewrite with opt; auto with opt.
Variable T : Type.
Require Export CatSem.CAT.monad_h_module.
Require Export CatSem.CAT.cat_INDEXED_TYPE.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Transparent Obligations.
Unset Automatic Introduction.
Ltac app_any := match goal with [H:_|-_] => app H end.
Section arities.
Notation "[ T ]" := (list T) (at level 5).
Ltac opt := simpl in *; intros;
autorewrite with opt; auto with opt.
Variable T : Type.
definition of a signature
Record Signature_t (t : T) : Type := {
sig_index : Type ;
sig : sig_index -> [[T] * T]
}.
Definition Signature := forall t, Signature_t t.
given a list of types, we add successively a variable of
that type to a set of indexed variables
Notation "V * u" := (opt u V).
Notation "^ f" := (lift (M:= opt_monad _) f) (at level 5).
Fixpoint pow (l : [T]) (V : ITYPE T) : ITYPE T :=
match l with
| nil => V
| b::bs => pow bs (V * b)
end.
Notation "V ** l" := (pow l V) (at level 10).
Notation "^ f" := (lift (M:= opt_monad _) f) (at level 5).
Fixpoint pow (l : [T]) (V : ITYPE T) : ITYPE T :=
match l with
| nil => V
| b::bs => pow bs (V * b)
end.
Notation "V ** l" := (pow l V) (at level 10).
adding variables is functorial
Fixpoint pow_map (l : [T]) V W (f : V ---> W) :
V ** l ---> W ** l :=
match l return V ** l ---> W ** l with
| nil => f
| b::bs => pow_map (^ f)
end.
Notation "f ^^ l" := (pow_map (l:=l) f) (at level 10).
Lemma lift_opt_monad u (V W : ITYPE T) (f g : V ---> W)
(H : forall t x, f t x = g t x) :
forall t x, lift (M:=opt_monad u) f t x = ^g t x.
Proof.
intros;
apply (lift_eq (opt_monad _));
auto.
Qed.
this thing works cuz of the strange semantics of the
Ltac match
Lemma pow_map_eq l (V W : ITYPE T) (f g : V ---> W)
(H : forall t (x : V t) , f t x = g _ x) :
forall t x, f ^^ l t x = g ^^ l t x.
Proof.
induction l;
repeat (cat || app_any ||
app lift_opt_monad).
Qed.
Hint Rewrite pow_map_eq : opt.
Hint Resolve pow_map_eq : opt.
Obligation Tactic := intros; do 2 red; opt.
Program Instance pow_map_oid V W (l : [T]) :
Proper (equiv ==> equiv) (pow_map (V:=V) (W:=W) (l:=l)).
Lemma pow_id (l : [T]) (a : ITYPE T) : (id a) ^^ l == id (a ** l).
Proof.
induction l;
repeat (cat || rewrite (pow_map_eq (g:=fun t x => x)) ||
app_any ||
elim_opt; auto).
Qed.
Lemma pow_eq_id l (a : ITYPE T) f : f == id a -> f ^^ l == id _ .
Proof.
intros;
repeat (rew_all || auto using pow_id).
Qed.
Lemma pow_comp (l : [T]) (a b c : ITYPE T) (f : a ---> b) (g : b ---> c):
(f;; g) ^^ l == f ^^ l;; g ^^ l.
Proof.
induction l;
repeat (cat ||
match goal with
[l: list T,a : T |- _ = ^?g ^^ _ _ (^?f ^^ _ _ _ )] =>
rew (pow_map_eq (l:=l)(f:= ^(f ;; g))
(g:=^f ;; lift (M:=opt_monad a) g)) end ||
rew_all ||
match goal with [a:T |- _ ] => rew (lift_lift (opt_monad a)) end).
Qed.
multiple adding of variables is a functor BLOWUP
Obligation Tactic := auto using pow_id, pow_comp.
Program Instance POW_struct (l : [T]) : Functor_struct (@pow_map l).
Canonical Structure POW l := Build_Functor (POW_struct l).
Program Instance POW_struct (l : [T]) : Functor_struct (@pow_map l).
Canonical Structure POW l := Build_Functor (POW_struct l).
now some functions to blow up under monads and modules
Section pow_and_product.
Variable P : Monad (ITYPE T).
Notation "'Var' x" := (weta (Monad_struct := P) _ _ x) (at level 55).
Notation "x >>= f" := (kleisli (Monad_struct := P) f _ x) (at level 65).
Hint Resolve (shift_eq (P:=P)) (shift_weta P)
(shift_weta_f P) f_equal : opt.
Hint Rewrite (shift_eq (P:=P)) (shift_weta P)
(shift_weta_f P) : opt.
lshift is SHIFTING wrt to a list of added variables
it enjoys the same properties as its little brother shift
it enjoys the same properties as its little brother shift
Fixpoint lshift (l : [T]) (V W: ITYPE T) (f:V ---> P W) :
V ** l ---> P (W ** l) :=
match l return V ** l ---> P (W ** l) with
| nil => f
| b::bs => lshift (shift f)
end.
Notation "x >>- f" := (lshift f x)(at level 60).
Lemma lshift_eq l V W (f g : V ---> P W)
(H : forall t x, f t x = g t x):
forall t (x : V ** l t),
x >>- f = x >>- g.
Proof.
induction l; opt.
Qed.
Hint Resolve lshift_eq : opt.
Hint Rewrite lshift_eq : opt.
Ltac t l := induction l;
repeat (cat ||
match goal with [H:_|-_] => rewrite <- H end ||
apply lshift_eq || opt).
Lemma lshift_weta (l : [T]) V t (x : V ** l t) :
x >>- (weta _) = Var x.
Proof.
t l.
Qed.
Hint Resolve lshift_weta : opt.
Hint Rewrite lshift_weta : opt.
Lemma lshift_weta' l V :
lshift (l:=l) (weta (Monad_struct := P)V) == weta _ .
Proof.
opt.
Qed.
Lemma lshift_weta_f (l : [T]) V W (f : V ---> W) t x:
x >>- (f ;; weta W) = Var (f ^^ l t x).
Proof.
t l.
Qed.
Lemma kleisli_lshift (l : [T]) V W (f : V ---> P W)
X (g : W ---> P X) (t : T) (x : (V ** l) t) :
(x >>- f) >>= (lshift g) = x >>- (fun s y => f s y >>= g).
Proof.
induction l;
repeat (rew_all || apply lshift_eq || rew shift_kl || opt).
Qed.
multiple derivation of a module M wrt a list l
we never actually USE these definitions,
but we use parts of the properties
the carrier of the often derived module
is needed in the proofs of mkl_mkl and mkl_weta,
so we do it before
Lemma der_mod_etakl c l:
mkleisli (d:=c ** l) (lshift (l:=l) (V:=c) (W:=c) (weta c)) ==
id (der_mod_c l c).
Proof.
intros; rewrite lshift_weta'; mod.
Qed.
Hint Rewrite der_mod_etakl : opt.
Obligation Tactic := opt;
repeat (unf_Proper ||
match goal with [|-mkleisli ?a ;; mkleisli ?b == _ ] =>
rew (mklmkl M a b) end ||
apply (mkl_eq M) || apply lshift_eq ||
rewrite kleisli_lshift || opt); mod.
Program Instance der_mod_struct (l : [T]) :
Module_struct P (der_mod_c l):= {
mkleisli V W f:= mkleisli (Module_struct := M) (lshift (l:=l) f)
}.
Definition D_mod (l : [T]) := Build_Module (der_mod_struct l).
End many_derivs.
now for
morally this product module carries the arguments of the constructors
- M a module
- l an arity
morally this product module carries the arguments of the constructors
the carrier of the module as an inductive type
Inductive prod_mod_c (V : ITYPE T) : [[T] * T] -> Type :=
| TTT : prod_mod_c V nil
| CONSTR : forall b bs,
M (V ** (fst b)) (snd b) -> prod_mod_c V bs ->
prod_mod_c V (b::bs) .
Lemma CONSTR_eq (V : ITYPE T) (b : [T] * T)
(bs : [[T] * T])
(elem elem' : M (V ** (fst b)) (snd b))
(elems elems' : prod_mod_c V bs) :
elem = elem' -> elems = elems' ->
CONSTR elem elems = CONSTR elem' elems'.
Proof.
intros; subst; auto.
Qed.
End prod_mod_built_from_scratch_carrier.
if M is a module, then the product of fibres of derived M also is
the product module mkleisli is defined by structural recursion
Fixpoint pm_mkl l V W (f : V ---> P W)
(X : prod_mod_c M V l) : prod_mod_c M W l :=
match X in prod_mod_c _ _ l return prod_mod_c M W l with
| TTT => TTT M W
| CONSTR b bs elem elems =>
CONSTR (M:=M) (V:=W)
(mkleisli (Module_struct := M) (lshift f) (snd b) elem)
(pm_mkl f elems)
end.
and enjoys the mkl properties
Ltac t x := induction x;
simpl; intros; auto;
cat; repeat
match goal with
| [|-CONSTR _ _ = CONSTR _ _ ] => apply CONSTR_eq
| [b : prod _ _ |-_ ]=>
try app (mkl_eq (der_mod_struct M (fst b)));
try app (mklmkl (der_mod_struct M (fst b)));
try rew (mkl_weta (Module_struct := der_mod_struct M (fst b)))
end; cat.
Lemma pm_mkl_eq l V W (f g : V ---> P W)
(H : forall t x, f t x = g t x) (x : prod_mod_c M V l) :
pm_mkl f x = pm_mkl g x.
Proof.
t x.
Qed.
Lemma pm_mkl_mkl l V (x : prod_mod_c M V l) W (f : V ---> P W)
X (g : W ---> P X) :
pm_mkl g (pm_mkl f x) =
pm_mkl (fun (t : T) (x0 : V t) => kleisli g t (f t x0)) x .
Proof.
t x.
Qed.
Lemma pm_mkl_weta l V (v : prod_mod_c M V l) :
pm_mkl (weta V) v = v.
Proof.
t v.
Qed.
Hint Rewrite pm_mkl_mkl pm_mkl_weta pm_mkl_eq : opt.
Hint Resolve pm_mkl_mkl pm_mkl_weta pm_mkl_eq : opt.
Obligation Tactic := unfold Proper; red; opt.
Program Instance pm_mkl_oid l V W : Proper
(A:= (V ---> P W) ->
(prod_mod_c M V l ---> prod_mod_c M W l))
(equiv ==> equiv) (@pm_mkl l V W).
Program Instance prod_mod_struct l : Module_struct P (D:=TYPE)
(fun V => prod_mod_c M V l) := {
mkleisli := pm_mkl (l:=l)
}.
Definition prod_mod l := Build_Module (prod_mod_struct l).
End prod_mod_carrier_is_mod.
we are now ready to define what the representation of an arity is
Notation "M [( s )]" := (ITFIB_MOD _ s M) (at level 60).
Section arity_rep.
Variable M : Module P (ITYPE T).
to each arity we associate a type of module morphisms
Definition modhom_from_arity (ar : [[T] * T] * T) : Type :=
Module_Hom (prod_mod M (fst ar)) (M [(snd ar)]).
End arity_rep.
End pow_and_product.
the type of representations associated to a signature
a represention is - for each arity - a type of module morphisms
Definition Repr_t (t : T) :=
forall i : sig_index (S t),
modhom_from_arity P ((sig i),t).
Definition Repr := forall t, Repr_t t.
End rep_struct.
Record Representation := {
rep_monad :> Monad (ITYPE T);
repr : Repr rep_monad
}.
now we come to the MORPHISMS OF REPRESENTATIONS
they are more complicated than in a "strict theory" since we
must insert isomorphisms where on paper we have equality of objects
the commutative diagrams we must have for a morphism of
representations
Section arrows.
Variables P Q : Monad (ITYPE T).
Variable f : Monad_Hom P Q.
Notation "x >>- f" := (shift f x)(at level 60).
Notation "x >-- f" := (lshift f x)(at level 60).
Lemma lshift_monad_hom l V W (g : V ---> P W) t (x : V ** l t) :
f _ t (x >-- g) = x >-- (g ;; f _ ).
Proof.
induction l;
repeat (opt || rew_all || apply lshift_eq ||
rew (shift_monad_hom)).
Qed.
Hint Rewrite lshift_monad_hom : opt.
the lower left corner of the commutative diagram
the left morphism of the commutative diagram
at first its carrier
Fixpoint Prod_mor_c (l : [[T] * T])
(V : ITYPE T) (X : prod_mod P l V) :
f* (prod_mod Q l) V :=
match X in prod_mod_c _ _ l
return f* (prod_mod Q l) V with
| TTT => TTT _ _
| CONSTR b bs elem elems =>
CONSTR (f _ _ elem) (Prod_mor_c elems)
end.
Lemma prod_mod_c_kl (ar : [[T] * T]) V
(x : prod_mod_c P V ar):
forall (W : ITYPE T) (g : V ---> P W),
Prod_mor_c (l:=ar) (V:=W) (pm_mkl (M:=P) (W:=W) g x) =
pm_mkl (M:=Q) (W:=W) (fun (t : T) (x0 : V t) => f W t (g t x0))
(Prod_mor_c (l:=ar) (V:=V) x).
Proof.
induction x;
repeat (opt || apply CONSTR_eq ||
rew (monad_hom_kl (Monad_Hom_struct := f)) ||
app (kl_eq Q)).
Qed.
Obligation Tactic := simpl; intros; rew prod_mod_c_kl.
the left morphism has a module morphism structure
Program Instance prod_mor_s l :
Module_Hom_struct (S:=prod_mod P l)
(T:=f* (prod_mod Q l))
(Prod_mor_c (l:=l)).
Definition Prod_mor ar :=
Build_Module_Hom (prod_mor_s ar).
Module_Hom_struct (S:=prod_mod P l)
(T:=f* (prod_mod Q l))
(Prod_mor_c (l:=l)).
Definition Prod_mor ar :=
Build_Module_Hom (prod_mor_s ar).
definition of the diagram that we kindly ask to commute
at first for ONE arity
Variable a : [[T] * T] * T.
Variable RepP : modhom_from_arity P a.
Variable RepQ : modhom_from_arity Q a.
the left - lower side of the diagram
Notation "'f*' M" := (# (PB_MOD f _ ) M).
Definition commute_left :=
Prod_mor (fst a) ;;
f* RepQ ;;
ITPB_FIB f _ _.
the right - upper side
Coercion PbMod_ind_Hom : Monad_Hom >-> mor.
Notation "y [( s )]" := (#(ITFIB_MOD _ s) y) (at level 40).
Definition commute_right :=
RepP ;; f [(snd a)].
Notation "y [( s )]" := (#(ITFIB_MOD _ s) y) (at level 40).
Definition commute_right :=
RepP ;; f [(snd a)].
they are equal
definition of "morphism of representations"
a representation morphism should make commute something
Class Representation_Hom_struct (f : Monad_Hom P Q) :=
repr_hom_s : forall t (i : sig_index (S t)),
commute f (repr P i) (repr Q i).
Record Representation_Hom : Type := {
repr_hom_c :> Monad_Hom P Q;
repr_hom :> Representation_Hom_struct repr_hom_c
}.
End signature_rep.
End arities.
Existing Instance repr_hom.
Existing Instance pow_map_oid.