Library models.Signature
Effect signatures and their homomorphisms.
Dependent type presentation
Inductive Ebq : esig :=
| enq : bool → Ebq unit
| deq : Ebq bool.
Inductive Erb : esig :=
| set : nat → bool → Erb unit
| get : nat → Erb bool
| inc1 : Erb nat
| inc2 : Erb nat.
Hence we define the following conversion.
Record esig_op (E : esig) :=
{
esig_ar : Type;
eop : E esig_ar
}.
Canonical Structure esig_sig (E : esig) : sig :=
{|
op := esig_op E;
ar := esig_ar E;
|}.
Coercion esig_sig : esig >-> sig.
Notation "# m" := {| eop := m |} (at level 35, format "# m").
Endofunctors
Simple terms
Record application (E : sig) (X : Type) :=
apply {
operator : op E;
operand : ar operator → X;
}.
Coercion application : sig >-> Funclass.
Arguments apply {E X}.
Arguments operator {E X}.
Arguments operand {E X}.
We will sometimes use the following notation for simple terms,
which evokes the game/effects interpretation of signatures.
application E is in fact the endofunctor on Set associated with E.
The action on functions is defined as follows.
Definition amap {E : sig} {X Y} (f : X → Y) : E X → E Y :=
fun '(apply m x) ⇒ (m ≥ n ⇒ f (x n)).
Lemma amap_id {E : sig} {X} (t : E X) :
amap (fun x ⇒ x) t = t.
Lemma amap_compose {E : sig} {X Y Z} (g : Y → Z) (f : X → Y) (t : E X) :
amap g (amap f t) = amap (fun x ⇒ g (f x)) t.
Check #deq ≥ r ⇒ (match r with true ⇒ 42 | false ⇒ 0%nat end).
Eval cbn in amap (mult 2) (#deq ≥ r ⇒ (match r with true ⇒ 42 | false ⇒ 0%nat end)).
Homomorphisms
Definition
It can be used to transform the simple terms of the signature E
into simple terms of the signature F.
In fact, application, amap and hmap together define a
functor from the category of signatures and signature homomorphisms
to the category of endofunctors on Set and natural transformations.
Lemma hmap_natural {E F} (ϕ : sighom E F) {X Y} (f : X → Y) (t : E X) :
amap f (hmap ϕ X t) = hmap ϕ Y (amap f t).
Every natural transformation between endofunctors associated to
signatures is completely determined by its action on the terms
m ≥ n ⇒ n, so the functor is full and faithful.
Definition basis {E F : sig} (η : ∀ X, E X → F X) : sighom E F :=
fun m ⇒ η (ar m) (m ≥ n ⇒ n).
Lemma hmap_basis {E F : sig} (η : ∀ X, E X → F X) :
(∀ X Y f t, η Y (amap f t) = amap f (η X t)) →
(∀ X t, hmap (basis η) X t = η X t).
Lemma basis_hmap {E F : sig} (ϕ : sighom E F) :
∀ m, basis (hmap ϕ) m = ϕ m.
Definition sigid {E} : sighom E E :=
basis (fun X t ⇒ t).
Lemma hmap_id {E : sig} :
∀ X t, hmap (@sigid E) X t = t.
Definition sigcomp {E F G} (ψ : sighom F G) (ϕ : sighom E F) : sighom E G :=
fun m ⇒ hmap ψ _ (ϕ m).
Lemma hmap_compose {E F G} (ψ : sighom F G) (ϕ : sighom E F) :
∀ X t, hmap (sigcomp ψ ϕ) X t = hmap ψ X (hmap ϕ X t).
Lemma sigcomp_id_l {E F} (ϕ : sighom E F) :
sigcomp sigid ϕ = ϕ.
Lemma sigcomp_id_r {E F} (ϕ : sighom E F) :
sigcomp ϕ sigid = ϕ.
Lemma sigcomp_assoc {E F G H} (θ: sighom G H) (ψ: sighom F G) (ϕ: sighom E F) :
sigcomp (sigcomp θ ψ) ϕ = sigcomp θ (sigcomp ψ ϕ).
Definition ex1 : sighom Ebq Erb :=
fun '#m ⇒
match m with
| enq v ⇒ #set 0 v ≥ _ ⇒ tt
| deq ⇒ #inc2 ≥ n ⇒ Nat.eqb n 0
end.
Definition ex2 : sighom Ebq Ebq :=
fun '#m ⇒
match m with
| enq v ⇒ #deq ≥ _ ⇒ tt
| deq ⇒ #enq true ≥ _ ⇒ false
end.
Operations on signatures
Sum
Canonical Structure sigsum (E F : sig) :=
{|
op := op E + op F;
ar m := match m with inl me ⇒ ar me | inr mf ⇒ ar mf end;
|}.
Bind Scope sig_scope with sig.
Delimit Scope sig_scope with sig.
Infix "+" := sigsum : sig_scope.
Definition siginl {E F} : sighom E (E + F) :=
fun m ⇒ inl m ≥ n ⇒ n.
Definition siginr {E F} : sighom F (E + F) :=
fun m ⇒ inr m ≥ n ⇒ n.
Definition sigtup {E F G} (ϕ1 : sighom E G) (ϕ2 : sighom F G) : sighom (E + F) G :=
fun m ⇒
match m with
| inl me ⇒ ϕ1 me
| inr mf ⇒ ϕ2 mf
end.
Lemma sigtup_inl {E F G} (ϕ1 : sighom E G) (ϕ2 : sighom F G) :
sigcomp (sigtup ϕ1 ϕ2) siginl = ϕ1.
Lemma sigtup_inr {E F G} (ϕ1 : sighom E G) (ϕ2 : sighom F G) :
sigcomp (sigtup ϕ1 ϕ2) siginr = ϕ2.
Lemma sigtup_uniq {E F G} (ϕ : sighom (E + F) G) :
sigtup (sigcomp ϕ siginl) (sigcomp ϕ siginr) = ϕ.
Local Open Scope type_scope.
Definition sigtens (E F : sig) : sig :=
{|
op := op E × op F;
ar '(me, mf) := ar me × ar mf;
|}.