Message-Id: <9011131623.AA11834@cheetah.cs.uidaho.edu>
To: info-hol@iris.ucdavis.edu
Subject: RE: primitive recursive functions
Date: Tue, 13 Nov 90 08:23:58 -0800
From: Phil Windley <windley@cheetah.cs.uidaho.edu>


[ This is from Tom Melham.  It bounced for some reason, so I'm resending
  it.  If you got two copies, I apologize. -- PJW ]



RE: Sandy Murphy's recent message about recursive definitions.

The function new_prim_rec_definition does indeed work only for SYNTACTICALLY
primitive recursive definitions (that's all it was designed to do).  Although
things like the fibonacci function, whose definition can be expressed by:

   1:  f(n) = f(n-1) + f(n-2)

are in fact primitive recursive FUNCTIONS, constants intended to satisfy
equations like (1) cannot be introduced using new_prim_rec_definition.

In the past, I have manually derived recursive definitions like:

  2: f(n) = E[f(h n)]

where h:num->num is decreasing.  For example, in my paper in the proceedings
of the IFIP WG 10.2 workshop (Glasgow), I display the following `definition'
of a recursive function f:num->tree

  3:  GEN(n) = (n<2 =>  Leaf | Node (GEN(n DIV 2)) (GEN(n-(n DIV 2))))

where

  tree = Leaf | Node tree tree

is defined using the types package.  Equation (3) was proved in HOL from
the following general (but still slightly ad-hoc) theorem:

  4: |- !f g. ((!n. f(n+2) < n+2) /\ (!n. g(n+2) < n+2))
                ==>
              !x1:*. !x2:*. !h. ?fn.
               (fn 0 = x1) /\  (fn (SUC 0) = x2) /\
               (!n. fn (n+2) = h (fn (f (n+2))) (fn (g (n+2))))

This says: assume we've got two functions f:num->num and g:num->num which are
both decreasing (for arguments greater than two); then there is a total
function fn:num->* that satisfies any given recursive defining-equation in
which the arguments to recursive calls of fn are obtained using f or g.  I
think this is something like what Sandy Murphy wanted for "course-of-values"
recursion (for the case where h1 = f and h2 = g).  There is a fairly standard
trick for proving equations like (4).  Details on request.

Given (4), it was relatively straightforward to derive (3) by taking:

  f = \n. n DIV 2     and     g = \n. n - (n DIV 2)

and proving that for these choices of f and g:

  !n. f(n+2) < n+2    and    !n. g(n+2) < n+2

The existence of a function GEN satisfying the desired definition (equation 3)
then follows easily by just picking appropriate values for x1, x2, and h.
And from this existence theorem, one can very easily introduce a constant GEN
satisfying (3), either by using new_specification or by using epsilon.

The trick, of course, is to automate all this.  This should be reasonably
straightforward (i.e. it won't require any `deep' theoretical results) but the
programming will be rather messy, and a production-quality tool will take some
time to create.  For this reason, I've stuck in the past to deriving equations
like (3) manually---it would take MUCH longer to program a general tool.  But,
eventually, a tool should be created that will (for example) take theorems of
the form:

  |- !n. f n < n

to rules of definition for user-supplied recursive equations in which
arguments to recursive `calls' are constructed using f.  This could also be
extended to other types (by using a provably well-founded ordering in the type
in question in place of <).


Hope this helps,
Tom

PS: where's TIS.COM?



