% LaTeX source for CIVL Reference Manual. % \documentclass[11pt]{article} \usepackage{amsmath} \usepackage{amsthm} \usepackage{xcolor} \usepackage{bbold} \usepackage[lined,vlined,linesnumbered,noresetcount]{algorithm2e} \include{preambular} \title{The CIVL Reference Manual} \begin{document} \maketitle \section{CIVL Model Syntax} \subsection{Notation and terminology} \label{sec:notation} Let $\B=\{\true,\false\}$ (the set of boolean values). Let $\N=\{0,1,2,\ldots\}$ (the set of natural numbers). Given a node $u$ in a tree, we let $\ancestors(u)$ denote the set of all ancestors of $u$, including $u$. We let $\descendants(u)$ denote the set of all descendants of $u$, including $u$. For any set $S$, let $S^*$ denote the set of all finite sequences of elements of $S$. The length of a sequence $\xi\in S^*$ is denoted $\len(\xi)$. % This is a lie: % The elements of the sequence are indexed from $0$ to % $\len(\xi)-1$. \subsection{Definition of Context} \label{sec:context} \begin{definition} A \emph{CIVL type system} is a tuple comprising the following components: \begin{enumerate} \item a set $\Type$ (the set of \emph{types}), \item a type $\bool\in\Type$ (the \emph{boolean type}), \item a type $\proc\in\Type$ (the \emph{process-reference type}), \item a set $\Var$ (the set of all \emph{typed variables}), \item a function $\vtype\colon \Var\ra\Type$ (which gives the type of each variable), \item a set $\Val$ (the set of all \emph{values}), \item a function which assigns to each $t\in\Type$ a subset $\Val_t\subseteq\Val$ (the set of values of type $t$) and which satisfies $\Val_{\bool}=\B$ and $\Val_{\proc}=\N$, \item a function which assigns to each $t\in\Type$ a value $\default_t\in\Val_t$. \end{enumerate} \end{definition} The default value will be used to give an initial value to any variable. It could represent something like ``an undefined value of type $t$'' or a reasonable initial value ($0$ for integers, etc.), depending on the language one is modeling. \begin{definition} Given a CIVL type system, a \emph{valuation} in that system is a function $\eta\colon\Var\ra\Val$ with the property that for any $v\in\Var$, $\eta(v)\in\Val_{\vtype(v)}$. \end{definition} Given a CIVL type system, we let $\Eval$ denote the set of all valuations in that system. \begin{definition} Given a CIVL type system, A \emph{CIVL expression system} for that type system is a tuple comprising the following components: \begin{enumerate} \item a set $\Expr$ (the set of all \emph{typed expressions} over $\Var$), \item a function $\etype\colon\Expr\ra\Type$ (giving the type of each expression), \item a function $\eval\colon\Expr\times\Eval\ra\Val$ (the \emph{evaluation function}), satisyfing \begin{itemize} \item for any $e\in\Expr$ and $\eta\in\Eval$, $\eval(e,\eta)\in\Val_{\etype(e)}$, \end{itemize} \item a function which associates to any $V\subseteq\Var$, a subset $\Expr(V)\subseteq\Expr$ (the set of \emph{expressions which involve only variables in $V$}) satisfying the following: \begin{itemize} \item for any $V\subseteq\Var$ and $\eta,\eta'\in\Eval$, if $\eta(v)=\eta'(v)$ for all $v\in V$, then for any $e\in\Expr(V)$, $\eval(e,\eta)=\eval(e,\eta')$ \end{itemize} \end{enumerate} \end{definition} \begin{definition} A \emph{CIVL context} is a CIVL type system together with a CIVL expression system for that type system. \end{definition} \begin{figure} \notationtable \caption{Table of Notation Used to Define CIVL Model Syntax} \label{fig:notation} \end{figure} \subsection{Lexical scopes} \label{sec:scopes} \begin{definition} Given a CIVL context $\mathcal{C}$, a \emph{lexical scope system} over $\mathcal{C}$ is a tuple $(\Sigma,\rootscope,\sparent,\vars)$ consisting of \begin{enumerate} \item a set $\Sigma$ (the set of \emph{static scopes}), \item a scope $\rootscope\in\Sigma$ (the \emph{root scope}), \item a function $\sparent\colon\Sigma\setminus\{\rootscope\}\rightarrow \Sigma$ such that \[\{(\sparent(\sigma),\sigma)\mid \sigma\in\Sigma\setminus\{\rootscope\}\}\] gives $\Sigma$ the structure of a rooted tree with root $\rootscope$, \item a function $\vars\colon\Sigma\rightarrow 2^{\Var}$ (specifying the variables \emph{declared} in each scope) satisfying \begin{itemize} \item $\sigma\neq\tau\implies \vars(\sigma)\cap \vars(\tau)=\emptyset$. \end{itemize} \end{enumerate} \end{definition} \begin{definition} Given a CIVL context and scope $\sigma\in\Sigma$, the set of \emph{visible variables} in $\sigma$ is $\bigcup_{\sigma'\in\ancestors(\sigma)}\vars(\sigma')$. \end{definition} One way this notion will be used: expressions used in a scope $\sigma$ can only involve variables visible in $\sigma$. \subsection{Functions} \label{sec:functions} Fix a CIVL context $\mathcal{C}$ and lexical scope system \[\Lambda=(\Sigma,\rootscope,\sparent,\vars)\] over $\mathcal{C}$. We introduce a new type symbol $\void$, as in C, to use as the return type for a function that does not return a value. Let $\Type'=\Type\cup\{\void\}$. \begin{definition} A \emph{function prototype} for $\Lambda$ is a tuple $(\sigma, t, \xi)$ consisting of \begin{enumerate} \item a scope $\sigma\in\Sigma\setminus\{\rootscope\}$ (the \emph{function scope}), \item a type $t\in\Type'$ (the \emph{return type}), \item a finite sequence $\xi=v_1v_2\cdots v_n\in\vars(\sigma)^*$ consisting of variables declared in the function scope (the \emph{formal parameters}). \end{enumerate} \end{definition} \begin{definition} A \emph{CIVL function prototype system} consists of \begin{enumerate} \item a set $\Func$ (the \emph{function symbols}), \item a function which assigns to each $f\in\Func$ a function prototype, denoted \[ (\fscope(f), \returntype(f), \params(f)), \] and satisfying \begin{itemize} \item for any $\sigma\in\Sigma$, there is at most one $f\in\Func$ such that $\sigma=\fscope(f)$, and \end{itemize} \item a \emph{root function} $f_0$ with $\fscope(f_0)=\rootscope$ and which is the only function with root scope. \end{enumerate} \end{definition} \begin{definition} Given a CIVL function prototype system, and function symbol $f\in\Func\setminus\{f_0\}$, the \emph{declaration scope} of $f$ is the scope $\sigma=\sparent(\fscope(f))$. We also write \emph{$f$ is declared in $\sigma$.} \end{definition} Note the root function $f_0$ has no declaration scope. Just as every scope has a set of visible variables, there is also a set of visible functions: \begin{definition} The functions \emph{visible at scope $\sigma$} are those declared in $\sigma$ or an ancestor of $\sigma$. \end{definition} We will see that the variables and functions visible at $\sigma$ are the only variables and functions that can be referred to by statements and expressions used within $\sigma$. Note that only certain scopes are function scopes. There can be additional scopes (intuitively corresponding to block scopes in a source program). Every scope, however, must ``belong to'' exactly one function. The precise definition is as follows: \begin{definition} \label{def:func} Given a CIVL function prototype system, define \[ \func \colon \Sigma \ra \Func \] by \[ \func(\sigma)= \begin{cases} f & \text{if $\sigma=\fscope(f)$ for some $f\in\Func$}\\ \func(\sparent(\sigma)) & \text{otherwise.} \end{cases} \] We say \emph{$\sigma$ belongs to $f$} when $\func(\sigma)=f$. \end{definition} Note that the recursion in Definition \ref{def:func} must stop as the root scope belongs to the root function and the scopes form a tree. \subsection{Statements} Fix a CIVL function prototype system. A \emph{CIVL statement} is defined to be a tuple of one of the forms described below. In each case, we give any restritions on the components of the tuple and a brief intuition on the statement's semantics. The precise semantics will be described in \S\ref{sec:semantics}. \begin{enumerate} \item $\langle\code{parassign},V_1,V_2,\psi\rangle$ \begin{itemize} \item $V_1,V_2\subseteq\Var$ \item $\psi\colon V_2\ra\Expr(V_1)$ satisfying $\etype(\psi(v))=\vtype(v)$ for all $v\in V_2$ \item \emph{meaning}: parallel assignment, i.e., the assignment of new values to any or all of the variables in $V_2$. For each variable in $V_2$ an expression is given which will be evaluated in the old state to compute the new value for that variable. $V_1$ contains all the variables that may be used in those expressions. Hence $V_1$ is the ``read set'' and $V_2$ is the ``write set'' for the parallel assignment. \end{itemize} \item $\langle\code{assign},v,e\rangle$ \begin{itemize} \item $v\in\Var$, $e\in\Expr$, $\etype(e)=\vtype(v)$ \item \emph{meaning}: simple assignment: evaluate an expression $e$ and assign result to variable $v$. It is a special case of \code{parassign} but is provided for convenience. \end{itemize} \item $\langle\code{call},y,f,e_1,\ldots,e_n\rangle$ \begin{itemize} \item $y\in\Var$, $f\in\Func$, $e_1,\ldots,e_n\in\Expr$ \item $n=\numparams(f)$ \item $\etype(e_i)=\vtype(v_i)$, where $\params(f)=v_1\cdots v_n$ \item $\returntype(f)=\vtype(y)$ \item \emph{meaning}: evaluate expressions $e_1,\ldots,e_n$; push frame on call stack and move control to guarded transition system (see \S\ref{sec:gts}) for function $f$; when $f$ returns, pop stack and store returned result in $y$ \end{itemize} \item $\langle\code{call},f,e_1,\ldots,e_n\rangle$ \begin{itemize} \item $f\in\Func$, $e_1,\ldots,e_n\in\Expr$ \item $n=\numparams(f)$ \item $\etype(e_i)=\vtype(v_i)$, where $\params(f)=v_1\cdots v_n$ \item \emph{meaning}: like above, but return type may be \code{void} or returned value could just be ignored \end{itemize} \item $\langle\code{fork},p,f,e_1,\ldots,e_n\rangle$ \begin{itemize} \item $p\in\Var$, $f\in\Func$, $e_1,\ldots,e_n\in\Expr$ \item $n=\numparams(f)$ \item $\etype(e_i)=\vtype(v_i)$, where $\params(f)=v_1\cdots v_n$ \item $\returntype(f)=\void$ \item $\vtype(p)=\proc$ \item \emph{meaning}: evaluate expressions $e_1,\ldots,e_n$; create new process and invoke function $f$ in it; return, immediately, a reference to the new process and store that reference in $p$ \end{itemize} \item $\langle\code{join},e\rangle$ \begin{itemize} \item $e\in\Expr$ \item $\etype(e)=\proc$ \item \emph{meaning}: evaluate $e$ and wait for the referenced process to terminate \end{itemize} \item $\langle\code{return},e\rangle$ \begin{itemize} \item $e\in\Expr$ \item \emph{meaning}: evaluate $e$, pop the call stack and return control, along with the value, to caller \end{itemize} \item $\langle\code{return}\rangle$ \begin{itemize} \item \emph{meaning}: pop the call stack and return control to caller; only to be used in functions returning \code{void} \end{itemize} \item $\langle\code{write},e\rangle$ \begin{itemize} \item $e\in\Expr$ \item \emph{meaning}: evaluate $e$ and send result to output \end{itemize} \item $\langle\code{noop}\rangle$ \begin{itemize} \item \emph{meaning}: does nothing \end{itemize} \item $\langle\code{assert}, e\rangle$ \begin{itemize} \item $e\in\Expr$, $\vtype(e)=\bool$ \item \emph{meaning}: evaluate $e$; if result is false, stop execution and report error \end{itemize} \item $\langle\code{assume}, e\rangle$ \begin{itemize} \item $e\in\Expr$, $\vtype(e)=\bool$ \item \emph{meaning}: assume $e$ holds (i.e., if $e$ does not hold, the execution sequence is not a real execution) \end{itemize} \end{enumerate} \subsubsection{Remarks} The system described is sufficiently general to model pointers. There can be (one or more) pointer types and corresponding values. The parallel assignment statement can be used to model statements like C's \texttt{*p=e;}. In the worst case (if no information is known about where \texttt{p} could point), one can let $V_2=\Var$. Similarly, expressions that involve \texttt{*p} as a right-hand side subexpression can always take $V_1=\Var$. Heaps can also be modeled. A heap type may be defined and a variable of that type declared. Expressions to modify and read from the heap can be defined, as can pointers into the heap. \subsection{Transition system representation of functions} \label{sec:gts} \begin{definition} Given a CIVL function prototype system and $f\in\Func$, a \emph{guarded transition system} for $f$ is a tuple $(\Loc,\lscope,\start, T)$, where \begin{itemize} \item $\Loc$ is a set (the set of \emph{locations}), \item $\lscope\colon\Loc\ra\Sigma$ is a function which associates to each $l\in\Loc$ a scope $\lscope(l)\in\Sigma$ belonging to $f$, \item $\start\in\Loc$ (the \emph{start location}), \item $T$ is a set of \emph{guarded transitions}, each of which has the form $\langle l,g,s,l'\rangle$, where \begin{itemize} \item $l,l'\in\Loc$ (the \emph{source} and \emph{target} locations) \item $g\in\Expr(V)$, where $V$ is the set of variables visible at $\lscope(l)$, and $\etype(g)=\bool$ ($g$ is called the \emph{guard}), \item $s$ is a statment all of whose constituent variables, expressions, and function symbols are visible at $\lscope(l)$. \end{itemize} \end{itemize} Furthermore, if the guarded transition system contains a statement of the form $\langle\code{return}\rangle$ then $\returntype(f)=\void$. If it contains a statement of the form $\langle\code{return},e\rangle$ then $\etype(e)=\returntype(f)$. \end{definition} \begin{definition} Given a CIVL prototype system, a \emph{CIVL model} $M$ for that system assigns, to each $f\in\Func$, a guarded transition system \[(\Loc_f,\lscope_f, \start_f,T_f)\] for $f$. Moreover, if $f\neq f'$ then $\Loc_f\cap\Loc_{f'}=\emptyset$. \end{definition} \begin{definition} Given a CIVL model $M$, let $\Loc=\bigcup_{f\in\Func}\Loc_f$. \end{definition} \section{CIVL Model Semantics} \label{sec:semantics} \subsection{State} \label{sec:state} Fix a CIVL model $M$. Recall that a valuation is a type-respecting function from $\Var$ to $\Val$. Given a subset $V\subseteq\Var$ of variables, we define a \emph{valuation on $V$} to be a type-respecting function from $V$ to $\Val$. Let $\Eval(V)$ denote the set of all valuations on $V$. Note that $\Eval(\Var)=\Eval$. \begin{definition} \label{def:state} A \emph{state} of a CIVL model $M$ is a tuple \[ s=(\Delta, \droot, \dparent, \static, \deval, P, \stack), \] where \begin{enumerate} \item $\Delta$ is a finite set (the set of \emph{dynamic scopes} in $s$), \item $\droot\in\Delta$ (the \emph{root dynamic scope}), \item $\dparent\colon \Delta\setminus\{\droot\}\ra\Delta$ is a function such that the set \[ \{(\dparent(\delta),\delta)\mid \delta\in \Delta\setminus\{\droot\}\} \] gives $\Delta$ the structure of a rooted tree with root $\droot$, \item $\static\colon\Delta\ra\Sigma$, \item $\static(\droot)=\rootscope$ and $\droot$ is the only $\delta\in\Delta$ satisfying $\static(\delta)=\rootscope$, \item $\static(\dparent(\delta))=\sparent(\static(\delta))$ for any $\delta\in\Delta$, \item $\deval$ is a function that assigns to each $\delta\in\Delta$ a valuation $\deval(\delta)\in\Eval(\vars(\static(\delta)))$, \item $P$ (the set of \emph{process IDs} in $s$) is a finite subset of $\Val_{\proc}$, and \item $\stack\colon P\ra \Frame^*$, where \[ \Frame=\{(\delta,l)\in\Delta\times\Loc\mid\lscope(l)=\static(\delta)\}. \] \end{enumerate} Let $\State$ denote the set of all states of $M$. \end{definition} % say entrance and exit from scopes does not have to be "structured". Remarks: \begin{enumerate} \item We will also refer to dynamic scopes as \emph{dyscopes}. \item The elements of $\Delta$ contain no intrinsic information. Instead, all of the information concerning dyscopes is encoded in the functions that take elements of $\Delta$ as arguments. Hence we might just as well call the elements of $\Delta$ ``dynamic scope IDs'' (just as we call the elements of $P$ ``process IDs''). One could use natural numbers for the dyscopes, just as one does for processes. \item The reason for using some form of ID for dyscopes and processes, rather than just incorporating the data in the appropriate part of the state, is that both kinds of objects may be shared. There can be several components of the state that refer to the same dyscope $d$: e.g., $d$ could have several children, each of which has a parent reference to $d$, as well as a reference from a frame. A process can be referred to by any number of variables of type $\proc$. \item If $\sigma=\static(\delta)$, we say that \emph{$\delta$ is an instance of $\sigma$} or \emph{$\sigma$ is the static scope associated to $\delta$}. In general, a static scope can have any number (including 0) of dynamic instances. The exception is the root scope $\rootscope$, which must have exactly one instance ($\droot$). \item A valuation $\deval(\delta)$ assigns a value to each variable in the static scope associated to $\delta$. The function $\deval$ thereby encodes the value of all variables ``in scope'' in state $s$. \item The sequence $\stack(p)$ encodes the state of the call stack of process $p$. The elements of the sequence are called \emph{activation frames}. The first frame in the sequence, i.e., the frame in position $0$, is the bottom of the stack; the last frame is the top of the stack. \item Each frame refers to a dyscope $\delta$ and a location in the static scope associated to $\delta$. \end{enumerate} \begin{definition} A dyscope $\delta\in\Delta$ is a \emph{function node} if $\static(\delta)$ is the function scope of some function. \end{definition} \begin{definition} Given any $\delta\in\Delta$, $\fnode(\delta)\in\Delta$ is defined as follows: if $\delta$ is a function node, then $\fnode(\delta)=\delta$, else $\fnode(\delta)=\fnode(\dparent(\delta))$. We call $\fnode(\delta)$ the \emph{function node associated to $\delta$}. \end{definition} The relation $\{(\delta,\delta')\mid \fnode(\delta)=\fnode(\delta')\}$ is an equivalence relation $\sim$ on $\Delta$. Let $\bar{\Delta}=\Delta/\sim$ and write $[\delta]$ for the equivalence class containing $\delta$. The set of activation frames in a state $s$ may be identified with the set \[ AF(s)=\bigcup_{p\in P}\{p\}\times\{0,\ldots,\len(\stack(p))-1\} \] Namely, $(p,i)$ corresponds to the $i^{\text{th}}$ entry in the call stack $\stack(p)$ (where the elements of the stacks are indexed from $0$). Define $\Psi\colon AF(s)\ra \bar{\Delta}$ as follows: given $(p,i)$, let $(\delta,l)$ be the corresponding frame; set $\Psi(p,i)=[\delta]$. % \begin{definition} % A state $s$ is \emph{well-formed} if all of the following hold: % \begin{enumerate} % \item for any $\delta\in\Delta$, at most one child of $\delta$ is not % a function node, % \item the function $\Psi$ is a one-to-one correspondence, % \item any $\delta$ occurring in the top frame of a call stack % is a leaf node. % \end{enumerate} % \end{definition} \subsection{Jump protocol} \label{sec:jump} % can only jump if \delta is a leaf node. % also no other frame can point to a dyscope between \delta % and the dyscope corresponding to the function scope % in any state, a "region" of the dyscope tree can have at % most one (exactly one?) stack frame pointing into it. % a region in a chain of nodes starting from a dyanmic scope corresonding % to a function scopes and leading down until you reach another % function scope. % whenever you have more than one child in the dynamic tree, all but % 0 or 1 children must be a function scope % every dyscope is owned by at most one frame % can a frame point only to a leaf node? No, but all of its children % must be function nodes % to find out which frame owns which dyscopes: % approach 1: start from a frame. frame owns the node it points to. % move up parents until you hit a function scope and stop. % that is that frame's region. No other frame can point into its % region. Proof: true in initial state, invariant under % call and fork. % invariant: every leaf node in the dyscope tree is pointed % to by the top frame of the call stack of some process % Define a \emph{well-formed state}: % every dyscope node has at most one child which is not a function node % 1-1 correspondence between leaf nodes and top frames of stacks. % Define regions in the dyscope tree. (each region contains one % function node) \newcommand{\lub}{\sigma_{\textsf{lub}}} \begin{figure} \begin{algorithm}[H] \Procedure{$\textsf{\textup{jump}}(s\colon\State, p\colon\Val_{\proc}, l'\colon\Loc)\colon\State$}{% let $(\Delta, \droot, \dparent, \static, \deval, P, \stack)=s$\; let $\delta$ be the dyscope of the last frame on $\stack(p)$\; let $\sigma=\static(\delta)$\; let $\sigma'=\lscope(l')$\; let $\lub$ be the least upper bound of $\sigma$ and $\sigma'$ in the tree $\Sigma$\; let $m$ be the minimum integer such that $\sparent^m(\sigma)=\lub$\; let $\delta_{\textsf{lub}}=\dparent^m(\delta)$\; let $n$ be the minimum integer such that $\sparent^{n}(\sigma')=\lub$\; let $\delta_0,\ldots,\delta_{n-1}$ be $n$ distinct objects not in $\Delta$\; let \( \displaystyle \Delta'=\Delta \cup \{ \delta_0,\ldots,\delta_{n-1} \} %\setminus \{ \dparent^j(\delta)\mid 0\leq j and use it. CIVL-C is a programming language. It is an extension of the C11 dialect of C. It does not however, include the entire standard C library. A CIVL-C program encodes a CIVL model for a particular CIVL context. The types are essentially the C types with the additional process reference type (denoted \cproc). The expressions are C expressions with some additional expressions defined below. In CIVL-C, functions can be defined in any scope, not just in file scope. The lexical scope structure and placement of function definitions determine the static scope tree $\Sigma$ and the function prototype system. A function's defining scope is, as you would expect, the scope in which its definition occurs. The CIVL-C code will not have an explicit ``root'' procedure. Instead, a root procedure will be implicitly wrapped around the entire code. The global input variables will become the inputs to the root procedure. A ``\texttt{main}'' procedure must be delcared that takes no parameters but can have any return type. The body of \texttt{main} becomes the body of the root procedure. The return type of \texttt{main} becomes the return type of the root procedure. The \texttt{main} procedure itself disappears in translation. The reason for this protocol is that an arbitrary (sequential) C program is a legal (and reasonable) CIVL-C program. The global variables in the C program simply become variables declared in the root scope. The additional language elements are shown in Figure \ref{fig:cc}. \begin{figure} \begin{tabular}{ll} \cproc & the process type \\ \cself & the evaluating process (constant of type \cproc) \\ \cinput & type qualifier declaring variable to be a program input \\ \coutput & type qualifier declaring variable to be a program output \\ \cspawn & create a new process running procedure \\ \cwait & wait for a process to terminate \\ \cassert & check something holds \\ \ctrue & boolean value true, used in assertions \\ \cfalse & boolean value false, used in assertions \\ \cassume & assume something holds \\ \cwhen & guarded statement \\ \cchoose & nondeterministic choice statement \\ \cchooseint & nondeterministic choice of integer \\ \cinvariant & declare a loop invariant \\ \crequires & procedure precondition \\ \censures & procedure postcondition \\ \cresult & refers to result returned by procedure in contracts \\ \cat & refer to variable in other process, e.g., \texttt{p@x} \\ \ccollective & a collective expression\\ \cheap & the heap type \\ \cscope & the scope type, used to give a name to a scope \\ \cmalloc & malloc function with additional heap arguments \\ \cregion & region qualifier for a pointer type \end{tabular} \caption{CIVL-C primitives. Some of these are part of the grammar of the language; others are defined in the header file \texttt{civlc.h}.} \label{fig:cc} \end{figure} \subsection{Detailed descriptions} \subsubsection{\cproc} This is a primitive object type and functions like any other primitive C type (e.g., \texttt{int}). An object of this type refers to process. It can be thought of as a process ID, but it is not an integer and cannot be cast to one. Certain expressions take an argument of \cproc{} type and some return something of \cproc{} type. \subsubsection{\cself} This is a constant of type \cproc. It can be used wherever an argument of type \cproc{} is called for. It refers to the process that is evaluating the expression containing ``\cself''. \subsubsection{\cinput} A variable in the root scope only may be declared with this type modifier indicating it is an ``input'' variable, as in \begin{verbatim} $input int n; \end{verbatim} As explained above, the variable becomes a parameter to the root procedure. This is used when comparing two programs for functional equivalence. The two programs are functionally equivalent if, whenever they are given the same inputs (i.e., corresponding \cinput{} variables are initialized with the same values) they will produce the same outputs (i.e., corresponding \coutput{} variables will end up with the same values at termination). \subsubsection{\coutput} A variable in the root scope may be declared with this type modifier to declare it to be an output variable. \subsubsection{\cspawn} This is an expression with side-effects. It spawns a new process and returns a reference to the new process, i.e., an object of type \cproc. The syntax is the same as a procedure invocation with the keyword ``\cspawn'' inserted in front: \begin{verbatim} $spawn f(expr1, ..., exprn) \end{verbatim} Typically the returned value is assigned to a variable, e.g., \begin{verbatim} $proc p = $spawn f(i); \end{verbatim} If the invoked function \texttt{f} returns a value, that value is simply ignored. \subsubsection{\cwait} This is a statement that takes an argument of type \cproc{} and blocks until the referenced process terminates: \begin{verbatim} $wait expr; \end{verbatim} \subsubsection{\cassert} This is an assertion statement. It takes as its sole argument an expression of boolean type. The expressions have a richer syntax than C expressions. During verification, the assertion is checked. If it does not hold, a violation is reported. \begin{verbatim} $assert expr; \end{verbatim} Boolean values \ctrue{} and \cfalse{} may be used in assertions and assumptions. \subsubsection{\cassume} This is an assume statement. Its syntax is the same as that of \cassert. During verification, the assumed expression is assumed to hold. If this leads to a contradiction on some execution, that execution is simply ignored. It never reports a violation, it only restricts the set of possible executions that will be explored by the verification algorithm. \begin{verbatim} $assume expr; \end{verbatim} \subsubsection{\cwhen} This represents a guarded comment: \begin{verbatim} $when (expr) stmt; \end{verbatim} All statements have a guard, either implicit or explicit. For most statements, the guard is \ctrue. The \cwhen{} statement allows one to attach an explicit guard to a statement. When \texttt{expr} is \emph{true}, the statement is enabled, otherwise it is disabled. A disabled statement is \emph{blocked}---it will not be scheduled for execution. When it is enabled, it may execute by moving control to the \texttt{stmt} and executing the first atomic action in the \texttt{stmt}. If \texttt{stmt} itself has a non-trivial guard, the guard of the \cwhen{} statement is effectively the conjunction of the \texttt{expr} and the guard of \texttt{stmt}. The evaluation of \texttt{expr} and the first atomic action of \texttt{stmt} effectively occur as a single atomic action. There is no guarantee that execution of \texttt{stmt} will continue atomically if it contains more than one atomic action, i.e., other processes may be scheduled. Examples: \begin{verbatim} $when (s>0) s--; \end{verbatim} This will block until \texttt{s} is positive and then decrement \texttt{s}. The execution of \texttt{s--} is guaranteed to take place in an environment in which \texttt{s} is positive. \begin{verbatim} $when (s>0) {s--; t++} \end{verbatim} The execution of \texttt{s--} must happen when \texttt{s>0}, but between \texttt{s--} and \texttt{t++}, other processes may execute. \begin{verbatim} $when (s>0) $when (t>0) x=y*t; \end{verbatim} This blocks until both \texttt{x} and \texttt{t} are positive then executes the assignment in that state. It is equivalent to \begin{verbatim} $when (s>0 && t>0) x=y*t; \end{verbatim} \subsubsection{\cchoose} A \cchoose{} statement has the form \begin{verbatim} $choose { stmt1; stmt2; ... default: stmt } \end{verbatim} The \texttt{default} clause is optional. The guards of the statements are evaluated and among those that are \emph{true}, one is chosen nondeterministically and executed. If none are \emph{true} and the \texttt{default} clause is present, it is chosen. The \texttt{default} clause will only be selected if all guards are \emph{false}. If no \texttt{default} clause is present and all guards are \emph{false}, the statement blocks. Hence the implicit guard of the \cchoose{} statement without a \texttt{default} clause is the disjunction of the guards of its sub-statements. The implicit guard of the \cchoose{} statement with a default clause is \emph{true}. Example: this shows how to encode a ``low-level'' CIVL guarded transition system: \begin{verbatim} l1: $choose { $when (x>0) {x--; goto l2;} $when (x==0) {y=1; goto l3;} default: {z=1; goto l4;} } l2: $choose { ... } l3: $choose { ... } \end{verbatim} \subsubsection{\cchooseint} This is a function with the following prototype: \begin{verbatim} int $choose_int(int n); \end{verbatim} It takes as input a positive integer \texttt{n} and returns an integer in the range $[0,\texttt{n}-1]$. \subsubsection{\cinvariant} This indicates a loop invariant. Each C loop construct has an optional invariant clause as follows: \begin{verbatim} while (expr) $invariant (expr) stmt for (e1; e2; e3) $invariant (expr) stmt do stmt while (expr) $invariant (expr) ; \end{verbatim} The invariant encodes the claim that if \texttt{expr} holds upon entering the loop and the loop condition holds, then it will hold after completion of execution of the loop body. The invariant is used by certain verification techniques. \subsubsection{Procedure contracts} The \crequires{} and \censures{} primitives are used to encode procedure contracts. There are optional elements that may occur in a procedure declaration or definition, as follows. For a function prototype: \begin{verbatim} T f(...) $requires expr; $ensures expr; ; \end{verbatim} For a function definition: \begin{verbatim} T f(...) $requires expr; $ensures expr; { ... } \end{verbatim} The value \cresult{} may be used in post-conditions to refer to the result returned by a procedure. \subsubsection{Remote expressions}. These have the form \verb!expr@x! and refer to a variable in another process, e.g., \verb!procs[i]@x!. This special kind of expression is used in collective expressions, which are used to formulate collective assertions and invariants. The expression \verb!expr! must have \cproc{} type. The variable \texttt{x} must be a statically visible variable in the context in which it is occurs. When this expression is evaluated, the evaluation context will be shifted to the process referred to by \texttt{expr}. \subsubsection{Collective expressions}. These have the form \begin{verbatim} $collective(proc_expr, int_expr) expr \end{verbatim} This is a collective expression over a set of processes. The expression \texttt{proc{\U}expr} yields a pointer to the first element of an array of \cproc. The expression \texttt{int{\U}expr} gives the length of that array, i.e., the number of processes. Expression \texttt{expr} is a boolean-valued expression; it may use remote expressions to refer to variables in the processes specified in the array. Example: \begin{verbatim} $proc procs[N]; ... $assert $collective(procs, N) i==procs[(pid+1)%N]@i ; \end{verbatim} \subsection{Pointers and heaps} CIVL-C supports pointers, using the same operators with the same meanings as C (\texttt{\&}, \texttt{*}, pointer arithmetic). The standard CIVL-C library defines a type \cheap{} for explicit modeling of a heap. The default value of \cheap{} type is an empty heap, so you only need to declare a variable to have type \cheap{} in order to create a new heap: \begin{verbatim} $heap h; /* a new empty heap */ \end{verbatim} The following functions are also defined: \begin{verbatim} void* $malloc($heap *h, int size); void memcpy(void *p, void *q, size_t size); void free(void *p) \end{verbatim} The first function is like C's \texttt{malloc}, except that you specify the heap in which the allocation takes place by passing a pointer to the heap as the first argument. This modifies the specified heap and returns a pointer to the new object. The function can only occur in a context in which the type of the object is specified, as in: \begin{verbatim} $heap h; int n = 10; double *p = (double*)$malloc(&h, n*sizeof(double)); \end{verbatim} The second and third functions are exactly the same as in C. Note that \texttt{free} modifies the heap which was used to allocate \texttt{p}. CIVL-C allows an additional qualifier to be added to a pointer type. The qualifier limits the region into which the pointer may point. To use it, you first need to give a name to a scope. This is accomplished by just declaring a variable of type \cscope{} in the scope you wish to name. Example: \begin{verbatim} { { /* beginning of scope s */ $scope s; /* names this scope */ ... } /* end of scope s */ } \end{verbatim} At runtime, \texttt{s} is assigned the value of a dynamic scope ID (i.e., an element of $\Delta$; see Def.\ \ref{def:state}). Currently, there are no operations on \cscope{} variables and they cannot be assigned. They can only be used in a pointer qualifier as described below. The primitive \texttt{\cregion(s)}, where \texttt{s} is a \cscope{} variable, denotes the set of dynamic scopes consisting of \texttt{s} and all descendants of \texttt{s}. This expression can be used in a pointer type as follows: \begin{verbatim} { $scope s; /* gives name s to this scope */ int x; ... { int *$region(s) p = &x; ... } } \end{verbatim} The declaration of \texttt{p} states that \texttt{p} can only point to an object declared in \texttt{s} or one of its descendants (inner scopes). If the optional region qualifier is not used, the assumption is the pointer could point anywhere, i.e., the default region is the one determined by the \emph{root} dynamic scope. Another pointer example: \begin{verbatim} { $heap h; { $scope s1; double x; { $scope s2; double y; double *$region(s1) p; /* p can only point to something in s1 or descendant, * for example, s2 */ p = &x; // fine p = &y; p = (double*)$malloc(&h,10*sizeof(double)); // syntax error } } } \end{verbatim} \section{Some Translation Examples} \subsection{Structured parallelism} Structured \verb!parbegin!/\verb!parend! statements look like this: \begin{verbatim} $parbegin S1; S2; S2 $parend \end{verbatim} (See Dijkstra, Cooperating Sequential Processes.) The meaning is: run the three statements in parallel, and block at the end until all have completed. This can be represented in CIVL-C as follows: \begin{verbatim} { void f_1() {S1} void f_2() {S2} void f_3() {S3} $proc tmp1 = $fork f_1(), tmp2=$fork f_2(), tmp3=$fork f_3(); $join(tmp1); $join(tmp2); $join(tmp3); } \end{verbatim} \subsection{Parallel for loops} The standard parallel ``for'' loop looks like \begin{verbatim} $parfor(T i = e; cond; inc) S \end{verbatim} It indicates each iteration should be run concurrently, blocking at end until all complete. In CIVL-C: \begin{verbatim} { void f(T i) {S} T i = e; int c = 0; Vector<$proc> list; while (cond) { list.add($fork f()); c++; inc; } for (int j=0; j /* includes basic message-passing library */ % void System() { % proc procs[2]; % void MPI_Process(int pid) { % proc threads[2]; % void Thread(int tid) { % int x=0, y=0; % for (int j=0; j<2; j++) { % if (pid == 1) { % for (int i=0; i<3; i++) send(procs[pid], &x, 1, procs[1-pid], 0); % for (int i=0; i<3; i++) recv(procs[pid], &y, 1, procs[1-pid], 0); % } else { /* pid==0 */ % for (int i=0; i<3; i++) recv(procs[pid], &y, 1, procs[1-pid], 0); % for (int i=0; i<3; i++) send(procs[pid], &x, 1, procs[1-pid], 0); % } % } % } % for (int i=0; i<2; i++) threads[i] = fork Thread(i); % for (int i=0; i<2; i++) join threads[i]; % } % for (int i=0; i<2; i++) procs[i] = fork MPI_Process(i); % for (int i=0; i<2; i++) join procs[i]; % } % \end{verbatim} \appendix \end{document} OpenMP loop? \begin{verbatim} T1 x1; ... // private U1 y1; ... // shared #pragma omp parallel private(x1,...) S(x1,...,y1,...); => T1 x1; ... U1 y1; ... { void _tmp(int _tid) { T1 _x1; ... S(_x1,...,y1,...); } int numThreads = $choose_int(THREAD_MAX); $proc _threads[numThreads]; int i; for (i=0; i { void _tmp1(int _tid) { int i; ... { void _tmp2(int _i) { S(_i) } int j; for (j=...) { int w = $choose_int(numThreads); } } } \end{verbatim}