%%% This is the scribe notes template for CS611
%%% There are several comments preceded by CS611: and boxed in %%%%'s
%%% which indicate where macros should be altered to set up the header
%%% for the paper.  Your Notes should go at the comment SCRIBE NOTES GO HERE!.

%%% In the various .sty files that accompany this .tex file you will
%%% find LaTeX macros that make it easier to typeset inference rules
%%% and programming language constructs.  You must make sure that the
%%% file proof.sty is in a path searched by LaTeX when you try to
%%% use this file.  Take a look to see what macros are available--it
%%% will save you time and make the notes look better.  Feel free to
%%% extend the set of macros--post them to the newsgroup and contact
%%% the course staff if you come up with some good ones so they can be
%%% added to the template.

%%% This template includes examples of how to use some of the macros
%%% to give you an idea of how they work.  (Delete the examples when
%%% you do your scribing.)

\documentclass{article} \usepackage{611-lecture}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% CS611: Please fill in these macros as appropriate:
\lecture{8}                  %% Lecture number
\title{Evaluation Contexts}   %% Title of lecture
\author{Georgios Piliouras, Raghuram Ramanujan}       %% name of scribe
\date{14 September, 2005}     %% Date of lecture, e.g., 1 January 2001
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% See 611.sty for a variety of macros that will be helpful in
% typesetting the lecture. Here are a few of particular interest:
%
% "x"       x in keyword font (e.g., "if", "#t")
% _x_       x in italics
% \nm{n}    n in slanted font (used for abbreviations)
% <e>       e in angle brackets
% \lt       less-than sign
% \gt       greater-than sign
% \SB{x}    x in semantic brackets
% \Tr x{y}  x[[y]] with x in calligraphic font
%           (if x is more than a single character, use \Tr{x}{y})

\begin{document}

\maketitle

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% CS611: SCRIBE NOTES GO HERE!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\noindent
In this lecture, we
\begin{itemize}
    \item revisit the notion of defining functions inductively
    \item explore the use of _Evaluation Contexts_ for creating more compact structural operational semantics
    \item and observe how non-determinism in a language creates problems for big step semantics
\end{itemize}

\section{Inductive Definitions}

Consider the following definition of the Fibonacci sequence:

\begin{displaymath}
    f(x)=\left\{
    \begin{array}{rl}
        1 & \mbox{if }x \leq 2\\
        f(x - 1) + f(x - 2) & \mbox{if }x \gt 2\\
        & \mbox{where }x \in \mbox{\textbf{N}}
    \end{array}\right.
\end{displaymath}

This is a well-founded definition since _f(x)_ is defined in terms of _f_ applied to successively smaller arguments _i.e._ there is no infinitely descending recursive chain. The function can thus be captured with the following pair of rewrite rules:


\begin{center}
\medskip
\begin{tabular}{cc}
    \infer[x \leq 2]{x \mapsto 1}{} &
    \infer[x \gt 2]{x \mapsto a + b}{x - 1 \mapsto a & x - 2 \mapsto b}
\end{tabular}
\bigskip
\end{center}

In general, in a valid inductive definition, the argument that appears in the rule must be related through some well-founded relation to what appears in the left-hand side of the premise(s). A function with such a definition has a finite derivation tree. Now consider the function:

\begin{displaymath}
    f(x) = f(x) + 1
\end{displaymath}

\noindent
This yields the rewrite rule:

\begin{displaymath}
	\infer{x \mapsto a + 1}{x \mapsto a}
\end{displaymath}

\noindent
This is an example of an invalid inductive definition. In fact, this definition derives the empty function.

\section{Evaluation Contexts}

Recall the context-free grammar that was used to define expressions in the lambda calculus:

\begin{eqnarray*}
    e & ::= & x \bnf e_0 \mbox{ } e_1 \bnf \lambda x.e
\end{eqnarray*}

This context-free grammar induces a language. The language corresponding to a context-free grammar is a set comprising all the finitely-derivable strings (or abstract syntax trees). In this example, the following rewrite rules derive all the members of the language:

\begin{center}
\medskip
\begin{tabular}{ccc}
    \infer{x}{} &
    \infer{\lambda x.e}{e} &
    \infer{e_0~e_1}{e_0 & e_1}
\end{tabular}
\bigskip
\end{center}


\noindent
The rewrite rules for structural operational semantics can broadly be classified into two types:
\begin{itemize}
    \item reduction rules - these are often more interesting as they offer an insight into the workings of the language
    \item evaluation order rules - these are typically not as interesting, though they are usually more numerous
\end{itemize}

\noindent
Earlier in the semester, we captured the semantics of the call-by-value lambda calculus via the following rewrite rules:

\begin{center}
\medskip
\begin{tabular}{ccc}
    \infer{(\lam xe) ~ \stepsone \subst{e}{v}{x}}{} &
    \infer{e_1 \mbox{ } e_2 \stepsone e'_1 \mbox{ } e_2}{e_1 \stepsone e'_1} &
    \infer{v \mbox{ } e_2 \stepsone v \mbox{ } e'_2}{e_2 \stepsone e'_2}
\end{tabular}
\bigskip
\end{center}

The first rule here ($\beta \mbox{ } reduction$) falls under the category of reduction rules, whereas the latter two are evaluation order rules. Though there are relatively few evaluation order rules in the call-by-value lambda calculus, they are much more numerous in real-world programming languages and thus tedious to write. This motivates the need to find a more compact representation for such rules. _Evaluation Contexts_ provide a mechanism to do just that. An evaluation context "E" (alternately "E"[$\bullet$]) is an expression (term) with a 'hole' where a reduction is allowed. For example:

\begin{displaymath}
    (((\lambda x.x)[\bullet])(\lambda z.z\mbox{ }z)) \mbox{ where }[\bullet]\mbox{ represents the hole}
\end{displaymath}

If "E" is a context, then "E"[_e_] represents "E" with the hole plugged by _e_. This definition of a context yields a generic _context rule_ that can be applied to any defined context "E":

\begin{displaymath}
    \infer{"E"[e] \stepsone "E"[e']}{e \stepsone e'}
\end{displaymath}

For the case of the call-by-value lambda calculus that we have been
looking at so far, the two evaluation order rules give rise to the
following two contexts:

\medskip
\begin{center}
\begin{tabular}{ccc}
    $\infer{e_1~e_2 \stepsone e'_1~e_2}{e_1 \stepsone e'_1}$ & $\equiv$ & $[\bullet]~e$ \\
    $\infer{v~e_2 \stepsone v~e'_2}{e_2 \stepsone e'_2}$ & $\equiv$ & $v~[\bullet]$
\end{tabular}
\end{center}

\bigskip \noindent
These define the legal evaluation contexts _i.e._~the ones in which
the context rule defined earlier can be applied. Hence, we derive a
compact way for representing rules. Namely, for the case of
call-by-value lambda calculus we get:


\begin{eqnarray*}
    "E" & ::= & [\bullet]~"e" \bnf "v"~[\bullet]
\end{eqnarray*}

 \noindent The benefits of evaluation context will become
exceedingly obvious in the future, as we add more features to the language than just
applications. For the time being however, we will present an example
of its usage for producing the proof tree of a given expression:\\

% FIXME: we should put a line above this, to show that the topmost thing is an axiom
%\begin{center}
\[
%\begin{tabular}{ccc}
    \infer[~where~ "E"={[\bullet]}(\lambda "z.zz")]{((\lambda x.x)((\lambda x.x)0)(\lambda "z.zz"))\stepsone(((\lambda x.x)0)(\lambda "z.zz"))}
    {\infer[~where~ "E"=(\lambda "x.x") {[\bullet]}]{(\lambda "x.x")((\lambda x.x)0)\stepsone(\lambda "x.x")0}{(\lambda "x.x")0 \stepsone 0}}
%\end{tabular}
\]

\bigskip
\noindent where in the above tree we indicate the term being reduced in italic typeface.

\bigskip
For the case of call-by-name lambda calculus, given the context
rule, we achieve an equally compact representation:

\begin{displaymath}
	"E"  ::=  [\bullet]~"e"
\end{displaymath}
\begin{displaymath}
	\infer{(\lambda x.e)~e' \stepsone \subst{e}{e'}{x}}{}
\end{displaymath}

% er... the stuff about the multiple nested holes is not exactly true...
%There is an alternate way to define evaluation contexts which leads to even more savings. Observe that the contexts as defined above allow for only a single hole in a term - we can extend this to allow contexts with multiple (nested) holes as in:

The contexts defined above look like one of these two abstract syntax trees:\\

\begin{center}
  ($\bullet$ @ $e$) and ($v$ @ $\bullet$)\\
\end{center}

where the @ symbol denotes application.

Consider the following tree:\\

\begin{center}
  (($v$ @ $\bullet$) @ $e$)\\
\end{center}

To define a semantic small-step for this piece of syntax, we have to
apply the $E[e] \stepsone E[e']$ rule twice (once for each @ starting
from the topmost @), because by our current definition, $E$ can only
have one application (@).  The example above illustrates this, with 
$v = (\lambda x.x)$, $e = (\lambda z.z z)$.

So our definition of contexts does not cover such ``deep'' contexts in
one step.  You have to apply the reduction rule multiple times, thus
requiring a multi-level proof tree.

But by changing our definition of evaluation contexts to include these
``deep'' contexts, we can make our proof trees shorter.  This fits the
bill:

\begin{eqnarray*}
    "E" & ::= & [\bullet] \bnf "E~e" \bnf "v~E"
\end{eqnarray*}

\noindent
This yields a modified context rule:

\begin{displaymath}
    \infer{"E"[e] \stepsone "E"[e']}{e \stepsone _r e'}
\end{displaymath}

Taken together, the new representation flattens out the multiple
``boring'' steps corresponding to the repeated application of the
evaluation order rules to a single level.

This means that the lower arrow in the context rule actually does more
stepping than the upper arrow, and so they are not the same arrow.
Hence the $r$ suffix on the upper arrow.  Technically (for the same
reason) $e \stepsone _r e'$ should actually be a side condition.

Note that even though the lower arrow does more stepping, it only does
the stepping that is defined in the grammar for evaluation contexts:
that is, the stepping of evaluation-order rules only, not the
reduction rules.  So the single level still contains only one
reduction.

Revisiting the example above, we get a much shorter proof tree, where
we use a single evaluation order rule:

\begin{displaymath}
  \infer[~where~ "E" = ((\lambda x.x){})(\lambda z.z)]{((\lambda x.x)((\lambda x.x)0)(\lambda "z.zz"))\stepsone(((\lambda x.x)0)(\lambda "z.zz"))}
    {\infer{(\lambda "x.x")0 \stepsone 0}{}}
\end{displaymath}

\indent 
Lastly, evaluation contexts can be used to easily define the semantics
of error exceptions, since we can very easily propagate an error value
using the evaluation order rule below:


\begin{displaymath}
    "E"[error] \stepsone error
\end{displaymath}

\noindent
This alleviates the need to show in painstaking detail how error propagates up through each rewrite rule.

\section{Non-determinism}

A non-deterministic computation can be informally defined as one,
where starting from the same input we might have more than one
possible transition, each one leading possibly to different
results.


\begin{center}
\bigskip
\begin{tabular}{ccc}
    $e \stepsone e'$ \\
    $e \stepsone e''$
    \end{tabular}
 where $e' \neq e''$
\bigskip
\end{center}

Of course, this raises the issue of how can one express
non-determinism. As we shall see, a rather natural choice is by the
use of small step semantics. Indeed, we can easily define the
non-deterministic choice operator $\square$, where by $c_1 \square
c_2$ we express that the system can do either:


\begin{center}
\medskip
\begin{tabular}{c}
    \infer{<c_1 \square c_2, \sigma> \stepsone <c_1, \sigma>}{} \\ \\
    \infer{<c_1 \square c_2, \sigma> \stepsone <c_2, \sigma>}{}
\end{tabular}
\bigskip
\end{center}

However, if we try to express non-determinism using big step
semantics, then we immediately face severe problems. For example, a
natural approach for tackling the issue of non-determinism in big
step semantics would be the following:


\begin{center}
\medskip
\begin{tabular}{cc}
    \infer{<c_1 \square c_2, \sigma> \Downarrow \sigma '}{<c_1, \sigma> \Downarrow \sigma '} &
    \infer{<c_1 \square c_2, \sigma> \Downarrow \sigma '}{<c_2, \sigma> \Downarrow \sigma '}
\end{tabular}
\bigskip
\end{center}

Although at a first glance this approach seems to work, let's
examine what happens if exactly one of $c_1,c_2$ diverges. Indeed,
in this case, according to our semantics we will always choose the
\emph{good} one, the one that terminates. For obvious reasons this kind
of non-determinism is referred to as _angelic nondeterminism_.\\

A closely related issue to the definition of non-determinism using
semantics is capturing the notion of parallel processing. Again, in
this case small step semantics seem to provide a rather natural
solution to the problem:


\begin{center}
\medskip
\begin{tabular}{c}
    \infer{<c_1 || c_2, \sigma> \stepsone <c_1' || c_2, \sigma'>}{<c_1,\sigma> \stepsone <c_1', \sigma'>} \\ \\
    \infer{<c_1 || c_2, \sigma> \stepsone <c_1 || c_2', \sigma'>}{<c_2,\sigma> \stepsone <c_2', \sigma'>}
\end{tabular}
\bigskip
\end{center}

\noindent
Big step semantics on the other hand does not capture interleaving.
For example, we could try to express the semantics for the concurrent statements $c_1 || c_2$ as follows:

\begin{center}
\medskip
\begin{tabular}{c}
    \infer{<c_1 || c_2, \sigma> \Downarrow \sigma '}{<c_1, \sigma> \Downarrow \sigma ''~<c_2, \sigma''> \Downarrow \sigma '}
\end{tabular}
\bigskip
\end{center}

\noindent
However, we have only ended up defining $c_1 ; c_2$, that is the
serial execution of commands $c_1$ and $c_2$. Thus, in general, big step semantics are often not faithful when it comes to representing non-determinism.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}
