Suppose we have a list:
List = nil | Cons(car cdr:List).
Note that I am talking about modifiable lists! And a trivial recursive length function:
recursive Length(List l) = match l with
| nil => 0
| Cons(car cdr) => 1 + Length cdr
end.
Naturally, it terminates only when the list is non-circular:
inductive NonCircular(List l) = {
empty: NonCircular(nil) |
\forall head, tail: NonCircular(tail) => NonCircular (Cons(head tail))
}
Note that this predicate, being implemented as a recursive function, also does not terminate on a circular list.
Usually I see proofs of list traversal termination that use list length as a bounded decreasing factor. They suppose that Length
is non-negative. But, as I see it, this fact (Length l >= 0
) follows from the termination of Length
on the first place.
How do you prove, that the Length
terminates and is non-negative on NonCircular
(or an equivalent, better defined predicate) lists?
Am I missing an important concept here?