| 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 | You must have a Java virtual machine (version 7) installed on your
|
|---|
| 33 | system and "java" should be in your path.
|
|---|
| 34 |
|
|---|
| 35 | Installation for Mac OS X:
|
|---|
| 36 |
|
|---|
| 37 | The complete distribution for Mac OS X 64-bit Intel
|
|---|
| 38 | comes in a folder named CIVL-TAG, where TAG is some version
|
|---|
| 39 | id string. This folder contains the following:
|
|---|
| 40 |
|
|---|
| 41 | - README : this file
|
|---|
| 42 | - bin : containing one executable sh script called "civl"
|
|---|
| 43 | - lib : containing civl-TAG.jar and native libraries
|
|---|
| 44 | used by CIVL
|
|---|
| 45 | - doc : containing some documentation about CIVL
|
|---|
| 46 | - licenses : licenses for CIVL and included libraries
|
|---|
| 47 | - examples : some example CIVL programs
|
|---|
| 48 |
|
|---|
| 49 | Installation instructions:
|
|---|
| 50 | 1. Move folder CIVL-TAG into the /Applications folder
|
|---|
| 51 | 2. Put the civl script in your path however you like to put things
|
|---|
| 52 | into your path. Either move it to a directory in your path,
|
|---|
| 53 | or create a symlink to it, or edit your .profile or equivalent
|
|---|
| 54 | to put it in your path.
|
|---|
| 55 |
|
|---|
| 56 | Now you should be able to run CIVL from the command line by
|
|---|
| 57 | typing "civl <filename>".
|
|---|
| 58 |
|
|---|
| 59 | Installation for Linux:
|
|---|
| 60 |
|
|---|
| 61 | Same as above, except the folder goes into /usr/local.
|
|---|
| 62 |
|
|---|
| 63 | ------------------------------- License -------------------------------
|
|---|
| 64 |
|
|---|
| 65 | CIVL is open source software distributed under the GNU
|
|---|
| 66 | General Public License. However, the libraries used by CIVL
|
|---|
| 67 | (and incorporated into the complete distribution) use various
|
|---|
| 68 | licenses. See directory licenses for the license of each component.
|
|---|
| 69 |
|
|---|
| 70 | ------------------------ Language Summary -----------------------------
|
|---|
| 71 |
|
|---|
| 72 | Summary of new keywords:
|
|---|
| 73 |
|
|---|
| 74 | $proc : the process type
|
|---|
| 75 | $self : the process invoking the statement (constant of type $proc)
|
|---|
| 76 | $input : type qualifier declaring variable to be a program input
|
|---|
| 77 | $output : type qualifier declaring variable to be a program output
|
|---|
| 78 | $spawn : create a new process running procedure
|
|---|
| 79 | $wait : wait for a process to terminate
|
|---|
| 80 | $assert : check something holds
|
|---|
| 81 | $true : boolean value true, used in assertions
|
|---|
| 82 | $false: boolean value false, used in assertions
|
|---|
| 83 | $assume : assume something holds
|
|---|
| 84 | $when : guarded statement
|
|---|
| 85 | $choose : nondeterministic choice statement
|
|---|
| 86 | $invariant : declare a loop invariant
|
|---|
| 87 | $requires : procedure precondition
|
|---|
| 88 | $ensures : procedure postcondition
|
|---|
| 89 | $result : refers to result returned by procedure in contracts
|
|---|
| 90 | @ : refer to variable in other process, e.g., p@x
|
|---|
| 91 | $collective : a collective expression
|
|---|
| 92 |
|
|---|
| 93 | Other syntactic changes:
|
|---|
| 94 |
|
|---|
| 95 | - procedure definitions may occur in any scope
|
|---|
| 96 |
|
|---|
| 97 | ------------------------------------------------------------------------
|
|---|
| 98 |
|
|---|
| 99 | Detailed description:
|
|---|
| 100 |
|
|---|
| 101 | $proc : this is a primitive object type and functions like any other
|
|---|
| 102 | primitive C type (e.g., int). An object of this type refers
|
|---|
| 103 | to process. It can be thought of as a process ID, but it is not
|
|---|
| 104 | an integer and cannot be cast to one. Certain expressions take
|
|---|
| 105 | an argument of $proc type and some return something of $proc type.
|
|---|
| 106 |
|
|---|
| 107 | ------------------------------------------------------------------------
|
|---|
| 108 |
|
|---|
| 109 | $self: this is a constant of type $proc. It can be used wherever
|
|---|
| 110 | an argument of type $proc is called for. It refers to the process
|
|---|
| 111 | that is evaluating the expression containing "$self".
|
|---|
| 112 |
|
|---|
| 113 | ------------------------------------------------------------------------
|
|---|
| 114 |
|
|---|
| 115 | $input : A variable in the global scope only may be declared with this
|
|---|
| 116 | type modifier indicating it is an "input" variable, as in
|
|---|
| 117 |
|
|---|
| 118 | $input int n;
|
|---|
| 119 |
|
|---|
| 120 | As explained above, the variable becomes a parameter to the Root
|
|---|
| 121 | procedure. This is used when comparing two programs for functional
|
|---|
| 122 | equivalence. The two programs are functionally equivalent if,
|
|---|
| 123 | whenever they are given the same inputs (i.e., corresponding $input
|
|---|
| 124 | variables are initialized with the same values) they will produce the
|
|---|
| 125 | same outputs (i.e., corresponding $output variables will end up with
|
|---|
| 126 | the same values at termination).
|
|---|
| 127 |
|
|---|
| 128 | ------------------------------------------------------------------------
|
|---|
| 129 |
|
|---|
| 130 | $output : A variable in the global scope may be declared with
|
|---|
| 131 | this type modifier to declare it to be an output variable.
|
|---|
| 132 |
|
|---|
| 133 | ------------------------------------------------------------------------
|
|---|
| 134 |
|
|---|
| 135 | $spawn : this is an expression with side-effects. It spawns a new
|
|---|
| 136 | process and returns a reference to the new process, i.e., an object of
|
|---|
| 137 | type $proc. The syntax is the same as a procedure invocation with the
|
|---|
| 138 | keyword "$spawn" inserted in front:
|
|---|
| 139 |
|
|---|
| 140 | $spawn f(expr1, ..., exprn)
|
|---|
| 141 |
|
|---|
| 142 | Typically the returned value is assigned to a variable, e.g.,
|
|---|
| 143 |
|
|---|
| 144 | $proc p = $spawn f(i);
|
|---|
| 145 |
|
|---|
| 146 | If the invoked function f returns a value, that value is simply
|
|---|
| 147 | ignored.
|
|---|
| 148 |
|
|---|
| 149 | ------------------------------------------------------------------------
|
|---|
| 150 |
|
|---|
| 151 | $wait: this is a statement that takes an argument of type $proc
|
|---|
| 152 | and blocks until the referenced process terminates:
|
|---|
| 153 |
|
|---|
| 154 | $wait expr;
|
|---|
| 155 |
|
|---|
| 156 | ------------------------------------------------------------------------
|
|---|
| 157 |
|
|---|
| 158 | $assert: This is an assertion statement. It takes as its sole
|
|---|
| 159 | argument an expression of boolean type. The expressions have a
|
|---|
| 160 | richer syntax than C expressions. During verification, the
|
|---|
| 161 | assertion is checked. If it does not hold, a violation is reported.
|
|---|
| 162 |
|
|---|
| 163 | $assert expr;
|
|---|
| 164 |
|
|---|
| 165 | Boolean values $true and $false may be used in assertions
|
|---|
| 166 | and assumptions.
|
|---|
| 167 |
|
|---|
| 168 | ------------------------------------------------------------------------
|
|---|
| 169 |
|
|---|
| 170 | $assume: This is an assume statement. Its syntax is the same as that
|
|---|
| 171 | of $assert. During verification, the assumed expression is assumed to
|
|---|
| 172 | hold. If this leads to a contradiction on some execution, that
|
|---|
| 173 | execution is simply ignored. It never reports a violation, it only
|
|---|
| 174 | restricts the set of possible executions that will be explored by the
|
|---|
| 175 | verification.
|
|---|
| 176 |
|
|---|
| 177 | $assume expr;
|
|---|
| 178 |
|
|---|
| 179 | ------------------------------------------------------------------------
|
|---|
| 180 |
|
|---|
| 181 | $when (expr) stmt;
|
|---|
| 182 |
|
|---|
| 183 | A guarded command.
|
|---|
| 184 |
|
|---|
| 185 | All statements have a guard, either implicit or explicit. For most
|
|---|
| 186 | statements, the guard is "true". The $when statement allows one to
|
|---|
| 187 | attach an explicit guard to a statement.
|
|---|
| 188 |
|
|---|
| 189 | When expr is true, the statement is enabled, otherwise it is
|
|---|
| 190 | disabled. A disabled statement is "blocked"---it will not be
|
|---|
| 191 | scheduled for execution. When it is enabled, it may execute by moving
|
|---|
| 192 | control to the stmt and executing the first atomic action in the stmt.
|
|---|
| 193 |
|
|---|
| 194 | If stmt itself has a guard, the guard of the $when statement is
|
|---|
| 195 | effectively the conjunction of the expr and the guard of the stmt.
|
|---|
| 196 |
|
|---|
| 197 | The evaluation of expr and the first atomic action of stmt effectively
|
|---|
| 198 | occur as a single atomic action. There is no guarantee that execution
|
|---|
| 199 | of stmt will continue atomically if it contains more than one atomic
|
|---|
| 200 | action, i.e., other processes may be scheduled.
|
|---|
| 201 |
|
|---|
| 202 | Examples:
|
|---|
| 203 |
|
|---|
| 204 | $when (s>0) s--;
|
|---|
| 205 |
|
|---|
| 206 | This will block until s is positive then decrement s. The execution
|
|---|
| 207 | of s-- is guaranteed to take place in an environment in which s is
|
|---|
| 208 | positive.
|
|---|
| 209 |
|
|---|
| 210 | $when (s>0) {s--; t++}
|
|---|
| 211 |
|
|---|
| 212 | The execution of s-- must happen when s>0, but between s-- and t++,
|
|---|
| 213 | other processes may execute.
|
|---|
| 214 |
|
|---|
| 215 | $when (s>0) $when (t>0) x=y*t;
|
|---|
| 216 |
|
|---|
| 217 | This blocks until both x and t are positive then executes
|
|---|
| 218 | the assignment in that state. It is equivalent to
|
|---|
| 219 |
|
|---|
| 220 | $when (s>0 && t>0) x=y*t;
|
|---|
| 221 |
|
|---|
| 222 | ------------------------------------------------------------------------
|
|---|
| 223 |
|
|---|
| 224 | A $choose statement has the form
|
|---|
| 225 |
|
|---|
| 226 | $choose {
|
|---|
| 227 | stmt1;
|
|---|
| 228 | stmt2;
|
|---|
| 229 | ...
|
|---|
| 230 | default: stmt
|
|---|
| 231 | }
|
|---|
| 232 |
|
|---|
| 233 | The "default" clause is optional.
|
|---|
| 234 |
|
|---|
| 235 | The guards of the statements are evaluated and among those that are
|
|---|
| 236 | true, one is chosen nondeterministically and executed. If none are
|
|---|
| 237 | true and the default clause is present, it is chosen. The default
|
|---|
| 238 | clause will only be selected if all guards are false. If no default
|
|---|
| 239 | clause is present and all guards are false, the statement blocks.
|
|---|
| 240 | Hence the implicit guard of the $choose statement without a default
|
|---|
| 241 | clause is the disjunction of the guards of its sub-statements.
|
|---|
| 242 | The implicit guard of the $choose statement with a default clause
|
|---|
| 243 | is "true".
|
|---|
| 244 |
|
|---|
| 245 | Example: this shows how to encode "low-level" CIVL:
|
|---|
| 246 |
|
|---|
| 247 | l1: $choose {
|
|---|
| 248 | $when (x>0) {x--; goto l2;}
|
|---|
| 249 | $when (x==0) {y=1; goto l3;}
|
|---|
| 250 | default: {z=1; goto l4;}
|
|---|
| 251 | }
|
|---|
| 252 | l2: $choose {
|
|---|
| 253 | ...
|
|---|
| 254 | }
|
|---|
| 255 | l3: $choose {
|
|---|
| 256 | ...
|
|---|
| 257 | }
|
|---|
| 258 |
|
|---|
| 259 | ------------------------------------------------------------------------
|
|---|
| 260 |
|
|---|
| 261 | $invariant: indicates a loop invariant. Each C loop construct has an
|
|---|
| 262 | optional invariant clause as follows:
|
|---|
| 263 |
|
|---|
| 264 | while (expr) $invariant (expr) stmt
|
|---|
| 265 |
|
|---|
| 266 | for (e1; e2; e3) $invariant (expr) stmt
|
|---|
| 267 |
|
|---|
| 268 | do stmt while (expr) $invariant (expr) ;
|
|---|
| 269 |
|
|---|
| 270 | The invariant is a claim that if if the expr holds upon entering
|
|---|
| 271 | the loop and the loop condition holds, then it will hold
|
|---|
| 272 | after completion of execution of the loop body.
|
|---|
| 273 |
|
|---|
| 274 | The invariant is used by certain verification techniques.
|
|---|
| 275 |
|
|---|
| 276 | ------------------------------------------------------------------------
|
|---|
| 277 |
|
|---|
| 278 | Procedure contracts: $requires and $ensures. There are optional
|
|---|
| 279 | elements that may occur in a procedure declaration or definition:
|
|---|
| 280 |
|
|---|
| 281 | T f(...)
|
|---|
| 282 | $requires expr;
|
|---|
| 283 | $ensures expr;
|
|---|
| 284 | ;
|
|---|
| 285 |
|
|---|
| 286 | or
|
|---|
| 287 |
|
|---|
| 288 | T f(...)
|
|---|
| 289 | $requires expr ;
|
|---|
| 290 | $ensures expr ;
|
|---|
| 291 | {
|
|---|
| 292 | ...
|
|---|
| 293 | }
|
|---|
| 294 |
|
|---|
| 295 | The value $result may be used in post-conditions to refer
|
|---|
| 296 | to the result returned by a procedure.
|
|---|
| 297 |
|
|---|
| 298 | ------------------------------------------------------------------------
|
|---|
| 299 |
|
|---|
| 300 | expr@x: remote expressions refer to a variable in another process,
|
|---|
| 301 | e.g., procs[i]@x. This special kind of expression is used in
|
|---|
| 302 | collective expressions, which are used to formulate collective
|
|---|
| 303 | assertions and invariants.
|
|---|
| 304 |
|
|---|
| 305 | The expr must have $proc type. The variable x must be a statically
|
|---|
| 306 | visible variable in the context in which it is occurs. When
|
|---|
| 307 | this expression is evaluated, the evaluation context will be shifted
|
|---|
| 308 | to the process referred to by the expr.
|
|---|
| 309 |
|
|---|
| 310 | ------------------------------------------------------------------------
|
|---|
| 311 |
|
|---|
| 312 | $collective(proc_expr, int_expr) expr
|
|---|
| 313 |
|
|---|
| 314 | This is a collective expression over a set of processes. The
|
|---|
| 315 | proc_expr is a pointer to the first element of an array of $proc. The
|
|---|
| 316 | int_expr gives the length of that array, i.e., the number of
|
|---|
| 317 | processes. expr is a boolean-valued expression; it may use remote
|
|---|
| 318 | expressions to refer to variables in the processes specified in the
|
|---|
| 319 | array.
|
|---|
| 320 |
|
|---|
| 321 | example:
|
|---|
| 322 |
|
|---|
| 323 | $proc procs[N];
|
|---|
| 324 | ...
|
|---|
| 325 | $assert $collective(procs, N) i==procs[(pid+1)%N]@i ;
|
|---|
| 326 |
|
|---|