Skip to content

Commit ae9cdcb

Browse files
authored
Update termination.md (#21)
- Removed imports of well-founded orders - Added naming convention for domains for custom well-founded orders - Added example showing that ADTs can be used as termination measures
1 parent 550e3e2 commit ae9cdcb

4 files changed

Lines changed: 19 additions & 5 deletions

File tree

src/termination-custom-orders.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ v1 <_ v2 <==> decreasing(v1, v2) && bounded(v2)
4141
The necessary properties of `decreasing` and `bounded` for values of type `T` can be defined via axioms. For the `MyInt` type from before, suitable axioms would be:
4242

4343
```viper
44+
import <decreases/declaration.vpr>
45+
4446
domain MyIntWellFoundedOrder {
4547
axiom {
4648
forall i1: MyInt, i2: MyInt :: {decreasing(i1, i2)}
@@ -55,7 +57,8 @@ domain MyIntWellFoundedOrder {
5557

5658
> **Note**
5759
>
58-
> The functions `decreasing` and `bounded` must be declared by the Viper program to verify, which is easiest done by importing `decreases/declaration.vpr`. This is also what the predefined orders, e.g., `decreases/int.vpr`, do.
60+
> The functions `decreasing` and `bounded` must be declared by the Viper program to verify, which is easiest done by importing `decreases/declaration.vpr`, as shown in the example. This is also what the predefined orders do.
61+
> Viper uses a naming convention where the well-founded order for type `T` should be defined in a domain called `TWellFoundedOrder`; giving it a different name will result in a warning.
5962
6063
> **Exercise**
6164
> * Change the `factorial` function in the program above such that parameter `m` is used as its termination measure. The termination check should then fail because no well-founded order for `MyInt` has been defined.

src/termination-measures.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,22 @@ function length(this: Ref): Int
6161
>
6262
> Change the body of `length` to just the recursive call `length(this)`. Which error message do you expect?
6363
64+
Additionally, Viper's ADT plugin automatically generated well-founded orders for any ADT defined in the program. Thus, ADT values can also be used as termination measures:
65+
66+
```silver-runnable
67+
adt List[T] {
68+
Nil()
69+
Cons(hd: T, tl: List[T])
70+
}
71+
72+
function llen(l: List[Int]): Int
73+
decreases l
74+
{
75+
l.isNil ? 0 : 1 + llen(l.tl)
76+
}
77+
```
78+
6479
Final remarks:
6580

6681
* Note that `PredicateInstance` is an internal Viper type, and currently supported only in decreases tuples. The `nested` function is also internal and cannot be used by users.
67-
* For simplicity, all standard well-founded orders can be imported via `decreases/all.vpr`.
6882
* Users can also define [custom well-founded orders](./termination-custom-orders.md).

src/termination-mutual-recursion.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,4 @@ function fun2(x: Int): Int
4242
At indirectly recursive calls, two decreases tuples are compared by lexicographical order of their longest commonly typed prefix (as does, e.g., Dafny). E.g., for the indirectly recursive call `fun2(y-1)` in function `fun1`, Viper verifies that `y-1 <_ y`, while for the recursive call `fun1(y, false)`, it verifies that `y <_ y || (y == y && false <_ b)`.
4343

4444
> **Exercise**
45-
> * Comment the import of `bool.vpr`, and reverify the program. Can you explain the resulting verification error?
4645
> * In the above example, change the call `fun1(x-1, true)` to `fun1(x, true)` -- the program still verifies. That's because Viper appends a `Top` element (an internal value of any type, larger than any other value) to each tuple, a neat trick also implemented by, e.g., Dafny and F*. Can you explain how this helps with checking termination of the call `fun1(x, true)`?

src/termination-syntax.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,3 @@ For the first recursive call `ack(m - 1, 1)`, and the second (outer) recursive c
3232
> **Exercise**
3333
>
3434
> Swap the tuple elements, i.e., change the decreases clause to `n, m`. For which of the recursive calls do you expect error messages?
35-
36-
The well-founded order over tuples need not be imported (and cannot be customised). However, the well-founded orders of the types appearing in the tuple must be.

0 commit comments

Comments
 (0)