mirror of
https://github.com/dhil/phd-dissertation
synced 2026-03-13 02:58:26 +00:00
Tidy up HO translation.
This commit is contained in:
185
thesis.tex
185
thesis.tex
@@ -860,8 +860,9 @@ given term.
|
||||
The function computes the set of free variables bottom-up. Most cases
|
||||
are homomorphic on the syntax constructors. The interesting cases are
|
||||
those constructs which feature term binders: lambda abstraction, let
|
||||
bindings, pair destructing, and case splitting. In each of those cases
|
||||
we subtract the relevant binder(s) from the set of free variables.
|
||||
bindings, pair deconstructing, and case splitting. In each of those
|
||||
cases we subtract the relevant binder(s) from the set of free
|
||||
variables.
|
||||
|
||||
\subsection{Typing rules}
|
||||
\label{sec:base-language-type-rules}
|
||||
@@ -1007,7 +1008,7 @@ application $V\,A$ is well-typed whenever the abstractor term $V$ has
|
||||
the polymorphic type $\forall \alpha^K.C$ and the type $A$ has kind
|
||||
$K$. This rule makes use of type substitution.
|
||||
%
|
||||
The \tylab{Split} rule handles typing of record destructing. When
|
||||
The \tylab{Split} rule handles typing of record deconstructing. When
|
||||
splitting a record term $V$ on some label $\ell$ binding it to $x$ and
|
||||
the remainder to $y$. The label we wish to split on must be present
|
||||
with some type $A$, hence we require that
|
||||
@@ -1566,9 +1567,9 @@ effect handlers which are an alternative to deep effect handlers.
|
||||
%
|
||||
Programming with effect handlers is a dichotomy of \emph{performing}
|
||||
and \emph{handling} of effectful operations -- or alternatively a
|
||||
dichotomy of \emph{constructing} and \emph{destructing}. An operation
|
||||
dichotomy of \emph{constructing} and \emph{deconstructing}. An operation
|
||||
is a constructor of an effect without a predefined semantics. A
|
||||
handler destructs effects by pattern-matching on their operations. By
|
||||
handler deconstructs effects by pattern-matching on their operations. By
|
||||
matching on a particular operation, a handler instantiates the said
|
||||
operation with a particular semantics of its own choosing. The key
|
||||
ingredient to make this work in practice is \emph{delimited
|
||||
@@ -2534,28 +2535,12 @@ operation clauses extract and convert the current resumption stack
|
||||
into a function using the $\Res$, and $\hforward$ augments the current
|
||||
resumption stack with the current continuation pair.
|
||||
%
|
||||
% Since we have only changed the representation of resumptions, the
|
||||
% translation of top-level programs remains the same.
|
||||
|
||||
\subsection{Higher-order translation for deep effect handlers}
|
||||
\label{sec:higher-order-uncurried-deep-handlers-cps}
|
||||
%
|
||||
\begin{figure}
|
||||
%
|
||||
% \textbf{Static patterns and static lists}
|
||||
% %
|
||||
% \begin{syntax}
|
||||
% \slab{Static patterns} &\sP& ::= & \sk \scons \sP \mid \sks \\
|
||||
% \slab{Static lists} &\VS& ::= & V \scons \VS \mid \reflect V \\
|
||||
% \end{syntax}
|
||||
% %
|
||||
% \textbf{Reification}
|
||||
% %
|
||||
% \begin{equations}
|
||||
% \reify (V \scons \VS) &\defas& V \dcons \reify \VS \\
|
||||
% \reify \reflect V &\defas& V \\
|
||||
% \end{equations}
|
||||
%
|
||||
\textbf{Values}
|
||||
%
|
||||
\begin{displaymath}
|
||||
@@ -2594,19 +2579,6 @@ resumption stack with the current continuation pair.
|
||||
\cps{-} &:& \HandlerCat \to \UCompCat\\
|
||||
\cps{\{\Return \; x \mapsto N\}} &\defas& \dlam x\, ks.\Let\; (h \dcons ks') = ks \;\In\; \cps{N} \sapp \reflect ks'
|
||||
\\
|
||||
% \cps{\{(\ell \; p \; r \mapsto N_\ell)_{\ell \in \mathcal{L}}\}}
|
||||
% &\defas&
|
||||
% \bl
|
||||
% \dlam z \, ks.\Case \;z\; \{
|
||||
% \bl
|
||||
% (\ell~\Record{p, s} \mapsto \dLet\;r=\Fun\,s \;\dIn\; \cps{N_{\ell}} \sapp \reflect ks)_{\ell \in \mathcal{L}};\,
|
||||
% y \mapsto \hforward \} \\
|
||||
% \el \\
|
||||
% \el \\
|
||||
% \hforward &\defas& \bl
|
||||
% \dLet\; (k' \dcons h' \dcons ks') = ks \;\dIn\; \\
|
||||
% \Vmap\,(\dlam\Record{p, s}\,(k \dcons ks).k\,\Record{p, h' \dcons k' \dcons s}\,ks)\,y\,(h' \dcons ks') \\
|
||||
% \el\\
|
||||
\cps{\{(\ell \; p \; r \mapsto N_\ell)_{\ell \in \mathcal{L}}\}}
|
||||
&\defas& \bl
|
||||
\dlam \Record{z,\Record{p,rs}}\,ks.\Case \;z\; \{
|
||||
@@ -2666,15 +2638,6 @@ alternating lists of pure continuation functions and effect
|
||||
continuation functions. To ease notation we are going make use of
|
||||
pattern matching notation. The static meta language is generated by
|
||||
the following productions.
|
||||
% Static constructs are marked in
|
||||
% {\color{blue}$\overline{\text{static blue}}$}, and their redexes are
|
||||
% reduced as part of the translation (at compile time). We make use of
|
||||
% static lambda abstractions, pairs, and lists. Reflection of dynamic
|
||||
% language values into the static language is written as $\reflect V$.
|
||||
% %
|
||||
% We use $\shk$ for variables representing statically known
|
||||
% continuations (frame stacks), $\shf$ for variables representing pure
|
||||
% frame stacks, and $\chi$ for variables representing handlers.
|
||||
%
|
||||
\begin{syntax}
|
||||
\slab{Static patterns} &\sP \in \SPatCat &::=& \sks \mid \sk \scons \sP\\
|
||||
@@ -2682,8 +2645,8 @@ the following productions.
|
||||
\slab{Static computations} & \sM \in \SCompCat &::=& \sV \sapp \sW \mid \sV \dapp V \dapp W
|
||||
\end{syntax}
|
||||
%
|
||||
The patterns comprise only static list destructing. We let $\sP$ range
|
||||
over static patterns.
|
||||
The patterns comprise only static list deconstructing. We let $\sP$
|
||||
range over static patterns.
|
||||
%
|
||||
The static values comprise dynamic values, reflected dynamic values,
|
||||
static lists, and static lambda abstractions. We let $\sV, \sW$ range
|
||||
@@ -2706,8 +2669,8 @@ Static computations are subject to the following equational axioms.
|
||||
The first equation is static $\beta$-equivalence, it states that
|
||||
applying a static lambda abstraction with binder $\sks$ and body $\sM$
|
||||
to a static value $\sV$ is equal to substituting $\sV$ for $\sks$ in
|
||||
$\sM$. The second equation allows us to apply a static list
|
||||
component-wise.
|
||||
$\sM$. The second equation provides a means for applying a static
|
||||
lambda abstraction to a static list component-wise.
|
||||
%
|
||||
\dhil{What about $\eta$-equivalence?}
|
||||
|
||||
@@ -2720,32 +2683,38 @@ $\reify \sV$ by induction on their structure.
|
||||
&\reify (\sV \scons \sW) \defas \reify \sV \dcons \reify \sW
|
||||
\ea
|
||||
\]
|
||||
|
||||
|
||||
%
|
||||
\dhil{Need to spell out that static pattern matching may induce dynamic (administrative) reductions}
|
||||
%
|
||||
\paragraph{Higher-order translation}
|
||||
The CPS translation is given in
|
||||
%
|
||||
The complete CPS translation is given in
|
||||
Figure~\ref{fig:cps-higher-order-uncurried}. In essence, it is the
|
||||
same as the CPS translation for deep and shallow handlers we described
|
||||
in Section~\ref{sec:pure-as-stack}, albeit separated into static and
|
||||
dynamic parts. A major difference that has a large cosmetic effect on
|
||||
the presentation of the translation is that we maintain the invariant
|
||||
that the statically known stack ($\sk$) always contains at least one
|
||||
frame, consisting of a triple
|
||||
$\sRecord{\reflect V_{fs}, \sRecord{\reflect V_{ret}, \reflect
|
||||
V_{ops}}}$ of reflected dynamic pure frame stacks, return
|
||||
handlers, and operation handlers. Maintaining this invariant ensures
|
||||
that all translations are uniform in whether they appear statically
|
||||
within the scope of a handler or not, and this simplifies our
|
||||
correctness proof. To maintain the invariant, any place where a
|
||||
dynamically known stack is passed in (as a continuation parameter
|
||||
$k$), it is immediately decomposed using a dynamic language $\Let$ and
|
||||
repackaged as a static value with reflected variable
|
||||
names. Unfortunately, this does add some clutter to the translation
|
||||
definition, as compared to the translations above. However, there is a
|
||||
payoff in the removal of administrative reductions at run time.
|
||||
same as the refined first-order uncurried CPS translation, although
|
||||
the notation is slightly more involved due to the separation of static
|
||||
and dynamic parts.
|
||||
%
|
||||
\dhil{Rewrite the above.}
|
||||
The translation on values is mostly homomorphic on the syntax
|
||||
constructors, except for $\lambda$- and $\Lambda$-abstractions which
|
||||
are translated in the exact same way, because the target calculus has
|
||||
no notion of types. As per usual continuation passing style practice,
|
||||
the translation of a lambda abstraction yields a dynamic binary lambda
|
||||
abstraction, where the second parameter is intended to be the
|
||||
continuation parameter. However, the translation slightly diverge from
|
||||
the usual practice in the translation of the body as the result of
|
||||
$\cps{M}$ is applied statically, rather than dynamically, to the
|
||||
(reflected) continuation parameter.
|
||||
%
|
||||
The reason is that the translation on computations is staged: for any
|
||||
given computation term the translation yields a static function, which
|
||||
can be applied to a static continuation to ultimately produce a
|
||||
$\UCalc$-computation term. This staging is key to eliminating static
|
||||
administrative redexes as any static function may perform static
|
||||
computation by manipulating its provided static continuation, as is
|
||||
for instance done in the translation of $\Let$.
|
||||
%
|
||||
\dhil{Spell out why this translation qualifies as `higher-order'.}
|
||||
|
||||
Let us again revisit the example from
|
||||
Section~\ref{sec:first-order-curried-cps} to see that the higher-order
|
||||
translation eliminates the static redex at translation time.
|
||||
@@ -2758,15 +2727,19 @@ translation eliminates the static redex at translation time.
|
||||
\end{equations}
|
||||
%
|
||||
In contrast with the previous translations, the image of this
|
||||
translation admits only a single dynamic reduction.
|
||||
translation admits only a single dynamic reduction (disregarding the
|
||||
dynamic administrative reductions arising from continuation
|
||||
construction and deconstruction).
|
||||
|
||||
\subsubsection{Correctness}
|
||||
\label{sec:higher-order-cps-deep-handlers-correctness}
|
||||
|
||||
In order to prove the correctness of the higher-order uncurried CPS
|
||||
translation (Theorem~\ref{thm:ho-simulation}), we first state several
|
||||
auxiliary lemmas describing how translated terms behave. First, the
|
||||
higher-order CPS translation commutes with substitution.
|
||||
We establish the correctness of the higher-order uncurried CPS
|
||||
translation via a simulation result in style of
|
||||
Plotkin~\cite{Plotkin75} (Theorem~\ref{thm:ho-simulation}). However,
|
||||
before we can state and prove this result, we first several auxiliary
|
||||
lemmas describing how translated terms behave. First, the higher-order
|
||||
CPS translation commutes with substitution.
|
||||
%
|
||||
\begin{lemma}[Substitution]\label{lem:ho-cps-subst}
|
||||
%
|
||||
@@ -2811,8 +2784,8 @@ It follows as a corollary that top-level substitution is well-behaved.
|
||||
Lemma~\ref{lem:ho-cps-subst}.
|
||||
\end{proof}
|
||||
%
|
||||
In order to reason about the behaviour of the \semlab{Op} rule,
|
||||
which is defined in terms of an evaluation context, we extend the CPS
|
||||
In order to reason about the behaviour \semlab{Op} rule, which is
|
||||
defined in terms of an evaluation context, we need to extend the CPS
|
||||
translation to evaluation contexts.
|
||||
%
|
||||
\begin{equations}
|
||||
@@ -2825,8 +2798,9 @@ translation to evaluation contexts.
|
||||
The following lemma is the characteristic property of the CPS
|
||||
translation on evaluation contexts.
|
||||
%
|
||||
This allows us to focus on the computation contained within
|
||||
an evaluation context.
|
||||
It provides a means for decomposing an evaluation context, such that
|
||||
we can focus on the computation contained within the evaluation
|
||||
context.
|
||||
%
|
||||
\begin{lemma}[Decomposition]
|
||||
\label{lem:decomposition}
|
||||
@@ -2841,26 +2815,27 @@ an evaluation context.
|
||||
Proof by structural induction on the evaluation context $\EC$.
|
||||
\end{proof}
|
||||
%
|
||||
Though we have eliminated the static administrative redexes, we are
|
||||
still left with one form of administrative redex that cannot be
|
||||
eliminated statically because it only appears at run-time. These arise
|
||||
from pattern matching against a reified stack of continuations and are
|
||||
given by the $\usemlab{SplitList}$ rule.
|
||||
Even though we have eliminated the static administrative redexes, we
|
||||
still need to account for the dynamic administrative redexes that
|
||||
arise from pattern matching against a reified continuation. To
|
||||
properly account for these administrative redexes it is convenient to
|
||||
treat list pattern matching as a primitive in $\UCalc$, therefore we
|
||||
introduce a new reduction rule $\usemlab{SplitList}$ in $\UCalc$.
|
||||
%
|
||||
\begin{reductions}
|
||||
\usemlab{SplitList} & \Let\; (k \dcons ks) = V \dcons W \;\In\; M &\reducesto& M[V/k, W/ks] \\
|
||||
\end{reductions}
|
||||
%
|
||||
This is isomorphic to the \usemlab{Split} rule, but we now treat lists
|
||||
and \usemlab{SplitList} as distinct from pairs, unit, and
|
||||
\usemlab{Split} in the higher-order translation so that we can
|
||||
properly account for administrative reduction.
|
||||
Note this rule is isomorphic to the \usemlab{Split} rule with lists
|
||||
encoded as right nested pairs using unit to denote nil.
|
||||
%
|
||||
We write $\areducesto$ for the compatible closure of
|
||||
\usemlab{SplitList}.
|
||||
|
||||
By definition, $\reify \reflect V = V$, but we also need to reason
|
||||
about the inverse composition.
|
||||
We also need to be able to reason about the computational content of
|
||||
reflection after reification. By definition we have that
|
||||
$\reify \reflect V = V$, the following lemma lets us reason about the
|
||||
inverse composition.
|
||||
%
|
||||
\begin{lemma}[Reflect after reify]
|
||||
\label{lem:reflect-after-reify}
|
||||
@@ -2917,10 +2892,10 @@ Follows from Lemmas~\ref{lem:decomposition},
|
||||
\ref{lem:reflect-after-reify}, and \ref{lem:forwarding}.
|
||||
\end{proof}
|
||||
%
|
||||
We now turn to our main result which is a simulation result in style
|
||||
of Plotkin~\cite{Plotkin75}. The theorem shows that the only extra
|
||||
behaviour exhibited by a translated term is the bureaucracy of
|
||||
deconstructing the continuation stack.
|
||||
Finally, we have the ingredients to state and prove the simulation
|
||||
result. The following theorem shows that the only extra behaviour
|
||||
exhibited by a translated term is the bureaucracy of deconstructing
|
||||
the continuation stack.
|
||||
%
|
||||
\begin{theorem}[Simulation]
|
||||
\label{thm:ho-simulation}
|
||||
@@ -2933,18 +2908,18 @@ If $M \reducesto N$ then $\pcps{M} \reducesto^+ \areducesto^* \pcps{N}$.
|
||||
follows from Lemma~\ref{lem:handle-op}.
|
||||
\end{proof}
|
||||
%
|
||||
In common with most CPS translations, full abstraction does not
|
||||
hold. However, as our semantics is deterministic it is straightforward
|
||||
to show a backward simulation result.
|
||||
%
|
||||
\begin{corollary}[Backwards simulation]
|
||||
If $\pcps{M} \reducesto^+ \areducesto^* V$ then there exists $W$ such that
|
||||
$M \reducesto^* W$ and $\pcps{W} = V$.
|
||||
\end{corollary}
|
||||
%
|
||||
\begin{proof}
|
||||
TODO\dots
|
||||
\end{proof}
|
||||
% In common with most CPS translations, full abstraction does not
|
||||
% hold. However, as our semantics is deterministic it is straightforward
|
||||
% to show a backward simulation result.
|
||||
% %
|
||||
% \begin{corollary}[Backwards simulation]
|
||||
% If $\pcps{M} \reducesto^+ \areducesto^* V$ then there exists $W$ such that
|
||||
% $M \reducesto^* W$ and $\pcps{W} = V$.
|
||||
% \end{corollary}
|
||||
% %
|
||||
% \begin{proof}
|
||||
% TODO\dots
|
||||
% \end{proof}
|
||||
%
|
||||
\chapter{Abstract machine semantics}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user