diff --git a/05-control-flow/README.md b/05-control-flow/README.md index 47480a6..b103a1c 100644 --- a/05-control-flow/README.md +++ b/05-control-flow/README.md @@ -108,7 +108,7 @@ claim STORE => STORE [ $a <- A ] [ $b <- B ] [ $c <- ?C:Int ] ensures A <=Int ?C andBool - B <=Int ?C + B <=Int ?C ``` introduces two symbolic integers, `A` and `B`, and states that after the execution of the given program, the store will have been updated so that the value of `$a` equals `A`, the value of `$b` equals `B`, and the value of `$c` equals *some* symbolic integer `?C` such that `A <= C` and `B <= C`. More precisely, for symbolic variables, the notation `?` denotes *existential quantification*, whereas the absence of `?` (for example, the way `A` and `B` are introduced) denotes *universal quantification*. The `ensures` clause corresponds to a post-condition of sorts, stating conditions that must hold after the execution. The last claim states precisely what the value of `?C` is, replacing it with the function `maxInt(A, B)`, defined in the `VERIFICATION` module as the greater of the two parameters. diff --git a/06-procedures/README.md b/06-procedures/README.md index 65ece16..1f0a2ed 100644 --- a/06-procedures/README.md +++ b/06-procedures/README.md @@ -85,4 +85,42 @@ Follow the instructions from the top-level [`README`](../README.md) file to comp ## Proving program properties -TODO \ No newline at end of file +For this exercise, we re-use the `while` loop from the [previous exercise](../05-control-flow/README.md), together with its specification, wrap it in a function, then call that function and reason about the obtained result. Using slightly different identifiers and symbolic variables, the specification of the `while` loop is as follows: + +``` +claim + + while ( 0 < NID ) { + SID = SID + NID ; + NID = NID - 1 ; + } + => . ... + + SID |-> (S:Int => S +Int ((N +Int 1) *Int N /Int 2)) + NID |-> (N:Int => 0) + +requires N >=Int 0 +``` + +and the main program, together with its specification, is as follows: + +``` +claim + + def $sum($n, .Ids) { + $s = 0 ; + while (0 < $n) { + $s = $s + $n ; + $n = $n - 1 ; + } + return $s ; + } + $n := $sum(N:Int, .Ints) ; + => . ... + .Map => ?_ + $n |-> (_ => ((N +Int 1) *Int N /Int 2)) + .List + requires N >=Int 0 +``` + +The specification states that this program, which consists of declaring a function `$sum` and then calling it with a non-negative symbolic integer `N`, ends up storing the sum of first `N` integers in the variable `$n`. \ No newline at end of file diff --git a/tests/06-procedures/sum-spec.k b/tests/06-procedures/sum-spec.k index cba250e..4546be7 100644 --- a/tests/06-procedures/sum-spec.k +++ b/tests/06-procedures/sum-spec.k @@ -28,26 +28,26 @@ module SUM-SPEC } => . ... SID |-> (S:Int => S +Int ((N +Int 1) *Int N /Int 2)) - NID |-> (N:Int => 0) + NID |-> (N:Int => 0) requires N >=Int 0 - andBool S >=Int 0 - - claim def $sum($n, .Ids) { - $s = 0 ; - while (0 < $n) { - $s = $s + $n ; - $n = $n - 1 ; - } - return $s ; - } - return $sum(N:Int, .Ints) ; - => return (N +Int 1) *Int N /Int 2 ; - - .Map => ?_ - .Map => ?_ - .List - requires N >=Int 0 + +claim + + def $sum($n, .Ids) { + $s = 0 ; + while (0 < $n) { + $s = $s + $n ; + $n = $n - 1 ; + } + return $s ; + } + $n = $sum(N:Int, .Ints) ; + => . ... + .Map => ?_ + $n |-> (_ => ((N +Int 1) *Int N /Int 2)) + .List + requires N >=Int 0 endmodule