| 492 | | |
| 493 | | There are some limitations. Support for the standard library is only partial. Small bounds will have to be placed on many parameters in order for CIVL verification to terminate (or terminate in a reasonable amount of time). |
| 494 | | |
| 495 | | Another approach for separating the CIVL driver code from the "real" program is to place these in separate translation units. |
| | 496 | Another approach for separating the CIVL driver code from the "real" program is to place these in separate translation units. In the following example, a toy library "sumlib" has been implemented using a header file `sumlib.h` and an implementation `sumlib.c`: |
| | 497 | |
| | 498 | {{{ |
| | 499 | basie:sumlib siegel$ cat sumlib.c |
| | 500 | |
| | 501 | #include "sumlib.h" |
| | 502 | int sum(int n) { |
| | 503 | int result = 0; |
| | 504 | for (int i=1; i<=n; i++) result += i; |
| | 505 | return result; |
| | 506 | } |
| | 507 | }}} |
| | 508 | |
| | 509 | A simple test has been implemented in a separate translation unit named `sumlib_test.c`. The translation units can be compiled, linked, and executed, in the usual way. |
| | 510 | |
| | 511 | {{{ |
| | 512 | basie:sumlib siegel$ cat sumlib_test.c |
| | 513 | |
| | 514 | #include <stdio.h> |
| | 515 | #include <assert.h> |
| | 516 | #include "sumlib.h" |
| | 517 | #define N 100 |
| | 518 | int main() { |
| | 519 | int result = sum(N); |
| | 520 | printf("N=%d, sum = %d\n", N, result); |
| | 521 | assert(result == (N+1)*N/2); |
| | 522 | } |
| | 523 | |
| | 524 | basie:sumlib siegel$ cc sumlib_test.c sumlib.c |
| | 525 | basie:sumlib siegel$ ./a.out |
| | 526 | N=100, sum = 5050 |
| | 527 | }}} |
| | 528 | |
| | 529 | Finally, a CIVL verification driver is provided in another translation unit, `sumlib_driver.cvl`. The CIVL verifier can be applied to the whole program composed of the two translation units `sumlib_driver.cvl` and `sumlib.c`: |
| | 530 | |
| | 531 | {{{ |
| | 532 | basie:sumlib siegel$ cat sumlib_driver.cvl |
| | 533 | |
| | 534 | #include <stdio.h> |
| | 535 | #include "sumlib.h" |
| | 536 | $input int B=5, N; |
| | 537 | $assume(1<=N && N<=B); |
| | 538 | int main() { |
| | 539 | int result = sum(N); |
| | 540 | printf("N=%d, sum = %d\n", N, result); |
| | 541 | $assert(result == (N+1)*N/2); |
| | 542 | } |
| | 543 | |
| | 544 | basie:sumlib siegel$ civl verify sumlib_driver.cvl sumlib.c |
| | 545 | CIVL v1.18+ of 2018-12-28 -- http://vsl.cis.udel.edu/civl |
| | 546 | N=5, sum = 15 |
| | 547 | N=4, sum = 10 |
| | 548 | N=3, sum = 6 |
| | 549 | N=2, sum = 3 |
| | 550 | N=1, sum = 1 |
| | 551 | |
| | 552 | === Source files === |
| | 553 | sumlib_driver.cvl (sumlib_driver.cvl) |
| | 554 | sumlib.h (sumlib.h) |
| | 555 | sumlib.c (sumlib.c) |
| | 556 | |
| | 557 | |
| | 558 | === Command === |
| | 559 | civl verify sumlib_driver.cvl sumlib.c |
| | 560 | |
| | 561 | === Stats === |
| | 562 | time (s) : 2.78 |
| | 563 | memory (bytes) : 163053568 |
| | 564 | max process count : 1 |
| | 565 | states : 47 |
| | 566 | states saved : 32 |
| | 567 | state matches : 0 |
| | 568 | transitions : 46 |
| | 569 | trace steps : 16 |
| | 570 | valid calls : 49 |
| | 571 | provers : cvc4, z3 |
| | 572 | prover calls : 13 |
| | 573 | |
| | 574 | === Result === |
| | 575 | The standard properties hold for all executions. |
| | 576 | }}} |
| | 577 | |
| | 578 | There are limitations to the application of CIVL to C programs. Support for the standard library is only partial. Small bounds will have to be placed on many parameters in order for CIVL verification to terminate (or terminate in a reasonable amount of time). |