| 1 |
|
|---|
| 2 | The CIVL-C code will not have an explicit "Root" procedure. Instead,
|
|---|
| 3 | a Root procedure will be implicitly wrapped around the enitre code.
|
|---|
| 4 | The global input variables will become the inputs to the Root
|
|---|
| 5 | procedure. A "main" procedure must be delcared that takes
|
|---|
| 6 | no parameters but can have any return type. The body of the
|
|---|
| 7 | main procedure becomes the body of the Root procedure. The return
|
|---|
| 8 | type of the main procedure becomes the return type of the body.
|
|---|
| 9 | The main procedure disappears.
|
|---|
| 10 |
|
|---|
| 11 | ------------------------------------------------------------------------
|
|---|
| 12 |
|
|---|
| 13 | Summary of new keywords:
|
|---|
| 14 |
|
|---|
| 15 | $proc : the process type
|
|---|
| 16 | $self : the process invoking the statement (constant of type $proc)
|
|---|
| 17 | $input : type qualifier declaring variable to be a program input
|
|---|
| 18 | $output : type qualifier declaring variable to be a program output
|
|---|
| 19 | $spawn : create a new process running procedure
|
|---|
| 20 | $wait : wait for a process to terminate
|
|---|
| 21 | $assert : check something holds
|
|---|
| 22 | $true : boolean value true, used in assertions
|
|---|
| 23 | $false: boolean value false, used in assertions
|
|---|
| 24 | $assume : assume something holds
|
|---|
| 25 | $when : guarded statement
|
|---|
| 26 | $choose : nondeterministic choice statement
|
|---|
| 27 | $invariant : declare a loop invariant
|
|---|
| 28 | $requires : procedure precondition
|
|---|
| 29 | $ensures : procedure postcondition
|
|---|
| 30 | $result : refers to result returned by procedure in contracts
|
|---|
| 31 | @ : refer to variable in other process, e.g., p@x
|
|---|
| 32 | $collective : a collective expression
|
|---|
| 33 |
|
|---|
| 34 | Other syntactic changes:
|
|---|
| 35 |
|
|---|
| 36 | - procedure definitions may occur in any scope
|
|---|
| 37 |
|
|---|
| 38 | ------------------------------------------------------------------------
|
|---|
| 39 |
|
|---|
| 40 | Detailed description:
|
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 | $proc : this is a primitive object type and functions like any other
|
|---|
| 44 | primitive C type (e.g., int). An object of this type refers
|
|---|
| 45 | to process. It can be thought of as a process ID, but it is not
|
|---|
| 46 | an integer and cannot be cast to one. Certain expressions take
|
|---|
| 47 | an argument of $proc type and some return something of $proc type.
|
|---|
| 48 |
|
|---|
| 49 | ------------------------------------------------------------------------
|
|---|
| 50 |
|
|---|
| 51 | $self: this is a constant of type $proc. It can be used wherever
|
|---|
| 52 | an argument of type $proc is called for. It refers to the process
|
|---|
| 53 | that is evaluating the expression containing "$self".
|
|---|
| 54 |
|
|---|
| 55 | ------------------------------------------------------------------------
|
|---|
| 56 |
|
|---|
| 57 | $input : A variable in the global scope only may be declared with this
|
|---|
| 58 | type modifier indicating it is an "input" variable, as in
|
|---|
| 59 |
|
|---|
| 60 | $input int n;
|
|---|
| 61 |
|
|---|
| 62 | As explained above, the variable becomes a parameter to the Root
|
|---|
| 63 | procedure. This is used when comparing two programs for functional
|
|---|
| 64 | equivalence. The two programs are functionally equivalent if,
|
|---|
| 65 | whenever they are given the same inputs (i.e., corresponding $input
|
|---|
| 66 | variables are initialized with the same values) they will produce the
|
|---|
| 67 | same outputs (i.e., corresponding $output variables will end up with
|
|---|
| 68 | the same values at termination).
|
|---|
| 69 |
|
|---|
| 70 | ------------------------------------------------------------------------
|
|---|
| 71 |
|
|---|
| 72 | $output : A variable in the global scope may be declared with
|
|---|
| 73 | this type modifier to declare it to be an output variable.
|
|---|
| 74 |
|
|---|
| 75 | ------------------------------------------------------------------------
|
|---|
| 76 |
|
|---|
| 77 | $spawn : this is an expression with side-effects. It spawns a new
|
|---|
| 78 | process and returns a reference to the new process, i.e., an object of
|
|---|
| 79 | type $proc. The syntax is the same as a procedure invocation with the
|
|---|
| 80 | keyword "$spawn" inserted in front:
|
|---|
| 81 |
|
|---|
| 82 | $spawn f(expr1, ..., exprn)
|
|---|
| 83 |
|
|---|
| 84 | Typically the returned value is assigned to a variable, e.g.,
|
|---|
| 85 |
|
|---|
| 86 | $proc p = $spawn f(i);
|
|---|
| 87 |
|
|---|
| 88 | If the invoked function f returns a value, that value is simply
|
|---|
| 89 | ignored.
|
|---|
| 90 |
|
|---|
| 91 | ------------------------------------------------------------------------
|
|---|
| 92 |
|
|---|
| 93 | $wait: this is a statement that takes an argument of type $proc
|
|---|
| 94 | and blocks until the referenced process terminates:
|
|---|
| 95 |
|
|---|
| 96 | $wait expr;
|
|---|
| 97 |
|
|---|
| 98 | ------------------------------------------------------------------------
|
|---|
| 99 | $assert: This is an assertion statement. It takes as its sole
|
|---|
| 100 | argument an expression of boolean type. The expressions have a
|
|---|
| 101 | richer syntax than C expressions. During verification, the
|
|---|
| 102 | assertion is checked. If it does not hold, a violation is reported.
|
|---|
| 103 |
|
|---|
| 104 | $assert expr;
|
|---|
| 105 |
|
|---|
| 106 | Boolean values $true and $false may be used in assertions
|
|---|
| 107 | and assumptions.
|
|---|
| 108 |
|
|---|
| 109 | ------------------------------------------------------------------------
|
|---|
| 110 |
|
|---|
| 111 | $assume: This is an assume statement. Its syntax is the same as that
|
|---|
| 112 | of $assert. During verification, the assumed expression is assumed to
|
|---|
| 113 | hold. If this leads to a contradiction on some execution, that
|
|---|
| 114 | execution is simply ignored. It never reports a violation, it only
|
|---|
| 115 | restricts the set of possible executions that will be explored by the
|
|---|
| 116 | verification.
|
|---|
| 117 |
|
|---|
| 118 | $assume expr;
|
|---|
| 119 |
|
|---|
| 120 | ------------------------------------------------------------------------
|
|---|
| 121 |
|
|---|
| 122 | $when (expr) stmt;
|
|---|
| 123 |
|
|---|
| 124 | A guarded command.
|
|---|
| 125 |
|
|---|
| 126 | All statements have a guard, either implicit or explicit. For most
|
|---|
| 127 | statements, the guard is "true". The $when statement allows one to
|
|---|
| 128 | attach an explicit guard to a statement.
|
|---|
| 129 |
|
|---|
| 130 | When expr is true, the statement is enabled, otherwise it is
|
|---|
| 131 | disabled. A disabled statement is "blocked"---it will not be
|
|---|
| 132 | scheduled for execution. When it is enabled, it may execute by moving
|
|---|
| 133 | control to the stmt and executing the first atomic action in the stmt.
|
|---|
| 134 |
|
|---|
| 135 | If stmt itself has a guard, the guard of the $when statement is
|
|---|
| 136 | effectively the conjunction of the expr and the guard of the stmt.
|
|---|
| 137 |
|
|---|
| 138 | The evaluation of expr and the first atomic action of stmt effectively
|
|---|
| 139 | occur as a single atomic action. There is no guarantee that execution
|
|---|
| 140 | of stmt will continue atomically if it contains more than one atomic
|
|---|
| 141 | action, i.e., other processes may be scheduled.
|
|---|
| 142 |
|
|---|
| 143 | Examples:
|
|---|
| 144 |
|
|---|
| 145 | $when (s>0) s--;
|
|---|
| 146 |
|
|---|
| 147 | This will block until s is positive then decrement s. The execution
|
|---|
| 148 | of s-- is guaranteed to take place in an environment in which s is
|
|---|
| 149 | positive.
|
|---|
| 150 |
|
|---|
| 151 | $when (s>0) {s--; t++}
|
|---|
| 152 |
|
|---|
| 153 | The execution of s-- must happen when s>0, but between s-- and t++,
|
|---|
| 154 | other processes may execute.
|
|---|
| 155 |
|
|---|
| 156 | $when (s>0) $when (t>0) x=y*t;
|
|---|
| 157 |
|
|---|
| 158 | This blocks until both x and t are positive then executes
|
|---|
| 159 | the assignment in that state. It is equivalent to
|
|---|
| 160 |
|
|---|
| 161 | $when (s>0 && t>0) x=y*t;
|
|---|
| 162 |
|
|---|
| 163 | ------------------------------------------------------------------------
|
|---|
| 164 |
|
|---|
| 165 | A $choose statement has the form
|
|---|
| 166 |
|
|---|
| 167 | $choose {
|
|---|
| 168 | stmt1;
|
|---|
| 169 | stmt2;
|
|---|
| 170 | ...
|
|---|
| 171 | default: stmt
|
|---|
| 172 | }
|
|---|
| 173 |
|
|---|
| 174 | The "default" clause is optional.
|
|---|
| 175 |
|
|---|
| 176 | The guards of the statements are evaluated and among those that are
|
|---|
| 177 | true, one is chosen nondeterministically and executed. If none are
|
|---|
| 178 | true and the default clause is present, it is chosen. The default
|
|---|
| 179 | clause will only be selected if all guards are false. If no default
|
|---|
| 180 | clause is present and all guards are false, the statement blocks.
|
|---|
| 181 | Hence the implicit guard of the $choose statement without a default
|
|---|
| 182 | clause is the disjunction of the guards of its sub-statements.
|
|---|
| 183 | The implicit guard of the $choose statement with a default clause
|
|---|
| 184 | is "true".
|
|---|
| 185 |
|
|---|
| 186 |
|
|---|
| 187 | Example: this shows how to encode "low-level" CIVL:
|
|---|
| 188 |
|
|---|
| 189 | l1: $choose {
|
|---|
| 190 | $when (x>0) {x--; goto l2;}
|
|---|
| 191 | $when (x==0) {y=1; goto l3;}
|
|---|
| 192 | default: {z=1; goto l4;}
|
|---|
| 193 | }
|
|---|
| 194 | l2: $choose {
|
|---|
| 195 | ...
|
|---|
| 196 | }
|
|---|
| 197 | l3: $choose {
|
|---|
| 198 | ...
|
|---|
| 199 | }
|
|---|
| 200 |
|
|---|
| 201 | ------------------------------------------------------------------------
|
|---|
| 202 |
|
|---|
| 203 | $invariant: indicates a loop invariant. Each C loop construct has an
|
|---|
| 204 | optional invariant clause as follows:
|
|---|
| 205 |
|
|---|
| 206 | while (expr) $invariant (expr) stmt
|
|---|
| 207 |
|
|---|
| 208 | for (e1; e2; e3) $invariant (expr) stmt
|
|---|
| 209 |
|
|---|
| 210 | do stmt while (expr) $invariant (expr) ;
|
|---|
| 211 |
|
|---|
| 212 | The invariant is a claim that if if the expr holds upon entering
|
|---|
| 213 | the loop and the loop condition holds, then it will hold
|
|---|
| 214 | after completion of execution of the loop body.
|
|---|
| 215 |
|
|---|
| 216 | The invariant is used by certain verification techniques.
|
|---|
| 217 |
|
|---|
| 218 | ------------------------------------------------------------------------
|
|---|
| 219 |
|
|---|
| 220 | Procedure contracts: $requires and $ensures. There are optional
|
|---|
| 221 | elements that may occur in a procedure declaration or definition:
|
|---|
| 222 |
|
|---|
| 223 | T f(...)
|
|---|
| 224 | $requires expr;
|
|---|
| 225 | $ensures expr;
|
|---|
| 226 | ;
|
|---|
| 227 |
|
|---|
| 228 | or
|
|---|
| 229 |
|
|---|
| 230 | T f(...)
|
|---|
| 231 | $requires expr ;
|
|---|
| 232 | $ensures expr ;
|
|---|
| 233 | {
|
|---|
| 234 | ...
|
|---|
| 235 | }
|
|---|
| 236 |
|
|---|
| 237 | The value $result may be used in post-conditions to refer
|
|---|
| 238 | to the result returned by a procedure.
|
|---|
| 239 |
|
|---|
| 240 | ------------------------------------------------------------------------
|
|---|
| 241 |
|
|---|
| 242 | expr@x: remote expressions refer to a variable in another process,
|
|---|
| 243 | e.g., procs[i]@x. This special kind of expression is used in
|
|---|
| 244 | collective expressions, which are used to formulate collective
|
|---|
| 245 | assertions and invariants.
|
|---|
| 246 |
|
|---|
| 247 | The expr must have $proc type. The variable x must be a statically
|
|---|
| 248 | visible variable in the context in which it is occurs. When
|
|---|
| 249 | this expression is evaluated, the evaluation context will be shifted
|
|---|
| 250 | to the process referred to by the expr.
|
|---|
| 251 |
|
|---|
| 252 | ------------------------------------------------------------------------
|
|---|
| 253 |
|
|---|
| 254 | $collective(proc_expr, int_expr) expr
|
|---|
| 255 |
|
|---|
| 256 | This is a collective expression over a set of processes. The
|
|---|
| 257 | proc_expr is a pointer to the first element of an array of $proc. The
|
|---|
| 258 | int_expr gives the length of that array, i.e., the number of
|
|---|
| 259 | processes. expr is a boolean-valued expression; it may use remote
|
|---|
| 260 | expressions to refer to variables in the processes specified in the
|
|---|
| 261 | array.
|
|---|
| 262 |
|
|---|
| 263 | example:
|
|---|
| 264 |
|
|---|
| 265 | $proc procs[N];
|
|---|
| 266 | ...
|
|---|
| 267 | $assert $collective(procs, N) i==procs[(pid+1)%N]@i ;
|
|---|
| 268 |
|
|---|
| 269 | ------------------------------------------------------------------------
|
|---|
| 270 |
|
|---|
| 271 |
|
|---|
| 272 |
|
|---|
| 273 | Arrays.......
|
|---|
| 274 |
|
|---|
| 275 |
|
|---|
| 276 | Type: array of T
|
|---|
| 277 |
|
|---|
| 278 | expression: newArray(int n);
|
|---|
| 279 |
|
|---|
| 280 | double a[][N][]; translates to:
|
|---|
| 281 |
|
|---|
| 282 | a : array of array of array of double
|
|---|
| 283 |
|
|---|
| 284 | needs to be a type.
|
|---|
| 285 |
|
|---|
| 286 | static type: Array(T, expr) = array of T of length expr;
|
|---|
| 287 |
|
|---|
| 288 | not used for type checking but imposes some additional information
|
|---|
| 289 | or restriction on the values that a may hold. kind of initializes a
|
|---|
| 290 | .
|
|---|
| 291 |
|
|---|
| 292 | double a[][N]; array of (array of double of len N)
|
|---|
| 293 | double b[N][]; array of (array of double) of len N
|
|---|
| 294 |
|
|---|
| 295 |
|
|---|
| 296 | decls:
|
|---|
| 297 | we want to allow a[] to allow sequences of any sides
|
|---|
| 298 |
|
|---|
| 299 | difference between restricting type and allocating memory
|
|---|
| 300 |
|
|---|
| 301 | how to initialize: need expression newArray(T, n).
|
|---|
| 302 |
|
|---|
| 303 |
|
|---|
| 304 |
|
|---|
| 305 | Translation:
|
|---|
| 306 |
|
|---|
| 307 | ordinary variable decl:
|
|---|
| 308 | if initializer is present: use initializer expr to allocate.
|
|---|
| 309 | if initializer not present: type must be complete.
|
|---|
| 310 | example:
|
|---|
| 311 | formal parameter:
|
|---|
| 312 | field:
|
|---|