Return-Path: <john.harrison-request@uk.ac.cam.cl>
Received: from ted.cs.uidaho.edu by swan.cl.cam.ac.uk with SMTP (PP-6.0) 
          id <29310-0@swan.cl.cam.ac.uk>; Thu, 14 May 1992 11:20:24 +0100
Received: by ted.cs.uidaho.edu (16.6/1.34) id AA10170;
          Thu, 14 May 92 03:12:29 -0700
Sender: info-hol-request@edu.uidaho.cs.ted
Errors-To: info-hol-request@edu.uidaho.cs.ted
Received: from swan.cl.cam.ac.uk by ted.cs.uidaho.edu (16.6/1.34) id AA10166;
          Thu, 14 May 92 03:12:24 -0700
Received: from oxley.cl.cam.ac.uk by swan.cl.cam.ac.uk with SMTP (PP-6.0) to cl 
          id <29084-0@swan.cl.cam.ac.uk>; Thu, 14 May 1992 11:12:43 +0100
Received: by oxley (5.57/SMI-3.0DEV3) id AA25702; Thu, 14 May 92 11:12:18 +0100
From: Andy.Gordon@uk.ac.cam.cl
Message-Id: <9205141012.AA25702@oxley>
Date: 14 May 1992 1110-WET (Thursday)
To: toal@edu.ucla.cs
Cc: info-hol@edu.uidaho.cs.ted
X-Folder-Carbon: Hol
Subject: Re: Ackermann's function
In-Reply-To: Message of Wed, 13 May 92 17:08:42 PDT from toal@edu.ucla.cs <9205140008.AA15050@ewa.cs.ucla.edu>

Ackermann's function is a curried function A:num->num->num that satisfies the 
predicate:

    "!m n.
        (A 0 n = SUC n) /\
        (A (SUC m) 0 = A m 1) /\
        (A (SUC m) (SUC n) = A m (A (SUC m) n))"

We can define such an A using primitive recursion in HOL as follows:

    new_theory `ackermann`;;

    let G =
        new_prim_rec_definition
        (`G`,
         "(G Am 0 = Am 1) /\
          (G Am (SUC n) = Am (G Am n))");;

    let A =
        new_prim_rec_definition
        (`A`,
         "(A 0 n = SUC n) /\
          (A (SUC m) n = G (A m) n)");;

    let Intuition =
        prove(
        "!m. G (A m) = A (SUC m)",
        GEN_TAC THEN
        CONV_TAC FUN_EQ_CONV THEN
        REWRITE_TAC [A]);;
    
    let Ackermann =
        prove(
        "!m n.
            (A 0 n = SUC n) /\
            (A (SUC m) 0 = A m 1) /\
            (A (SUC m) (SUC n) = A m (A (SUC m) n))",
        INDUCT_TAC THEN
        REWRITE_TAC [G;A]);;

    close_theory();;

The trick here is the higher-order function G: (num->num)->num->num,
with the property (that I've proved as Intuition above):

    G (A m) = A (SUC m)

This way of defining Ackermann's function depends on your logic being able 
to define the higher-order function G by primitive recursion; typically 
a first-order logic wouldn't let you do this.

Andy.
