> I'm interested in proving termination of nested functions and I  
> have some questions:
>
> 1- First I noticed that HOL is able to prove the termination of  
> this definition
>    automatically:
>
>    Define `(ack 0 y = 1 + y)
>        /\ (ack (SUC u) 0 = ack u (SUC 0))
>        /\ (ack (SUC u) (SUC v) = ack u (ack (SUC u) v))`;
>
> I want to know how, because I'm tried to prove it manually using  
> Hol_defn and
> I couldn't.
>

Lexicographic combination of <. If you apply TotalDefn.guessR to the
result of Hol_defn on the above recursion equations, you get the
"guesses" that the automated termination prover makes when trying
to find a suitable termination relation. In the above case, there are
two:

- TotalDefn.guessR defn;
 > val it =
     [``inv_image $< (\(x,y). x + y)``,
      ``inv_image ($< LEX $<) (\(v1,v2). (v1,v2))``] : term list

and the second one works.

> 2 - Although the function above can be proved automatically the  
> following can't:
>
> Define `ack x y = if (x = 0) then (1 + y) else
>                   if (y = 0) then (ack (x - 1) 1) else
>                   ack (x - 1) (ack x (y - 1))`;
>
> I wanted to know why, and again if it is possible to prove it  
> manually.
>

In recent versions of HOL-4 this is proved automatically.

> 3 - I want to know if it is possible to prove termination of a  
> function like this:
>
> val defn = Hol_defn "nest" `nest x = if x = 0 then 0 else nest  
> (nest x-1)`
>

No. Your recursive call is ((nest x) - 1). You probably meant to
write (nest (x-1)), and when the function is defined that way, it is
possible to show termination.  It's not obvious how to do this, though,
since there is a bit of an involved story. First, the termination  
conditions
that need to be proved are phrased in terms of an auxiliary function
"nest_aux":

   ?R. WF R /\ (!x. ~(x = 0) ==> R (x - 1) x) /\
        !x. ~(x = 0) ==> R (nest_aux R (x - 1)) x

The equations and induction theorem for nest_aux can be extracted from
the defn datastructure. They also have to be instantiated to the
desired termination relation (less-than, in this case). Once
instantiated with (<), some of the constraints on the induction
theorem and recursion equations can be eliminated, via Defn.prove_tcs.

   val nest_aux_defn = Defn.set_reln (valOf (Defn.aux_defn defn)) `` 
(<)``;
   val nest_aux_defn' = Defn.prove_tcs nest_aux_defn
                          (SIMP_TAC arith_ss [prim_recTheory.WF_LESS]);
   val nest_aux_ind = valOf (Defn.ind_of nest_aux_defn');
   val [E] = Defn.eqns_of nest_aux_defn';

Now the termination proof can most easily be accomplished by proving  
that
nest_aux (<) is the constant 0 function, and this is done by  
induction with
nest_aux_ind':

    val nest_aux_thm = Q.prove
    (`!n. nest_aux (<) n = 0`,
     recInduct nest_aux_ind' THEN
     REPEAT STRIP_TAC THEN RW_TAC arith_ss [DISCH_ALL E]);

With this theorem in hand, termination is quite simple to prove:

    val (nest_def,nest_ind) =
      Defn.tprove
      (defn, WF_REL_TAC `$<` THEN RW_TAC arith_ss [nest_aux_thm]);

which yields the desired recursion equations and induction theorem  
for nest:

    val nest_def = |- nest x = (if x = 0 then 0 else nest (nest (x -  
1)))
    val nest_ind =
     |- !P. (!x. (~(x = 0) ==> P (nest (x - 1))) /\
                 (~(x = 0) ==> P (x - 1)) ==>  P x) ==> !v. P v

There is some detail on this approach in Chapter 4 of

   http://www.cs.utah.edu/~slind/papers/phd.html

Konrad.


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
hol-info mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/hol-info

Reply via email to