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