source: CIVL/doc/manual/part-introduction.tex@ b7bd088

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since b7bd088 was 11dee25, checked in by Stephen Siegel <siegel@…>, 12 years ago

Small corrections to manual.

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

  • Property mode set to 100644
File size: 12.0 KB
Line 
1\part{Introduction}
2\label{part:intro}
3
4\chapter{Acknowledgement}
5
6The CIVL project is funded by the U.S.\ National Science Foundation
7under awards CCF-1346769 and CCF-1346756.
8
9\chapter{What is CIVL?}
10
11\textbf{CIVL} stands for \emph{Concurrency Intermediate Verification
12 Language}. The \emph{CIVL platform} encompasses:
13\begin{enumerate}
14\item the programming language \textbf{CIVL-C}, a dialect of C with
15 additional primitives supporting concurrency, specification, and modeling;
16\item verification and
17 analysis tools, including a symbolic execution-based model checker for
18 checking various properties of, or finding defects in, CIVL-C
19 programs; and
20\item tools that translate from many commonly used
21 languages/APIs to CIVL-C.
22\end{enumerate}
23
24The CIVL-C language is primarily intended to be an intermediate
25representation for verification. A C program using
26MPI~\cite{mpi-forum:2012:mpi30}, CUDA~\cite{cuda-programming-guide},
27OpenMP~\cite{openmp-standard}, OpenCL~\cite{opencl-standard}, or
28another API (or even some combination of APIs), will be automatically
29translated into CIVL-C and then verified. The advantages of such a
30framework are clear: the developer of a new verification technique
31could implement it for CIVL-C and then immediately see its impact
32across a broad range of concurrent programs. Likewise, when a new
33concurrency API is introduced, one only needs to implement a
34translator from it to CIVL-C in order to reap the benefits of all the
35verification tools in the platform. Programmers would have a valuable
36verification and debugging tool, while API designers could use CIVL as
37a ``sandbox'' to investigate possible API modifications, additions,
38and interactions.
39
40This manual covers all aspects of the CIVL framework, and is organized in parts
41as follows:
42\begin{enumerate}
43\item this introduction, including ``quick start'' instructions for
44 downloading and installing CIVL and several examples;
45\item a complete description of the CIVL-C language;
46\item a formal semantics for the language; and
47\item a description of the tools in the framework.
48\end{enumerate}
49
50\chapter{Installation and Quick Start}
51
52This chapter gives instructions for downloading and installing CIVL,
53and running the verification tool on an example.
54
55\textbf{Note.} The following instructions explain how to install CIVL
56under the directory \texttt{/opt}, which is the standard installation
57point. If you do not wish to install CIVL there (e.g., because you
58don't want to use \texttt{sudo}, or you want to install it in your
59home directory), you can just modify the instructions by replacing
60\texttt{/opt} with another directory. You will just need to edit the
61script file \texttt{civl} appropriately, replacing the default paths
62with your chosen paths.
63
64\begin{enumerate}
65\item Download and unpack the appropriate pre-compiled library of CIVL
66 dependencies from
67 \url{http://vsl.cis.udel.edu/tools/vsl_depend/}.
68 There are versions for Darwin (OS X), 32-bit Linux, and 64-bit Linux.
69 After unpacking, you should have a directory named \texttt{vsl}.
70\item If you do not already have a directory \texttt{/opt},
71 create it; use \texttt{sudo} as needed (\verb!sudo mkdir /opt!).
72\item Move the directory \texttt{vsl} into \texttt{/opt}
73 (\verb!mv vsl /opt!).
74\item Download and unpack the latest stable release of CIVL from
75 \url{http://vsl.cis.udel.edu/civl}. Again there are versions
76 for Darwin, 32-bit Linux, and 64-bit Linux.
77\item The resulting directory should be named
78 \texttt{CIVL-\textit{tag}} for some string \textit{tag} which
79 identifies the version of CIVL you downloaded. Move this directory
80 into \texttt{/opt} (\texttt{mv\ CIVL-\textit{tag}\ /opt}).
81\item There should now be an executable script at
82 \texttt{/opt/CIVL-\textit{tag}/bin/civl}. Move this script into
83 your path, or create a symlink from somewhere in your path to it, or
84 add the directory \texttt{/opt/CIVL-\textit{tag}/bin} to your path.
85\end{enumerate}
86
87From the command line, you should now be able to type ``\texttt{civl
88 help}'' and see a help message describing the command line syntax.
89
90Copy the file
91\texttt{CIVL-\textit{tag}/examples/concurrency/locksBad.cvl} to your
92working directory. Look at the program: it is a simple 2-process
93program with two shared variables used as locks. The two processes
94try to obtain the locks in opposite order, which can lead to a
95deadlock if both processes obtain their first lock before either
96obtains the second. Type
97``\verb!civl verify locksBad.cvl!''. You should see some output
98culminating in a message
99\begin{verbatim}
100The program MAY NOT be correct. See CIVLREP/locksBad_log.txt
101\end{verbatim}
102
103Type ``\verb!civl replay locksBad.cvl!''. You should see a
104step-by-step account of how the program arrived at the deadlock.
105
106
107\chapter{Examples}
108
109In this section we show a few simple CIVL-C programs which illustrate
110some of the pertinent features of the language. We also show the results
111of running some of the tools on them.
112
113\section{Dining Philosophers}
114
115Dijkstra's well-known Dining Philosophers system can be encoded in
116CIVL-C as shown in Figure \ref{fig:dining}.
117
118\begin{figure}[t]
119 \begin{small}
120\begin{verbatim}
121#include <civlc.h>
122
123$input int B; // upper bound on number of philosophers
124$input int n; // number of philosophers
125$assume 2<=n && n<=B;
126_Bool forks[n]; // Each fork will be on the table (0) or in a hand (1).
127
128void dine(int id) {
129 int left = id;
130 int right = (id + 1) % n;
131
132 while (1) {
133 $when (forks[left] == 0) forks[left] = 1;
134 $when (forks[right] == 0) forks[right] = 1;
135 forks[right] = 0;
136 forks[left] = 0;
137 }
138}
139
140void main() {
141 for (int i = 0; i < n; i++) forks[i] = 0;
142 for (int i = 0; i < n; i++) $spawn dine(i);
143}
144\end{verbatim}
145 \end{small}
146 \caption{CIVL-C encoding of Dijkstra's Dining Philosophers}
147 \label{fig:dining}
148\end{figure}
149
150In this encoding, an upper bound \ct{B} is placed on the number of
151philosophers \ct{n}. When verifying this program, a concrete value
152will be specified for \ct{B}. Hence the result of verification will
153apply to all \ct{n} between $2$ and \ct{B}, inclusive.
154
155Both \ct{B} and \ct{n} are delcared as \emph{input} variables using
156the type qualifier \cinput. An input variable may be
157initialized with any valid value of its type. In contrast, non-input
158variables declared in file scope will be initialized with a
159special \emph{undefined} value; if such a variable is read before it
160is defined, an error will be reported. In addition, any input variable
161may have a concrete initial value specified on the command line. In
162this case, we will specify a concrete value for \ct{B} on the command
163line but leave \ct{n} unconstrained.
164
165An $\cassume$ statement restricts the set of executions of the program
166to include only those traces in which the assumptions hold. In
167contrast with an $\cassert$ statement, CIVL does not check that the
168assumed expression holds, and will not generate an error message if it
169fails to hold. Thus an $\cassume$ statement allows the programmer to
170say to CIVL ``assume that this is true,'' while an $\cassert$
171statement allows the programmer to say to CIVL ``check that this is
172true.''
173
174A $\cwhen$ statement encodes a \emph{guarded command}. The $\cwhen$
175statement includes a boolean expression called the \emph{guard} and a
176statement body. The $\cwhen$ statement is enabled if and only if the
177\emph{guard} evaluates to \emph{true}, in which case the body may be
178executed. The first atomic statement in the body executes atomically
179with the evaluation of the guard, so it is guaranteed that the guard
180will hold when this initial sub-statement executes. Since assignment
181statements are atomic in CIVL, in this example the bodiy of each
182$\cwhen$ statement executes atomically with the guard evaluation.
183
184The $\cspawn$ statement is very similar to a function call. The main
185difference is that the function called is invoked in a new process
186which runs concurrently with the existing processes. The $\cspawn$
187statement itself returns immediately.
188
189The program may be verified for an upper bound of $5$ by typing the
190following at the command line:
191\begin{verbatim}
192 civl verify -inputB=5 diningBad.cvl
193\end{verbatim}
194
195The output indicates that a deadlock has been found and a
196counterexample has been produced and saved. We can examine the
197counterexample, but it is more helpful to work with a \emph{minimal}
198counterexample, i.e., a deadlocking trace of minimal length. To find a
199minimal counterexample, we issue the command
200
201\begin{verbatim}
202 civl verify -inputB=5 -min diningBad.cvl
203\end{verbatim}
204
205\begin{figure}[t]
206 \begin{small}
207\begin{verbatim}
208CIVL v0.8 of 2014-02-28 -- http://vsl.cis.udel.edu/civl
209Error 0 encountered at depth 129:
210...
211Error 25 encountered at depth 16:
212CIVL execution error (kind: DEADLOCK, certainty: PROVEABLE)
213A deadlock is possible:
214 Path condition: true
215 Enabling predicate: false
216ProcessState 0: terminated
217ProcessState 1: at location 26, f0:21.30-42 "forks[right]"
218 Enabling predicate: false
219ProcessState 2: at location 26, f0:21.30-42 "forks[right]"
220 Enabling predicate: false
221at f0:21.30-42 "forks[right]".
222State 664
223| Path condition
224| | true
225| Dynamic scopes
226| | dyscope 0 (parent=-1, static=0)
227| | | reachers = {1,2}
228| | | variables
229| | | | __atomic_lock_var = process<-1>
230| | | | B = 5
231| | | | n = 2
232| | | | forks = X_s0v3[0:=1, 1:=1]
233...
234| Process states
235...
236| | process 2
237| | | atomicCount = 0
238| | | call stack
239| | | | Frame[function=dine, location=26, f0:21.30-42 "forks[right]", scope=3]
240...
241=================== Stats ===================
242 validCalls : 15328
243 proverCalls : 17
244 memory (bytes) : 26738688
245 time (s) : 2.24
246 maxProcs : 6
247 statesInstantiated : 9267
248 statesSaved : 665
249 statesSeen : 1758
250 statesMatched : 1177
251 steps : 2994
252 transitions : 2934
253
254The program MAY NOT be correct. See CIVLREP/diningBad_log.txt
255\end{verbatim}
256 \end{small}
257 \caption{Output from \texttt{civl verify -inputB=5 -min diningBad.cvl}}
258 \label{fig:diningOut}
259\end{figure}
260
261The result of this command is shown in Figure \ref{fig:diningOut}. The
262output indicates that a minimal counterexample has length 19, i.e.,
263involves 20 states and 19 transitions (the depth of 20 is one more
264than 19). It was the 26th and shortest trace found. It was deemed
265equivalent to the earlier traces and hence the earlier ones were
266discarded and only this one saved. We can replay the trace with the command
267\begin{verbatim}
268 civl replay diningBad.cvl
269\end{verbatim}
270
271\begin{figure}
272 \begin{small}
273\begin{verbatim}
274...
275Transition 1: State 0, proc 0:
276 0->1: B = 5 at f0:9.0-12 "$input int B";
277 1->2: n = InitialValue(n) at f0:10.0-12 "$input int n";
278 2->3: $assume ((2<=n)&&(n<=B)) at f0:11.0-20 "$assume 2<=n && n ... B";
279 3->4: forks = InitialValue(forks) at f0:13.0-12 "int forks[n]";
280 4->6: __h__ = InitialValue(__h__) at f0:27.12-13 "{";
281 6->7: i = 0 at f0:28.7-16 "int i = 0";
282--> State 1
283
284Transition 2: State 1, proc 0:
285 7->9: LOOP_TRUE_BRANCH at f0:28.18-23 "i < n";
286--> State 2
287
288...
289
290Transition 12: State 12, proc 2:
291 19->20: left = id at f0:16.2-15 "int left = id";
292 20->21: right = ((id+1)%n) at f0:17.2-26 "int right = (id ... n";
293--> State 13
294
295Transition 13: State 13, proc 2:
296 21->24: LOOP_TRUE_BRANCH at f0:19.9-10 "1";
297--> State 14
298
299Transition 14: State 14, proc 1:
300 24->26: forks[left] = 1 at f0:20.29-44 "forks[left] = 1";
301--> State 15
302
303Transition 15: State 15, proc 2:
304 24->26: forks[left] = 1 at f0:20.29-44 "forks[left] = 1";
305--> State 16
306
307Violation of Deadlock found in State 16:
308A deadlock is possible:
309 Path condition: true
310 Enabling predicate: false
311ProcessState 0: terminated
312ProcessState 1: at location 26, f0:21.30-42 "forks[right]"
313 Enabling predicate: false
314ProcessState 2: at location 26, f0:21.30-42 "forks[right]"
315 Enabling predicate: false
316
317Trace ends after 15 transitions.
318Violation(s) found.
319...
320\end{verbatim}
321 \end{small}
322 \caption{Output from \texttt{civl replay}}
323 \label{fig:diningReplay}
324\end{figure}
325
326The result of this command is shown in Figure \ref{fig:diningReplay}.
327The output indicates that a deadlock has been found involving 2
328philosophers. The trace has 15 transitions; after the initialization
329sequence, each philosopher picks up her left fork.
Note: See TracBrowser for help on using the repository browser.