I am trying to define the Ackermann-Peters function in Coq, and I'm getting an error message that I don't understand. As you can see, I'm packaging the arguments a, b
of Ackermann in a pair ab
; I provide an ordering defining an ordering function for the arguments. Then I use the Function
form to define Ackermann itself, providing it with the ordering function for the ab
argument.
Require Import Recdef.
Definition ack_ordering (ab1 ab2 : nat * nat) :=
match (ab1, ab2) with
|((a1, b1), (a2, b2)) =>
(a1 > a2) \/ ((a1 = a2) /\ (b1 > b2))
end.
Function ack (ab : nat * nat) {wf ack_ordering} : nat :=
match ab with
| (0, b) => b + 1
| (a, 0) => ack (a-1, 1)
| (a, b) => ack (a-1, ack (a, b-1))
end.
What I get is the following error message:
Error: No such section variable or assumption:
ack
.
I'm not sure what bothers Coq, but searching the internet, I found a suggestion there may be a problem with using a recursive function defined with an ordering or a measure, where the recursive call occurs within a match. However, using the projections fst
and snd
and an if-then-else
generated a different error message. Can someone please suggest how to define Ackermann in Coq?
You get this error because you are referencing the
ack
function while you are defining it. Self reference is only allowed inFixpoint
s (ie. recursive functions) but the problem is, as you probably know, that the Ackermann function is not a primitive recursive function.See Coq'Art section 4.3.2.2 for some more information on this.
So one alternative way to define it is by inlining a second recursive function that is structurally recursive for the second argument; so something like
It seems like
Function
can't solve this problem. However, its cousinProgram Fixpoint
can.Let's define some lemmas treating well-foundedness first:
Now we can define the Ackermann-Péter function:
Some simple tests demonstrating that we can compute with
ack
:Using the Equations plugin by M. Sozeau and C. Mangin it is possible to define the function this way:
Unfortunately, it's not possible to use the
( , )
notation for pairs due to issue #81. The code is taken from Equation's test suite: ack.v.I just tried your function with Coq 8.4, and the error is slightly different:
I guess the inner call to ack is the problem, but I don't know why.
Hope this helps a bit, V.
PS: The usual way I define Ack is what wires wrote, with an inner fixpoint.