source: CIVL/doc/manual/civl-manual.tex@ 4f22a92

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since 4f22a92 was c3eca1d, checked in by Stephen Siegel <siegel@…>, 13 years ago

Worked on manual.
Corrected bug in Evalatuator; no need to call validOrModel at one point, just valid.
Set debug flag correctly in Enabler.

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

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