Changes between Version 28 and Version 29 of Fundamentals


Ignore:
Timestamp:
05/16/23 22:57:46 (3 years ago)
Author:
siegel
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Fundamentals

    v28 v29  
    5656As usual, a translation unit consists of a sequence of variable declarations, function prototypes, and function definitions in file scope. In addition, assume statements may occur in the file scope.  These are used to state assumptions on the input values to a program.
    5757
    58 
    59 == Qualifiers
    60 
    61 === The `$input` and  `$output` type qualifiers
    62 
    63 The declaration of a variable in the root scope may include the type qualifier `$input`, e.g.,
    64 {{{
    65 $input int N;
    66 }}}
    67 This declares the variable to be an input variable, i.e., one which is considered to be an input to the program.
    68 Such a variable is initialized with an arbitrary (unconstrained) value of its type.
    69 When using symbolic execution to verify a program, such a variable will be assigned a unique symbolic constant of its type.
    70 In contrast, variables in the root scope which are not input variables will instead be initialized with the “undefined” value.
    71 Reading an undefined value is erroneous. [Note: the model checker attempts to catch such errors but currently
    72 does not do so for arrays, which are always initialized with unconstrained values.]
    73 In addition, input variables may only be read, never written to; an attempt to write to an input variable is also flagged as an error.
    74 
    75 Alternatively, it is possible to specify a particular concrete value for an input variable, either on the command line, e.g.,
    76 {{{
    77 civl verify -inputN=8 ...
    78 }}}
    79 or by including an initializer in the declaration, e.g.
    80 {{{
    81 $input int N=8;
    82 }}}
    83 The protocol for initializing an input variable is the following: if a command line value is specified, it is used.
    84 Otherwise, if an initializer is present, it is used.   Otherwise, the variable is assigned an arbitrary value of its type.
    85 
    86 A variable in the root scope may be declared with `$output` to declare it to be an output variable.
    87 Output variables may only be written to, never read.
    88 They are used primarily in functional equivalence checking.
    89 
    90 Input and output variables play a key role when determining whether two programs are functionally equivalent.
    91 Two programs are considered functionally equivalent if, whenever they are given the same inputs (i.e., corresponding $input
    92 variables are initialized with the same values) they will produce the same outputs (i.e., corresponding $output variables will
    93 end up with the same values at termination).
    94 
    95 === `$abstract`
    96 
    97 An abstract function declares a function without a body.  An abstract function is declared using a standard function prototype with the function qualifier `$abstract`, e.g.,
    98 {{{
    99   $abstract int f(int x);
    100 }}}
    101 An abstract function must have a non-void return type and take at least one parameter.   An invocation of an abstract function is an expression and can be used anywhere an expression is allowed.  The interpretation is an "uninterpreted function".    A unique symbolic constant of function type will be created, corresponding to the abstract function, and invocations are represented as applications of the uninterpreted function to the arguments. 
    102 
    103 === `$atomic_f`
    104 
    105 A function is declared atomic using the function qualifier `$atomic_f`, e.g.,
    106 {{{
    107 $atomic_f int f(int x) {
    108   ...
    109 }
    110 }}}
    111 A call to such a function executes as a single atomic step, i.e., without interleaving from other processes.   Hence, this is only relevant for concurrent programs.  Declaring a function to be atomic is almost equivalent to placing `$atomic{ ... }` around the function body.   The difference is that in the latter case, the call to the function and the execution of the body are executed in two atomic steps, i.e., after activation frame is pushed onto the call stack, another process could execute before the first process obtains the atomic lock and executes its body.   For an atomic function, the entire sequence of events happens in one atomic step.
    112 
    113 An atomic function must have a definition; in particular, neither a system function nor an abstract function may be declared using `$atomic_f`.
    114 
    115 === `$system`
    116 
    117 A system function is one in which the definition of the function is not provided in CIVL-C code, but is implemented instead in a certain Java class.  A system function is declared by adding the function qualifier `$system` to a function prototype.  Invocation of a system function always takes place in a single atomic step.
    118 
    119 A system function may have a guard, which is specified in the function contract using a `$executes_when` clause.  Unless constrained by its contract or other qualifiers, a system function may modify the stay in an arbitrary way.
    120 
    121 === `$pure`
    122 
    123 A system or atomic function may be declared to be `$pure`, e.g.,
    124 {{{
    125 $pure $system double sin(double x);
    126 $pure $atomic_f double mysin(double x) {
    127   return  x - x*x*x/6.;
    128 }
    129 }}}
    130 This means that the function is a mathematical function of its arguments only.    I.e., an invocation of the function has no side-effects and the return value depends on the arguments only (if called twice with the same arguments, it will return the same value, regardless of any differences in the state).   The user is responsible for ensuring that a function declared pure actually is pure.    If this is not the case, the model checker may produce incorrect results.
    131 
    132 == Types
    133 
    134 === The Boolean type
    135 
    136 The boolean type is denoted `_Bool`, as in C. Its values are 0 and 1, which are also denoted by `$false` and `$true`, respectively.
    137 
    138 === The integer type
    139 
    140 There is one integer type, corresponding to the mathematical integers. Currently, all of the C integer types `int`, `long`, `unsigned int`, `short`, etc., are mapped to the CIVL integer type.   [This is expected to change.]
    141 
    142 === The real type
    143 
    144 There is one real type, corresponding to the mathematical real numbers. Currently, all of the C real types `double`, `float`, etc., are mapped to the CIVL real type. [This is expected to change.]
    145 
    146 === The process type `$proc`
    147 
    148 This is a primitive object type and functions like any other primitive C type (e.g., `int`). An object of this type refers to a process. It can be thought of as a process ID, but it is not an integer and cannot be cast to one.  Certain expressions take an argument of `$proc` type and some return something of `$proc` type. The operators `==` and `!=` may be used with two arguments of type `$proc` to determine whether the two arguments refer to the same process.  The constant `$self` has `$proc` type and refers to the process evaluating this expression;  constant `$proc_null` has `$proc` type and refers to no process.
    149 
    150 === The scope type `$scope`
    151 
    152 An object of this type is a reference to a dynamic scope.
    153 Several constants, expressions, and functions dealing with the $scope type are also provided.
    154 The `$scope` type is like any other object type.
    155 It may be used as the element type of an array, a field in a structure or union, and so on.
    156 Expressions of type `$scope` may occur on the left or right-hand sides of assignments and as arguments in function calls just like any other expression.
    157 Two different variables of type `$scope` may be aliased, i.e., they may refer to the same dynamic scope.
    158 
    159 === Domain types: `$domain` and `$domain(n)`
    160 
    161 A domain type is used to represent a set of tuples of integer values.
    162 Every tuple in a domain object has the same arity (i.e., number of components).
    163 The arity must be at least 1, and is called the dimension of the domain object.
    164 For each integer constant expression n, there is a type `$domain(n)`, representing domains of dimension n.
    165 The universal domain type, denoted `$domain`, represents domains of all positive dimensions, i.e., it is the union over all n ≥ 1 of `$domain(n)`.
    166 In particular, each `$domain(n)` is a subtype of `$domain`.
    167 There are expressions for specifying domain values.
    168 Certain statements use domains, such as the “CIVL-for” loop `$for`.
    169 
    170 === The range type `$range`
    171 
    172 An object of this type represents an ordered set of integers.
    173 Ranges are typically used as a step in constructing domains.
    174 They can also be used in quantified expressions to specify the domain of a bound variable (see `$forall` and `$exists`).
    175 
    176 == Expressions
    177 
    178 === Boolean expressions
    179 
    180 CIVL-C provides the boolean constants`$true` and `$false`, which are simply defined as 1 and 0, respectively.
    181 CIVL-C is, after all, an extension of C.
    182 A program may also include the standard C library header file `stdbool.h`, which defines `true` and `false` in the exact same way.
    183 
    184 In addition to the standard logical operators `&&`, `||`, and `!`, CIVL-C provides `=>` (implies).
    185 `p => q` is equivalent to `!(p) || q` (and has the same short-circuit semantics).
    186 
    187 A universally quantified formula has the form
    188 
    189   `$forall` `(` ''variable-decls'' (`;` ''variable-decls'' )* (`|` ''restriction'')? `)` ''expr''
    190 
    191 where ''variable-decls'' has one of the forms
    192 
    193   ''type'' ''identifier'' (`,` ''identifier'')*
    194 
    195   ''type'' ''identifier'' `:` ''range''
    196 
    197 where ''type'' is a type name (e.g., `int` or `double`), ''identifier'' is the name of the bound variable,
    198 ''restriction'' is a formula (boolean expression) which expresses some restriction on the values that the bound variable can take,
    199 ''range'' is an expression of `$range` type, and ''expr'' is a formula.
    200 The universally quantified formula holds iff for all values assignable to the bound variable for which the restriction holds, the formula expr holds.
    201 
    202 The syntax for existential quantification is the same, with `$exists` in place of `$forall`. 
    203 
    204 Examples:
    205 {{{
    206 int a[3], b[3][2];
    207 int main() {
    208   int n=3, m=2;
    209   $assert($forall (int i | 0<=i && i<n) a[i]==0); // all elements of a are 0
    210   $assert($forall (int i: 0..n-1) a[i]==0); // same as above
    211   $assert($forall (int i: 0..n-1 | i%2==0) a[i]==0); // even elements are 0
    212   $assert($forall (int i: 0..n-1#2) a[i]==0); // same as above
    213   $assert($forall (int i: 0..n-1; int j: 0..m-1) b[i][j]==0); // all elements of b are 0
    214   $assert($forall (int i: 0..n-1; int j | 0<=j && j<m) b[i][j]==0); // same
    215   $assert($forall (int i: 0..n-1; int j: 0..m-1 | i<j ) b[i][j]==0); // lower triangle is 0
    216   $assert($forall (int i,j | 0<=i && i<n && 0<=j && j<m) b[i][j]==0); // all elements of b are 0
    217   $assert($exists (int i | 0<=i && i<n) a[i]==0); // existential: some element of a is 0
    218   $assert($forall (int i: 0..n-1) $exists (int j: 0..i) a[j]<=a[i]); // nested quantification
    219 }
    220 }}}
    221 
    222 === Domain literals
    223 
    224 An expression of the form
    225 
    226   `(``$domain``)`  `{` ''r1'' `,` ... `,` ''rn'' `}`
    227 
    228 where ''r1'', . . . , ''rn'' are ''n'' expressions of type `$range`, is a ''Cartesian domain expression''.
    229 It represents the domain of dimension ''n'' which is the Cartesian product of the ''n'' ranges,
    230 i.e., it consists of all ''n''-tuples (''x1'',...,''xn'') where ''x1'' ∈ ''r1'', ..., ''xn'' ∈ ''rn''.
    231 The order on the domain is the dictionary order on tuples.
    232 The type of this expression is `$domain(n)`.
    233 When a Cartesian domain expression is used to initialize an object of domain type, the `($domain)` may be omitted. For example:
    234 {{{
    235 $domain(3) dom = { 0 .. 3, r2, 10 .. 2 # -2 };
    236 }}}
    237 
    238 
    239 === `$here`
    240 Expression of type `$scope`, evaluating to the dynamic scope in which the evaluation takes place.
    241 
    242 === `$proc_null`
    243 The null process constant.  Similar to the NULL pointer, this gives an object of `$proc` type a defined value, and can be used in `==` and `!=` expressions.  It cannot be used as the argument to `$wait` or `$waitall`.
    244 
    245 === `$root`
    246 Constant of type `$scope`, the root dynamic scope.
    247 
    248 === Range literals
    249 
    250 An expression of the form `lo .. hi` where `lo` and `hi` are integer expressions, represents the range consisting of the integers `lo`, `lo` + 1, ..., `hi` (in that order).
    251 An expression of the form `lo .. hi # step`, where `lo`, `hi`, and `step` are integer expressions is interpreted as follows.
    252 If `step` is positive, it represents the range consisting of `lo`, `lo` + `step`, `lo` + 2 ∗ `step`, …, up to and possibly including `hi`.
    253 To be precise, the infinite sequence is intersected with the set of integers less than or equal to `hi`.
    254 If `step` is negative, the expression represents the range consisting of `hi`, `hi` + `step`, `hi` + 2 ∗ `step`, . . ., down to and possibly including `lo`.
    255 Precisely, the infinite sequence is intersected with the set of integers greater than or equal to `lo`.
    256 
    257 === `$scopeof`
    258 
    259 Given any left-hand-side expression ''expr'', the expression `$scopeof(`''expr''`)` evaluates to the dynamic scope containing the object specified by ''expr''.
    260 The following example illustrates the semantics of the `$scopeof` operator. All of the assertions hold:
    261 {{{
    262 {
    263   $scope s1 = $here;
    264   int x;
    265   double a[10];
    266   {
    267     $scope s2 = $here;
    268     int *p = &x;
    269     double *q = &a[4];
    270     assert($scopeof(x)==s1);
    271     assert($scopeof(p)==s2);
    272     assert($scopeof(*p)==s1);
    273     assert($scopeof(a)==s1);
    274     assert($scopeof(a[5])==s1);
    275     assert($scopeof(q)==s2);
    276     assert($scopeof(*q)==s1);
    277   }
    278 }
    279 }}}
    280 
    281 === Scope relational expressions
    282 
    283 Let `s1` and `s2` be expressions of type `$scope`. The following are all CIVL-C expressions of boolean type:
    284 
    285 * `s1 == s2`. Holds iff `s1` and `s2` refer to the same dynamic scope.
    286 * `s1 != s2`. Holds iff `s1` and `s2` refer to different dynamic scopes.
    287 * `s1 <= s2`. Holds iff `s1` is equal to or a descendant of `s2`, i.e., `s1` is equal to or contained in `s2`.
    288 * `s1 < s2`. Holds iff `s1` is a strict descendant of `s2`, i.e., `s1` is contained in `s2` and is not equal to `s2`.
    289 * `s1 > s2`. Equivalent to `s2 < s1`.
    290 * `s1 >= s2`. Equivalent to `s2 <= s1`.
    291 
    292 Each of these expressions is erroneous if `s1` or `s2` is undefined.  This error is reported by the model checker.
    293 
    294 === `$self`
    295 
    296 This expression of `$proc` type returns a reference to the process which is evaluating this expression.  It provides a way for code to obtain the identity of the process executing the code.
    297 
    298 == Statements
    299 
    300 
    301 === `$atomic`
    302 
    303 === `$choose`
    304 
    305 === `$for`
    306 
    307 === `$parfor`
    308 
    309 === `$spawn`
    310 
    311 === `$when`
    312 
    313 
    314 == Functions
    315 
    316 === `$assert`
    317 
    318 === `$assume`
    319 
    320 === `$assume_push`
    321 
    322 === `$assume_pop`
    323 
    324 === `$choose_int`
    325 
    326 === `$default_value`
    327 
    328 === `$elaborate_domain`
    329 
    330 === `$exit`
    331 
    332 === `$free`
    333 
    334 === `$havoc`
    335 
    336 === `$hidden`
    337 
    338 === `$hide`
    339 
    340 === `$is_derefable`
    341 
    342 === `$is_terminated`
    343 
    344 === `$local_end`
    345 
    346 === `$local_start`
    347 
    348 === `$malloc`
    349 
    350 === `$pathCondition`
    351 
    352 === `$pow`
    353 
    354 `$pow(double, double)`
    355 
    356 === `$reveal`
    357 
    358 === `$wait` and `$waitall`
    359 
    360 === `$yield`
    361 
    362 
    363 == Macros
    364 
    365 
    366 === `$elaborate`
    367 
    368 
    369 
    370 
    371 == Contract Annotations
    372 
    373 clauses
    374 
    375 === The `depends_on` clause
    376 
    377 `\nothing`
    378 
    379 === The `executes_when` clause