source: CIVL/doc/manual/civl-manual.tex@ c46e702

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since c46e702 was 3ee3e7f, checked in by Manchun Zheng <zmanchun@…>, 12 years ago

edit manual

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@463 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 62.9 KB
Line 
1% LaTeX source for CIVL Reference Manual.
2%
3\documentclass[11pt, oneside, letterpaper]{book}
4\usepackage[letterpaper,textheight=9in,left=1in,%
5 textwidth=6.5in,bottom=1in]{geometry}
6\usepackage{amsmath}
7\usepackage{amsthm}
8\usepackage{xcolor}
9\usepackage{bbold}
10\usepackage{url}
11\usepackage[lined,vlined,linesnumbered,noresetcount]{algorithm2e}
12
13\include{preambular}
14
15\title{{\huge\bf CIVL}\\\mbox{The Concurrency Intermediate Verification
16 Language}\\Reference Manual\\ v0.5}
17\author{%
18 Matthew B.\ Dwyer \and
19 Ganesh Gopalakrishnan \and
20 Zvonimir Rakamaric \and
21 Stephen F.\ Siegel \and
22 Manchun Zheng \and
23 Timothy K.\ Zirkel
24}
25
26\begin{document}
27\maketitle
28\tableofcontents
29
30\chapter{Quick Start}
31
32\begin{enumerate}
33\item Download and unpack the appropriate pre-compiled library of CIVL
34 dependencies from \url{http://vsl.cis.udel.edu/tools/vsl_depend/}.
35 There are versions for Darwin (OS X), 32-bit linux, and 64-bit
36 linux.
37\item Move the resulting directory \texttt{vsl} to \texttt{/opt/vsl}.
38\item Download and unpack the latest stable release of CIVL from
39 \url{http://vsl.cis.udel.edu/civl}. Again there are versions
40 for Darwin, 32-bit linux, and 64-bit linux.
41\item The resulting directory should be named
42 \texttt{CIVL-\textit{tag}} for some string \textit{tag} which
43 identifies the version of CIVL you downloaded. Move this directory
44 into \texttt{/opt}.
45\item You should now have an executable script
46 \texttt{/opt/CIVL-\textit{tag}/bin/civl}. Move this script into
47 your path, or create a symlink from somewhere in your path to it, or
48 add the directory \texttt{/opt/CIVL-\textit{tag}/bin} to your path.
49\end{enumerate}
50
51From the command line, you should now be able to type \texttt{civl
52 help} and see a help message describing the command line syntax.
53
54Copy the file
55\texttt{CIVL-\textit{tag}/examples/concurrency/locksBad.cvl} to your
56working directory. Look at the program: it is a simple 2-process
57program with two shared variables used as locks. The 2 processes try
58to obtain the locks in opposite order, leading to a deadlock.
59
60Type
61\begin{verbatim}
62civl verify locksBad.cvl
63\end{verbatim}
64You should see some output culminating in a message
65\begin{verbatim}
66The program MAY NOT be correct. See CIVLREP/locksBad_log.txt
67\end{verbatim}
68
69Type
70\begin{verbatim}
71civl replay locksBad.cvl
72\end{verbatim}
73You should see a step-by-step account of how the program arrived
74at the deadlock.
75
76\textbf{Note.} You can install \texttt{CIVL-\textit{tag}} and
77\texttt{vsl} in any directory you want, not just in \texttt{/opt}.
78You just need to edit the script file \texttt{civl} appropriately,
79replacing the default paths with the new paths.
80
81\part{Language}
82
83\chapter{Overview of CIVL-C}
84
85% write a grammar. Leave out type qualifiers, etc. Keep pointers.
86% Keep simple types? Why not keep all the standard types.
87% How about "symbolic types"? Make all the casts explicit.
88% Look at CIL?
89
90% Describe as subset of C, but leave out:... and add...
91
92% add Set<proc> and use it.
93
94\section{CIVL-C concepts and primitives}
95
96CIVL-C is a programming language. It is an extension of a subset of
97the C11 dialect of C. It does not include the standard C library.
98
99A CIVL-C program should begin with the line
100\begin{verbatim}
101#include <civlc.h>
102\end{verbatim}
103which includes the main CIVL-C header file, which declares all the
104types and other CIVL primitives. Almost all of the CIVL-C primitives
105which are not already in C begin with the symbol \texttt{\$} to easily
106distinguish them from any reserved work or identifier in a C program.
107
108A CIVL-C program encodes a CIVL model for a particular CIVL
109context. The types are essentially the C types with the additional
110process reference type (denoted \cproc). The expressions are C
111expressions with some additional expressions defined below.
112
113In CIVL-C, functions can be defined in any scope, not just in file
114scope. The lexical scope structure and placement of function
115definitions determine the static scope tree $\Sigma$ and the function
116prototype system. A function's defining scope is, as you would
117expect, the scope in which its definition occurs.
118
119The CIVL-C code will not have an explicit ``root'' procedure.
120Instead, a root procedure will be implicitly wrapped around the entire
121code. The global input variables will become the inputs to the root
122procedure. A ``\texttt{main}'' procedure must be delcared that takes
123no parameters but can have any return type. The body of \texttt{main}
124becomes the body of the root procedure. The return type of
125\texttt{main} becomes the return type of the root procedure. The
126\texttt{main} procedure itself disappears in translation.
127
128The reason for this protocol is that an arbitrary (sequential) C program
129is a legal (and reasonable) CIVL-C program. The global variables in the
130C program simply become variables declared in the root scope.
131
132The additional language elements are shown in Figure \ref{fig:cc}.
133
134\begin{figure}[t]
135 \begin{tabular}{ll}
136 \cassert & check something holds \\
137 \cassume & assume something holds \\
138 \catom & defines statements to be executed as one transition\\
139 \catomic & defines statements to be executed without interleaving other processes\\
140 \cchoose & nondeterministic choice statement \\
141 \cchooseint & nondeterministic choice of integer \\
142 \ccollective & a collective expression\\
143 \censures & procedure postcondition \\
144 \cfalse & boolean value false, used in assertions \\
145 \cheap & the heap type \\
146 \cinput & type qualifier declaring variable to be a program input \\
147 \cinvariant & declare a loop invariant \\
148 \cmalloc & malloc function with additional heap arguments \\
149 \coutput & type qualifier declaring variable to be a program output \\
150 \cproc & the process type \\
151 \crequires & procedure precondition \\
152 \cresult & refers to result returned by procedure in contracts \\
153 \cscope & the scope type, used to give a name to a scope \\
154 \cself & the evaluating process (constant of type \cproc) \\
155 \cspawn & create a new process running procedure \\
156 \ctrue & boolean value true, used in assertions \\
157 \cwait & wait for a process to terminate \\
158 \cwhen & guarded statement \\
159 \cat & refer to variable in other process, e.g., \texttt{p@x} \\
160 \texttt{*<...>} & scope-qualified pointer type
161 \end{tabular}
162 \caption{CIVL-C primitives. Some of these are part of the grammar of the language;
163 others are defined in the header file \texttt{civlc.h}.}
164 \label{fig:cc}
165\end{figure}
166
167
168
169\section{Detailed descriptions of primitives}
170
171\subsection{\cproc} This is a primitive object type and functions like
172any other primitive C type (e.g., \texttt{int}). An object of this
173type refers to a process. It can be thought of as a process ID, but
174it is not an integer and cannot be cast to one. Certain expressions
175take an argument of \cproc{} type and some return something of
176\cproc{} type.
177
178\subsection{\cassert} This is an assertion statement. It takes as its
179sole argument an expression of boolean type. The expressions have a
180richer syntax than C expressions. During verification, the assertion
181is checked. If it does not hold, a violation is reported.
182\begin{verbatim}
183 $assert expr;
184\end{verbatim}
185Boolean values \ctrue{} and \cfalse{} may be used in assertions
186and assumptions.
187
188
189\subsection{\cassume} This is an assume statement. Its syntax is the
190same as that of \cassert. During verification, the assumed expression
191is assumed to hold. If this leads to a contradiction on some
192execution, that execution is simply ignored. It never reports a
193violation, it only restricts the set of possible executions that will
194be explored by the verification algorithm.
195\begin{verbatim}
196 $assume expr;
197\end{verbatim}
198
199\subsection{\catom} This defines a number of statements to be executed as one transition. An \catom~block has the following form.
200\begin{verbatim}
201 $atom {
202 stmt1;
203 stmt2;
204 ...
205 }
206\end{verbatim}
207
208The statements inside an \catom~block are to be executed as one transition. It is required that the execution of the statements in an \catom~block is deterministic, non-blocking and finite. If one of the requirement is found to be violated, an error or a warning will be reported. For example, an error will be reported when executing the code below, because the \cwait~statement is blocked.
209
210\begin{verbatim}
211$atom{
212 for(int i = 0; i < 5; i++) p[i] = $spawn foo(i);
213 for(int i = 0; i < 5; i++) $wait p[i];
214}
215\end{verbatim}
216
217
218\subsection{\catomic} This defines a number of statements that will only allow the process to interleave with others when necessary. An \catomic~block has the following form.
219
220\begin{verbatim}
221 $atomic {
222 stmt1;
223 stmt2;
224 ...
225 }
226\end{verbatim}
227
228A process executing an \catomic~block will try to execute statements contained in the \catomic~block without interleaving with other processes, unless the process is blocked. For example, the following loop will be executed without interleaving with other processes.
229
230\begin{verbatim}
231$atomic{
232 for(int i = 0; i < 5; i++) p[i] = $spawn foo(i);
233}
234\end{verbatim}
235
236When no transition can be enabled, the execution of the \catomic~block will be interrupted. And other processes are allowed to execute, until the process gets enabled again to continue executing its \catomic~block. For example, in the following lines of code, after executing the first loop, the \catomic~block is blocked, because it has to wait for other processes' termination.
237
238\begin{verbatim}
239$atomic{
240 for(int i = 0; i < 5; i++) p[i] = $spawn foo(i);
241 for(int i = 0; i < 5; i++) $wait p[i];
242}
243\end{verbatim}
244
245\subsection{\cchoose} A \cchoose{} statement has the form
246\begin{verbatim}
247 $choose {
248 stmt1;
249 stmt2;
250 ...
251 default: stmt
252 }
253\end{verbatim}
254The \texttt{default} clause is optional.
255
256The guards of the statements are evaluated and among those that are
257\emph{true}, one is chosen nondeterministically and executed. If none
258are \emph{true} and the \texttt{default} clause is present, it is
259chosen. The \texttt{default} clause will only be selected if all
260guards are \emph{false}. If no \texttt{default} clause is present and
261all guards are \emph{false}, the statement blocks. Hence the implicit
262guard of the \cchoose{} statement without a \texttt{default} clause is
263the disjunction of the guards of its sub-statements. The implicit
264guard of the \cchoose{} statement with a default clause is
265\emph{true}.
266
267Example: this shows how to encode a ``low-level'' CIVL guarded
268transition system:
269
270\begin{verbatim}
271 l1: $choose {
272 $when (x>0) {x--; goto l2;}
273 $when (x==0) {y=1; goto l3;}
274 default: {z=1; goto l4;}
275 }
276 l2: $choose {
277 ...
278 }
279 l3: $choose {
280 ...
281 }
282\end{verbatim}
283
284\subsection{\cchooseint} This is a function with the following prototype:
285\begin{verbatim}
286 int $choose_int(int n);
287\end{verbatim}
288It takes as input a positive integer \texttt{n} and non-deterministicaly returns
289an integer in the range $[0,\texttt{n}-1]$.
290
291\subsection{\cinput} A variable in the root scope only may be declared
292with this type modifier indicating it is an ``input'' variable, as in
293\begin{verbatim}
294 $input int n;
295\end{verbatim}
296As explained above, the variable becomes a parameter to the root
297procedure. This is used when comparing two programs for functional
298equivalence. The two programs are functionally equivalent if,
299whenever they are given the same inputs (i.e., corresponding \cinput{}
300variables are initialized with the same values) they will produce the
301same outputs (i.e., corresponding \coutput{} variables will end up
302with the same values at termination). Input variables can also be
303assigned a concrete value on the command line.
304
305\subsection{\cinvariant} This indicates a loop invariant. Each C loop
306construct has an optional invariant clause as follows:
307\begin{verbatim}
308 while (expr) $invariant (expr) stmt
309 for (e1; e2; e3) $invariant (expr) stmt
310 do stmt while (expr) $invariant (expr) ;
311\end{verbatim}
312The invariant encodes the claim that if \texttt{expr} holds upon
313entering the loop and the loop condition holds, then it will hold
314after completion of execution of the loop body. The invariant is used
315by certain verification techniques.
316
317\emph{Status:} parsed, but nothing is currently done with this
318information.
319
320\subsection{\coutput} A variable in the root scope may be declared
321with this type modifier to declare it to be an output variable.
322
323\subsection{\cself} This is a constant of type \cproc. It can be used
324wherever an argument of type \cproc{} is called for. It refers to the
325process that is evaluating the expression containing ``\cself''.
326
327\subsection{\cspawn} This is an expression with side-effects. It
328spawns a new process and returns a reference to the new process, i.e.,
329an object of type \cproc. The syntax is the same as a procedure
330invocation with the keyword ``\cspawn'' inserted in front:
331\begin{verbatim}
332 $spawn f(expr1, ..., exprn)
333\end{verbatim}
334Typically the returned value is assigned to a variable, e.g.,
335\begin{verbatim}
336 $proc p = $spawn f(i);
337\end{verbatim}
338If the invoked function \texttt{f} returns a value, that value is
339simply ignored.
340
341\subsection{\cwait} This is a statement that takes an argument of type
342\cproc{} and blocks until the referenced process terminates:
343\begin{verbatim}
344 $wait expr;
345\end{verbatim}
346
347\subsection{\cwhen} This represents a guarded command:
348\begin{verbatim}
349 $when (expr) stmt;
350\end{verbatim}
351All statements have a guard, either implicit or explicit. For most
352statements, the guard is \ctrue. The \cwhen{} statement allows one to
353attach an explicit guard to a statement.
354
355When \texttt{expr} is \emph{true}, the statement is enabled, otherwise
356it is disabled. A disabled statement is \emph{blocked}---it will not
357be scheduled for execution. When it is enabled, it may execute by
358moving control to the \texttt{stmt} and executing the first atomic
359action in the \texttt{stmt}.
360
361If \texttt{stmt} itself has a non-trivial guard, the guard of the
362\cwhen{} statement is effectively the conjunction of the \texttt{expr}
363and the guard of \texttt{stmt}.
364
365The evaluation of \texttt{expr} and the first atomic action of
366\texttt{stmt} effectively occur as a single atomic action. There is
367no guarantee that execution of \texttt{stmt} will continue atomically
368if it contains more than one atomic action, i.e., other processes may
369be scheduled.
370
371Examples:
372\begin{verbatim}
373 $when (s>0) s--;
374\end{verbatim}
375This will block until \texttt{s} is positive and then decrement
376\texttt{s}. The execution of \texttt{s--} is guaranteed to take place
377in an environment in which \texttt{s} is positive.
378
379\begin{verbatim}
380 $when (s>0) {s--; t++}
381\end{verbatim}
382The execution of \texttt{s--} must happen when \texttt{s>0}, but
383between \texttt{s--} and \texttt{t++}, other processes may execute.
384
385\begin{verbatim}
386 $when (s>0) $when (t>0) x=y*t;
387\end{verbatim}
388This blocks until both \texttt{x} and \texttt{t} are positive then
389executes the assignment in that state. It is equivalent to
390\begin{verbatim}
391 $when (s>0 && t>0) x=y*t;
392\end{verbatim}
393
394\subsection{Procedure contracts}
395The \crequires{} and \censures{} primitives are used to encode
396procedure contracts. There are optional
397elements that may occur in a procedure declaration or definition,
398as follows. For a function prototype:
399\begin{verbatim}
400 T f(...)
401 $requires expr;
402 $ensures expr;
403 ;
404\end{verbatim}
405For a function definition:
406\begin{verbatim}
407 T f(...)
408 $requires expr;
409 $ensures expr;
410 {
411 ...
412 }
413\end{verbatim}
414The value \cresult{} may be used in post-conditions to refer
415to the result returned by a procedure.
416
417\emph{Status}: parsed, but nothing is currently done with this
418information.
419
420\subsection{Remote expressions}. These have the form \verb!expr@x!
421and refer to a variable in another process, e.g., \verb!procs[i]@x!.
422This special kind of expression is used in collective expressions,
423which are used to formulate collective assertions and invariants.
424
425The expression \verb!expr! must have \cproc{} type. The variable
426\texttt{x} must be a statically visible variable in the context in
427which it is occurs. When this expression is evaluated, the evaluation
428context will be shifted to the process referred to by \texttt{expr}.
429
430\emph{Status}: not implemented.
431
432\subsection{Collective expressions}. These have the form
433\begin{verbatim}
434 $collective(proc_expr, int_expr) expr
435\end{verbatim}
436This is a collective expression over a set of processes. The
437expression \texttt{proc{\U}expr} yields a pointer to the first element
438of an array of \cproc. The expression \texttt{int{\U}expr} gives the
439length of that array, i.e., the number of processes. Expression
440\texttt{expr} is a boolean-valued expression; it may use remote
441expressions to refer to variables in the processes specified in the
442array. Example:
443\begin{verbatim}
444 $proc procs[N];
445 ...
446 $assert $collective(procs, N) i==procs[(pid+1)%N]@i ;
447\end{verbatim}
448
449\emph{Status}: not implemented.
450
451\chapter{Pointers and heaps}
452
453CIVL-C supports pointers, using the same operators with the same
454meanings as C (\texttt{\&}, \texttt{*}, pointer arithmetic).
455As mentioned above, there is also a heap type \cheap{}, which can
456be used to declare multiple heaps in a CIVL-C program. The
457interaction between pointers, heaps, and scopes is an important
458aspect of CIVL-C.
459
460\section{Pointer types}
461
462Given any object type $T$ and a static scope $s$ in a CIVL-C program,
463there is a type \emph{pointer-to-$T$-in-$s$}. The type is used to
464represent a pointer to a memory location of type $T$ in scope $s$ or a
465descendant of $s$ (i.e., some scope contained in $s$).
466
467If scope $s_1$ is a descendant of $s_2$ (i.e., $s_1$ is lexically
468contained in $s_2$), the type \emph{pointer-to-$T$-in-$s_1$} is a
469subtype of \emph{pointer-to-$T$-in-$s_2$}. This means that any
470expression of the first type can be used wherever an object of the
471second type is expected. In particular, any expression $e$ of the
472subtype can be assigned to a left-hand-side expression of the
473supertype without explicit casts; also $e$ can be used as an argument
474to a function for which the corresponding parameter has the supertype.
475
476The syntax for denoting this type adheres to the usual C syntax for
477denoting the type \emph{pointer-to-$T$} with the addition of a scope
478parameter within angular brackets immediately following the \texttt{*}
479token. For example, to declare a variable \texttt{p} of type
480\emph{pointer-to-$T$-in-$s$}, one writes
481\begin{verbatim}
482 int *<s> p;
483\end{verbatim}
484If the scope modifier \texttt{<...>} is absent, the scope is taken to
485be the root scope $s_0$. The object has type
486\emph{pointer-to-$T$-in-$s_0$}, which is abreviated as
487\emph{pointer-to-$T$}. In this way, stanard C programs can be
488interpreted as CIVL-C programs.
489
490\section{Address-of operator}
491
492The address-of operator \texttt{\&} returns a pointer of the
493appropriate subtype using the innermost scope in which its left-hand-side
494argument is declared. For example
495
496\begin{verbatim}
497 {
498 $scope s1;
499 int x;
500 double a[N];
501 int *<s1> p = &x;
502 double *<s1> q = &a[2];
503 }
504\end{verbatim}
505is correct (in particular, it is type-correct) because \texttt{\&x}
506has type \emph{pointer-to-\texttt{int}-in-\texttt{s1}}, since
507\texttt{s1} is the scope in which \texttt{x} is declared.
508
509\section{Pointer addition and subtractions}
510
511If \texttt{e} is an expression of type \emph{pointer-to-$T$-in-$s$}
512and \texttt{i} is an expression of integer type then \texttt{e+i} also
513has type \emph{pointer-to-$T$-in-$s$}. In other words, pointer
514addition cannot leave the scope of the original pointer. This
515reflects the fact that every object is contained in one scope, and
516pointer addition cannot leave the object.
517
518
519Pointer subtraction is defined on two pointers of the same type, where
520``same'' includes the scope. That is checked statically. As in C, it
521is only defined if the two pointers point to the same object. In
522CIVL-C, a runtime error will be thrown if they do not point to the
523same object.
524
525\section{Semantics of scopes and pointer types}
526
527A variable of type \cscope{} is treated like any other variable.
528It becomes part of the state when the scope in which it is declared
529is instantiated to form a dynamic scope. The variable is
530initialized at that time and its value cannot change.
531
532Each time a dynamic scope is instantiated, it is assigned a unique ID
533number. The exactly value of the ID number is not relevant, it just
534has to be distince from any other scope ID number that currently
535exists in the state. This is the value that is assigned to the scope
536variable. Therefore, if a static scope contains a scope variable, and
537that scope is instantiated twice to form two distinct dynamic scopes,
538the values assigned to the two variables will be distinct.
539
540A pointer value is an ordered pair $\langle \delta,r \rangle$, where
541$\delta$ is a dynamic scope ID and $r$ is a reference to a memory
542location in the static scope associated to $\delta$. (We will define
543the exact form of a reference later.)
544
545When a dynamic scope is instantiated, each new variable created is
546assigned a \emph{dynamic type}. This is a refinement of the static
547type associated to the static variable. Every dynamic type
548is an instance of exactly one static type. The dynamic
549type of the newly instantiated variable is an instance of the
550static type of the static variable.
551
552The dynamic pointer types have the form
553\emph{pointer-to-$t$-in-$\delta$}, where $t$ is a dynamic type and
554$\delta$ is a dynamic scope ID. For a program to be dynamically type
555safe, such a variable should hold only values of the form $\langle
556\delta, r\rangle$. In particular, the variable should never be
557assigned a value where the dynamic scope component is a different
558instance of the static scope $s$ associated to $\delta$.
559
560\section{Pointer casts}
561
562If scope $s_1$ is contained in scope $s_2$, an expression of type
563\emph{pointer-to-$T$-in-$s_1$} can always be cast to
564\emph{pointer-to-$T$-in-$s_2$},
565 because the first is a subtype of the second. (As described above,
566the cast is unnecessary.)
567
568The cast in the other direction is also allowed, but the dynamic type
569safety of that cast will only be checked at runtime. In particular, a
570runtime error will result if the cast attempts to cast the pointer
571value to a dynamic scope which does not contain (is an ancestor of)
572the dynamic scope component of the pointer value.
573
574A type \emph{pointer-to-$T_1$-in-$s$} can be cast to a type
575\emph{pointer-to-$T_2$-in-$s$} according to the usual rules of C. In
576other words, usual casting rules apply as long as you don't change the
577scope.
578
579
580
581\section{Heaps}
582
583The standard CIVL-C library defines a type \cheap{} for explicit
584modeling of a heap. The default value of \cheap{} type is an empty
585heap, so you only need to declare a variable to have type \cheap{}
586in order to create a new heap:
587\begin{verbatim}
588 $heap h; /* a new empty heap */
589\end{verbatim}
590
591The following functions are also defined:
592\begin{verbatim}
593void* $malloc($heap *h, int size);
594void memcpy(void *p, void *q, size_t size);
595void free(void *p)
596\end{verbatim}
597The first function is like C's \texttt{malloc}, except that you
598specify the heap in which the allocation takes place by passing a
599pointer to the heap as the first argument. This modifies the
600specified heap and returns a pointer to the new object. The function
601can only occur in a context in which the type of the object is
602specified, as in:
603\begin{verbatim}
604 $heap h;
605 int n = 10;
606 double *p = (double*)$malloc(&h, n*sizeof(double));
607\end{verbatim}
608The second and third functions are exactly the same as in C. Note that
609\texttt{free} modifies the heap which was used to allocate \texttt{p}.
610
611Another pointer example:
612\begin{small}
613\begin{verbatim}
614{ $heap h;
615 { $scope s1;
616 double x;
617 { $scope s2;
618 double y;
619 double *<s1> p;
620 /* p can only point to something in s1 or descendant,
621 * for example, s2 */
622 p = &x; // fine
623 p = &y; // fine
624 p = (double*)$malloc(&h,10*sizeof(double)); // static type error
625 }
626 }
627}
628\end{verbatim}
629\end{small}
630
631\emph{Status}: Pointer type, \texttt{\&}, \texttt{*}, pointer addition
632all implemented. Type \cheap{}, \texttt{malloc}, \texttt{free}
633implemented. Scope-qualified pointers: parsed, type-checked, but
634information not currently used.
635
636\section{Scope-Parameterized Functions}
637
638Coming soon. (Parsed, type checked, not currently used otherwise.)
639
640\section{Scope-Parameterized Type Definitions}
641
642Coming soon. (Ditto.)
643
644% \chapter{Some Translation Examples}
645
646% \section{Structured parallelism}
647% Structured \verb!parbegin!/\verb!parend! statements look like this:
648% \begin{verbatim}
649% $parbegin
650% S1; S2; S2
651% $parend
652% \end{verbatim}
653% (See Dijkstra, Cooperating Sequential Processes.) The meaning is: run
654% the three statements in parallel, and block at the end until all have
655% completed.
656
657% This can be represented in CIVL-C as follows:
658
659% \begin{verbatim}
660% {
661% void f_1() {S1}
662% void f_2() {S2}
663% void f_3() {S3}
664% $proc tmp1 = $fork f_1(), tmp2=$fork f_2(), tmp3=$fork f_3();
665% $join(tmp1); $join(tmp2); $join(tmp3);
666% }
667% \end{verbatim}
668
669% \subsection{Parallel for loops}
670% The standard parallel ``for'' loop looks like
671% \begin{verbatim}
672% $parfor(T i = e; cond; inc) S
673% \end{verbatim}
674% It indicates each iteration should be run concurrently, blocking
675% at end until all complete. In CIVL-C:
676
677% \begin{verbatim}
678% {
679% void f(T i) {S}
680% T i = e;
681% int c = 0;
682% Vector<$proc> list;
683
684% while (cond) {
685% list.add($fork f());
686% c++;
687% inc;
688% }
689% for (int j=0; j<c; j++) $join(list.get(j));
690% }
691% \end{verbatim}
692
693% (This is assuming we have some sort of Vector datatype. Need to think
694% about that.)
695
696% \subsection{Message Passing}
697
698% There will be a bunch of standard libraries that can be included
699% into CIVL-C. One of these will be the message-passing library.
700% It will define a bunch of primitives that we will fill in shortly.
701% Among them will be basic send and receive functions.
702
703% The message-passing library can be defined entirely in CIVL-C.
704% (See Figure \ref{fig:mp1}.)
705
706% \begin{figure}
707% \begin{verbatim}
708% typedef struct _CIVL_Message {
709% struct _CIVL_Message *next; // next message in this queue
710% struct _CIVL_Message *prev; // previous message in this queue
711% int tag; // message tag
712% int size; // size of buffer
713% void *data; // pointer to first element
714% } *CIVL_Message;
715
716% typedef struct _CIVL_Comm {
717% $heap heap;
718% int numProcs; // number of procs in this communicator
719% $proc *procs; // array of length numProcs
720% CIVL_Message buf_front[][]; // oldest element of each queue
721% CIVL_Message buf_back[][]; // newest element of each queue
722% } *CIVL_Comm;
723% \end{verbatim}
724% \caption{CIVL Message Passing library: basic definitions}
725% \label{fig:mp1}
726% \end{figure}
727
728% Message passing functions may be defined with prototypes such as:
729% \begin{verbatim}
730% CIVL_Comm CIVL_Comm_create($proc procs[], int numProcs);
731% void CIVL_send(int src, void *buf, int size, int dest,
732% int tag, CIVL_Comm comm);
733% void CIVL_recv(int dest, void *buf, int size, int src,
734% int tag, CIVL_Comm comm);
735% \end{verbatim}
736
737% The arguments for \texttt{send} are:
738% \begin{enumerate}
739% \item rank of process issuing the send
740% \item address of buffer containing data to be sent
741% \item size of message
742% \item an integer tag
743% \item rank of destination process
744% \item communicator
745% \end{enumerate}
746
747% The arguments for \texttt{recv} are:
748% \begin{enumerate}
749% \item rank of process issuing the receive
750% \item address of receive buffer
751% \item size of receive buffer (must be large enough to hold any incoming message)
752% \item rank of source process or \code{CIVL{\U}ANY{\U}SOURCE}
753% \item tag or \code{CIVL{\U}ANY{\U}TAG}
754% \item communicator
755% \end{enumerate}
756
757% Notice one difference from MPI: we have to specify the process to
758% which the send or receive is associated in the first argument. This is
759% because we need to be more general than MPI. In MPI, that process is
760% always the MPI process invoking the send or receive. In CIVL, you
761% might want to have threads within processes (for example) and
762% associate the message to the MPI process, even though the thread is
763% actually invoking the send. Or you might want to associate it to
764% something else in some other language/library/API.
765
766% How they are implemented: \texttt{CIVL{\U}Comm{\U}create}
767% mallocs a new object of type \texttt{struct {\U}CIVL{\U}Comm} and returns
768% a pointer to it.
769
770
771\part{Semantics}
772
773\chapter{CIVL Model Syntax}
774
775\section{Notation and terminology}
776\label{sec:notation}
777
778Let $\B=\{\true,\false\}$ (the set of boolean values). Let
779$\N=\{0,1,2,\ldots\}$ (the set of natural numbers).
780
781Given a node $u$ in a tree, we let $\ancestors(u)$ denote the set of
782all ancestors of $u$, including $u$. We let $\descendants(u)$ denote
783the set of all descendants of $u$, including $u$.
784
785For any set $S$, let $S^*$ denote the set of all finite sequences of
786elements of $S$. The length of a sequence $\xi\in S^*$ is denoted
787$\len(\xi)$.
788
789% This is a lie:
790% The elements of the sequence are indexed from $0$ to
791% $\len(\xi)-1$.
792
793\section{Definition of Context}
794\label{sec:context}
795
796\begin{definition}
797 A \emph{CIVL type system} is a tuple comprising the following
798 components:
799 \begin{enumerate}
800 \item a set $\Type$ (the set of \emph{types}),
801 \item a type $\bool\in\Type$ (the \emph{boolean type}),
802 \item a type $\proc\in\Type$ (the \emph{process-reference type}),
803 \item a set $\Var$ (the set of all \emph{typed variables}),
804 \item a function $\vtype\colon \Var\ra\Type$ (which gives the
805 type of each variable),
806 \item a set $\Val$ (the set of all \emph{values}),
807 \item a function which assigns to each $t\in\Type$ a subset
808 $\Val_t\subseteq\Val$ (the set of values of type $t$)
809 and which satisfies $\Val_{\bool}=\B$ and $\Val_{\proc}=\N$,
810 \item a function which assigns to each $t\in\Type$ a value
811 $\default_t\in\Val_t$.
812 \end{enumerate}
813\end{definition}
814
815The default value will be used to give an initial value to any
816variable. It could represent something like ``an undefined value of
817type $t$'' or a reasonable initial value ($0$ for integers, etc.),
818depending on the language one is modeling.
819
820\begin{definition}
821 Given a CIVL type system, a \emph{valuation} in that system is a
822 function $\eta\colon\Var\ra\Val$ with the property that for any
823 $v\in\Var$, $\eta(v)\in\Val_{\vtype(v)}$.
824\end{definition}
825
826Given a CIVL type system, we let $\Eval$ denote the set of all
827valuations in that system.
828
829\begin{definition}
830 Given a CIVL type system, A \emph{CIVL expression system} for that
831 type system is a tuple comprising the following components:
832 \begin{enumerate}
833 \item a set $\Expr$ (the set of all \emph{typed expressions} over
834 $\Var$),
835 \item a function $\etype\colon\Expr\ra\Type$ (giving the type
836 of each expression),
837 \item a function
838 $\eval\colon\Expr\times\Eval\ra\Val$ (the \emph{evaluation
839 function}), satisyfing
840 \begin{itemize}
841 \item for any $e\in\Expr$ and $\eta\in\Eval$,
842 $\eval(e,\eta)\in\Val_{\etype(e)}$,
843 \end{itemize}
844 \item a function which associates to any $V\subseteq\Var$, a
845 subset $\Expr(V)\subseteq\Expr$ (the set of
846 \emph{expressions which involve only variables in $V$}) satisfying
847 the following:
848 \begin{itemize}
849 \item for any $V\subseteq\Var$ and $\eta,\eta'\in\Eval$, if
850 $\eta(v)=\eta'(v)$ for all $v\in V$, then for any $e\in\Expr(V)$,
851 $\eval(e,\eta)=\eval(e,\eta')$
852 \end{itemize}
853 \end{enumerate}
854\end{definition}
855
856\begin{definition}
857 A \emph{CIVL context} is a CIVL type system together with
858 a CIVL expression system for that type system.
859\end{definition}
860
861\begin{figure}
862 \notationtable
863 \caption{Table of Notation Used to Define CIVL Model Syntax}
864 \label{fig:notation}
865\end{figure}
866
867\section{Lexical scopes}
868\label{sec:scopes}
869
870\begin{definition}
871 Given a CIVL context $\mathcal{C}$, a \emph{lexical scope system}
872 over $\mathcal{C}$ is a tuple $(\Sigma,\rootscope,\sparent,\vars)$
873 consisting of
874 \begin{enumerate}
875 \item a set $\Sigma$ (the set of \emph{static scopes}),
876 \item a scope $\rootscope\in\Sigma$ (the \emph{root scope}),
877 \item a function
878 $\sparent\colon\Sigma\setminus\{\rootscope\}\rightarrow
879 \Sigma$ such that
880 \[\{(\sparent(\sigma),\sigma)\mid \sigma\in\Sigma\setminus\{\rootscope\}\}\]
881 gives $\Sigma$ the structure of a rooted tree with root $\rootscope$,
882 \item a function $\vars\colon\Sigma\rightarrow 2^{\Var}$
883 (specifying the variables \emph{declared} in each scope) satisfying
884 \begin{itemize}
885 \item $\sigma\neq\tau\implies \vars(\sigma)\cap \vars(\tau)=\emptyset$.
886 \end{itemize}
887 \end{enumerate}
888\end{definition}
889
890\begin{definition}
891 Given a CIVL context and scope $\sigma\in\Sigma$,
892 the set of \emph{visible variables} in $\sigma$
893 is $\bigcup_{\sigma'\in\ancestors(\sigma)}\vars(\sigma')$.
894\end{definition}
895
896One way this notion will be used: expressions used in a scope $\sigma$
897can only involve variables visible in $\sigma$.
898
899\section{Functions}
900\label{sec:functions}
901
902Fix a CIVL context $\mathcal{C}$ and lexical scope system
903\[\Lambda=(\Sigma,\rootscope,\sparent,\vars)\] over $\mathcal{C}$.
904
905We introduce a new type symbol $\void$, as in C, to use as the return
906type for a function that does not return a value. Let
907$\Type'=\Type\cup\{\void\}$.
908
909\begin{definition}
910 A \emph{function prototype} for $\Lambda$ is a tuple
911 $(\sigma, t, \xi)$ consisting of
912 \begin{enumerate}
913 \item a scope $\sigma\in\Sigma\setminus\{\rootscope\}$
914 (the \emph{function scope}),
915 \item a type $t\in\Type'$ (the \emph{return type}),
916 \item a finite sequence $\xi=v_1v_2\cdots v_n\in\vars(\sigma)^*$
917 consisting of variables declared in the function scope
918 (the \emph{formal parameters}).
919 \end{enumerate}
920\end{definition}
921
922\begin{definition}
923 A \emph{CIVL function prototype system} consists of
924 \begin{enumerate}
925 \item a set $\Func$ (the \emph{function symbols}),
926 \item a function which assigns to each $f\in\Func$ a
927 function prototype, denoted
928 \[
929 (\fscope(f), \returntype(f), \params(f)),
930 \]
931 and satisfying
932 \begin{itemize}
933 \item for any $\sigma\in\Sigma$, there is at most
934 one $f\in\Func$ such that $\sigma=\fscope(f)$, and
935 \end{itemize}
936 \item a \emph{root function} $f_0$ with $\fscope(f_0)=\rootscope$
937 and which is the only function with root scope.
938 \end{enumerate}
939\end{definition}
940
941
942\begin{definition}
943 Given a CIVL function prototype system, and function symbol
944 $f\in\Func\setminus\{f_0\}$, the \emph{declaration scope} of $f$ is
945 the scope $\sigma=\sparent(\fscope(f))$. We also write \emph{$f$ is
946 declared in $\sigma$.}
947\end{definition}
948
949Note the root function $f_0$ has no declaration scope.
950
951Just as every scope has a set of visible variables, there is also
952a set of visible functions:
953\begin{definition}
954 The functions \emph{visible at scope $\sigma$} are
955 those declared in $\sigma$ or an ancestor of $\sigma$.
956\end{definition}
957We will see that the variables and functions visible at $\sigma$ are
958the only variables and functions that can be referred to by statements
959and expressions used within $\sigma$.
960
961Note that only certain scopes are function scopes. There can be
962additional scopes (intuitively corresponding to block scopes in a
963source program). Every scope, however, must ``belong to'' exactly one
964function. The precise definition is as follows:
965\begin{definition}
966 \label{def:func}
967 Given a CIVL function prototype system, define
968 \[
969 \func \colon \Sigma \ra \Func
970 \]
971 by
972 \[
973 \func(\sigma)=
974 \begin{cases}
975 f & \text{if $\sigma=\fscope(f)$ for some $f\in\Func$}\\
976 \func(\sparent(\sigma)) & \text{otherwise.}
977 \end{cases}
978 \]
979 We say \emph{$\sigma$ belongs to $f$} when $\func(\sigma)=f$.
980\end{definition}
981Note that the recursion in Definition \ref{def:func} must stop as the
982root scope belongs to the root function and the scopes form a tree.
983
984
985\section{Statements}
986
987Fix a CIVL function prototype system. A \emph{CIVL statement} is
988defined to be a tuple of one of the forms described below.
989In each case, we give any restritions on the components of the tuple
990and a brief intuition on the statement's semantics. The precise
991semantics will be described in \S\ref{sec:semantics}.
992
993\begin{enumerate}
994\item $\langle\code{parassign},V_1,V_2,\psi\rangle$
995 \begin{itemize}
996 \item $V_1,V_2\subseteq\Var$
997 \item $\psi\colon V_2\ra\Expr(V_1)$ satisfying
998 $\etype(\psi(v))=\vtype(v)$ for all $v\in V_2$
999 \item \emph{meaning}: parallel assignment, i.e., the assignment of new
1000 values to any or all of the variables in $V_2$. For each variable
1001 in $V_2$ an expression is given which will be evaluated in the old
1002 state to compute the new value for that variable. $V_1$ contains
1003 all the variables that may be used in those expressions. Hence
1004 $V_1$ is the ``read set'' and $V_2$ is the ``write set'' for the
1005 parallel assignment.
1006 \end{itemize}
1007\item $\langle\code{assign},v,e\rangle$
1008 \begin{itemize}
1009 \item $v\in\Var$, $e\in\Expr$, $\etype(e)=\vtype(v)$
1010 \item \emph{meaning}: simple assignment: evaluate an expression $e$ and
1011 assign result to variable $v$. It is a special case of
1012 \code{parassign} but is provided for convenience.
1013 \end{itemize}
1014\item $\langle\code{call},y,f,e_1,\ldots,e_n\rangle$
1015 \begin{itemize}
1016 \item $y\in\Var$, $f\in\Func$, $e_1,\ldots,e_n\in\Expr$
1017 \item $n=\numparams(f)$
1018 \item $\etype(e_i)=\vtype(v_i)$, where $\params(f)=v_1\cdots v_n$
1019 \item $\returntype(f)=\vtype(y)$
1020 \item \emph{meaning}: evaluate expressions $e_1,\ldots,e_n$; push
1021 frame on call stack and move control to guarded transition system
1022 (see \S\ref{sec:gts}) for function $f$; when $f$ returns, pop
1023 stack and store returned result in $y$
1024 \end{itemize}
1025\item $\langle\code{call},f,e_1,\ldots,e_n\rangle$
1026 \begin{itemize}
1027 \item $f\in\Func$, $e_1,\ldots,e_n\in\Expr$
1028 \item $n=\numparams(f)$
1029 \item $\etype(e_i)=\vtype(v_i)$, where $\params(f)=v_1\cdots v_n$
1030 \item \emph{meaning}: like above, but return type may be \code{void}
1031 or returned value could just be ignored
1032 \end{itemize}
1033\item $\langle\code{fork},p,f,e_1,\ldots,e_n\rangle$
1034 \begin{itemize}
1035 \item $p\in\Var$, $f\in\Func$, $e_1,\ldots,e_n\in\Expr$
1036 \item $n=\numparams(f)$
1037 \item $\etype(e_i)=\vtype(v_i)$, where $\params(f)=v_1\cdots v_n$
1038 \item $\returntype(f)=\void$
1039 \item $\vtype(p)=\proc$
1040 \item \emph{meaning}: evaluate expressions $e_1,\ldots,e_n$;
1041 create new process and invoke function $f$ in it;
1042 return, immediately, a reference to the new process and store
1043 that reference in $p$
1044 \end{itemize}
1045\item $\langle\code{join},e\rangle$
1046 \begin{itemize}
1047 \item $e\in\Expr$
1048 \item $\etype(e)=\proc$
1049 \item \emph{meaning}: evaluate $e$ and wait for the referenced process to terminate
1050 \end{itemize}
1051\item $\langle\code{return},e\rangle$
1052 \begin{itemize}
1053 \item $e\in\Expr$
1054 \item \emph{meaning}: evaluate $e$, pop the call stack and return
1055 control, along with the value, to caller
1056 \end{itemize}
1057\item $\langle\code{return}\rangle$
1058 \begin{itemize}
1059 \item \emph{meaning}: pop the call stack and return control to caller;
1060 only to be used in functions returning \code{void}
1061 \end{itemize}
1062\item $\langle\code{write},e\rangle$
1063 \begin{itemize}
1064 \item $e\in\Expr$
1065 \item \emph{meaning}: evaluate $e$ and send result to output
1066 \end{itemize}
1067\item $\langle\code{noop}\rangle$
1068 \begin{itemize}
1069 \item \emph{meaning}: does nothing
1070 \end{itemize}
1071\item $\langle\code{assert}, e\rangle$
1072 \begin{itemize}
1073 \item $e\in\Expr$, $\vtype(e)=\bool$
1074 \item \emph{meaning}: evaluate $e$; if result is false, stop
1075 execution and report error
1076 \end{itemize}
1077\item $\langle\code{assume}, e\rangle$
1078 \begin{itemize}
1079 \item $e\in\Expr$, $\vtype(e)=\bool$
1080 \item \emph{meaning}: assume $e$ holds (i.e., if $e$ does not hold,
1081 the execution sequence is not a real execution)
1082 \end{itemize}
1083\end{enumerate}
1084
1085\section{Remarks}
1086
1087The system described is sufficiently general to model pointers. There
1088can be (one or more) pointer types and corresponding values. The
1089parallel assignment statement can be used to model statements like
1090C's \texttt{*p=e;}. In the worst case (if no information is known
1091about where \texttt{p} could point), one can let $V_2=\Var$.
1092Similarly, expressions that involve \texttt{*p} as a right-hand
1093side subexpression can always take $V_1=\Var$.
1094
1095Heaps can also be modeled. A heap type may be defined and a variable
1096of that type declared. Expressions to modify and read from the heap
1097can be defined, as can pointers into the heap.
1098
1099
1100\section{Transition system representation of functions}
1101\label{sec:gts}
1102
1103\begin{definition}
1104 Given a CIVL function prototype system and $f\in\Func$,
1105 a \emph{guarded transition system} for $f$
1106 is a tuple $(\Loc,\lscope,\start, T)$, where
1107 \begin{itemize}
1108 \item $\Loc$ is a set (the set of \emph{locations}),
1109 \item $\lscope\colon\Loc\ra\Sigma$ is a function which associates
1110 to each $l\in\Loc$ a scope $\lscope(l)\in\Sigma$ belonging to $f$,
1111 \item $\start\in\Loc$ (the \emph{start location}),
1112 \item $T$ is a set of \emph{guarded transitions}, each of which has
1113 the form $\langle l,g,s,l'\rangle$, where
1114 \begin{itemize}
1115 \item $l,l'\in\Loc$ (the \emph{source} and \emph{target}
1116 locations)
1117 \item $g\in\Expr(V)$, where $V$ is the set of variables visible at
1118 $\lscope(l)$, and $\etype(g)=\bool$ ($g$ is called the
1119 \emph{guard}),
1120 \item $s$ is a statment all of whose constituent variables,
1121 expressions, and function symbols are visible at $\lscope(l)$.
1122 \end{itemize}
1123 \end{itemize}
1124 Furthermore, if the guarded transition system contains a statement
1125 of the form $\langle\code{return}\rangle$ then
1126 $\returntype(f)=\void$. If it contains a statement of the form
1127 $\langle\code{return},e\rangle$ then $\etype(e)=\returntype(f)$.
1128\end{definition}
1129
1130\begin{definition}
1131 Given a CIVL prototype system, a \emph{CIVL model} $M$ for that
1132 system assigns, to each $f\in\Func$, a guarded transition system
1133 \[(\Loc_f,\lscope_f, \start_f,T_f)\] for $f$. Moreover, if $f\neq f'$
1134 then
1135 $\Loc_f\cap\Loc_{f'}=\emptyset$.
1136\end{definition}
1137
1138\begin{definition}
1139 Given a CIVL model $M$, let $\Loc=\bigcup_{f\in\Func}\Loc_f$.
1140\end{definition}
1141
1142\chapter{CIVL Model Semantics}
1143\label{sec:semantics}
1144
1145\section{State}
1146\label{sec:state}
1147
1148Fix a CIVL model $M$. Recall that a valuation is a type-respecting
1149function from $\Var$ to $\Val$. Given a subset $V\subseteq\Var$ of
1150variables, we define a \emph{valuation on $V$} to be a type-respecting
1151function from $V$ to $\Val$. Let $\Eval(V)$ denote the set of all
1152valuations on $V$. Note that $\Eval(\Var)=\Eval$.
1153
1154\begin{definition}
1155 \label{def:state}
1156 A \emph{state} of a CIVL model $M$ is a tuple
1157 \[
1158 s=(\Delta, \droot, \dparent, \static, \deval, P, \stack),
1159 \]
1160 where
1161 \begin{enumerate}
1162 \item $\Delta$ is a finite set (the set of \emph{dynamic scopes} in
1163 $s$),
1164 \item $\droot\in\Delta$ (the \emph{root dynamic scope}),
1165 \item $\dparent\colon \Delta\setminus\{\droot\}\ra\Delta$
1166 is a function such that the set
1167 \[
1168 \{(\dparent(\delta),\delta)\mid \delta\in
1169 \Delta\setminus\{\droot\}\}
1170 \]
1171 gives $\Delta$ the structure of a rooted tree with root $\droot$,
1172 \item $\static\colon\Delta\ra\Sigma$,
1173 \item $\static(\droot)=\rootscope$ and $\droot$ is the only
1174 $\delta\in\Delta$ satisfying $\static(\delta)=\rootscope$,
1175 \item $\static(\dparent(\delta))=\sparent(\static(\delta))$ for any
1176 $\delta\in\Delta$,
1177 \item $\deval$ is a function that assigns to each $\delta\in\Delta$
1178 a valuation $\deval(\delta)\in\Eval(\vars(\static(\delta)))$,
1179 \item $P$ (the set of \emph{process IDs} in $s$)
1180 is a finite subset of $\Val_{\proc}$, and
1181 \item $\stack\colon P\ra \Frame^*$, where
1182 \[
1183 \Frame=\{(\delta,l)\in\Delta\times\Loc\mid\lscope(l)=\static(\delta)\}.
1184 \]
1185 \end{enumerate}
1186 Let $\State$ denote the set of all states of $M$.
1187\end{definition}
1188
1189% say entrance and exit from scopes does not have to be "structured".
1190
1191Remarks:
1192\begin{enumerate}
1193\item We will also refer to dynamic scopes as \emph{dyscopes}.
1194\item The elements of $\Delta$ contain no intrinsic information.
1195 Instead, all of the information concerning dyscopes is encoded
1196 in the functions that take elements of $\Delta$ as arguments. Hence
1197 we might just as well call the elements of $\Delta$ ``dynamic scope
1198 IDs'' (just as we call the elements of $P$ ``process IDs''). One
1199 could use natural numbers for the dyscopes, just as one does
1200 for processes.
1201\item The reason for using some form of ID for dyscopes and
1202 processes, rather than just incorporating the data in the
1203 appropriate part of the state, is that both kinds of objects may be
1204 shared. There can be several components of the state that refer to
1205 the same dyscope $d$: e.g., $d$ could have several children,
1206 each of which has a parent reference to $d$, as well as a reference
1207 from a frame. A process can be referred to by any number of
1208 variables of type $\proc$.
1209\item If $\sigma=\static(\delta)$, we say that \emph{$\delta$ is an
1210 instance of $\sigma$} or \emph{$\sigma$ is the static scope
1211 associated to $\delta$}. In general, a static scope can have any
1212 number (including 0) of dynamic instances. The exception is the root
1213 scope $\rootscope$, which must have exactly one instance ($\droot$).
1214\item A valuation $\deval(\delta)$ assigns a value to each variable in
1215 the static scope associated to $\delta$. The function $\deval$
1216 thereby encodes the value of all variables ``in scope'' in state
1217 $s$.
1218\item The sequence $\stack(p)$ encodes the state of the call stack of
1219 process $p$. The elements of the sequence are called
1220 \emph{activation frames}. The first frame in the sequence, i.e.,
1221 the frame in position $0$, is the bottom of the stack; the last
1222 frame is the top of the stack.
1223\item Each frame refers to a dyscope $\delta$ and a
1224 location in the static scope associated to $\delta$.
1225\end{enumerate}
1226
1227
1228\begin{definition}
1229 A dyscope $\delta\in\Delta$ is a \emph{function node}
1230 if $\static(\delta)$ is the function scope of some function.
1231\end{definition}
1232
1233\begin{definition}
1234 Given any $\delta\in\Delta$, $\fnode(\delta)\in\Delta$ is defined as
1235 follows: if $\delta$ is a function node, then
1236 $\fnode(\delta)=\delta$, else
1237 $\fnode(\delta)=\fnode(\dparent(\delta))$. We call $\fnode(\delta)$
1238 the \emph{function node associated to $\delta$}.
1239\end{definition}
1240
1241The relation $\{(\delta,\delta')\mid \fnode(\delta)=\fnode(\delta')\}$
1242is an equivalence relation $\sim$ on $\Delta$. Let
1243$\bar{\Delta}=\Delta/\sim$ and write $[\delta]$ for the equivalence
1244class containing $\delta$.
1245
1246The set of activation frames in a state $s$ may be identified with the
1247set
1248\[
1249AF(s)=\bigcup_{p\in P}\{p\}\times\{0,\ldots,\len(\stack(p))-1\}
1250\]
1251Namely, $(p,i)$ corresponds to the $i^{\text{th}}$ entry in the call
1252stack $\stack(p)$ (where the elements of the stacks are indexed from
1253$0$).
1254
1255Define $\Psi\colon AF(s)\ra \bar{\Delta}$ as follows: given $(p,i)$,
1256let $(\delta,l)$ be the corresponding frame; set $\Psi(p,i)=[\delta]$.
1257
1258% \begin{definition}
1259% A state $s$ is \emph{well-formed} if all of the following hold:
1260% \begin{enumerate}
1261% \item for any $\delta\in\Delta$, at most one child of $\delta$ is not
1262% a function node,
1263% \item the function $\Psi$ is a one-to-one correspondence,
1264% \item any $\delta$ occurring in the top frame of a call stack
1265% is a leaf node.
1266% \end{enumerate}
1267% \end{definition}
1268
1269
1270\section{Jump protocol}
1271\label{sec:jump}
1272
1273% can only jump if \delta is a leaf node.
1274% also no other frame can point to a dyscope between \delta
1275% and the dyscope corresponding to the function scope
1276
1277% in any state, a "region" of the dyscope tree can have at
1278% most one (exactly one?) stack frame pointing into it.
1279
1280% a region in a chain of nodes starting from a dyanmic scope corresonding
1281% to a function scopes and leading down until you reach another
1282% function scope.
1283
1284% whenever you have more than one child in the dynamic tree, all but
1285% 0 or 1 children must be a function scope
1286
1287% every dyscope is owned by at most one frame
1288
1289% can a frame point only to a leaf node? No, but all of its children
1290% must be function nodes
1291
1292% to find out which frame owns which dyscopes:
1293
1294% approach 1: start from a frame. frame owns the node it points to.
1295% move up parents until you hit a function scope and stop.
1296% that is that frame's region. No other frame can point into its
1297% region. Proof: true in initial state, invariant under
1298% call and fork.
1299
1300% invariant: every leaf node in the dyscope tree is pointed
1301% to by the top frame of the call stack of some process
1302
1303% Define a \emph{well-formed state}:
1304
1305% every dyscope node has at most one child which is not a function node
1306
1307% 1-1 correspondence between leaf nodes and top frames of stacks.
1308
1309% Define regions in the dyscope tree. (each region contains one
1310% function node)
1311
1312\newcommand{\lub}{\sigma_{\textsf{lub}}}
1313
1314\begin{figure}[t]
1315 \begin{algorithm}[H]
1316 \Procedure{$\textsf{\textup{jump}}(s\colon\State, p\colon\Val_{\proc},
1317 l'\colon\Loc)\colon\State$}{%
1318 let $(\Delta, \droot, \dparent, \static, \deval, P, \stack)=s$\;
1319 let $\delta$ be the dyscope of the last frame on $\stack(p)$\;
1320 let $\sigma=\static(\delta)$\;
1321 let $\sigma'=\lscope(l')$\;
1322 let $\lub$ be the least upper bound of $\sigma$ and
1323 $\sigma'$ in the tree $\Sigma$\;
1324 let $m$ be the minimum integer such that
1325 $\sparent^m(\sigma)=\lub$\;
1326 let $\delta_{\textsf{lub}}=\dparent^m(\delta)$\;
1327 let $n$ be the minimum integer such that
1328 $\sparent^{n}(\sigma')=\lub$\;
1329 let $\delta_0,\ldots,\delta_{n-1}$ be $n$ distinct objects not in $\Delta$\;
1330 let
1331 \( \displaystyle
1332 \Delta'=\Delta
1333 \cup \{ \delta_0,\ldots,\delta_{n-1} \}
1334 %\setminus \{ \dparent^j(\delta)\mid 0\leq j<m\}
1335 \)\;
1336 define $\dparent'\colon\Delta'\setminus\{\droot\}\ra\Delta'$ by
1337 \(
1338 \dparent'(\delta')=
1339 \begin{cases}
1340 \dparent(\delta') & \text{if $\delta'\in\Delta$}\\
1341 \delta_{i+1} & \text{if $\delta'=\delta_{i}$ for some $0\leq i<n-1$}\\
1342 \delta_{\textsf{lub}} & \text{if $n\geq 1$ and $\delta'=\delta_{n-1}$}
1343 \end{cases}
1344 \)\;
1345 define $\static'\colon\Delta'\ra\Sigma$ by
1346 \(
1347 \static'(\delta')=
1348 \begin{cases}
1349 \static(\delta') & \text{if $\delta'\in\Delta$}\\
1350 \sparent^i(\sigma') & \text{if $\delta'=\delta_i$ for some $0\leq i<n$}
1351 \end{cases}
1352 \)\;
1353 for $\delta'\in\Delta'$ and $v\in\vars(\static(\delta'))$,
1354 let
1355 \(
1356 \deval'(\delta')(v) =
1357 \begin{cases}
1358 \deval(\delta')(v) & \text{if $\delta'\in\Delta$}\\
1359 \default_t & \text{otherwise}
1360 \end{cases}
1361 \)\;
1362 define $\stack'$ to be the same as $\stack$ except that
1363 the last frame on $\stack'(p)$ is replaced with
1364 $(\delta_0,l')$ if $n\geq 1$, or with $(\delta_{\textsf{lub}},l')$
1365 if $n=0$\;
1366 let $s'(\Delta',\droot,\dparent',\static',\deval',P,\stack')$\;
1367 return the result of removing all unreachable dyscopes from $s'$\;
1368 }
1369 \end{algorithm}
1370 \caption{Jump protocol: how the state changes when control moves
1371 to a new location within a function. The procedure may only
1372 be called if $\func(\sigma)=\func(\sigma')$, i.e., the jump
1373 is contained within one function.}
1374 \label{fig:jump}
1375\end{figure}
1376
1377When control moves from one location to another within a function's
1378transition system, dyscopes may be added, because you can jump out of
1379scope nests and into new scope nests. The motivating idea is that you
1380have to move up the dyscope tree every time you move past a right
1381curly brace (i.e., leave a scope) and then push on a new scope for
1382each left curly brace you move past. So there is a sequence of upward
1383moves followed by a sequence of pushes to get to the new
1384location. (And either or both sequences could be empty.) At the end,
1385if any dyscopes become unreachable, they are removed from the state.
1386
1387Note however, that we do not assume that scopes are associated to
1388locations in a nice lexical pattern (or any pattern at all). The
1389protocol described here works for any arbitrary assignment of scopes
1390to locations.
1391
1392The precise protocol is described in Figure \ref{fig:jump}. The
1393algorithm shown there takes as input a well-formed state, a process
1394ID, and a location $l'$ for the function that $p$ is currently in.
1395Say the current dyscope for $p$ is $\delta$, and $l'$ is in
1396static scope $\sigma'$. Let $\sigma=\static(\delta)$. Hence the
1397current static scope is $\sigma$ and the new static scope will be $\sigma'$.
1398
1399First, you have to find the \emph{least upper bound} $\lub$ of
1400$\sigma$ and $\sigma'$ in the static scope tree. (Hence $\lub$ is a
1401common anecestor of $\sigma$ and $\sigma'$, and if $\sigma''$ is any
1402common ancestor of $\sigma$ and $\sigma'$ then $\sigma''$ is an
1403ancestor or equal to $\lub$.) Note that the least upper bound must
1404exist since the function scope is a common ancestor of $\sigma$ and
1405$\sigma'$. There is a chain of static scopes from $\sigma$ up to
1406$\lub$ and a corresponding chain
1407$\delta,\dparent(\delta),\ldots,\dparent^m(\delta)$ in the dynamic
1408scope tree. Let $\delta_{\textsf{lub}}=\dparent^m(\delta)$. This
1409will become the least upper bound of $\delta$ and the new dynamic
1410scope corresponding to $\sigma'$ that will be added to the state.
1411
1412Next you add new dyscopes corresponding to the chain of static
1413scopes leading from $\lub$ down to $\sigma'$. The variables in the
1414new scopes are assigned the default values for their respective types.
1415The $\dparent$, $\static$, and $\deval$ maps are adjusted
1416accordingly. Finally, the stack is modified by replacing the last
1417activation frame with a frame referring to the (possibly) new dynamic
1418scope and new location $l'$.
1419
1420This protocol is executed every time control moves from one location
1421to another.
1422
1423Note that in CIVL all jumps stay within a function. There is no
1424way to jump from one function to another (without returning).
1425
1426A small variation is the protocol for moving to the start location of
1427a function when the function is first pushed on the stack. Since the
1428start location is not necessarily in the function scope (it may be a
1429proper descendant of that scope), you have to execute the second half
1430of the protocol to push a sequence of scopes from the function scope
1431to the scope of the start location.
1432
1433\section{Initial State}
1434
1435The \emph{initial state} for $M$ is obtained by creating one process
1436(let $P=\{0\}$) and having it call the root function $f_0$.
1437Hence start with the state $s$ in which $P=\{0\}$, $\ldots$.
1438The initial state is $\textsf{jump}(s,0,\start_{f_0})$.
1439
1440\section{Transitions}
1441
1442The transitions follow the usual ``interleaving'' semantics. Given a
1443state $\sigma$, one defines the set of enabled transitions in $\sigma$
1444as follows. Let $p\in P$. Look at the last frame $(d,l)$ of
1445$\stack(p)$ (i.e., the top of the call stack), assuming the stack is
1446nonempty. Look at all guarded transitions emanating from $l$. For each
1447such transition, evaluate the guard using the valuation formed by
1448taking the union of the valuations of all ancestors of $d$ (including
1449$d$). In other words, follow the standard ``lexical scoping'' protocol
1450to determine the value of any variable that could occur at this point.
1451Those transitions whose guard evaluates to $\emph{true}$ are enabled.
1452
1453For each enabled transition, a new state is generated by executing
1454the transition's statement. For the most part, the semantics are obvious,
1455but there are a few details that are a bit subtle.
1456
1457\section{Calls and Spawns}
1458
1459Both calls and forks of a function $f$ entail the creation of a new
1460frame. First, a new dyscope $d$ corresponding to $\fscope(f)$ is
1461created. To find out where to stick that new scope in the dynamic
1462scope tree, proceed as follows: begin in the dyscope for the
1463process invoking the fork or call and start moving up its parent
1464sequence until you reach the first dyscope $d'$ whose associated
1465static scope is the defining scope of $f$. (You must reach such a
1466scope, or else $f$ would not be visible, and the model would have a
1467syntax error!) Insert $d$ right under $d'$, i.e.,
1468$\dparent(d)=d'$. This preserves the required correspondence between
1469static scopes and dyscopes. Now you move to the start location,
1470using the jump protocol, which may involve the creation of additional
1471dyscopes under $d$. The new frame references the last dynamic
1472scope you created, and the location is the start location of $f$.
1473Variables are given their initial values in all the newly created
1474dyscopes (however that is done).
1475
1476All of that is the same whether the statement is a fork or call. The
1477only difference is what happens next: for a call, the new frame is
1478pushed onto the calling process' call stack. For a fork, a new process
1479is ``created'', i.e., you pick a natural number not in $P$ and
1480add it to $P$, and push the frame onto the new stack. To be totally
1481deterministic, you could pick the least natural number not in $P$.
1482
1483\section{Garbage collection}
1484
1485In a state $s$, a dyscope is unreachable if there is no path
1486from a frame in a call stack to that dyscope (following the
1487$\dparent$ edges). You can remove all unreachable dyscopes.
1488
1489If a process has terminated (has empty stack) and \emph{there are no
1490references to that process} in the state, you can just remove the process
1491from the state.
1492
1493In any state, you can renumber the processes (and update the
1494references accordingly) however you want, to get rid of gaps, put them
1495in a canonic order, etc.
1496
1497
1498\part{Tools}
1499
1500\chapter{Overiew of CIVL Tools}
1501
1502Current tools allow one to \emph{run} a CIVL program using random
1503choice to resolve nondeterministic choices; \emph{verify} a program
1504using model checking to explore all states of the program;
1505\emph{replay} a trace if an error is found.
1506
1507The properties checked are assertion violations, division by zero,
1508illegal pointer accesses, etc.
1509
1510The available tools and options are summarized by the \texttt{civl
1511 help} command:
1512
1513\begin{verbatim}
1514Usage: civl <command> <options> filename ...
1515Commands:
1516 verify : verify program filename
1517 run : run program filename
1518 help : print this message
1519 replay : replay trace for program filename
1520 parse : show result of preprocessing and parsing filename
1521 preprocess : show result of preprocessing filename
1522Options:
1523 -debug or -debug=BOOLEAN (default: false)
1524 debug mode: print very detailed information
1525 -echo or -echo=BOOLEAN (default: false)
1526 print the command line
1527 -errorBound=INTEGER (default: 1)
1528 stop after finding this many errors
1529 -guided or -guided=BOOLEAN
1530 user guided simulation; applies only to run, ignored
1531 for all other commands
1532 -id=INTEGER (default: 0)
1533 ID number of trace to replay
1534 -inputKEY=VALUE
1535 initialize input variable KEY to VALUE
1536 -maxdepth=INTEGER (default: 2147483647)
1537 bound on search depth
1538 -min or -min=BOOLEAN (default: false)
1539 search for minimal counterexample
1540 -por=STRING (default: std)
1541 partial order reduction (por) choices:
1542 std (standard por) or scp (scoped por)
1543 -random or -random=BOOLEAN
1544 select enabled transitions randomly; default for run,
1545 ignored for all other commands
1546 -saveStates or -saveStates=BOOLEAN (default: true)
1547 save states during depth-first search
1548 -seed=STRING
1549 set the random seed; applies only to run
1550 -showModel or -showModel=BOOLEAN (default: false)
1551 print the model
1552 -showProverQueries or -showProverQueries=BOOLEAN (default: false)
1553 print theorem prover queries only
1554 -showQueries or -showQueries=BOOLEAN (default: false)
1555 print all queries
1556 -showSavedStates or -showSavedStates=BOOLEAN (default: false)
1557 print saved states only
1558 -showStates or -showStates=BOOLEAN (default: false)
1559 print all states
1560 -showTransitions or -showTransitions=BOOLEAN (default: false)
1561 print transitions
1562 -simplify or -simplify=BOOLEAN (default: true)
1563 simplify states?
1564 -solve or -solve=BOOLEAN (default: false)
1565 try to solve for concrete counterexample
1566 -states=STRING (default: immutable)
1567 state implementation: immutable, transient, persistent
1568 -sysIncludePath=STRING
1569 set the system include path
1570 -trace=STRING
1571 filename of trace to replay
1572 -userIncludePath=STRING
1573 set the user include path
1574 -verbose or -verbose=BOOLEAN (default: false)
1575 verbose mode
1576\end{verbatim}
1577
1578
1579\chapter{Transitions}
1580In CIVL, a transition stands for the execution of a number of statements of a certain process from one state, and the execution of each statement is considered as one step. A transition has the following form in the output, where sid and sid' are the identifiers for the source and the target states, pid is the identifier of the process that this transition belongs to, and step 0,1 ... are the steps contained in the transitions.
1581
1582\begin{verbatim}
1583State sid, proc pid:
1584 step 0;
1585 step 1;
1586 ...
1587--> State sid'
1588\end{verbatim}
1589
1590A step of a transition has the following form in the CIVL output, where src and dst is the source and destination location of the statement executed in the step, file is the file that contains the source code of the statement, location and text are the location and summary of text of the statement in the source file.
1591
1592\begin{verbatim}
1593 src->dst: statement at file:location "text";
1594\end{verbatim}
1595
1596For example, the following is a transition from state 0 to state 1, containing 6 steps. File names are renamed with short names and the mapping of short names and the original files is presented in output as well.
1597
1598\begin{verbatim}
1599File name list:
1600f0 : atomicBlockedResume.cvl
1601
1602State 0, proc 0:
1603 0->1: x = 1 at f0:3.0-9 "int x = 1";
1604 1->2: y = 0 at f0:4.0-9 "int y = 0";
1605 2->3: z = 0 at f0:5.0-9 "int z = 0";
1606 3->6: sum = 0 at f0:6.0-11 "int sum = 0";
1607 6->8: $spawn foo(1) at f0:22.4-17 "$spawn foo(1)";
1608 8->10: $spawn foo(2) at f0:23.4-17 "$spawn foo(2)";
1609--> State 1
1610\end{verbatim}
1611
1612To make use of this feature, one needs to specify the option ``-showTransitions'' when running CIVL.
1613
1614
1615
1616% \subsection{Example 1}
1617
1618% Here is a simple example based on a tricky MPI+Pthreads example given
1619% to us once by Rajeev Thakur at Argonne. It has nondeterministic
1620% behavior which can lead to a deadlock for certain interleavings, even
1621% though it does not use wildcards (\code{ANY{\U}SOURCE}). Very subtle
1622% bug. I can show you MPI-Spin finding the bug if you are interested. I
1623% don't actually have the original code, but could probably dig it up.
1624
1625% \begin{verbatim}
1626% #include <mp.civl> /* includes basic message-passing library */
1627
1628% void System() {
1629% proc procs[2];
1630
1631% void MPI_Process(int pid) {
1632% proc threads[2];
1633
1634% void Thread(int tid) {
1635% int x=0, y=0;
1636
1637% for (int j=0; j<2; j++) {
1638% if (pid == 1) {
1639% for (int i=0; i<3; i++) send(procs[pid], &x, 1, procs[1-pid], 0);
1640% for (int i=0; i<3; i++) recv(procs[pid], &y, 1, procs[1-pid], 0);
1641% } else { /* pid==0 */
1642% for (int i=0; i<3; i++) recv(procs[pid], &y, 1, procs[1-pid], 0);
1643% for (int i=0; i<3; i++) send(procs[pid], &x, 1, procs[1-pid], 0);
1644% }
1645% }
1646% }
1647
1648% for (int i=0; i<2; i++) threads[i] = fork Thread(i);
1649% for (int i=0; i<2; i++) join threads[i];
1650% }
1651
1652% for (int i=0; i<2; i++) procs[i] = fork MPI_Process(i);
1653% for (int i=0; i<2; i++) join procs[i];
1654% }
1655% \end{verbatim}
1656
1657\appendix
1658
1659
1660\end{document}
1661
1662
1663OpenMP loop?
1664\begin{verbatim}
1665T1 x1; ... // private
1666U1 y1; ... // shared
1667#pragma omp parallel private(x1,...)
1668 S(x1,...,y1,...);
1669
1670=>
1671
1672T1 x1; ...
1673U1 y1; ...
1674{
1675 void _tmp(int _tid) {
1676 T1 _x1; ...
1677 S(_x1,...,y1,...);
1678 }
1679 int numThreads = $choose_int(THREAD_MAX);
1680 $proc _threads[numThreads];
1681 int i;
1682
1683 for (i=0; i<numThreads; i++)
1684 _threads[i] = $spawn _tmp(i);
1685 for (i=0; i<numThreads; i++)
1686 $wait _threads[i];
1687}
1688
1689--
1690
1691#pragma parallel
1692{ ...
1693 int i; ...
1694 #pragma for
1695 for (i=...) S(i)
1696}
1697
1698=>
1699
1700{
1701 void _tmp1(int _tid) {
1702 int i; ...
1703 {
1704 void _tmp2(int _i) { S(_i) }
1705 int j;
1706 for (j=...) {
1707 int w = $choose_int(numThreads);
1708 }
1709 }
1710 }
1711
1712
1713\end{verbatim}
Note: See TracBrowser for help on using the repository browser.