mirror of
https://github.com/dhil/phd-dissertation
synced 2026-03-13 02:58:26 +00:00
Parameterised semantics
This commit is contained in:
164
thesis.tex
164
thesis.tex
@@ -7498,7 +7498,10 @@ being handled. Semantically, parameterised handlers are defined as
|
|||||||
folds with state threading over computation trees.
|
folds with state threading over computation trees.
|
||||||
|
|
||||||
We take the deep handler calculus $\HCalc$ as our starting point and
|
We take the deep handler calculus $\HCalc$ as our starting point and
|
||||||
extend it with parameterised handlers to yield the calculus $\HPCalc$.
|
extend it with parameterised handlers to yield the calculus
|
||||||
|
$\HPCalc$. The parameterised handler extension interacts nicely with
|
||||||
|
shallow handlers, and as such it can be added to $\SCalc$ with low
|
||||||
|
effort.
|
||||||
|
|
||||||
\subsection{Syntax and static semantics}
|
\subsection{Syntax and static semantics}
|
||||||
In addition to a computation, a parameterised handler also take a
|
In addition to a computation, a parameterised handler also take a
|
||||||
@@ -7511,16 +7514,26 @@ cell embedded inside the handler.
|
|||||||
\slab{Parameterised\textrm{ }definitions} & H^\param &::=& q^A.~H
|
\slab{Parameterised\textrm{ }definitions} & H^\param &::=& q^A.~H
|
||||||
\end{syntax}
|
\end{syntax}
|
||||||
%
|
%
|
||||||
Figure~\ref{fig:param-syntax} extends the syntax of
|
The syntactic category of handler types $F$ is extended with a new
|
||||||
$\HCalc$ with parameterised handlers. Syntactically a parameterised
|
kind of handler arrow for parameterised handlers. The left hand side
|
||||||
handler is new binding form $(q^A.~H)$, where $q$ is the name of the
|
of the arrow is a pair, whose first component denotes the type of the
|
||||||
parameter, whose type is $A$. The name is bound in the ordinary
|
input computation and the second component denotes the type of the
|
||||||
handler definition $H$. The elimination form
|
handler parameter. The right hand side denotes the return type of the
|
||||||
($\ParamHandle\; M\;\With\;H^\param(W)$) is similar to the form for
|
handler.
|
||||||
ordinary deep handlers, except that the parameterised handler
|
%
|
||||||
definition is applied to a value $W$, which is the initial value of
|
The computations category is extended with a new application form for
|
||||||
the parameter $q$.
|
handlers, which runs a computation $M$ under a parameterised handler
|
||||||
|
$H$ applied to the value $W$.
|
||||||
|
%
|
||||||
|
Finally, a new category is added for parameterised handler
|
||||||
|
definitions. A parameterised handler definition is a new binding form
|
||||||
|
$(q^A.~H)$, where $q$ is the name of the parameter, whose type is $A$,
|
||||||
|
and $H$ is an ordinary handler definition $H$. The parameter $q$ is
|
||||||
|
accessible in the $\Return$ and operation clauses of $H$.
|
||||||
|
|
||||||
|
As with ordinary deep handlers and shallow handlers, there are two
|
||||||
|
typing rules: one for handler application and another for handler
|
||||||
|
definitions.
|
||||||
%
|
%
|
||||||
\begin{mathpar}
|
\begin{mathpar}
|
||||||
% Handle
|
% Handle
|
||||||
@@ -7532,7 +7545,18 @@ the parameter $q$.
|
|||||||
\typ{\Gamma}{H^\param : \Record{C; A} \Harrow^\param D}
|
\typ{\Gamma}{H^\param : \Record{C; A} \Harrow^\param D}
|
||||||
}
|
}
|
||||||
{\Gamma \vdash \ParamHandle \; M \; \With\; H^\param(W) : D}
|
{\Gamma \vdash \ParamHandle \; M \; \With\; H^\param(W) : D}
|
||||||
|
\end{mathpar}
|
||||||
|
%
|
||||||
|
The $\tylab{Handle^\param}$ rule is similar to the $\tylab{Handle}$
|
||||||
|
and $\tylab{Handle^\dagger}$ rules, except that it has to account for
|
||||||
|
the parameter $W$, whose type has to be compatible with the second
|
||||||
|
component of the domain type of the handler definition $H^\param$.
|
||||||
|
%
|
||||||
|
The typing rule for parameterised handler definitions adapts the
|
||||||
|
corresponding typing rule $\tylab{Handler}$ for ordinary deep handlers
|
||||||
|
with the addition of a parameter.
|
||||||
|
%
|
||||||
|
\begin{mathpar}
|
||||||
% Parameterised handler
|
% Parameterised handler
|
||||||
\inferrule*[Lab=\tylab{Handler^\param}]
|
\inferrule*[Lab=\tylab{Handler^\param}]
|
||||||
{{\bl
|
{{\bl
|
||||||
@@ -7546,54 +7570,63 @@ the parameter $q$.
|
|||||||
{\typ{\Delta;\Gamma}{(q^{A'} . H) : \Record{C;A'} \Harrow^\param D}}
|
{\typ{\Delta;\Gamma}{(q^{A'} . H) : \Record{C;A'} \Harrow^\param D}}
|
||||||
\end{mathpar}
|
\end{mathpar}
|
||||||
%%
|
%%
|
||||||
We require two additional rules to type parameterised handlers. The
|
The key differences between the \tylab{Handler} and
|
||||||
rules are given in Figure~\ref{fig:param-static-semantics}. The main
|
\tylab{Handler^\param} rules are that in the latter the return and
|
||||||
differences between the \tylab{Handler} and \tylab{Handler^\param} are
|
operation cases are typed with respect to the parameter $q$, and that
|
||||||
that in the latter the return and operation cases are typed with
|
resumptions $r_i$ have type $\Record{B_\ell;A'} \to D$, that is a
|
||||||
respect to the parameter $q$, and that resumptions $r$ have type
|
parameterised resumption is a binary function, where the first
|
||||||
$\Record{B_\ell;A'} \to D$, that is they accept a pair as
|
argument is the interpretation of an operation and the second argument
|
||||||
input.
|
is the (updated) handler state. The return type of $r_i$ is the same
|
||||||
|
as the return type of the handler, meaning that an invocation of $r_i$
|
||||||
|
is guarded in the same way as an invocation of an ordinary deep
|
||||||
|
resumption.
|
||||||
|
|
||||||
\subsection{Dynamic semantics}
|
\subsection{Dynamic semantics}
|
||||||
Operationally, a parameterised resumption uses the first component as
|
The two reduction rules for parameterised handlers adapt the reduction
|
||||||
the return value of the operation, and the second component as the
|
rules for ordinary deep handlers with a parameter.
|
||||||
updated value of the handler parameter $q$.
|
|
||||||
%
|
%
|
||||||
This operational behaviour is formalised by following reduction rule
|
\begin{reductions}
|
||||||
$\semlab{Op^\param}$.
|
\semlab{Ret^\param} &
|
||||||
%
|
\ParamHandle \; (\Return \; V) \; \With \; (q.H)(W) &\reducesto& N[V/x,W/q],\\
|
||||||
\[
|
\multicolumn{4}{@{}r@{}}{
|
||||||
\ba{@{~}l@{~}l}
|
\hfill\text{where } \hret = \{ \Return \; x \mapsto N \}} \\
|
||||||
&\ParamHandle \; \EC[\Do \; \ell \; V] \; \With \; (q.~H)(W)\\
|
\semlab{Op^\param} &
|
||||||
\reducesto&
|
\ParamHandle \; \EC[\Do \; \ell \, V] \; \With \; (q.H)(W)
|
||||||
N[V/p,W/q,\lambda \Record{y;q'}.\Handle \; \EC[\Return \; y] \; \With \; (q.~H)(q')/r]\\
|
&\reducesto& N[V/p,W/q,R/r],\\
|
||||||
& \text{ where } \ell \notin BL(\EC) \text{ and } \hell = \{ \OpCase{\ell}{p}{r} \mapsto N \}
|
\multicolumn{4}{@{}r@{}}{
|
||||||
|
\hfill\ba[t]{@{~}r@{~}l}
|
||||||
|
\text{where}& R = \lambda\Record{y;q'}.\ParamHandle\;\EC[\Return \; y]\;\With\;(q.H)(q')\\
|
||||||
|
\text{and} &\hell = \{ \OpCase{\ell}{p}{r} \mapsto N \}\\
|
||||||
|
\text{and} &\ell \notin \BL(\EC)
|
||||||
\ea
|
\ea
|
||||||
\]
|
}
|
||||||
|
\end{reductions}
|
||||||
%
|
%
|
||||||
The parameter value $W$ is substituted for the parameter name $q$ into
|
The rule $\semlab{Ret^\param}$ handles the return value of a
|
||||||
the operation case body $N$. As with ordinary deep handlers, the
|
computation. Just like the rule $\semlab{Ret}$ the return value $V$ is
|
||||||
resumption rewraps its handler, but with the slight twist that the
|
substituted for the binder $x$ in the return case body
|
||||||
parameterised handler definition is applied to the updated parameter
|
$N$. Furthermore the value $W$ is substituted for the handler
|
||||||
value $q'$ rather than the original value $W$. The reduction rule for
|
parameter $q$ in $N$, meaning the handler parameter is accessible in
|
||||||
handling the return of a computation is as follows.
|
the return case.
|
||||||
%
|
|
||||||
\[
|
The $\semlab{Op^\param}$ handles an operation invocation. Both the
|
||||||
\ParamHandle \, (\Return \; V) \; \With \; (q.~H)(W) \reducesto N[V/x,W/q], \text{where } \hret = \{ \Return \; x \mapsto N \}
|
operation payload $V$ and handler argument $W$ are accessible inside
|
||||||
\]
|
the case body $N$. As with ordinary deep handlers, the resumption
|
||||||
%
|
rewraps its handler, but with the slight twist that the parameterised
|
||||||
Both the return value $V$ and the parameter value $W$ are substituted
|
handler definition is applied to the updated parameter value $q'$
|
||||||
into the return case body $N$ for their respective binders.
|
rather than the original value $W$. This achieves the effect of state
|
||||||
|
passing as the value of $q'$ becomes available upon the next
|
||||||
|
activation of the handler.
|
||||||
|
|
||||||
\subsection{Process synchronisation}
|
\subsection{Process synchronisation}
|
||||||
|
|
||||||
\[
|
\[
|
||||||
\Co \defas \{\UFork : \UnitType \opto \Int; \Wait : \Int \opto \UnitType; \Interrupt : \UnitType \opto \UnitType;\}
|
\Co \defas \{\UFork : \UnitType \opto \Int; \Wait : \Int \opto \UnitType; \Interrupt : \UnitType \opto \UnitType\}
|
||||||
\]
|
\]
|
||||||
|
|
||||||
\[
|
\[
|
||||||
\ba{@{~}l@{~}l@{~}c@{~}l}
|
\ba{@{~}l@{~}l@{~}c@{~}l}
|
||||||
\Proc &\alpha~\varepsilon &\defas& \Sstate \to \alpha \eff \varepsilon\\
|
\Proc &\alpha~\varepsilon &\defas& \Sstate \to \List~\alpha \eff \varepsilon\\
|
||||||
\Pstate &\alpha~\varepsilon &\defas& [\Ready:\Proc~\alpha~\varepsilon;\Blocked:\Record{\Int;\Proc~\alpha~\varepsilon}]\\
|
\Pstate &\alpha~\varepsilon &\defas& [\Ready:\Proc~\alpha~\varepsilon;\Blocked:\Record{\Int;\Proc~\alpha~\varepsilon}]\\
|
||||||
\Sstate &\alpha~\varepsilon &\defas& \Record{q:\List\,\Record{\Int;\Pstate~\alpha~\varepsilon};done:\List~\alpha;pid:\Int;pnext:\Int}\\
|
\Sstate &\alpha~\varepsilon &\defas& \Record{q:\List\,\Record{\Int;\Pstate~\alpha~\varepsilon};done:\List~\alpha;pid:\Int;pnext:\Int}\\
|
||||||
\ea
|
\ea
|
||||||
@@ -7642,12 +7675,6 @@ into the return case body $N$ for their respective binders.
|
|||||||
\Let\;st' \revto \Record{st\;\With\;q = q'; pnext = pid + 1}\;\In\\
|
\Let\;st' \revto \Record{st\;\With\;q = q'; pnext = pid + 1}\;\In\\
|
||||||
resume\,\Record{pid;st'}
|
resume\,\Record{pid;st'}
|
||||||
\el\\
|
\el\\
|
||||||
\OpCase{\Interrupt}{\Unit}{resume} \mapsto\\
|
|
||||||
\quad\bl
|
|
||||||
\Let\;resume' \revto \lambda st.resume\,\Record{\Unit;st}\;\In\\
|
|
||||||
\Let\;q' \revto st.q \concat [\Record{st.pid;\Ready~resume'}]\;\In\\
|
|
||||||
\runNext~\Record{st \;\With\; q = q'}
|
|
||||||
\el\\
|
|
||||||
\OpCase{\Wait}{pid}{resume} \mapsto\\
|
\OpCase{\Wait}{pid}{resume} \mapsto\\
|
||||||
\quad\bl
|
\quad\bl
|
||||||
\Let\;resume' \revto \lambda st.resume~\Record{\Unit;st}\;\In\\
|
\Let\;resume' \revto \lambda st.resume~\Record{\Unit;st}\;\In\\
|
||||||
@@ -7658,12 +7685,19 @@ into the return case body $N$ for their respective binders.
|
|||||||
\Else\;st.q \concat [\Record{st.pid;\Ready~resume'}]
|
\Else\;st.q \concat [\Record{st.pid;\Ready~resume'}]
|
||||||
\el\\
|
\el\\
|
||||||
\In\;\runNext\,\Record{st\;\With\;q = q'}
|
\In\;\runNext\,\Record{st\;\With\;q = q'}
|
||||||
|
\el\\
|
||||||
|
\OpCase{\Interrupt}{\Unit}{resume} \mapsto\\
|
||||||
|
\quad\bl
|
||||||
|
\Let\;resume' \revto \lambda st.resume\,\Record{\Unit;st}\;\In\\
|
||||||
|
\Let\;q' \revto st.q \concat [\Record{st.pid;\Ready~resume'}]\;\In\\
|
||||||
|
\runNext~\Record{st \;\With\; q = q'}
|
||||||
\el
|
\el
|
||||||
\el
|
\el
|
||||||
\el
|
\el
|
||||||
\el
|
\el
|
||||||
\]
|
\]
|
||||||
|
%
|
||||||
|
%
|
||||||
\[
|
\[
|
||||||
\bl
|
\bl
|
||||||
\timesharee : (\UnitType \to \alpha \eff \Co) \to \List~\alpha\\
|
\timesharee : (\UnitType \to \alpha \eff \Co) \to \List~\alpha\\
|
||||||
@@ -7674,7 +7708,21 @@ into the return case body $N$ for their respective binders.
|
|||||||
\el
|
\el
|
||||||
\el
|
\el
|
||||||
\]
|
\]
|
||||||
|
%
|
||||||
|
%
|
||||||
|
\[
|
||||||
|
\bl
|
||||||
|
\init : (\Unit \to \alpha \eff \varepsilon) \to \alpha \eff \{\Co;\Exit : \Int \opto \ZeroType;\varepsilon\}\\
|
||||||
|
\init~main \defas
|
||||||
|
\bl
|
||||||
|
\Let\;pid \revto \Do\;\UFork~\Unit\;\In\\
|
||||||
|
\If\;pid = 0\\
|
||||||
|
\Then\;main\,\Unit\\
|
||||||
|
\Else\;\Do\;\Wait~pid; \exit~1
|
||||||
|
\el
|
||||||
|
\el
|
||||||
|
\]
|
||||||
|
%
|
||||||
%
|
%
|
||||||
\[
|
\[
|
||||||
\ba{@{~}l@{~}l}
|
\ba{@{~}l@{~}l}
|
||||||
@@ -7708,10 +7756,10 @@ into the return case body $N$ for their respective binders.
|
|||||||
\ba[t]{@{}l}
|
\ba[t]{@{}l}
|
||||||
\Record{0;
|
\Record{0;
|
||||||
\ba[t]{@{}l@{}l}
|
\ba[t]{@{}l@{}l}
|
||||||
\texttt{"}&\texttt{UNIX is basically a simple operating system, but }\\
|
\texttt{"}&\texttt{To be, or not to be,\nl{}that is the question:\nl{}}\\
|
||||||
&\texttt{you have to be a genius to understand the simplicity.\nl}\\
|
&\texttt{Whether 'tis nobler in the mind to suffer\nl{}}\\
|
||||||
&\texttt{To be, or not to be,\nl{}that is the question:\nl{}}\\
|
&\texttt{UNIX is basically a simple operating system, but }\\
|
||||||
&\texttt{Whether 'tis nobler in the mind to suffer\nl{}"}}];
|
&\texttt{you have to be a genius to understand the simplicity.\nl"}}];
|
||||||
\ea\\
|
\ea\\
|
||||||
lnext=1; inext=1}}\\
|
lnext=1; inext=1}}\\
|
||||||
\ea
|
\ea
|
||||||
|
|||||||
Reference in New Issue
Block a user