| 1 | CIVL: The Concurrency Intermediate Verification Language
|
|---|
| 2 |
|
|---|
| 3 | ------------------------------ Overview -------------------------------
|
|---|
| 4 |
|
|---|
| 5 | CIVL is a framework encompassing...
|
|---|
| 6 |
|
|---|
| 7 | * a programming language, CIVL-C, which adds to C a number of
|
|---|
| 8 | concurrency primitives, as well as the ability to define
|
|---|
| 9 | functions in any scope. Together, these features make for
|
|---|
| 10 | a very expressive concurrent language that can faithfully
|
|---|
| 11 | represent programs using various APIs and parallel languages,
|
|---|
| 12 | such as MPI, OpenMP, CUDA, and Chapel. CIVL-C also provides
|
|---|
| 13 | a number of primitives supporting verification.
|
|---|
| 14 | * a model checker which uses symbolic execution to verify a
|
|---|
| 15 | number of safety properties of CIVL-C programs. The model
|
|---|
| 16 | checker can also be used to verify that two CIVL-C programs
|
|---|
| 17 | are functionally equivalent.
|
|---|
| 18 | * a number of translators from various commonly-used languages
|
|---|
| 19 | and APIs to CIVL-C. (This part is still a work in progress.)
|
|---|
| 20 |
|
|---|
| 21 | CIVL is developed by the Verified Software Laboratory at the
|
|---|
| 22 | University of Delaware Department of Computer Science.
|
|---|
| 23 | For more information, visit http://vsl.cis.udel.edu/civl
|
|---|
| 24 |
|
|---|
| 25 | Developers:
|
|---|
| 26 |
|
|---|
| 27 | Stephen F. Siegel
|
|---|
| 28 | Timothy K. Zirkel
|
|---|
| 29 |
|
|---|
| 30 | ---------------------------- Installation -----------------------------
|
|---|
| 31 |
|
|---|
| 32 | For most users, this will be the easiest way to install and use CIVL.
|
|---|
| 33 |
|
|---|
| 34 | 1. Install a Java 7 SDK if you have not already. Go to
|
|---|
| 35 | http://www.oracle.com/technetwork/java/javase/downloads/ for the
|
|---|
| 36 | latest from Oracle. On linux, you can optionally sudo apt-get install
|
|---|
| 37 | openjdk-7-jdk.
|
|---|
| 38 |
|
|---|
| 39 | 2. If you already have the VSL dependencies library, you may
|
|---|
| 40 | skip this step. Otherwise, download the archive of VSL
|
|---|
| 41 | dependencies from http://vsl.cis.udel.edu/tools/vsl_depend,
|
|---|
| 42 | choosing the version for your OS type (32-bit linux,
|
|---|
| 43 | 64-bit linux, or 64-bit OS X). Unzip and untar the
|
|---|
| 44 | downloaded .tgz file and you will have a folder named "vsl".
|
|---|
| 45 | If you do not already have a directory /opt, create one with
|
|---|
| 46 | "mkdir /opt". Move vsl into /opt. Use sudo as needed.
|
|---|
| 47 |
|
|---|
| 48 | 3. Download the appropriate CIVL distribution from
|
|---|
| 49 | http://vsl.cis.udel.edu/civl.
|
|---|
| 50 |
|
|---|
| 51 | 4. Unzip and untar the downloaded file if this does not happen
|
|---|
| 52 | automatically. This should result in a folder named
|
|---|
| 53 | CIVL-TAG, where TAG is some version id string. This folder
|
|---|
| 54 | contains the following:
|
|---|
| 55 |
|
|---|
| 56 | - README : this file
|
|---|
| 57 | - bin : containing one executable sh script called "civl"
|
|---|
| 58 | - lib : containing civl-TAG.jar
|
|---|
| 59 | - doc : containing some documentation about CIVL
|
|---|
| 60 | - licenses : licenses for CIVL and included libraries
|
|---|
| 61 | - examples : some example CIVL programs
|
|---|
| 62 |
|
|---|
| 63 | 5. Move CIVL-TAG into /opt.
|
|---|
| 64 |
|
|---|
| 65 | 6. Put the civl script in your path however you like to put things
|
|---|
| 66 | in your path. Either move it to a directory in your path,
|
|---|
| 67 | or create a symlink to it, or edit your .profile or equivalent
|
|---|
| 68 | to put it in your path.
|
|---|
| 69 |
|
|---|
| 70 | ---------------------------- CIVL help -----------------------------
|
|---|
| 71 |
|
|---|
| 72 | In command line, type just "civl help" for the usage information
|
|---|
| 73 | as shown below.
|
|---|
| 74 |
|
|---|
| 75 | CIVL v0.4 of 2013-12-06 -- http://vsl.cis.udel.edu/civl
|
|---|
| 76 | Usage: civl <command> <options> filename ...
|
|---|
| 77 | Commands:
|
|---|
| 78 | verify : verify program filename
|
|---|
| 79 | run : run program filename
|
|---|
| 80 | help : print this message
|
|---|
| 81 | replay : replay trace for program filename
|
|---|
| 82 | parse : show result of preprocessing and parsing filename
|
|---|
| 83 | preprocess : show result of preprocessing filename
|
|---|
| 84 | Options:
|
|---|
| 85 | -debug or -debug=BOOLEAN (default: false)
|
|---|
| 86 | debug mode: print very detailed information
|
|---|
| 87 | -errorBound=INTEGER (default: 1)
|
|---|
| 88 | stop after finding this many errors
|
|---|
| 89 | -guided or -guided=BOOLEAN
|
|---|
| 90 | user guided simulation; applies only to run, ignored
|
|---|
| 91 | for all other commands
|
|---|
| 92 | -id=INTEGER (default: 0)
|
|---|
| 93 | ID number of trace to replay
|
|---|
| 94 | -inputKEY=VALUE
|
|---|
| 95 | initialize input variable KEY to VALUE
|
|---|
| 96 | -maxdepth=INTEGER (default: 2147483647)
|
|---|
| 97 | bound on search depth
|
|---|
| 98 | -min or -min=BOOLEAN (default: false)
|
|---|
| 99 | search for minimal counterexample
|
|---|
| 100 | -por=STRING (default: std)
|
|---|
| 101 | partial order reduction (por) choices:
|
|---|
| 102 | std (standard por) or scp (scoped por)
|
|---|
| 103 | -random or -random=BOOLEAN
|
|---|
| 104 | select enabled transitions randomly; default for run,
|
|---|
| 105 | ignored for all other commands
|
|---|
| 106 | -saveStates or -saveStates=BOOLEAN (default: true)
|
|---|
| 107 | save states during depth-first search
|
|---|
| 108 | -seed=STRING
|
|---|
| 109 | set the random seed; applies only to run
|
|---|
| 110 | -showModel or -showModel=BOOLEAN (default: false)
|
|---|
| 111 | print the model
|
|---|
| 112 | -showProverQueries or -showProverQueries=BOOLEAN (default: false)
|
|---|
| 113 | print theorem prover queries only
|
|---|
| 114 | -showQueries or -showQueries=BOOLEAN (default: false)
|
|---|
| 115 | print all queries
|
|---|
| 116 | -showSavedStates or -showSavedStates=BOOLEAN (default: false)
|
|---|
| 117 | print saved states only
|
|---|
| 118 | -showStates or -showStates=BOOLEAN (default: false)
|
|---|
| 119 | print all states
|
|---|
| 120 | -showTransitions or -showTransitions=BOOLEAN (default: false)
|
|---|
| 121 | print transitions
|
|---|
| 122 | -simplify or -simplify=BOOLEAN (default: true)
|
|---|
| 123 | simplify states?
|
|---|
| 124 | -solve or -solve=BOOLEAN (default: false)
|
|---|
| 125 | try to solve for concrete counterexample
|
|---|
| 126 | -sysIncludePath=STRING
|
|---|
| 127 | set the system include path
|
|---|
| 128 | -trace=STRING
|
|---|
| 129 | filename of trace to replay
|
|---|
| 130 | -userIncludePath=STRING
|
|---|
| 131 | set the user include path
|
|---|
| 132 | -verbose or -verbose=BOOLEAN (default: false)
|
|---|
| 133 | verbose mode
|
|---|
| 134 |
|
|---|
| 135 | ------------------------------- License -------------------------------
|
|---|
| 136 |
|
|---|
| 137 | CIVL is open source software distributed under the GNU
|
|---|
| 138 | General Public License. However, the libraries used by CIVL
|
|---|
| 139 | (and incorporated into the complete distribution) use various
|
|---|
| 140 | licenses. See directory licenses for the license of each component.
|
|---|
| 141 |
|
|---|
| 142 | ------------------------ Language Summary -----------------------------
|
|---|
| 143 |
|
|---|
| 144 | Summary of new keywords:
|
|---|
| 145 |
|
|---|
| 146 | $proc : the process type
|
|---|
| 147 | $self : the process invoking the statement (constant of type $proc)
|
|---|
| 148 | $input : type qualifier declaring variable to be a program input
|
|---|
| 149 | $output : type qualifier declaring variable to be a program output
|
|---|
| 150 | $spawn : create a new process running procedure
|
|---|
| 151 | $wait : wait for a process to terminate
|
|---|
| 152 | $assert : check something holds
|
|---|
| 153 | $true : boolean value true, used in assertions
|
|---|
| 154 | $false: boolean value false, used in assertions
|
|---|
| 155 | $assume : assume something holds
|
|---|
| 156 | $when : guarded statement
|
|---|
| 157 | $choose : nondeterministic choice statement
|
|---|
| 158 | $invariant : declare a loop invariant
|
|---|
| 159 | $requires : procedure precondition
|
|---|
| 160 | $ensures : procedure postcondition
|
|---|
| 161 | $result : refers to result returned by procedure in contracts
|
|---|
| 162 | @ : refer to variable in other process, e.g., p@x
|
|---|
| 163 | $collective : a collective expression
|
|---|
| 164 |
|
|---|
| 165 | Other syntactic changes:
|
|---|
| 166 |
|
|---|
| 167 | - procedure definitions may occur in any scope
|
|---|
| 168 |
|
|---|
| 169 | ------------------------------------------------------------------------
|
|---|
| 170 |
|
|---|
| 171 | Detailed description:
|
|---|
| 172 |
|
|---|
| 173 | $proc : this is a primitive object type and functions like any other
|
|---|
| 174 | primitive C type (e.g., int). An object of this type refers
|
|---|
| 175 | to process. It can be thought of as a process ID, but it is not
|
|---|
| 176 | an integer and cannot be cast to one. Certain expressions take
|
|---|
| 177 | an argument of $proc type and some return something of $proc type.
|
|---|
| 178 |
|
|---|
| 179 | ------------------------------------------------------------------------
|
|---|
| 180 |
|
|---|
| 181 | $self: this is a constant of type $proc. It can be used wherever
|
|---|
| 182 | an argument of type $proc is called for. It refers to the process
|
|---|
| 183 | that is evaluating the expression containing "$self".
|
|---|
| 184 |
|
|---|
| 185 | ------------------------------------------------------------------------
|
|---|
| 186 |
|
|---|
| 187 | $input : A variable in the global scope only may be declared with this
|
|---|
| 188 | type modifier indicating it is an "input" variable, as in
|
|---|
| 189 |
|
|---|
| 190 | $input int n;
|
|---|
| 191 |
|
|---|
| 192 | As explained above, the variable becomes a parameter to the Root
|
|---|
| 193 | procedure. This is used when comparing two programs for functional
|
|---|
| 194 | equivalence. The two programs are functionally equivalent if,
|
|---|
| 195 | whenever they are given the same inputs (i.e., corresponding $input
|
|---|
| 196 | variables are initialized with the same values) they will produce the
|
|---|
| 197 | same outputs (i.e., corresponding $output variables will end up with
|
|---|
| 198 | the same values at termination).
|
|---|
| 199 |
|
|---|
| 200 | ------------------------------------------------------------------------
|
|---|
| 201 |
|
|---|
| 202 | $output : A variable in the global scope may be declared with
|
|---|
| 203 | this type modifier to declare it to be an output variable.
|
|---|
| 204 |
|
|---|
| 205 | ------------------------------------------------------------------------
|
|---|
| 206 |
|
|---|
| 207 | $spawn : this is an expression with side-effects. It spawns a new
|
|---|
| 208 | process and returns a reference to the new process, i.e., an object of
|
|---|
| 209 | type $proc. The syntax is the same as a procedure invocation with the
|
|---|
| 210 | keyword "$spawn" inserted in front:
|
|---|
| 211 |
|
|---|
| 212 | $spawn f(expr1, ..., exprn)
|
|---|
| 213 |
|
|---|
| 214 | Typically the returned value is assigned to a variable, e.g.,
|
|---|
| 215 |
|
|---|
| 216 | $proc p = $spawn f(i);
|
|---|
| 217 |
|
|---|
| 218 | If the invoked function f returns a value, that value is simply
|
|---|
| 219 | ignored.
|
|---|
| 220 |
|
|---|
| 221 | ------------------------------------------------------------------------
|
|---|
| 222 |
|
|---|
| 223 | $wait: this is a statement that takes an argument of type $proc
|
|---|
| 224 | and blocks until the referenced process terminates:
|
|---|
| 225 |
|
|---|
| 226 | $wait expr;
|
|---|
| 227 |
|
|---|
| 228 | ------------------------------------------------------------------------
|
|---|
| 229 |
|
|---|
| 230 | $assert: This is an assertion statement. It takes as its sole
|
|---|
| 231 | argument an expression of boolean type. The expressions have a
|
|---|
| 232 | richer syntax than C expressions. During verification, the
|
|---|
| 233 | assertion is checked. If it does not hold, a violation is reported.
|
|---|
| 234 |
|
|---|
| 235 | $assert expr;
|
|---|
| 236 |
|
|---|
| 237 | Boolean values $true and $false may be used in assertions
|
|---|
| 238 | and assumptions.
|
|---|
| 239 |
|
|---|
| 240 | ------------------------------------------------------------------------
|
|---|
| 241 |
|
|---|
| 242 | $assume: This is an assume statement. Its syntax is the same as that
|
|---|
| 243 | of $assert. During verification, the assumed expression is assumed to
|
|---|
| 244 | hold. If this leads to a contradiction on some execution, that
|
|---|
| 245 | execution is simply ignored. It never reports a violation, it only
|
|---|
| 246 | restricts the set of possible executions that will be explored by the
|
|---|
| 247 | verification.
|
|---|
| 248 |
|
|---|
| 249 | $assume expr;
|
|---|
| 250 |
|
|---|
| 251 | ------------------------------------------------------------------------
|
|---|
| 252 |
|
|---|
| 253 | $when (expr) stmt;
|
|---|
| 254 |
|
|---|
| 255 | A guarded command.
|
|---|
| 256 |
|
|---|
| 257 | All statements have a guard, either implicit or explicit. For most
|
|---|
| 258 | statements, the guard is "true". The $when statement allows one to
|
|---|
| 259 | attach an explicit guard to a statement.
|
|---|
| 260 |
|
|---|
| 261 | When expr is true, the statement is enabled, otherwise it is
|
|---|
| 262 | disabled. A disabled statement is "blocked"---it will not be
|
|---|
| 263 | scheduled for execution. When it is enabled, it may execute by moving
|
|---|
| 264 | control to the stmt and executing the first atomic action in the stmt.
|
|---|
| 265 |
|
|---|
| 266 | If stmt itself has a guard, the guard of the $when statement is
|
|---|
| 267 | effectively the conjunction of the expr and the guard of the stmt.
|
|---|
| 268 |
|
|---|
| 269 | The evaluation of expr and the first atomic action of stmt effectively
|
|---|
| 270 | occur as a single atomic action. There is no guarantee that execution
|
|---|
| 271 | of stmt will continue atomically if it contains more than one atomic
|
|---|
| 272 | action, i.e., other processes may be scheduled.
|
|---|
| 273 |
|
|---|
| 274 | Examples:
|
|---|
| 275 |
|
|---|
| 276 | $when (s>0) s--;
|
|---|
| 277 |
|
|---|
| 278 | This will block until s is positive then decrement s. The execution
|
|---|
| 279 | of s-- is guaranteed to take place in an environment in which s is
|
|---|
| 280 | positive.
|
|---|
| 281 |
|
|---|
| 282 | $when (s>0) {s--; t++}
|
|---|
| 283 |
|
|---|
| 284 | The execution of s-- must happen when s>0, but between s-- and t++,
|
|---|
| 285 | other processes may execute.
|
|---|
| 286 |
|
|---|
| 287 | $when (s>0) $when (t>0) x=y*t;
|
|---|
| 288 |
|
|---|
| 289 | This blocks until both x and t are positive then executes
|
|---|
| 290 | the assignment in that state. It is equivalent to
|
|---|
| 291 |
|
|---|
| 292 | $when (s>0 && t>0) x=y*t;
|
|---|
| 293 |
|
|---|
| 294 | ------------------------------------------------------------------------
|
|---|
| 295 |
|
|---|
| 296 | A $choose statement has the form
|
|---|
| 297 |
|
|---|
| 298 | $choose {
|
|---|
| 299 | stmt1;
|
|---|
| 300 | stmt2;
|
|---|
| 301 | ...
|
|---|
| 302 | default: stmt
|
|---|
| 303 | }
|
|---|
| 304 |
|
|---|
| 305 | The "default" clause is optional.
|
|---|
| 306 |
|
|---|
| 307 | The guards of the statements are evaluated and among those that are
|
|---|
| 308 | true, one is chosen nondeterministically and executed. If none are
|
|---|
| 309 | true and the default clause is present, it is chosen. The default
|
|---|
| 310 | clause will only be selected if all guards are false. If no default
|
|---|
| 311 | clause is present and all guards are false, the statement blocks.
|
|---|
| 312 | Hence the implicit guard of the $choose statement without a default
|
|---|
| 313 | clause is the disjunction of the guards of its sub-statements.
|
|---|
| 314 | The implicit guard of the $choose statement with a default clause
|
|---|
| 315 | is "true".
|
|---|
| 316 |
|
|---|
| 317 | Example: this shows how to encode "low-level" CIVL:
|
|---|
| 318 |
|
|---|
| 319 | l1: $choose {
|
|---|
| 320 | $when (x>0) {x--; goto l2;}
|
|---|
| 321 | $when (x==0) {y=1; goto l3;}
|
|---|
| 322 | default: {z=1; goto l4;}
|
|---|
| 323 | }
|
|---|
| 324 | l2: $choose {
|
|---|
| 325 | ...
|
|---|
| 326 | }
|
|---|
| 327 | l3: $choose {
|
|---|
| 328 | ...
|
|---|
| 329 | }
|
|---|
| 330 |
|
|---|
| 331 | ------------------------------------------------------------------------
|
|---|
| 332 |
|
|---|
| 333 | $invariant: indicates a loop invariant. Each C loop construct has an
|
|---|
| 334 | optional invariant clause as follows:
|
|---|
| 335 |
|
|---|
| 336 | while (expr) $invariant (expr) stmt
|
|---|
| 337 |
|
|---|
| 338 | for (e1; e2; e3) $invariant (expr) stmt
|
|---|
| 339 |
|
|---|
| 340 | do stmt while (expr) $invariant (expr) ;
|
|---|
| 341 |
|
|---|
| 342 | The invariant is a claim that if if the expr holds upon entering
|
|---|
| 343 | the loop and the loop condition holds, then it will hold
|
|---|
| 344 | after completion of execution of the loop body.
|
|---|
| 345 |
|
|---|
| 346 | The invariant is used by certain verification techniques.
|
|---|
| 347 |
|
|---|
| 348 | ------------------------------------------------------------------------
|
|---|
| 349 |
|
|---|
| 350 | Procedure contracts: $requires and $ensures. There are optional
|
|---|
| 351 | elements that may occur in a procedure declaration or definition:
|
|---|
| 352 |
|
|---|
| 353 | T f(...)
|
|---|
| 354 | $requires expr;
|
|---|
| 355 | $ensures expr;
|
|---|
| 356 | ;
|
|---|
| 357 |
|
|---|
| 358 | or
|
|---|
| 359 |
|
|---|
| 360 | T f(...)
|
|---|
| 361 | $requires expr ;
|
|---|
| 362 | $ensures expr ;
|
|---|
| 363 | {
|
|---|
| 364 | ...
|
|---|
| 365 | }
|
|---|
| 366 |
|
|---|
| 367 | The value $result may be used in post-conditions to refer
|
|---|
| 368 | to the result returned by a procedure.
|
|---|
| 369 |
|
|---|
| 370 | ------------------------------------------------------------------------
|
|---|
| 371 |
|
|---|
| 372 | expr@x: remote expressions refer to a variable in another process,
|
|---|
| 373 | e.g., procs[i]@x. This special kind of expression is used in
|
|---|
| 374 | collective expressions, which are used to formulate collective
|
|---|
| 375 | assertions and invariants.
|
|---|
| 376 |
|
|---|
| 377 | The expr must have $proc type. The variable x must be a statically
|
|---|
| 378 | visible variable in the context in which it is occurs. When
|
|---|
| 379 | this expression is evaluated, the evaluation context will be shifted
|
|---|
| 380 | to the process referred to by the expr.
|
|---|
| 381 |
|
|---|
| 382 | ------------------------------------------------------------------------
|
|---|
| 383 |
|
|---|
| 384 | $collective(proc_expr, int_expr) expr
|
|---|
| 385 |
|
|---|
| 386 | This is a collective expression over a set of processes. The
|
|---|
| 387 | proc_expr is a pointer to the first element of an array of $proc. The
|
|---|
| 388 | int_expr gives the length of that array, i.e., the number of
|
|---|
| 389 | processes. expr is a boolean-valued expression; it may use remote
|
|---|
| 390 | expressions to refer to variables in the processes specified in the
|
|---|
| 391 | array.
|
|---|
| 392 |
|
|---|
| 393 | example:
|
|---|
| 394 |
|
|---|
| 395 | $proc procs[N];
|
|---|
| 396 | ...
|
|---|
| 397 | $assert $collective(procs, N) i==procs[(pid+1)%N]@i ;
|
|---|
| 398 |
|
|---|