|
2 | 2 | a good way to state complex properties that will allow the proof process |
3 | 3 | to be more efficient by abstracting their complexity. Of course, as any |
4 | 4 | property expressed as an axiom is assumed to be true, we have to be very |
5 | | -careful when we use them to defined properties: if we introduce a false |
| 5 | +careful when we use them to define properties: if we introduce a false |
6 | 6 | property in our assumptions, ``false'' becomes ``true'' and we can then |
7 | 7 | prove anything. |
8 | 8 |
|
|
26 | 26 | axiom other_axiom_name { Label0, ..., LabelM }: |
27 | 27 | // property ; |
28 | 28 |
|
29 | | - // ... we can put as many axioms we need |
| 29 | + // ... we can put as many axioms as we need |
30 | 30 | } |
31 | 31 | */ |
32 | 32 | \end{CodeBlock} |
|
63 | 63 |
|
64 | 64 |
|
65 | 65 |
|
66 | | -Lemmas and axioms allows to express the same kinds of properties. |
67 | | -Namely, properties expressed about quantified variables (and possibly |
68 | | -global variables, but it is quite rare since it is often difficult to |
| 66 | +Lemmas and axioms allows us to express the same kinds of properties. |
| 67 | +Namely, they express properties about quantified variables (and possibly |
| 68 | +global variables, but this is quite rare since it is often difficult to |
69 | 69 | find a global property about such variables being both true and |
70 | | -interesting). Apart this first common point, we can also notice that |
| 70 | +interesting). In addition to this first common point, we can also notice that |
71 | 71 | when we are not considering the definition of the lemma itself, lemmas |
72 | 72 | are assumed to be true by WP exactly as axioms are. |
73 | 73 |
|
|
89 | 89 |
|
90 | 90 |
|
91 | 91 |
|
92 | | -The idea is then not to define directly the function or the predicate |
93 | | -but to declare it and then to define axioms that specify its |
| 92 | +The idea is to avoid defining the function or the predicate |
| 93 | +directly; instead we should declare it and then define axioms that specify its |
94 | 94 | behavior. If we come back to the factorial function, we can define it |
95 | 95 | axiomatically as follows: |
96 | 96 |
|
|
114 | 114 |
|
115 | 115 | In this axiomatic definition, our function does not have a body. Its |
116 | 116 | behavior is only defined by the axioms we have stated about it. |
117 | | -Except this, nothing changes, in particular the logic function can |
| 117 | +Apart from this, nothing changes, in particular the logic function can |
118 | 118 | be used in our specification just as before. |
119 | 119 |
|
120 | 120 |
|
121 | 121 |
|
122 | 122 | A small subtlety that we must take care of is the fact that if some |
123 | | -axioms state properties about the content of some pointed memory cells, |
124 | | -we have to specify considered memory blocks using the \CodeInline{reads} |
| 123 | +axioms state properties about the content of some pointed-to memory cells, |
| 124 | +we have to specify the memory blocks under consideration using the \CodeInline{reads} |
125 | 125 | notation in the declaration. If we omit such a specification, the |
126 | 126 | predicate or function will be considered to be stated about the received |
127 | 127 | pointers and not about pointer memory blocks. So, if the code modifies |
128 | | -the content of an array for which we had proven that the predicate or |
| 128 | +the contents of an array for which we had proven that the predicate or |
129 | 129 | function gives some result, this result will not be considered to be |
130 | 130 | potentially different. |
131 | 131 |
|
|
144 | 144 | Notice the \CodeInline{reads[b .. e-1]} that specifies the memory location |
145 | 145 | on which the predicate depends. While it is not necessary to specify what are |
146 | 146 | the memory locations read in an inductive definition, we have to specify such |
147 | | -an information for axiomatically defined properties. |
| 147 | +information for axiomatically-defined properties. |
148 | 148 |
|
149 | 149 |
|
150 | 150 | \levelThreeTitle{Consistency} |
151 | 151 |
|
152 | 152 |
|
153 | 153 | By adding axioms to our knowledge base, we can produce more complex |
154 | | -proofs since some part of these proofs, expressed by axioms, do not need |
| 154 | +proofs since some parts of these proofs, expressed by axioms, do not need |
155 | 155 | to be proved (they are already specified to be true) shortening |
156 | 156 | the proof process. However, using axiomatic definitions, \textbf{we must |
157 | 157 | be extremely careful}. Indeed, even a small error could introduce false |
158 | | -in the knowledge base, making our whole reasoning futile. Our reasoning |
| 158 | +into the knowledge base, making our whole reasoning futile. Our reasoning |
159 | 159 | would still be correct, but relying on false knowledge, it would only |
160 | 160 | learn incorrect things. |
161 | 161 |
|
|
169 | 169 |
|
170 | 170 |
|
171 | 171 |
|
172 | | -And everything is proved, comprising the fact that the dereferencing of |
| 172 | +And everything is proved, including the fact that the dereferencing of |
173 | 173 | 0 is valid: |
174 | 174 |
|
175 | 175 |
|
|
180 | 180 | Of course, this example is extreme, we would not write such an axiom. |
181 | 181 | The problem is in fact that it is really easy to write an axiomatic |
182 | 182 | definition that is subtly false when we express more complex properties, |
183 | | -or adding assumptions about the global state of the system. |
| 183 | +or add assumptions about the global state of the system. |
184 | 184 |
|
185 | 185 |
|
186 | 186 |
|
|
190 | 190 |
|
191 | 191 | When we start to create axiomatic definitions, it is worth adding |
192 | 192 | assertions or postconditions requiring a proof of false that we expect |
193 | | -to fail to ensure that the definition is not inconsistent. However, it |
194 | | -is often not enough! If the subtlety that creates the inconsistency is |
| 193 | +to fail to ensure that the definition is not inconsistent. However, |
| 194 | +this is often not enough! If the subtlety that creates the inconsistency is |
195 | 195 | hard enough to find, provers could need a lot of information other than |
196 | 196 | the axiomatic definition itself to be able to find and use the |
197 | | -inconsistency, we then need to always be careful! |
| 197 | +inconsistency, so we need to always be careful! |
198 | 198 |
|
199 | 199 |
|
200 | 200 |
|
|
223 | 223 |
|
224 | 224 | Note that unlike inductive definitions, where Why3 provides us a way to control |
225 | 225 | that what we write in ACSL is relatively well-defined, we do not have such a |
226 | | -mechanism for axiomatic definitions. Basically, even with Why3 such a definition |
| 226 | +mechanism for axiomatic definitions. Basically, even with Why3, such a definition |
227 | 227 | is translated into a list of axioms that are thus assumed. |
228 | 228 |
|
229 | 229 |
|
230 | 230 | \levelThreeTitle{Cluster of axiomatic blocks} |
231 | 231 |
|
232 | 232 |
|
233 | 233 | Most global annotations (logic functions, predicates, lemmas, ...) can be |
234 | | -defined at two different levels: either at top-level, the level of the |
| 234 | +defined at two different levels: either at the top-level, i.e., the level of the |
235 | 235 | functions, global variables, etc. (except for axioms and abstract functions and |
236 | | -predicates) or in axiomatic blocks. While top-level global annotations (in |
| 236 | +predicates); or in axiomatic blocks. While top-level global annotations (in |
237 | 237 | particular lemmas) are always embedded in the context of verification |
238 | | -conditions, it is not the case for the annotations in axiomatic blocks. |
| 238 | +conditions, this is not the case for the annotations in axiomatic blocks. |
239 | 239 |
|
240 | 240 |
|
241 | 241 | In the following example: |
|
246 | 246 |
|
247 | 247 | Since the \CodeInline{ensures} clause only uses \CodeInline{P} which is defined |
248 | 248 | in the axiomatic block \CodeInline{X}, WP only loads the axiom \CodeInline{x}. |
249 | | -On the opposite, if we replace \CodeInline{P(p)} with \CodeInline{Q(p)} in the |
| 249 | +On the other hand, if we replace \CodeInline{P(p)} with \CodeInline{Q(p)} in the |
250 | 250 | \CodeInline{ensures} clause, WP loads the axiomatic block \CodeInline{Y}, thus |
251 | 251 | the axiom \CodeInline{y} that uses \CodeInline{P}. Consequently, the axiomatic |
252 | 252 | block \CodeInline{X} is loaded too. The transitive closure of the loaded |
253 | 253 | axiomatic blocks forms a cluster of axiomatic definitions. |
254 | 254 |
|
255 | 255 |
|
256 | 256 | One can use this behavior to avoid providing too many lemmas and axioms to SMT |
257 | | -solvers. This can improve proof performances in some situations. We will present |
258 | | -more details about how to guide proof using lemmas in |
| 257 | +solvers. This can improve proof performance in some situations. We will present |
| 258 | +more details about how to guide proofs using lemmas in |
259 | 259 | Section~\ref{l2:proof-methodologies-triggering-lemmas}. |
260 | 260 |
|
261 | 261 |
|
|
317 | 317 | manually proved lemmas, we can often add useful tools to provers to |
318 | 318 | manipulate more efficiently our axiomatic definitions, without directly |
319 | 319 | adding new axioms that would augment the chances to introduce errors. |
320 | | -Here, we still have to realize the proof of the lemma to get a complete |
| 320 | +Here, we still have to carry out the proof of the lemma to get a complete |
321 | 321 | proof. |
322 | 322 |
|
323 | 323 |
|
|
344 | 344 |
|
345 | 345 |
|
346 | 346 | Basically, we want to receive a valid string in input, and we want to |
347 | | -compute a value that equals to the result of our logic function |
| 347 | +compute a value that is equal to the result of our logic function |
348 | 348 | \CodeInline{strlen} applied to this string, of course this function |
349 | 349 | does not assign anything. Defining what is a valid string is not that |
350 | 350 | simple. Indeed, previously in this tutorial, we only worked with |
351 | | -arrays, receiving in input both the array and the size of the array, |
352 | | -however here, and as it is common in C, we suppose that the string ends |
353 | | -with a character \CodeInline{'\textbackslash{}0'}. That means that we |
| 351 | +arrays, receiving as input both the array and the size of the array, |
| 352 | +however here, as is common in C, we suppose that the string ends |
| 353 | +with the character \CodeInline{'\textbackslash{}0'}. That means that we |
354 | 354 | basically need the \CodeInline{strlen} function to define what is a |
355 | 355 | valid string. Let us first use this definition (note that we use the |
356 | 356 | \CodeInline{\textbackslash{}valid\_read} variant of pointer validity |
|
375 | 375 |
|
376 | 376 | Thus, let us define this function axiomatically. First, let us define what |
377 | 377 | is read by the function, which is: any memory cell from the pointer to an |
378 | | -infinite range of address. Then we consider two cases: the string is |
379 | | -finite, or it is not, that leads to two axioms: \CodeInline{strlen} returns |
| 378 | +infinite range of addresses. Then we consider two cases: the string is |
| 379 | +finite, or it is not, which leads to two axioms: \CodeInline{strlen} returns |
380 | 380 | a positive value that corresponds to the index of the first |
381 | 381 | \CodeInline{'\textbackslash{}0'} character, and returns a negative value if |
382 | | -no such value exists. |
| 382 | +no such character exists. |
383 | 383 |
|
384 | 384 |
|
385 | 385 |
|
|
389 | 389 |
|
390 | 390 | And now, we can be more precise for our definition of |
391 | 391 | \CodeInline{\textbackslash{}valid\_read\_string}, a valid string is a |
392 | | -string such that it is valid from the first index to \CodeInline{strlen} |
393 | | -of the string and, such that this value is greater than 0 (since an |
| 392 | +string that is valid from the first index to \CodeInline{strlen} |
| 393 | +of the string, and whose value is nonnegative (since an |
394 | 394 | infinite string is not a valid string): |
395 | 395 |
|
396 | 396 |
|
|
402 | 402 |
|
403 | 403 |
|
404 | 404 | With this definition we can now go further and provide a suitable |
405 | | -invariant to the loop of the \CodeInline{strlen} function. It is quite |
406 | | -simple: \CodeInline{i} ranges between 0 and \CodeInline{strlen(s)}, for |
407 | | -all values met before the iteration \CodeInline{i}, they are not |
| 405 | +invariant for the loop of the \CodeInline{strlen} function. This loop invariant is quite |
| 406 | +simple: \CodeInline{i} ranges between 0 and \CodeInline{strlen(s)}, and for |
| 407 | +all values met before iteration \CodeInline{i}, they are not |
408 | 408 | \CodeInline{'\textbackslash{}0'}. This loop assigns \CodeInline{i} and |
409 | 409 | the variant corresponds to the distance between \CodeInline{i} and |
410 | 410 | \CodeInline{strlen(s)}. However, if we try to produce the proof of |
411 | 411 | correctness of the function, it fails. And to get more information |
412 | | -we can try a verification asking RTE with the verification that unsigned |
| 412 | +we can try a verification asking RTE to verify that unsigned |
413 | 413 | integers do not overflow: |
414 | 414 |
|
415 | 415 |
|
|
429 | 429 |
|
430 | 430 |
|
431 | 431 |
|
432 | | -However, it is not enough, and the reason is that while we have defined |
433 | | -that the value of \CodeInline{strlen(s)} is defined to be the index of |
| 432 | +However, this is not enough, and the reason is that while we have defined |
| 433 | +the value of \CodeInline{strlen(s)} to be the index of |
434 | 434 | the first \CodeInline{'\textbackslash{}0'} in the array, the converse is |
435 | 435 | not true: knowing that the value of \CodeInline{strlen(s)} is positive |
436 | 436 | is not enough to deduce that the value at the corresponding index is |
437 | 437 | \CodeInline{'\textbackslash{}0'}. Thus, we extend the axiomatic definition |
438 | 438 | with another proposition that gives us this fact (we also add one for the |
439 | | -values that precede the \CodeInline{strlen(s)} index even if here, it is |
| 439 | +values that precede the \CodeInline{strlen(s)} index, even if this is |
440 | 440 | not necessary): |
441 | 441 |
|
442 | 442 |
|
|
450 | 450 | library headers, and they include an |
451 | 451 | axiomatic definition for the \CodeInline{strlen} logic function. It can |
452 | 452 | be found in the installation directory of Frama-C, under the directory |
453 | | -\CodeInline{libc}, the file is named \CodeInline{\_\_fc\_string\_axiomatic.h}. |
454 | | -Note that this definition include more axioms in order to be able to |
| 453 | +\CodeInline{share/libc}, the file is named \CodeInline{\_\_fc\_string\_axiomatic.h}. |
| 454 | +Note that this definition includes more axioms in order to be able to |
455 | 455 | deduce more properties about \CodeInline{strlen}. |
456 | 456 |
|
457 | 457 |
|
|
469 | 469 | \CodeBlockInput[18][30]{c}{ex-1-occurrences_of.c} |
470 | 470 |
|
471 | 471 |
|
472 | | -Re-express the axiomatic definition in a form that allows to prove the |
| 472 | +Re-express the axiomatic definition in a form that allows you to prove the |
473 | 473 | program. |
474 | 474 |
|
475 | 475 |
|
476 | 476 | \levelFourTitle{Greatest Common Divisor} |
477 | 477 |
|
478 | 478 |
|
479 | | -Express the logic function that allows to compute the greatest common divisor as |
480 | | -an axiomatic definition, write the contract of the \CodeInline{gcd} function and |
| 479 | +Express the logic function that allows you to compute the greatest common divisor as |
| 480 | +an axiomatic definition. Write the contract of the \CodeInline{gcd} function and |
481 | 481 | prove it: |
482 | 482 |
|
483 | 483 |
|
|
487 | 487 | \levelFourTitle{Sum of the N first integers} |
488 | 488 |
|
489 | 489 |
|
490 | | -Express the logic function that allows to compute the sum of the N first |
| 490 | +Express the logic function that allows you to compute the sum of the N first |
491 | 491 | integers as an axiomatic definition. Write the contract of the following |
492 | 492 | \CodeInline{sum\_n} function and prove it: |
493 | 493 |
|
|
498 | 498 | \levelFourTitle{Permutation} |
499 | 499 |
|
500 | 500 |
|
501 | | -Take back the example about selection sort |
| 501 | +Let's take another look at the example about selection sort |
502 | 502 | (section~\ref{l3:acsl-logic-definitions-inductive-sort}). Re-express the |
503 | 503 | permutation predicate using an axiomatic definition. Take care of the |
504 | 504 | \CodeInline{reads} clause (in particular, note that the predicate relates |
|
0 commit comments