source: CIVL/doc/manual/civl-manual.tex@ 8fad75f

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since 8fad75f was 13ab238, checked in by Manchun Zheng <zmanchun@…>, 13 years ago

update version number, add explanation for transitions shown in output.

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

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