\documentstyle[12pt,pocs-header]{article}
\Scribes{Robert Grace and Albert Woo}
\Lecturer{Bill Weihl}
\LectureNumber{5}
\LectureDate{September 25, 1991}
\include{macros}
\begin{document}
\MakeScribeTop

\section{Handouts}

Handout 14, ``Fall 1990 Problem Set 2 and Solutions'' was handed out.

\section{Semantics of SPEC}
The first part of this lecture examined some of the semantics of the
SPEC language.  For our purposes, the semantics can be split into
three categories, listed by increasing complexity:
\begin{itemize}
\item {\bf Expressions} -- Simple functions based on current state.

\item {\bf Atomic Statements} -- Parts of atomic procedures that
describe a relation between the initial and final states of the
system.  The local state and environment are constant, since we deal
only with sequential semantics here.

\item {\bf Non-atomic Statements} -- General procedures where multiple
execution threads work concurrently through the states.  The state of
each thread must be saved during context switches.
\end{itemize}

When we talk about the semantics of SPEC, we describe a method for
interpreting a spec program in terms of {\em atomic states} (A) and an
{\em atomic transition relation} (aTr) that describes how a thread may
progress through these states as it executes statements in the spec
program.  The aTr is a relation because SPEC allows for
non-determinism -- a thread may end up in one of several states after
executing a given statement.

\subsection{Statements}
We define the transition relation of a SPEC program by defining {\em
meanings} of statements:  a mapping of states 'a' to possible outcomes
'o'.  The atomic transition relation is defined as a function from a
given state and outcome (a,o) to a boolean value which determines if
the mapping is valid (i.e. if a transition from 'a' to 'o' exists):
\begin{center}
$aTr: (a,o) --> BOOL$
\end{center}
The meaning function for statements maps a statement 'S' to an atomic
transition relation 'aTr' that properly describes its semantics:
\begin{center}
$MS: S --> aTr$
\end{center}

An {\em outcome} 'o' consists of two mappings:
\begin{itemize}
\item {\em environment:}  variable $-->$ memory location
\item {\em memory:}  memory location $-->$ value
\end{itemize}
The outcome also contains a value 'v' element which is used for
passing arguments and results during invocations.  Exceptional
outcomes are recorded in the exception 'x' field of an outcome, and
looping outcomes are encoded as the exception *LOOP.  Also, information
on forked threads are saved when concurrency is a factor.  An atomic
state 'a' is simply a non-exceptional outcome, where x=noX.  On page 6
of Handout 9, some SPEC statements and their corresponding (a,o)
pairings, or predicates, are listed.  The table lists meanings for
compound as well as simple statements -- the non-deterministic 'or' is
of worthy note.  The meaning of a compound 'or' statement is simply
the union of the results of each statement executed separately:  the
compound statement $S1 [] S2$ allows for (a,o) transitions that are
valid either by $S1$ or by $S2$.  

The meanings of different statements must be treated separately as there
are different kinds of statements.  A complete definition of MS would
involve an enumeration of these various statement types and their
meanings and is outlined on pages 4 and 5 of Handout 9.

\subsection{Expressions}
In contrast to statements, expressions are simple, deterministic
functions mapping a state to a particular result.  They do not cause
side effects that change the current state when evaluated, as
statement may.  The result of evaluating an expression is:
\begin{center}
$E: A --> UNION[V,X]$
\end{center}
In general, a result falls into one of four categories:
\begin{itemize}
\item {\em infinite loop}  -- denoted by the exception *LOOP
\item {\em exception} -- Not a failure.  x= a string identifying the
exception.
\item {\em value} 
\item {\em no outcome} -- A failure.  The expression does not return a
result;  this is most commonly caused by an unsatisfied guarded
statement that has no satisfiable alternative.  An example given in
lecture was:
\begin{verbatim}
APROC foo(x: INT) -> INT =
  <<  x>0 => RET x >>
\end{verbatim}   
If x=3, for example, the result is the value of x.  However, if x=-3,
there is no result, and the thread blocks.  It is important to note
that for the 'no outcome' result to be determined, one would have to
'look at' the statement before actually trying to compute the result.
The alternative, which involves 'backing up' after finding a blocked
guard statement, would be hard to implement.
\end{itemize}

To define the meaning of an expression in SPEC, the meaning function
ME maps the expression to the state/result mapping that properly
describes its semantics:
\begin{center}
$ME: E --> (A --> UNION[V,X])$
\end{center}
ME is defined differently for each of the expression types, similar to
MS.  Some expression types and their meanings are listed below:

\begin{tabular}{ll}
{\bf Expression} & {\bf Meaning}\\
{\em literal\/}, l: & constant function \\

{\em variable\/}, var:& {\tt (a.m (a.en(``var'')))}\\
& $ie.$: The meaning of a variable is the value stored in the\\
& memory location associated with that variable.\\
\\
{\em dereference\/}, e$\uparrow$: & {\tt a.m (ME(e)(a))} \ seems reasonable.\\
&This means find the meaning of $e$ in state $a$.  This should\\
&be a location, and the meaning is the value stored at that location.\\
& But this doesn't take exceptions into account! \\
& As usual treating exceptions adds extra hair:\\
& \hspace{.1in} {\tt VAR vx := ME(e)(a);} \\
& \hspace{.1in} {\tt vx isX --> RET vx} \\
& \hspace{.1in} {\tt [] vx isV --> RET a.m(vx)} \\
\\
{\em invocation\/}, f(e): & Informally:\\
& If $f$ or $e$ returns an exception then return the exception;\\
& otherwise $f$ must be a function from values to results, so\\
& we want the meaning of  $f$ applied to $e$.\\
& This will be discussed in more detail next class.\\
\end{tabular}


\section{Limitations of Abstraction Functions}

In Lecture 2, we learned how to use abstraction functions to prove the
correctness of module implementations.  We argued that the abstraction
function would map any given implementation state to a single state of 
the specification.  However, there are some modules in which a particular
implementation state can be mapped to {\bf several} different states in
the specification.  How can these modules then be proven correct, given
that simple abstraction functions are not valid for these examples?  This
question will be explored in the following sections.

\subsection{Statistical Database Example}

A module which illustrates this problem well is the statistical database
example.  This module is described in Handout 12, called ``History Variables''.
The basic premise of the statistical database is that the state of the
specification is given by a sequence of values called {\it db}, 
while the state of the
implementation is given by three values: {\it count},
the the number of items in
the database, {\it sum}, the sum of the the items, and {\it sumSquare}, 
the sum of the squares of the items.

The problem arises because a state in the implementation can map to many
states in the specification.  For example, if we are in the implementation
state ({\it count} = 4, {\it sum} = 10, {\it sumSquare} = 28), this state 
can map to either [2 2 2 4] or [3 3 3 1] in the specification.
The implementation state can also map to permutations
of these specification states, such as [2 4 2 2], [1 3 3 3], etc.
Obviously then, we cannot define an abstraction function for this module, 
because for each state of the implementation, there are many
corresponding states of the specification.  

In general, we can get around these types of problems by using one of
two methods: {\it multi-valued abstraction mapping}, which uses 
abstraction relations instead of abstraction functions, and {\it history
variables} which add variables to the implentation state.

\subsection{Multi-valued Abstraction mapping}

Multi-valued abstraction mapping deals with abstraction relations as
opposed to abstraction functions.  For each state of the implementation 
we map an abstraction relation to all possible states in the specification
that it can represent.  In the statistical database example, the abstraction
relation would relate a state of the implementation ({\it count, sum,
sumSquare}) to any sequence {\it db} such that {\it db} has {\it count}
elements, the sum of the elements equals {\it sum}, and the sum of the
squares of the elements equals {\it sumSquare}.  See Figure 1 for the
abstraction relation for the implementation state 
({\it count} = 4, {\it sum} = 10, {\it sumSquare} = 28).

\begin{figure}
\centerline{\psfig{width=4in,figure=arelation.idraw}}
\caption{Abstraction relation for (count=4, sum=10, sumSquare=28).}
\end{figure}

Using multi-valued abstraction mapping can be advantageous because no
additional state information needs to be added to the module.  On the 
other hand, abstraction relations can often be difficult to specify.
For more information for how multi-valued abstraction mapping works, please
refer to recent papers by Nancy Lynch (MIT/LCS/TM-422).

\subsection{History Variables}

The statistical database cannot use an abstraction function to prove its
correctness because the abstract state (namely, the specification) contains
more information than the concrete state (implementation).  The spec actually
contains a record of all the individual values, while the implementation 
only contains {\it count, sum,} and {\it sumSquare}.  Thus to reclaim
a deterministic relationship between states of the implementation and the
spec (and to restore the utility of abstraction functions), we can simply
add the missing state to the implementation.  Doing so is called adding
{\it history variables}, since these variables keep track of additional
information about the history of execution.

To illustrate how history variables work, let's look again at the statistical
database from Handout 12.  If we add a variable {\it db} to the 
implementation which behaves similarly to the variable {\it db} in the spec,
then we can access the complete execution history via this variable.
Now we can use a simple abstraction function to map states of the 
implementation deterministically with the states of the specification.
This abstraction function simply discards all components of the implementation
state except {\it db}, which it returns as the spec's state.

In general, adding history variables to an implementation is used when:
1) there is not enough information in the implementation state to map
the implementation states deterministically to specification states.
This is the case with the statistical database problem.  2) the
specification itself behaves non-deterministically.  This
will be explained in the next section.

It is important to use history variables properly.  History variables
should only be used if:

\begin{itemize}
\item A value assigned to an existing state 
component does not depend on the value of a history variable; and 

\item The result of an operation does not depend on any history variables.

\end{itemize}

It's also important to keep in mind that we use history variables solely
to prove our modules correct, not for actual implementation.  So it's OK 
that adding history variables usually makes our implementations less 
efficient, since we're not going to use it anyway.  Also, we don't always
need to add the entire specification state to the implementation, as was
the case with the statistical database.  In some cases, we only 
need to add a small piece of missing state to the implementation.

\subsection{Non-deterministic Specifications}

The other situation where you might need to use history variables is
the case in which the specification behaves non-deterministically.  Consider
the example illustrated in Figure 2a.  This specification has three states,
a, b, and c.  There are three operations, called B, C, and CURRENT.
If you are in initial state a, the operation B takes you to state b, 
while operation C takes you to state c.  The operation CURRENT behaves
non-deterministically; if you are in state a, CURRENT returns a, but if 
you are in state b or c, it either returns d or the current state.


\begin{figure}
\centerline{\psfig{width=4in,figure=non-det.idraw}}
\caption{Non-deterministic example: (a) Specification, (b) One Implementation}
\end{figure}

We can imagine a legal implementation of this spec in which the states
b and c are combined into one state called bc (see Figure 2b).  Operations
B and C take you from state a to state bc.  When CURRENT is applied in 
state bc, d is returned.  We can see that it will be impossible to define
an abstraction function, since state bc can be mapped in the spec 
to either state b or state c.  However, if a history variable is added
which traces the particular execution path, we will be able to determine
exactly which specification state we are in.

Please note that we could also solve this non-deterministic spec problem
by using an abstraction relation.

\end{document}
