mirror of
https://github.com/dhil/phd-dissertation
synced 2026-03-13 11:08:25 +00:00
WIP
This commit is contained in:
233
thesis.tex
233
thesis.tex
@@ -14839,7 +14839,7 @@ the captured context and continuation invocation context to coincide.
|
|||||||
% Felleisen's macro-expressiveness, Longley's type-respecting
|
% Felleisen's macro-expressiveness, Longley's type-respecting
|
||||||
% expressiveness, Kammar's typability-preserving expressiveness.
|
% expressiveness, Kammar's typability-preserving expressiveness.
|
||||||
|
|
||||||
\chapter{Asymptotic speedup with first-class control}
|
\chapter{Asymptotic speedup with effect handlers}
|
||||||
\label{ch:handlers-efficiency}
|
\label{ch:handlers-efficiency}
|
||||||
\def\LLL{{\mathcal L}}
|
\def\LLL{{\mathcal L}}
|
||||||
\def\N{{\mathbb N}}
|
\def\N{{\mathbb N}}
|
||||||
@@ -15068,12 +15068,12 @@ The rest of the paper is structured as follows.
|
|||||||
\item Section~\ref{sec:handlers-primer} provides an introduction to
|
\item Section~\ref{sec:handlers-primer} provides an introduction to
|
||||||
effect handlers as a programming abstraction.
|
effect handlers as a programming abstraction.
|
||||||
\item Section~\ref{sec:calculi} presents a PCF-like language
|
\item Section~\ref{sec:calculi} presents a PCF-like language
|
||||||
$\BCalc$ and its extension $\HCalc$ with effect handlers.
|
$\BPCF$ and its extension $\HPCF$ with effect handlers.
|
||||||
\item Section~\ref{sec:abstract-machine-semantics} defines abstract
|
\item Section~\ref{sec:abstract-machine-semantics} defines abstract
|
||||||
machines for $\BCalc$ and $\HCalc$, yielding a runtime cost model.
|
machines for $\BPCF$ and $\HPCF$, yielding a runtime cost model.
|
||||||
\item Section~\ref{sec:generic-search} introduces generic count and
|
\item Section~\ref{sec:generic-search} introduces generic count and
|
||||||
some associated machinery, and presents an implementation in
|
some associated machinery, and presents an implementation in
|
||||||
$\HCalc$ with runtime $\BigO(2^n)$.
|
$\HPCF$ with runtime $\BigO(2^n)$.
|
||||||
\item Section~\ref{sec:pure-counting} establishes that any generic
|
\item Section~\ref{sec:pure-counting} establishes that any generic
|
||||||
count implementation in $\BCalc$ must have runtime $\Omega(n2^n)$.
|
count implementation in $\BCalc$ must have runtime $\Omega(n2^n)$.
|
||||||
\item Section~\ref{sec:robustness} shows that our results scale to
|
\item Section~\ref{sec:robustness} shows that our results scale to
|
||||||
@@ -15081,11 +15081,11 @@ The rest of the paper is structured as follows.
|
|||||||
the adaptation from generic count to generic search, and an
|
the adaptation from generic count to generic search, and an
|
||||||
extension of the base language with state.
|
extension of the base language with state.
|
||||||
\item Section~\ref{sec:experiments} evaluates implementations of
|
\item Section~\ref{sec:experiments} evaluates implementations of
|
||||||
generic search based on $\BCalc$ and $\HCalc$ in Standard ML.
|
generic search based on $\BPCF$ and $\HPCF$ in Standard ML.
|
||||||
\item Section \ref{sec:conclusions} concludes.
|
\item Section \ref{sec:conclusions} concludes.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
%
|
%
|
||||||
The languages $\BCalc$ and $\HCalc$ are rather minimal versions of
|
The languages $\BPCF$ and $\HPCF$ are rather minimal versions of
|
||||||
previously studied systems --- we only include the machinery needed
|
previously studied systems --- we only include the machinery needed
|
||||||
for illustrating the generic search efficiency phenomenon.
|
for illustrating the generic search efficiency phenomenon.
|
||||||
%
|
%
|
||||||
@@ -15097,11 +15097,11 @@ version of the paper~\citep{HillerstromLL20}.
|
|||||||
%%
|
%%
|
||||||
\section{Calculi}
|
\section{Calculi}
|
||||||
\label{sec:calculi}
|
\label{sec:calculi}
|
||||||
In this section, we present our base language $\BCalc$ and its
|
In this section, we present our base language $\BPCF$ and its
|
||||||
extension with effect handlers $\HCalc$.
|
extension with effect handlers $\HPCF$.
|
||||||
|
|
||||||
\subsection{Base Calculus}
|
\subsection{Base Calculus}
|
||||||
The base calculus $\BCalc$ is a fine-grain
|
The base calculus $\BPCF$ is a fine-grain
|
||||||
call-by-value~\cite{LevyPT03} variation of PCF~\cite{Plotkin77}.
|
call-by-value~\cite{LevyPT03} variation of PCF~\cite{Plotkin77}.
|
||||||
%
|
%
|
||||||
Fine-grain call-by-value is similar to A-normal
|
Fine-grain call-by-value is similar to A-normal
|
||||||
@@ -15109,11 +15109,10 @@ form~\cite{FlanaganSDF93} in that every intermediate computation is
|
|||||||
named, but unlike A-normal form is closed under reduction.
|
named, but unlike A-normal form is closed under reduction.
|
||||||
|
|
||||||
The syntax of $\BCalc$ is as follows.
|
The syntax of $\BCalc$ is as follows.
|
||||||
{\small
|
{\noindent
|
||||||
\noindent
|
|
||||||
\begin{syntax}
|
\begin{syntax}
|
||||||
\slab{Types} &A,B,C,D\in\TypeCat &::= & \Nat \mid \One \mid A \to B \mid A \times B \mid A + B \\
|
\slab{Types} &A,B,C,D\in\TypeCat &::= & \Nat \mid \One \mid A \to B \mid A \times B \mid A + B \\
|
||||||
\slab{Type Environments} &\Gamma\in\CtxCat &::= & \cdot \mid \Gamma, x:A \\
|
\slab{Type\textrm{ }Environments} &\Gamma\in\CtxCat &::= & \cdot \mid \Gamma, x:A \\
|
||||||
\slab{Values} &V,W\in\ValCat &::= & x \mid k \mid c \mid \lambda x^A .\, M \mid \Rec \; f^{A \to B}\, x.M \\
|
\slab{Values} &V,W\in\ValCat &::= & x \mid k \mid c \mid \lambda x^A .\, M \mid \Rec \; f^{A \to B}\, x.M \\
|
||||||
& &\mid& \Unit \mid \Record{V, W} \mid (\Inl\, V)^B \mid (\Inr\, W)^A\\
|
& &\mid& \Unit \mid \Record{V, W} \mid (\Inl\, V)^B \mid (\Inr\, W)^A\\
|
||||||
% & & &
|
% & & &
|
||||||
@@ -15168,9 +15167,7 @@ A trivial computation $(\Return\;V)$ returns value $V$. The sequencing
|
|||||||
expression $(\Let \; x \revto M \; \In \; N)$ evaluates $M$ and binds
|
expression $(\Let \; x \revto M \; \In \; N)$ evaluates $M$ and binds
|
||||||
the result value to $x$ in $N$.
|
the result value to $x$ in $N$.
|
||||||
|
|
||||||
|
|
||||||
\begin{figure*}
|
\begin{figure*}
|
||||||
\small
|
|
||||||
\raggedright\textbf{Values}
|
\raggedright\textbf{Values}
|
||||||
\begin{mathpar}
|
\begin{mathpar}
|
||||||
% Variable
|
% Variable
|
||||||
@@ -15257,7 +15254,7 @@ the result value to $x$ in $N$.
|
|||||||
}
|
}
|
||||||
{\typ{\Gamma}{\Let \; x \revto M\; \In \; N : C}}
|
{\typ{\Gamma}{\Let \; x \revto M\; \In \; N : C}}
|
||||||
\end{mathpar}
|
\end{mathpar}
|
||||||
\caption{Typing Rules for $\BCalc$}
|
\caption{Typing rules for $\BPCF$.}
|
||||||
\label{fig:typing}
|
\label{fig:typing}
|
||||||
\end{figure*}
|
\end{figure*}
|
||||||
|
|
||||||
@@ -15272,7 +15269,7 @@ either a value term ($V$) or a computation term ($M$).
|
|||||||
%
|
%
|
||||||
The constants have the following types.
|
The constants have the following types.
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\begin{mathpar}
|
\begin{mathpar}
|
||||||
\{(+), (-)\} : \Nat \times \Nat \to \Nat
|
\{(+), (-)\} : \Nat \times \Nat \to \Nat
|
||||||
|
|
||||||
@@ -15280,15 +15277,14 @@ The constants have the following types.
|
|||||||
\end{mathpar}}
|
\end{mathpar}}
|
||||||
%
|
%
|
||||||
\begin{figure*}
|
\begin{figure*}
|
||||||
\small
|
|
||||||
\begin{reductions}
|
\begin{reductions}
|
||||||
\semlab{App} & (\lambda x^A . \, M) V &\reducesto& M[V/x] \\
|
\semlab{App} & (\lambda x^A . \, M) V &\reducesto& M[V/x] \\
|
||||||
\semlab{App-Rec} & (\Rec\; f^A \,x.\, M) V &\reducesto& M[(\Rec\;f^A\,x .\,M)/f,V/x]\\
|
\semlab{App\textrm{-}Rec} & (\Rec\; f^A \,x.\, M) V &\reducesto& M[(\Rec\;f^A\,x .\,M)/f,V/x]\\
|
||||||
\semlab{Const} & c~V &\reducesto& \Return\;(\const{c}\,(V)) \\
|
\semlab{Const} & c~V &\reducesto& \Return\;(\const{c}\,(V)) \\
|
||||||
\semlab{Split} & \Let \; \Record{x,y} = \Record{V,W} \; \In \; N &\reducesto& N[V/x,W/y] \\
|
\semlab{Split} & \Let \; \Record{x,y} = \Record{V,W} \; \In \; N &\reducesto& N[V/x,W/y] \\
|
||||||
\semlab{Case-inl} &
|
\semlab{Case\textrm{-}inl} &
|
||||||
\Case \; (\Inl\, V)^B \; \{\Inl \; x \mapsto M;\Inr \; y \mapsto N\} &\reducesto& M[V/x] \\
|
\Case \; (\Inl\, V)^B \; \{\Inl \; x \mapsto M;\Inr \; y \mapsto N\} &\reducesto& M[V/x] \\
|
||||||
\semlab{Case-inr} &
|
\semlab{Case\textrm{-}inr} &
|
||||||
\Case \; (\Inr\, V)^A \; \{\Inl \; x \mapsto M; \Inr \; y \mapsto N\} &\reducesto& N[V/y]\\
|
\Case \; (\Inr\, V)^A \; \{\Inl \; x \mapsto M; \Inr \; y \mapsto N\} &\reducesto& N[V/y]\\
|
||||||
\semlab{Let} &
|
\semlab{Let} &
|
||||||
\Let \; x \revto \Return \; V \; \In \; N &\reducesto& N[V/x] \\
|
\Let \; x \revto \Return \; V \; \In \; N &\reducesto& N[V/x] \\
|
||||||
@@ -15296,9 +15292,9 @@ The constants have the following types.
|
|||||||
\EC[M] &\reducesto& \EC[N], \hfill \text{if }M \reducesto N \\
|
\EC[M] &\reducesto& \EC[N], \hfill \text{if }M \reducesto N \\
|
||||||
\end{reductions}
|
\end{reductions}
|
||||||
\begin{syntax}
|
\begin{syntax}
|
||||||
\slab{Evaluation contexts} & \mathcal{E} &::=& [\,] \mid \Let \; x \revto \mathcal{E} \; \In \; N
|
\slab{Evaluation\textrm{ }contexts} & \mathcal{E} &::=& [\,] \mid \Let \; x \revto \mathcal{E} \; \In \; N
|
||||||
\end{syntax}
|
\end{syntax}
|
||||||
\caption{Contextual Small-Step Operational Semantics}
|
\caption{Contextual small-step operational semantics.}
|
||||||
\label{fig:small-step}
|
\label{fig:small-step}
|
||||||
\end{figure*}
|
\end{figure*}
|
||||||
%
|
%
|
||||||
@@ -15326,7 +15322,7 @@ call-by-value~\citep{Moggi91, FlanaganSDF93}.
|
|||||||
For example, the expression $f\,(h\,w) + g\,\Unit$ is syntactic sugar
|
For example, the expression $f\,(h\,w) + g\,\Unit$ is syntactic sugar
|
||||||
for:
|
for:
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\ba[t]{@{~}l}
|
\ba[t]{@{~}l}
|
||||||
\Let\; x \revto h\,w \;\In\;
|
\Let\; x \revto h\,w \;\In\;
|
||||||
@@ -15338,7 +15334,7 @@ for:
|
|||||||
%
|
%
|
||||||
We define sequencing of computations in the standard way.
|
We define sequencing of computations in the standard way.
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
M;N \defas \Let\;x \revto M \;\In\;N, \quad \text{where $x \notin FV(N)$}
|
M;N \defas \Let\;x \revto M \;\In\;N, \quad \text{where $x \notin FV(N)$}
|
||||||
\]}%
|
\]}%
|
||||||
@@ -15346,7 +15342,7 @@ We define sequencing of computations in the standard way.
|
|||||||
We make use of standard syntactic sugar for pattern matching. For
|
We make use of standard syntactic sugar for pattern matching. For
|
||||||
instance, we write
|
instance, we write
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\lambda\Unit.M \defas \lambda x^{\One}.M, \quad \text{where $x \notin FV(M)$}
|
\lambda\Unit.M \defas \lambda x^{\One}.M, \quad \text{where $x \notin FV(M)$}
|
||||||
\]}%
|
\]}%
|
||||||
@@ -15354,13 +15350,13 @@ instance, we write
|
|||||||
for suspended computations, and if the binder has a type other than
|
for suspended computations, and if the binder has a type other than
|
||||||
$\One$, we write:
|
$\One$, we write:
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\lambda\_^A.M \defas \lambda x^A.M, \quad \text{where $x \notin FV(M)$}
|
\lambda\_^A.M \defas \lambda x^A.M, \quad \text{where $x \notin FV(M)$}
|
||||||
\]}%
|
\]}%
|
||||||
%
|
%
|
||||||
We use the standard encoding of booleans as a sum:
|
We use the standard encoding of booleans as a sum:
|
||||||
{\small
|
{
|
||||||
\begin{mathpar}
|
\begin{mathpar}
|
||||||
\Bool \defas \One + \One
|
\Bool \defas \One + \One
|
||||||
|
|
||||||
@@ -15379,15 +15375,15 @@ We use the standard encoding of booleans as a sum:
|
|||||||
|
|
||||||
We now define $\HCalc$ as an extension of $\BCalc$.
|
We now define $\HCalc$ as an extension of $\BCalc$.
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\begin{syntax}
|
\begin{syntax}
|
||||||
\slab{Operation symbols} &\ell \in \mathcal{L} & & \\
|
\slab{Operation\textrm{ }symbols} &\ell \in \mathcal{L} & & \\
|
||||||
\slab{Signatures} &\Sigma&::=& \cdot \mid \{\ell : A \to B\} \cup \Sigma\\
|
\slab{Signatures} &\Sigma&::=& \cdot \mid \{\ell : A \to B\} \cup \Sigma\\
|
||||||
\slab{Handler types} &F &::=& C \Rightarrow D\\
|
\slab{Handler\textrm{ }types} &F &::=& C \Rightarrow D\\
|
||||||
\slab{Computations} &M, N &::=& \dots \mid \Do \; \ell \; V
|
\slab{Computations} &M, N &::=& \dots \mid \Do \; \ell \; V
|
||||||
\mid \Handle \; M \; \With \; H \\
|
\mid \Handle \; M \; \With \; H \\
|
||||||
\slab{Handlers} &H&::=& \{ \Val \; x \mapsto M \}
|
\slab{Handlers} &H&::=& \{ \Return \; x \mapsto M \}
|
||||||
\mid \{ \ell \; p \; r \mapsto N \} \uplus H\\
|
\mid \{ \OpCase{\ell}{p}{r} \mapsto N \} \uplus H\\
|
||||||
\end{syntax}}%
|
\end{syntax}}%
|
||||||
%
|
%
|
||||||
We assume a countably infinite set $\mathcal{L}$ of operation symbols
|
We assume a countably infinite set $\mathcal{L}$ of operation symbols
|
||||||
@@ -15398,7 +15394,7 @@ types, thus we assume that each operation symbol in a signature is
|
|||||||
distinct. An operation type $A \to B$ classifies operations that take
|
distinct. An operation type $A \to B$ classifies operations that take
|
||||||
an argument of type $A$ and return a result of type $B$.
|
an argument of type $A$ and return a result of type $B$.
|
||||||
%
|
%
|
||||||
We write $dom(\Sigma) \subseteq \mathcal{L}$ for the set of operation
|
We write $\dom(\Sigma) \subseteq \mathcal{L}$ for the set of operation
|
||||||
symbols in a signature $\Sigma$.
|
symbols in a signature $\Sigma$.
|
||||||
%
|
%
|
||||||
A handler type $C \Rightarrow D$ classifies effect handlers that
|
A handler type $C \Rightarrow D$ classifies effect handlers that
|
||||||
@@ -15419,11 +15415,10 @@ with missing operation clauses (with respect to $\Sigma$) is syntactic
|
|||||||
sugar for one in which all missing clauses perform explicit
|
sugar for one in which all missing clauses perform explicit
|
||||||
forwarding:
|
forwarding:
|
||||||
\[
|
\[
|
||||||
\{\ell \; p \; r \mapsto \Let\; x \revto \Do \; \ell \, p \;\In\; r \, x\}
|
\{\OpCase{\ell}{p}{r} \mapsto \Let\; x \revto \Do \; \ell \, p \;\In\; r \, x\}.
|
||||||
\]
|
\]
|
||||||
|
|
||||||
\begin{figure*}
|
\begin{figure*}
|
||||||
\small
|
|
||||||
\raggedright
|
\raggedright
|
||||||
\textbf{Computations}
|
\textbf{Computations}
|
||||||
\begin{mathpar}
|
\begin{mathpar}
|
||||||
@@ -15447,11 +15442,11 @@ forwarding:
|
|||||||
{{\Gamma} \vdash {H : C \Rightarrow D}}
|
{{\Gamma} \vdash {H : C \Rightarrow D}}
|
||||||
\end{mathpar}
|
\end{mathpar}
|
||||||
|
|
||||||
\caption{Additional Typing Rules for $\HCalc$}
|
\caption{Additional typing rules for $\HPCF$}
|
||||||
\label{fig:typing-handlers}
|
\label{fig:typing-handlers}
|
||||||
\end{figure*}
|
\end{figure*}
|
||||||
|
|
||||||
The typing rules for $\HCalc$ are those of $\BCalc$
|
The typing rules for $\HPCF$ are those of $\BPCF$
|
||||||
(Figure~\ref{fig:typing}) plus three additional rules for operations,
|
(Figure~\ref{fig:typing}) plus three additional rules for operations,
|
||||||
handling, and handlers given in Figure~\ref{fig:typing-handlers}.
|
handling, and handlers given in Figure~\ref{fig:typing-handlers}.
|
||||||
%
|
%
|
||||||
@@ -15473,11 +15468,11 @@ be handled by $H$.
|
|||||||
%
|
%
|
||||||
We write $\hell$ and $\hret$ for projecting success and operation
|
We write $\hell$ and $\hret$ for projecting success and operation
|
||||||
clauses.
|
clauses.
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\ba{@{~}r@{~}c@{~}l@{~}l}
|
\ba{@{~}r@{~}c@{~}l@{~}l}
|
||||||
\hret &\defas& \{\Val\, x \mapsto M \}, &\quad \text{where } \{\Val\, x \mapsto M \} \in H\\
|
\hret &\defas& \{\Return\, x \mapsto N \}, &\quad \text{where } \{\Return\, x \mapsto N \} \in H\\
|
||||||
\hell &\defas& \{\ell\, p\,r \mapsto M \}, &\quad \text{where } \{\ell\, p\;r \mapsto M \} \in H
|
\hell &\defas& \{\OpCase{\ell}{p}{r} \mapsto N \}, &\quad \text{where } \{\OpCase{\ell}{p}{r} \mapsto N \} \in H
|
||||||
\ea
|
\ea
|
||||||
\]}%
|
\]}%
|
||||||
|
|
||||||
@@ -15485,11 +15480,11 @@ We extend the operational semantics to $\HCalc$. Specifically, we add
|
|||||||
two new reduction rules: one for handling return values and another
|
two new reduction rules: one for handling return values and another
|
||||||
for handling operation invocations.
|
for handling operation invocations.
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\begin{reductions}
|
\begin{reductions}
|
||||||
\semlab{Ret} & \Handle \; (\Return \; V) \; \With \; H &\reducesto& N[V/x], \qquad
|
\semlab{Ret} & \Handle \; (\Return \; V) \; \With \; H &\reducesto& N[V/x], \qquad
|
||||||
\text{where } \hret = \{ \Val \; x \mapsto N \} \smallskip\\
|
\text{where } \hret = \{ \Return \; x \mapsto N \} \smallskip\\
|
||||||
\semlab{Op} & \Handle \; \EC[\Do \; \ell \, V] \; \With \; H &\reducesto& N[V/p,\; (\lambda y.\Handle \; \EC[\Return \; y] \; \With \; H)/r],\\
|
\semlab{Op} & \Handle \; \EC[\Do \; \ell \, V] \; \With \; H &\reducesto& N[V/p,(\lambda y.\Handle \; \EC[\Return \; y] \; \With \; H)/r],\\
|
||||||
\multicolumn{4}{@{}r@{}}{
|
\multicolumn{4}{@{}r@{}}{
|
||||||
\hfill\text{where } \hell = \{ \ell\, p \; r \mapsto N \}
|
\hfill\text{where } \hell = \{ \ell\, p \; r \mapsto N \}
|
||||||
}
|
}
|
||||||
@@ -15508,15 +15503,15 @@ In order to ensure that the semantics is deterministic, we instead add
|
|||||||
a distinct form of evaluation context for effectful computation, which
|
a distinct form of evaluation context for effectful computation, which
|
||||||
we call handler contexts.
|
we call handler contexts.
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\begin{syntax}
|
\begin{syntax}
|
||||||
\slab{Handler contexts} & \HC &::= & [\,] \mid \Handle \; \HC \; \With \; H
|
\slab{Handler\textrm{ }contexts} & \HC &::= & [\,] \mid \Handle \; \HC \; \With \; H
|
||||||
\mid \Let\;x \revto \HC\; \In\; N\\
|
\mid \Let\;x \revto \HC\; \In\; N\\
|
||||||
\end{syntax}}%
|
\end{syntax}}%
|
||||||
%
|
%
|
||||||
We replace the $\semlab{Lift}$ rule with a corresponding rule for
|
We replace the $\semlab{Lift}$ rule with a corresponding rule for
|
||||||
handler contexts.
|
handler contexts.
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\HC[M] ~\reducesto~ \HC[N], \qquad\hfill\text{if } M \reducesto N
|
\HC[M] ~\reducesto~ \HC[N], \qquad\hfill\text{if } M \reducesto N
|
||||||
\]}%
|
\]}%
|
||||||
@@ -15544,7 +15539,7 @@ property of $\HCalc$.
|
|||||||
%%
|
%%
|
||||||
%% Abstract machine semantics
|
%% Abstract machine semantics
|
||||||
%%
|
%%
|
||||||
\subsection{The Role of Types}
|
\subsection{The role of types}
|
||||||
|
|
||||||
Readers familiar with backtracking search algorithms may wonder where
|
Readers familiar with backtracking search algorithms may wonder where
|
||||||
types come into the expressiveness picture.
|
types come into the expressiveness picture.
|
||||||
@@ -15566,10 +15561,10 @@ include effect types.
|
|||||||
Future work includes reconciling effect typing with our approach to
|
Future work includes reconciling effect typing with our approach to
|
||||||
expressiveness.
|
expressiveness.
|
||||||
|
|
||||||
\section{Abstract Machine Semantics}
|
\section{Abstract machine semantics}
|
||||||
\label{sec:abstract-machine-semantics}
|
\label{sec:abstract-machine-semantics}
|
||||||
Thus far we have introduced the base calculus $\BCalc$ and its
|
Thus far we have introduced the base calculus $\BPCF$ and its
|
||||||
extension with effect handlers $\HCalc$.
|
extension with effect handlers $\HPCF$.
|
||||||
%
|
%
|
||||||
For each calculus we have given a \emph{small-step operational
|
For each calculus we have given a \emph{small-step operational
|
||||||
semantics} which uses a substitution model for evaluation. Whilst
|
semantics} which uses a substitution model for evaluation. Whilst
|
||||||
@@ -15578,7 +15573,7 @@ realistic account of practical computation as substitution is an
|
|||||||
expensive operation. We now develop a more practical model of
|
expensive operation. We now develop a more practical model of
|
||||||
computation based on an \emph{abstract machine semantics}.
|
computation based on an \emph{abstract machine semantics}.
|
||||||
|
|
||||||
\subsection{Base Machine}
|
\subsection{Base machine}
|
||||||
\label{sec:base-abstract-machine}
|
\label{sec:base-abstract-machine}
|
||||||
|
|
||||||
\newcommand{\Conf}{\dec{Conf}}
|
\newcommand{\Conf}{\dec{Conf}}
|
||||||
@@ -15597,7 +15592,7 @@ third component contains the continuation which instructs the machine
|
|||||||
how to proceed once evaluation of the current computation is complete.
|
how to proceed once evaluation of the current computation is complete.
|
||||||
%
|
%
|
||||||
The syntax of abstract machine states is as follows.
|
The syntax of abstract machine states is as follows.
|
||||||
{\small
|
{
|
||||||
\begin{syntax}
|
\begin{syntax}
|
||||||
\slab{Configurations} & \conf \in \Conf &::=& \cek{M \mid \env \mid \sigma} \\
|
\slab{Configurations} & \conf \in \Conf &::=& \cek{M \mid \env \mid \sigma} \\
|
||||||
% & &\mid& \cekop{M \mid \env \mid \kappa \mid \kappa'} \\
|
% & &\mid& \cekop{M \mid \env \mid \kappa \mid \kappa'} \\
|
||||||
@@ -15623,7 +15618,6 @@ pattern matching to deconstruct pure continuations.
|
|||||||
%
|
%
|
||||||
|
|
||||||
\begin{figure*}
|
\begin{figure*}
|
||||||
\small
|
|
||||||
\raggedright
|
\raggedright
|
||||||
\textbf{Transition relation}
|
\textbf{Transition relation}
|
||||||
\begin{reductions}
|
\begin{reductions}
|
||||||
@@ -15703,7 +15697,7 @@ pattern matching to deconstruct pure continuations.
|
|||||||
\el
|
\el
|
||||||
\]
|
\]
|
||||||
|
|
||||||
\caption{Abstract Machine Semantics for $\BCalc$}
|
\caption{Abstract machine semantics for $\BPCF$.}
|
||||||
\label{fig:abstract-machine-semantics}
|
\label{fig:abstract-machine-semantics}
|
||||||
\end{figure*}
|
\end{figure*}
|
||||||
|
|
||||||
@@ -15749,19 +15743,19 @@ terms~\citep{HillerstromLA20}.
|
|||||||
\newcommand{\contapp}[2]{#1 #2}
|
\newcommand{\contapp}[2]{#1 #2}
|
||||||
\newcommand{\contappp}[2]{#1(#2)}
|
\newcommand{\contappp}[2]{#1(#2)}
|
||||||
|
|
||||||
\subsection{Handler Machine}
|
\subsection{Handler machine}
|
||||||
\newcommand{\HClosure}{\dec{HClo}}
|
\newcommand{\HClosure}{\dec{HClo}}
|
||||||
We now enrich the $\BCalc$ machine to a $\HCalc$ machine.
|
We now enrich the $\BPCF$ machine to a $\HPCF$ machine.
|
||||||
%
|
%
|
||||||
We extend the syntax as follows.
|
We extend the syntax as follows.
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\begin{syntax}
|
\begin{syntax}
|
||||||
\slab{Configurations} &\conf \in \Conf &::=& \cek{M \mid \env \mid \kappa}\\
|
\slab{Configurations} &\conf \in \Conf &::=& \cek{M \mid \env \mid \kappa}\\
|
||||||
\slab{Resumptions} &\rho \in \dec{Res} &::=& (\sigma, \chi)\\
|
\slab{Resumptions} &\rho \in \dec{Res} &::=& (\sigma, \chi)\\
|
||||||
\slab{Continuations} &\kappa \in \Cont &::=& \nil \mid \rho \cons \kappa\\
|
\slab{Continuations} &\kappa \in \Cont &::=& \nil \mid \rho \cons \kappa\\
|
||||||
\slab{Handler closures} &\chi \in \HClosure &::=& (\env, H) \\
|
\slab{Handler\textrm{ }closures} &\chi \in \HClosure &::=& (\env, H) \\
|
||||||
\slab{Machine values} &v, w \in \MVal &::=& \cdots \mid \rho \\
|
\slab{Machine\textrm{ }values} &v, w \in \MVal &::=& \cdots \mid \rho \\
|
||||||
\end{syntax}}%
|
\end{syntax}}%
|
||||||
%
|
%
|
||||||
The notion of configurations changes slightly in that the continuation
|
The notion of configurations changes slightly in that the continuation
|
||||||
@@ -15777,7 +15771,7 @@ The identity continuation is a singleton list containing the identity
|
|||||||
resumption, which is an empty pure continuation paired with the
|
resumption, which is an empty pure continuation paired with the
|
||||||
identity handler closure:
|
identity handler closure:
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\kappa_0 \defas [(\nil, (\emptyset, \{\Val\;x \mapsto x\}))]
|
\kappa_0 \defas [(\nil, (\emptyset, \{\Val\;x \mapsto x\}))]
|
||||||
\]}%
|
\]}%
|
||||||
@@ -15810,7 +15804,6 @@ The handler machine has two possible final states: either it yields a
|
|||||||
value or it gets stuck on an unhandled operation.
|
value or it gets stuck on an unhandled operation.
|
||||||
|
|
||||||
\begin{figure*}
|
\begin{figure*}
|
||||||
\small
|
|
||||||
\raggedright
|
\raggedright
|
||||||
|
|
||||||
\textbf{Transition relation}
|
\textbf{Transition relation}
|
||||||
@@ -15848,14 +15841,14 @@ value or it gets stuck on an unhandled operation.
|
|||||||
\text{ and } \hell = \{\ell\; p \; r \mapsto M\}
|
\text{ and } \hell = \{\ell\; p \; r \mapsto M\}
|
||||||
\el\\
|
\el\\
|
||||||
\end{reductions}
|
\end{reductions}
|
||||||
\caption{Abstract Machine Semantics for $\HCalc$}
|
\caption{Abstract machine semantics for $\HPCF$.}
|
||||||
\label{fig:abstract-machine-semantics-handlers}
|
\label{fig:abstract-machine-semantics-handlers}
|
||||||
\end{figure*}
|
\end{figure*}
|
||||||
|
|
||||||
\paragraph{Correctness}
|
\paragraph{Correctness}
|
||||||
%
|
%
|
||||||
The handler machine faithfully simulates the operational semantics of
|
The handler machine faithfully simulates the operational semantics of
|
||||||
$\HCalc$.
|
$\HPCF$.
|
||||||
%
|
%
|
||||||
Extending the result for the base machine, we formally state and prove
|
Extending the result for the base machine, we formally state and prove
|
||||||
the correspondence in
|
the correspondence in
|
||||||
@@ -15913,11 +15906,11 @@ thus would add nothing but noise to the overall analysis.
|
|||||||
%%
|
%%
|
||||||
%% Generic search
|
%% Generic search
|
||||||
%%
|
%%
|
||||||
\section{Predicates, Decision Trees and Generic Count}
|
\section{Predicates, decision trees, and generic count}
|
||||||
\label{sec:generic-search}
|
\label{sec:generic-search}
|
||||||
|
|
||||||
We now come to the crux of the paper. In this section and the next, we
|
We now come to the crux of the chapter. In this section and the next, we
|
||||||
prove that $\HCalc$ supports implementations of certain operations
|
prove that $\HPCF$ supports implementations of certain operations
|
||||||
with an asymptotic runtime bound that cannot be achieved in $\BCalc$
|
with an asymptotic runtime bound that cannot be achieved in $\BCalc$
|
||||||
(Section~\ref{sec:pure-counting}).
|
(Section~\ref{sec:pure-counting}).
|
||||||
%
|
%
|
||||||
@@ -15939,7 +15932,6 @@ $n$-queens problem~\citep{BellS09} and graph colouring
|
|||||||
can be cast as instances of generic search, and similar ideas have
|
can be cast as instances of generic search, and similar ideas have
|
||||||
been explored in connection with Nash equilibria and
|
been explored in connection with Nash equilibria and
|
||||||
exact real integration~\citep{Simpson98, Daniels16}.
|
exact real integration~\citep{Simpson98, Daniels16}.
|
||||||
% Taken out Nash equilibria.
|
|
||||||
|
|
||||||
For simplicity, we will restrict attention to search spaces of the form $\B^n$,
|
For simplicity, we will restrict attention to search spaces of the form $\B^n$,
|
||||||
the set of bit vectors of length $n$.
|
the set of bit vectors of length $n$.
|
||||||
@@ -15956,9 +15948,9 @@ We will often informally write $\Nat_n$ in place of $\Nat$ to indicate that
|
|||||||
only the values $0,\dots,n-1$ are relevant, but this convention has no
|
only the values $0,\dots,n-1$ are relevant, but this convention has no
|
||||||
formal status since our setup does not support dependent types.
|
formal status since our setup does not support dependent types.
|
||||||
|
|
||||||
To summarise, in both $\BCalc$ and $\HCalc$ we will be working with the types
|
To summarise, in both $\BPCF$ and $\HPCF$ we will be working with the types
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\begin{twoeqs}
|
\begin{twoeqs}
|
||||||
\Point & \defas & \Nat \to \Bool & \hspace*{2.0em} &
|
\Point & \defas & \Nat \to \Bool & \hspace*{2.0em} &
|
||||||
@@ -15971,7 +15963,7 @@ To summarise, in both $\BCalc$ and $\HCalc$ we will be working with the types
|
|||||||
%
|
%
|
||||||
and will be looking for programs
|
and will be looking for programs
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\Count_n : \Predicate_n \to \Nat
|
\Count_n : \Predicate_n \to \Nat
|
||||||
\]}%
|
\]}%
|
||||||
@@ -15983,10 +15975,10 @@ Before formalising these ideas more closely, let us look at some examples,
|
|||||||
which will also illustrate the machinery of \emph{decision trees} that we will be using.
|
which will also illustrate the machinery of \emph{decision trees} that we will be using.
|
||||||
|
|
||||||
|
|
||||||
\subsection{Examples of Points, Predicates and Trees}
|
\subsection{Examples of points, predicates and trees}
|
||||||
\label{sec:predicates-points}
|
\label{sec:predicates-points}
|
||||||
Consider first the following terms of type $\Point$:
|
Consider first the following terms of type $\Point$:
|
||||||
{\small
|
{
|
||||||
\begin{mathpar}
|
\begin{mathpar}
|
||||||
\dec{q}_0 \defas \lambda \_. \True
|
\dec{q}_0 \defas \lambda \_. \True
|
||||||
|
|
||||||
@@ -16004,7 +15996,7 @@ and $\dec{q}_2$ represents $\langle{\True,\False}\rangle \in \B^2$.
|
|||||||
|
|
||||||
Next some predicates.
|
Next some predicates.
|
||||||
First, the following terms all represent the constant true predicate $\B^2 \to \B$:
|
First, the following terms all represent the constant true predicate $\B^2 \to \B$:
|
||||||
{\small
|
{
|
||||||
\begin{mathpar}
|
\begin{mathpar}
|
||||||
\dec{T}_0 \defas \lambda q. \True
|
\dec{T}_0 \defas \lambda q. \True
|
||||||
|
|
||||||
@@ -16017,7 +16009,7 @@ for each $i<n$ the value of $\dec{q}$ at $i$ may be inspected zero, one or many
|
|||||||
|
|
||||||
Likewise, the following all represent the `identity' predicate $\B^1 \to \B$
|
Likewise, the following all represent the `identity' predicate $\B^1 \to \B$
|
||||||
(here $\&\&$ is shortcut `and'):
|
(here $\&\&$ is shortcut `and'):
|
||||||
{\small
|
{
|
||||||
\begin{mathpar}
|
\begin{mathpar}
|
||||||
\dec{I}_0 \defas \lambda q. q\,0
|
\dec{I}_0 \defas \lambda q. q\,0
|
||||||
|
|
||||||
@@ -16029,13 +16021,13 @@ Likewise, the following all represent the `identity' predicate $\B^1 \to \B$
|
|||||||
Slightly more interestingly, for each $n$ we have the following program which determines
|
Slightly more interestingly, for each $n$ we have the following program which determines
|
||||||
whether a point contains an odd number of $\True$ components:
|
whether a point contains an odd number of $\True$ components:
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\dec{Odd}_n \defas \lambda q.\, \dec{fold}\otimes\False~(\dec{map}~q~[0,\dots,n-1])
|
\dec{odd}_n \defas \lambda q.\, \dec{fold}\otimes\False~(\dec{map}~q~[0,\dots,n-1])
|
||||||
\]}%
|
\]}%
|
||||||
%
|
%
|
||||||
Here $\dec{fold}$ and $\dec{map}$ are the standard combinators on lists, and $\otimes$ is exclusive-or.
|
Here $\dec{fold}$ and $\dec{map}$ are the standard combinators on lists, and $\otimes$ is exclusive-or.
|
||||||
Applying $\dec{Odd}_2$ to $\dec{q}_0$ yields $\False$;
|
Applying $\dec{odd}_2$ to $\dec{q}_0$ yields $\False$;
|
||||||
applying it to $\dec{q}_1$ or $\dec{q}_2$ yields $\True$.
|
applying it to $\dec{q}_1$ or $\dec{q}_2$ yields $\True$.
|
||||||
%
|
%
|
||||||
\medskip
|
\medskip
|
||||||
@@ -16180,7 +16172,7 @@ applying it to $\dec{q}_1$ or $\dec{q}_2$ yields $\True$.
|
|||||||
\caption{$\dec{Odd}_2$}
|
\caption{$\dec{Odd}_2$}
|
||||||
\label{fig:xor2-tree}
|
\label{fig:xor2-tree}
|
||||||
\end{subfigure}
|
\end{subfigure}
|
||||||
\caption{Examples of Decision Trees}
|
\caption{Examples of decision trees.}
|
||||||
\label{fig:example-models}
|
\label{fig:example-models}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
@@ -16242,7 +16234,7 @@ those for $\dec{I}_0$ and $\dec{I}_1$ are 1-standard; that for
|
|||||||
$\dec{Odd}_n$ is $n$-standard; and the rest are not $n$-standard for
|
$\dec{Odd}_n$ is $n$-standard; and the rest are not $n$-standard for
|
||||||
any $n$.
|
any $n$.
|
||||||
|
|
||||||
\subsection{Formal Definitions}
|
\subsection{Formal definitions}
|
||||||
\label{sec:predicate-models}
|
\label{sec:predicate-models}
|
||||||
We now formalise the above notions. We will present our definitions
|
We now formalise the above notions. We will present our definitions
|
||||||
in the setting of $\HCalc$, but everything can clearly be relativised
|
in the setting of $\HCalc$, but everything can clearly be relativised
|
||||||
@@ -16259,7 +16251,7 @@ as follows.
|
|||||||
\begin{definition}[$n$-points]\label{def:semantic-n-point}
|
\begin{definition}[$n$-points]\label{def:semantic-n-point}
|
||||||
A closed value $Q : \Point$ is said to be a \emph{syntactic $n$-point} if:
|
A closed value $Q : \Point$ is said to be a \emph{syntactic $n$-point} if:
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\forall k \in \N_n.\,\exists b \in \B.~ Q~k \reducesto^\ast \Return\;b
|
\forall k \in \N_n.\,\exists b \in \B.~ Q~k \reducesto^\ast \Return\;b
|
||||||
\]}%
|
\]}%
|
||||||
@@ -16269,7 +16261,7 @@ $\pi: \N_n \to \B$. (We shall also write $\pi \in \B^n$.) Any
|
|||||||
syntactic $n$-point $Q$ is said to \emph{denote} the semantic
|
syntactic $n$-point $Q$ is said to \emph{denote} the semantic
|
||||||
$n$-point $\val{Q}$ given by:
|
$n$-point $\val{Q}$ given by:
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\forall k \in \N_n,\, b \in \B.~ \val{Q}(k) = b \,\Iff\, Q~k \reducesto^\ast \Return\;b
|
\forall k \in \N_n,\, b \in \B.~ \val{Q}(k) = b \,\Iff\, Q~k \reducesto^\ast \Return\;b
|
||||||
\]}%
|
\]}%
|
||||||
@@ -16303,7 +16295,7 @@ label will represent the information present at a node. Formally:
|
|||||||
|
|
||||||
(ii) The label set $\Lab$ consists of \emph{queries} parameterised by a natural
|
(ii) The label set $\Lab$ consists of \emph{queries} parameterised by a natural
|
||||||
number and \emph{answers} parameterised by a boolean:
|
number and \emph{answers} parameterised by a boolean:
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\Lab \defas \{\query k \mid k \in \N \} \cup \{\ans b \mid b \in \B \}
|
\Lab \defas \{\query k \mid k \in \N \} \cup \{\ans b \mid b \in \B \}
|
||||||
\]
|
\]
|
||||||
@@ -16361,7 +16353,7 @@ It is convenient to define the timed tree and then extract the untimed one from
|
|||||||
minimal family of partial functions satisfying the following
|
minimal family of partial functions satisfying the following
|
||||||
equations:
|
equations:
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\begin{mathpar}
|
\begin{mathpar}
|
||||||
\ba{@{}r@{~}c@{~}l@{\qquad}l@{}}
|
\ba{@{}r@{~}c@{~}l@{\qquad}l@{}}
|
||||||
\tr(\cek{\Return\;W \mid \env \mid \nil})\, \nil &~=~& (!b, 0),
|
\tr(\cek{\Return\;W \mid \env \mid \nil})\, \nil &~=~& (!b, 0),
|
||||||
@@ -16416,7 +16408,7 @@ A closed term $P: \Predicate$ is a \emph{(syntactic) $n$-predicate} if $\tru(P)$
|
|||||||
|
|
||||||
If $\tree$ is an $n$-predicate tree, clearly any semantic $n$-point $\pi$ gives rise to a path $b_0 b_1 \dots $
|
If $\tree$ is an $n$-predicate tree, clearly any semantic $n$-point $\pi$ gives rise to a path $b_0 b_1 \dots $
|
||||||
through $\tree$, given inductively by:
|
through $\tree$, given inductively by:
|
||||||
{\small
|
{
|
||||||
\[ \forall j.~ \mbox{if~} \tau(b_0\dots b_{j-1}) = \query k_j \mbox{~then~} b_j = \pi(k_j) \]
|
\[ \forall j.~ \mbox{if~} \tau(b_0\dots b_{j-1}) = \query k_j \mbox{~then~} b_j = \pi(k_j) \]
|
||||||
}%
|
}%
|
||||||
This path will terminate at some answer node $b_0 b_1 \dots b_{r-1}$ of $\tree$,
|
This path will terminate at some answer node $b_0 b_1 \dots b_{r-1}$ of $\tree$,
|
||||||
@@ -16456,7 +16448,7 @@ An $n$-predicate $P$ is $n$-standard if $\tr(P)$ is $n$-standard.
|
|||||||
Clearly, in an $n$-standard tree, each of the $n$ queries $\query 0,\dots, \query(n-1)$
|
Clearly, in an $n$-standard tree, each of the $n$ queries $\query 0,\dots, \query(n-1)$
|
||||||
appears exactly once on the path to any leaf, and there are $2^n$ leaves, all of them answer nodes.
|
appears exactly once on the path to any leaf, and there are $2^n$ leaves, all of them answer nodes.
|
||||||
|
|
||||||
\subsection{Specification of Counting Programs}
|
\subsection{Specification of counting programs}
|
||||||
\label{sec:counting}
|
\label{sec:counting}
|
||||||
|
|
||||||
We can now specify what it means for a program
|
We can now specify what it means for a program
|
||||||
@@ -16483,7 +16475,7 @@ correctly on $n$-standard $\lambda_b$ predicates, can never compete
|
|||||||
with our $\HCalc$ program for asymptotic efficiency even in the most
|
with our $\HCalc$ program for asymptotic efficiency even in the most
|
||||||
favourable cases.
|
favourable cases.
|
||||||
|
|
||||||
\subsection{Efficient Generic Count with Effects}
|
\subsection{Efficient generic count with effects}
|
||||||
\label{sec:effectful-counting}
|
\label{sec:effectful-counting}
|
||||||
|
|
||||||
We now present the simplest version of our effectful implementation of
|
We now present the simplest version of our effectful implementation of
|
||||||
@@ -16507,7 +16499,7 @@ convention).
|
|||||||
%
|
%
|
||||||
The algorithm is then as follows.
|
The algorithm is then as follows.
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\bl
|
\bl
|
||||||
\ECount : ((\Nat \to \Bool) \to \Bool) \to \Nat\\
|
\ECount : ((\Nat \to \Bool) \to \Bool) \to \Nat\\
|
||||||
@@ -16550,7 +16542,7 @@ properties of $\ECount$.
|
|||||||
\item $\ECount$ correctly counts $P$.
|
\item $\ECount$ correctly counts $P$.
|
||||||
\item The number of machine steps required to evaluate $\ECount~P$ is
|
\item The number of machine steps required to evaluate $\ECount~P$ is
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\left( \displaystyle\sum_{bs \in \Addr_n} \steps(\tr(P))(bs) \right) ~+~ \BigO(2^n)
|
\left( \displaystyle\sum_{bs \in \Addr_n} \steps(\tr(P))(bs) \right) ~+~ \BigO(2^n)
|
||||||
\]}%
|
\]}%
|
||||||
@@ -16636,7 +16628,7 @@ these, each taking at most $d$ space.
|
|||||||
%
|
%
|
||||||
Thus the total space is $\BigO(n(d + c(\log c + \log n)))$.
|
Thus the total space is $\BigO(n(d + c(\log c + \log n)))$.
|
||||||
|
|
||||||
\section{Pure Generic Count: A Lower Bound}
|
\section{Pure generic count: a lower bound}
|
||||||
\label{sec:pure-counting}
|
\label{sec:pure-counting}
|
||||||
|
|
||||||
\newcommand{\naivecount}{\dec{naivecount}}
|
\newcommand{\naivecount}{\dec{naivecount}}
|
||||||
@@ -16647,8 +16639,8 @@ Thus the total space is $\BigO(n(d + c(\log c + \log n)))$.
|
|||||||
\newcommand{\GG}{\mathcal{G}}
|
\newcommand{\GG}{\mathcal{G}}
|
||||||
|
|
||||||
We have shown that there is an implementation of generic count in
|
We have shown that there is an implementation of generic count in
|
||||||
$\HCalc$ with a runtime bound of $\BigO(2^n)$ for certain well-behaved
|
$\HPCF$ with a runtime bound of $\BigO(2^n)$ for certain well-behaved
|
||||||
predicates. We now prove that no implementation in $\BCalc$ can match
|
predicates. We now prove that no implementation in $\BPCF$ can match
|
||||||
this: in fact, we establish a lower bound of $\Omega(n2^n)$ for the
|
this: in fact, we establish a lower bound of $\Omega(n2^n)$ for the
|
||||||
runtime of any counting program on \emph{any} $n$-standard predicate.
|
runtime of any counting program on \emph{any} $n$-standard predicate.
|
||||||
This mathematically rigorous characterisation of the efficiency gap
|
This mathematically rigorous characterisation of the efficiency gap
|
||||||
@@ -16673,7 +16665,7 @@ a count of those on which $P$ yields true. It is a routine exercise to
|
|||||||
implement this approach in $\BCalc$, yielding (parametrically in $n$)
|
implement this approach in $\BCalc$, yielding (parametrically in $n$)
|
||||||
a program
|
a program
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\naivecount_n ~: ((\Nat_n \to \Bool) \to \Bool) \to \Nat
|
\naivecount_n ~: ((\Nat_n \to \Bool) \to \Bool) \to \Nat
|
||||||
\]}%
|
\]}%
|
||||||
@@ -16697,7 +16689,7 @@ implementations that cleverly exploit \emph{nesting} of calls to $P$.
|
|||||||
The germ of the idea may be illustrated within $\BCalc$ itself.
|
The germ of the idea may be illustrated within $\BCalc$ itself.
|
||||||
Suppose that we first construct some program
|
Suppose that we first construct some program
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\bestshot_n ~: ((\Nat_n \to \Bool) \to \Bool) \to (\Nat_n \to \Bool)
|
\bestshot_n ~: ((\Nat_n \to \Bool) \to \Bool) \to (\Nat_n \to \Bool)
|
||||||
\]}%
|
\]}%
|
||||||
@@ -16716,7 +16708,7 @@ deferred until the argument of type $\Nat_n$ is supplied.
|
|||||||
|
|
||||||
Now consider the following program:
|
Now consider the following program:
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\lazycount_n \defas \lambda pred.\; \If \; pred~(\bestshot_n\;pred)\; \Then\; \naivecount_n\;pred\; \Else\; \Return\;0
|
\lazycount_n \defas \lambda pred.\; \If \; pred~(\bestshot_n\;pred)\; \Then\; \naivecount_n\;pred\; \Else\; \Return\;0
|
||||||
\]}%
|
\]}%
|
||||||
@@ -16755,7 +16747,7 @@ proof of this and tells us that such a proof will need to pay
|
|||||||
particular attention to the possibility of nesting.
|
particular attention to the possibility of nesting.
|
||||||
|
|
||||||
We now proceed to the proof itself. We here present the argument in
|
We now proceed to the proof itself. We here present the argument in
|
||||||
the basic setting of $\BCalc$; later we will see how a more delicate
|
the basic setting of $\BPCF$; later we will see how a more delicate
|
||||||
argument applies to languages with mutable state
|
argument applies to languages with mutable state
|
||||||
(Section~\ref{sec:mutable-state}).
|
(Section~\ref{sec:mutable-state}).
|
||||||
|
|
||||||
@@ -16772,11 +16764,11 @@ any generic program program in $\BCalc$ on any $n$-standard predicate
|
|||||||
is $\Omega(n2^n)$, this will establish the desired lower bound on the
|
is $\Omega(n2^n)$, this will establish the desired lower bound on the
|
||||||
runtime.
|
runtime.
|
||||||
|
|
||||||
Let us suppose, then, that $\Countprog$ is a program of $\BCalc$ that correctly counts
|
Let us suppose, then, that $\Countprog$ is a program of $\BPCF$ that correctly counts
|
||||||
all $n$-standard predicates of $\BCalc$ for some specific $n$.
|
all $n$-standard predicates of $\BPCF$ for some specific $n$.
|
||||||
We now establish a key lemma, which vindicates the \naive intuition
|
We now establish a key lemma, which vindicates the \naive intuition
|
||||||
that if $P$ is $n$-standard, the only way for $\Countprog$ to discover the correct
|
that if $P$ is $n$-standard, the only way for $\Countprog$ to discover the correct
|
||||||
value for $\sharp \val{P}$ is to perform $2^n$ separate applications $P\;Q$
|
value for $\sharp \val{P}$ is to perform $2^n$ separate applications $P~Q$
|
||||||
(allowing for the possibility that these applications need not
|
(allowing for the possibility that these applications need not
|
||||||
be performed `in turn' but might be nested in some complex way).
|
be performed `in turn' but might be nested in some complex way).
|
||||||
|
|
||||||
@@ -16887,7 +16879,7 @@ be performed `in turn' but might be nested in some complex way).
|
|||||||
By continuing in this way, we may analyse the reduction of $Q[P]~k$
|
By continuing in this way, we may analyse the reduction of $Q[P]~k$
|
||||||
as follows.
|
as follows.
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\begin{mathpar}
|
\begin{mathpar}
|
||||||
\begin{eqs}
|
\begin{eqs}
|
||||||
Q[P]~k & \reducesto^\ast & \EC_0[P~Q_0[P], P] ~\reducesto^\ast~ \EC_0[\Return\;b_0, P]
|
Q[P]~k & \reducesto^\ast & \EC_0[P~Q_0[P], P] ~\reducesto^\ast~ \EC_0[\Return\;b_0, P]
|
||||||
@@ -16911,7 +16903,7 @@ be performed `in turn' but might be nested in some complex way).
|
|||||||
reduction sequence:
|
reduction sequence:
|
||||||
%
|
%
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\begin{mathpar}
|
\begin{mathpar}
|
||||||
\begin{eqs}
|
\begin{eqs}
|
||||||
Q[P']~k & \reducesto^\ast & \EC_0[P'~Q_0[P'], P'] ~\reducesto^\ast~ \EC_0[\Return\;b_0, P']
|
Q[P']~k & \reducesto^\ast & \EC_0[P'~Q_0[P'], P'] ~\reducesto^\ast~ \EC_0[\Return\;b_0, P']
|
||||||
@@ -16932,7 +16924,7 @@ be performed `in turn' but might be nested in some complex way).
|
|||||||
Definition~\ref{def:model-construction}. In this way we may analyse
|
Definition~\ref{def:model-construction}. In this way we may analyse
|
||||||
the computation of $P~Q[P]$ as:
|
the computation of $P~Q[P]$ as:
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\begin{mathpar}
|
\begin{mathpar}
|
||||||
\begin{eqs}
|
\begin{eqs}
|
||||||
P~Q[P] & ~\reducesto^\ast~ & \EC_0[Q[P]~k_0, Q[P]] ~\reducesto^\ast~ \EC_0[\Return\;b_0, Q[P]]
|
P~Q[P] & ~\reducesto^\ast~ & \EC_0[Q[P]~k_0, Q[P]] ~\reducesto^\ast~ \EC_0[\Return\;b_0, Q[P]]
|
||||||
@@ -16978,7 +16970,7 @@ that $P~Q[P'] \reducesto^\ast \Return\;b$.
|
|||||||
|
|
||||||
To finish off the proof of Lemma~\ref{lem:no-shortcuts}, we apply the same analysis
|
To finish off the proof of Lemma~\ref{lem:no-shortcuts}, we apply the same analysis
|
||||||
one last time to the reduction of $\Countprog~P$ itself. This will have the form
|
one last time to the reduction of $\Countprog~P$ itself. This will have the form
|
||||||
{\small
|
{
|
||||||
\begin{mathpar}
|
\begin{mathpar}
|
||||||
\begin{eqs}
|
\begin{eqs}
|
||||||
\Countprog~P & ~\reducesto^\ast~ & \EC_0[P~Q_0[P], P] ~\reducesto^\ast \EC_0[\Return\;b_0,P]
|
\Countprog~P & ~\reducesto^\ast~ & \EC_0[P~Q_0[P], P] ~\reducesto^\ast \EC_0[\Return\;b_0,P]
|
||||||
@@ -17049,7 +17041,7 @@ at some invocation of $\ell$, so that control will then pass to the effect handl
|
|||||||
%%
|
%%
|
||||||
%% Generalising
|
%% Generalising
|
||||||
%%
|
%%
|
||||||
\section{Extensions and Variations}
|
\section{Extensions and variations}
|
||||||
\label{sec:robustness}
|
\label{sec:robustness}
|
||||||
|
|
||||||
Our complexity result is robust in that it continues to hold in more
|
Our complexity result is robust in that it continues to hold in more
|
||||||
@@ -17057,7 +17049,7 @@ general settings. We outline here how it generalises: beyond
|
|||||||
$n$-standard predicates, from generic count to generic search, and
|
$n$-standard predicates, from generic count to generic search, and
|
||||||
from pure $\BCalc$ to stateful $\BCalcS$.
|
from pure $\BCalc$ to stateful $\BCalcS$.
|
||||||
|
|
||||||
\subsection{Beyond $n$-Standard Predicates}
|
\subsection{Beyond $n$-standard predicates}
|
||||||
\label{sec:beyond}
|
\label{sec:beyond}
|
||||||
The $n$-standard restriction on predicates serves to make the
|
The $n$-standard restriction on predicates serves to make the
|
||||||
efficiency phenomenon stand out as clearly as possible. However, we
|
efficiency phenomenon stand out as clearly as possible. However, we
|
||||||
@@ -17084,7 +17076,7 @@ second argument is the updated state of type $S$.
|
|||||||
repeated queries by memoising previous answers. First, we generalise
|
repeated queries by memoising previous answers. First, we generalise
|
||||||
the type of $\Branch$ such that it carries an index of a query.
|
the type of $\Branch$ such that it carries an index of a query.
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\Branch : \Nat \to \Bool
|
\Branch : \Nat \to \Bool
|
||||||
\]}
|
\]}
|
||||||
@@ -17092,7 +17084,7 @@ the type of $\Branch$ such that it carries an index of a query.
|
|||||||
We assume a family of natural number to boolean maps, $\dec{Map}_n$
|
We assume a family of natural number to boolean maps, $\dec{Map}_n$
|
||||||
with the following interface.
|
with the following interface.
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\begin{equations}
|
\begin{equations}
|
||||||
\dec{empty}_n &:& \dec{Map}_n \\
|
\dec{empty}_n &:& \dec{Map}_n \\
|
||||||
\dec{add}_n &:& (\Nat_n \times \Bool) \to \dec{Map}_n \to \dec{Map}_n \\
|
\dec{add}_n &:& (\Nat_n \times \Bool) \to \dec{Map}_n \to \dec{Map}_n \\
|
||||||
@@ -17109,7 +17101,7 @@ $\dec{add}_n$ and $\dec{lookup}_n$ is
|
|||||||
$\BigO(\log n)$~\cite{Okasaki99}. We can then use parameter-passing
|
$\BigO(\log n)$~\cite{Okasaki99}. We can then use parameter-passing
|
||||||
to support repeated queries as follows.
|
to support repeated queries as follows.
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\bl
|
\bl
|
||||||
\ECount'_n : ((\Nat_n \to \Bool) \to \Bool) \to \Nat\\
|
\ECount'_n : ((\Nat_n \to \Bool) \to \Bool) \to \Nat\\
|
||||||
@@ -17147,7 +17139,7 @@ predicates performing the same query multiple times.
|
|||||||
%
|
%
|
||||||
Similarly, we can use parameter-passing to support missing queries.
|
Similarly, we can use parameter-passing to support missing queries.
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\bl
|
\bl
|
||||||
\ECount''_n : ((\Nat_n \to \Bool) \to \Bool) \to \Nat\\
|
\ECount''_n : ((\Nat_n \to \Bool) \to \Bool) \to \Nat\\
|
||||||
@@ -17186,14 +17178,14 @@ We leave it as an exercise for the reader to combine $\ECount'_n$ and
|
|||||||
$\ECount''_n$ in order to handle both repeated queries and missing
|
$\ECount''_n$ in order to handle both repeated queries and missing
|
||||||
queries.
|
queries.
|
||||||
|
|
||||||
\subsection{From Generic Count to Generic Search}
|
\subsection{From generic count to generic search}
|
||||||
\label{sec:count-vs-search}
|
\label{sec:count-vs-search}
|
||||||
|
|
||||||
We can generalise the problem of generic counting to generic
|
We can generalise the problem of generic counting to generic
|
||||||
searching. The main operational difference is that a generic search
|
searching. The main operational difference is that a generic search
|
||||||
procedure must materialise a list of solutions, thus its type is
|
procedure must materialise a list of solutions, thus its type is
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\mathsf{search}_{n} : ((\Nat_n \to \Bool) \to \Bool) \to \List_{\Nat_n \to \Bool}
|
\mathsf{search}_{n} : ((\Nat_n \to \Bool) \to \Bool) \to \List_{\Nat_n \to \Bool}
|
||||||
\]}%
|
\]}%
|
||||||
@@ -17211,7 +17203,7 @@ results $xs_\True$ and $xs_\False$ as follows.
|
|||||||
\newcommand{\Concat}{\mathsf{concat}}
|
\newcommand{\Concat}{\mathsf{concat}}
|
||||||
\newcommand{\HughesList}{\mathsf{HList}}
|
\newcommand{\HughesList}{\mathsf{HList}}
|
||||||
\newcommand{\ToConsList}{\mathsf{toConsList}}
|
\newcommand{\ToConsList}{\mathsf{toConsList}}
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\bl
|
\bl
|
||||||
\ESearch_n : ((\Nat_n \to \Bool) \to \Bool) \to \List_{\Nat_n \to \Bool}\\
|
\ESearch_n : ((\Nat_n \to \Bool) \to \Bool) \to \List_{\Nat_n \to \Bool}\\
|
||||||
@@ -17250,7 +17242,7 @@ $\HughesList_A \defas \List_A \to \List_A$. The empty Hughes list
|
|||||||
$\dec{nil} : \HughesList_A$ is defined as the identity function:
|
$\dec{nil} : \HughesList_A$ is defined as the identity function:
|
||||||
$\dec{nil} \defas \lambda xs. xs$.
|
$\dec{nil} \defas \lambda xs. xs$.
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[
|
\[
|
||||||
\ba{@{}l@{\qquad}l@{\qquad}l}
|
\ba{@{}l@{\qquad}l@{\qquad}l}
|
||||||
\Singleton_A : A \to \HughesList_A
|
\Singleton_A : A \to \HughesList_A
|
||||||
@@ -17266,7 +17258,7 @@ a standard cons-list at the end; this conversion has linear time
|
|||||||
complexity (it just conses all of the elements of the list together).
|
complexity (it just conses all of the elements of the list together).
|
||||||
|
|
||||||
|
|
||||||
\subsection{From Pure $\BCalc$ to Stateful $\BCalcS$}
|
\subsection{From pure $\BPCF$ to stateful $\BSPCF$}
|
||||||
\label{sec:mutable-state}
|
\label{sec:mutable-state}
|
||||||
|
|
||||||
Mutable state is a staple ingredient of many practical programming
|
Mutable state is a staple ingredient of many practical programming
|
||||||
@@ -17275,7 +17267,7 @@ extended to a language with state. We will not give full details, but
|
|||||||
merely point out the respects in which our earlier treatment needs to
|
merely point out the respects in which our earlier treatment needs to
|
||||||
be modified.
|
be modified.
|
||||||
|
|
||||||
We have in mind an extension $\BCalcS$ of $\BCalc$ with ML-style
|
We have in mind an extension $\BSPCF$ of $\BPCF$ with ML-style
|
||||||
reference cells: we extend our grammar for types with a reference type
|
reference cells: we extend our grammar for types with a reference type
|
||||||
($\PCFRef~A$), and that for computation terms with forms for creating
|
($\PCFRef~A$), and that for computation terms with forms for creating
|
||||||
references ($\keyw{letref}\; x = V\; \In\; N$), dereferencing ($!x$),
|
references ($\keyw{letref}\; x = V\; \In\; N$), dereferencing ($!x$),
|
||||||
@@ -17303,7 +17295,7 @@ state. In this situation, there is not even a clear specification for
|
|||||||
what an $n$-count program ought to do.
|
what an $n$-count program ought to do.
|
||||||
|
|
||||||
The simplest way to circumvent this difficulty is to restrict
|
The simplest way to circumvent this difficulty is to restrict
|
||||||
attention to predicates $P$ \emph{within the sublanguage $\BCalc$}.
|
attention to predicates $P$ \emph{within the sublanguage $\BPCF$}.
|
||||||
For such predicates, the notions of decision tree, counting and
|
For such predicates, the notions of decision tree, counting and
|
||||||
$n$-standardness are unproblematic. Our result will establish a
|
$n$-standardness are unproblematic. Our result will establish a
|
||||||
runtime lower bound of $\Omega(n2^n)$ for programs $\Countprog \in
|
runtime lower bound of $\Omega(n2^n)$ for programs $\Countprog \in
|
||||||
@@ -17322,7 +17314,7 @@ $\Countprog~P$ will feature terms $\EC[P~Q]$ which are then reduced to
|
|||||||
some $\EC[\Return\;b]$, via a reduction sequence which, modulo
|
some $\EC[\Return\;b]$, via a reduction sequence which, modulo
|
||||||
$\EC[-]$, has the following form:
|
$\EC[-]$, has the following form:
|
||||||
%
|
%
|
||||||
{\small
|
{
|
||||||
\[ P\,Q \reducesto^\ast \EC_0[Q~k_0] \reducesto^\ast \EC_0[\Return\,b_0] \reducesto^\ast \cdots
|
\[ P\,Q \reducesto^\ast \EC_0[Q~k_0] \reducesto^\ast \EC_0[\Return\,b_0] \reducesto^\ast \cdots
|
||||||
\reducesto^\ast \EC_{n-1}[Q~k_{n-1}] \reducesto^\ast \EC_{n-1}[\Return\,b_{n-1}]
|
\reducesto^\ast \EC_{n-1}[Q~k_{n-1}] \reducesto^\ast \EC_{n-1}[\Return\,b_{n-1}]
|
||||||
\reducesto^\ast \Return\;b
|
\reducesto^\ast \Return\;b
|
||||||
@@ -17378,7 +17370,7 @@ abstract on all these occurrences via an evident notion of
|
|||||||
argument of Lemma~\ref{lem:no-shortcuts} goes through.
|
argument of Lemma~\ref{lem:no-shortcuts} goes through.
|
||||||
|
|
||||||
A further argument is then needed to show that any two threads are
|
A further argument is then needed to show that any two threads are
|
||||||
indeed ‘disjoint’ as regards their $P$-sections, so that there must be
|
indeed `disjoint' as regards their $P$-sections, so that there must be
|
||||||
at least $n2^n$ steps in the overall reduction sequence.
|
at least $n2^n$ steps in the overall reduction sequence.
|
||||||
|
|
||||||
%% Since each thread involves at least the $n$ terms $\EC_j[Q~k_j]$, our
|
%% Since each thread involves at least the $n$ terms $\EC_j[Q~k_j]$, our
|
||||||
@@ -17862,9 +17854,10 @@ CPU E5-1620 v2 @ 3.70GHz powered workstation running Ubuntu 16.04. The
|
|||||||
effectful implementation uses an encoding of delimited control akin to
|
effectful implementation uses an encoding of delimited control akin to
|
||||||
effect handlers based on top of SML/NJ's call/cc.
|
effect handlers based on top of SML/NJ's call/cc.
|
||||||
%
|
%
|
||||||
The complete source code for the benchmarks is available at:
|
The complete source code for the benchmarks and instructions on how to
|
||||||
|
run them are available at:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\url{https://github.com/dhil/effects-for-efficiency-code}
|
\url{https://dl.acm.org/do/10.1145/3410231/abs/}
|
||||||
\end{center}
|
\end{center}
|
||||||
%
|
%
|
||||||
|
|
||||||
@@ -17878,7 +17871,7 @@ but less so over the Berger procedure. The pruned procedure is more
|
|||||||
competitive, but still slower than the baseline. Unsurprisingly, the
|
competitive, but still slower than the baseline. Unsurprisingly, the
|
||||||
baseline is slower than the bespoke implementation.
|
baseline is slower than the bespoke implementation.
|
||||||
|
|
||||||
\paragraph{Exact Real Integration}
|
\paragraph{Exact real integration}
|
||||||
The integration benchmarks are adapted from \citet{Simpson98}. We
|
The integration benchmarks are adapted from \citet{Simpson98}. We
|
||||||
integrate three different functions with varying precision in the
|
integrate three different functions with varying precision in the
|
||||||
interval $[0,1]$. For the identity function (Id) at precision $20$ the
|
interval $[0,1]$. For the identity function (Id) at precision $20$ the
|
||||||
|
|||||||
Reference in New Issue
Block a user