 ### verify termination (à la Fixpoint) of recursive logic definitions

```the verification algorithm must always terminate and be reasonably
performant in practice, but its worst-case complexity is unknown
and probably exponential. What is quite easy when there is only
one recursive definition, becomes difficult when there is a group
of mutually recursive definitions. An educated discussion would
be highly appreciated.

BTW, I had to convert a couple of recursive "logic"s on integers
into an abstract "logic" + axiom. Pretty much all of them supposed
that the argument was non-negative, and thus were non-terminating!```
parent 2792dbcf
 theory TreeForest type list 'a = Nil | Cons 'a (list 'a) type tree 'a = Leaf 'a | Node (forest 'a) type tree 'a = Leaf 'a | Node (tree 'a) (forest 'a) with forest 'a = list (tree 'a) use import int.Int logic count_forest (f : forest int) : int = match f, 1.0 with | Nil, _ -> 0 | Cons t f, _ -> count_tree t + count_forest f end with count_tree (t : tree int) : int = match t with | Leaf i -> i | Node t f -> 1 + count_tree t + count_forest f end type nat = Zero | Succ nat logic ack (m n : nat) : nat = match m, n with | Zero, _ -> Succ n | Succ m', Zero -> ack m' (Succ Zero) | Succ m', Succ n' -> ack m' (ack m n') end end
 ... ... @@ -2,8 +2,15 @@ (* Fibonacci function with memoisation *) { (* logic fib (n:int) : int = if n <= 1 then 1 else fib (n-1) + fib (n-2) *) logic fib int : int axiom Fib_def : forall n:int. fib n = if n <= 1 then 1 else fib (n-1) + fib (n-2) type option 'a = None | Some 'a ... ...
 ... ... @@ -17,8 +17,14 @@ let rec f91 (n:int) : int variant { 101-n } = if x >= 101 then x-10 else 91 (* iter_f(n,x) = f^n(x) *) (* logic iter_f (n x:int) : int = if n = 0 then x else iter_f (n-1) (f x) *) logic iter_f int int : int axiom Iter_def : forall n x : int. iter_f n x = if n <= 0 then x else iter_f (n-1) (f x) clone import relations.Lex with type t1 = int, type t2 = int, logic rel1 = lt_nat, logic rel2 = lt_nat ... ...
 ... ... @@ -18,8 +18,14 @@ logic (#) (a : array 'a) (i : int) : 'a = A.get a i (* logic sum_digits (n:int) : int = if n = 0 then 0 else sum_digits (div n 10) + mod n 10 *) logic sum_digits int : int axiom Sum_digits_def : forall n : int. sum_digits n = if n <= 0 then 0 else sum_digits (div n 10) + mod n 10 (* interp x i j is the integer X[j-1]...X[i] *) ... ...
 ... ... @@ -6,9 +6,15 @@ { use import int.EuclideanDivision use import int.Power (* logic sum_digits (n:int) : int = if n = 0 then 0 else sum_digits (div n 10) + mod n 10 *) logic sum_digits int : int axiom Sum_digits_def : forall n : int. sum_digits n = if n <= 0 then 0 else sum_digits (div n 10) + mod n 10 (* the number of n st 0 <= n mod 10 < c and sd(n) = sd(137n+a)+b *) ... ...