Hubbry Logo
Ackermann functionAckermann functionMain
Open search
Ackermann function
Community hub
Ackermann function
logo
7 pages, 0 posts
0 subscribers
Be the first to start a discussion here.
Be the first to start a discussion here.
Ackermann function
Ackermann function
from Wikipedia

In computability theory, the Ackermann function, named after Wilhelm Ackermann, is one of the simplest[1] and earliest-discovered examples of a total computable function that is not primitive recursive. All primitive recursive functions are total and computable, but the Ackermann function illustrates that not all total computable functions are primitive recursive.

After Ackermann's publication[2] of his function (which had three non-negative integer arguments), many authors modified it to suit various purposes, so that today "the Ackermann function" may refer to any of numerous variants of the original function. One common version is the two-argument Ackermann–Péter function developed by Rózsa Péter and Raphael Robinson. This function is defined from the recurrence relation with appropriate base cases. Its value grows very rapidly; for example, results in , an integer with 19,729 decimal digits.[3]

History

[edit]

In the late 1920s, the mathematicians Gabriel Sudan and Wilhelm Ackermann, students of David Hilbert, were studying the foundations of computation. Both Sudan and Ackermann are credited[4] with discovering total computable functions (termed simply "recursive" in some references) that are not primitive recursive. Sudan published the lesser-known Sudan function, then shortly afterwards and independently, in 1928, Ackermann published his function (from Greek, the letter phi). Ackermann's three-argument function, , is defined such that for , it reproduces the basic operations of addition, multiplication, and exponentiation as

and for it extends these basic operations in a way that can be compared to the hyperoperations:

(Aside from its historic role as a total-computable-but-not-primitive-recursive function, Ackermann's original function is seen to extend the basic arithmetic operations beyond exponentiation, although not as seamlessly as do variants of Ackermann's function that are specifically designed for that purpose—such as Goodstein's hyperoperation sequence.)

In On the Infinite,[5] David Hilbert hypothesized that the Ackermann function was not primitive recursive, but it was Ackermann, Hilbert's personal secretary and former student, who actually proved the hypothesis in his paper On Hilbert's Construction of the Real Numbers.[2][6]

Rózsa Péter[7] and Raphael Robinson[8] later developed a two-variable version of the Ackermann function that became preferred by almost all authors.

The generalized hyperoperation sequence, e.g. , is a version of the Ackermann function as well.[9]

In 1963 R. Creighton Buck based an intuitive two-variable [n 1] variant on the hyperoperation sequence:[10][11]

Compared to most other versions, Buck's function has no unessential offsets:

Many other versions of Ackermann function have been investigated.[12][13]

Definition

[edit]

Definition: as m-ary function

[edit]

Ackermann's original three-argument function is defined recursively as follows for nonnegative integers and :

Of the various two-argument versions, the one developed by Péter and Robinson (called "the" Ackermann function by most authors) is defined for nonnegative integers and as follows:

The Ackermann function has also been expressed in relation to the hyperoperation sequence:[14][15]

or, written in Knuth's up-arrow notation (extended to integer indices ):

or, equivalently, in terms of Buck's function F:[10]

By induction on , one can show that for all .

Definition: as iterated 1-ary function

[edit]

Define as the n-th iterate of :

Iteration is the process of composing a function with itself a certain number of times. Function composition is an associative operation, so .

Conceiving the Ackermann function as a sequence of unary functions, one can set .

The function then becomes a sequence of unary[n 2] functions, defined from iteration:

Computation

[edit]

Computation by LOOP program

[edit]

The functions fit into the (finite-level) fast-growing hierarchy (FGH) of functions[16]

The following inequality holds:[17]

For fixed , the function can be computed by a LOOP program of nesting depth :[18]

# INPUT (n)
LOOP n:                  # nesting depth: 1
    LOOP n:              # nesting depth: 2
        ...              # ...
            LOOP n:      # nesting depth: k
                n += 1   # 
# OUTPUT (n)

The function can also be computed by a LOOP-k program.[19] (The program (schema) is not listed here.)

It is obvious that , not being a primitive recursive function —see below—, cannot be computed by a LOOP program.

Computation by term rewriting system, based on 2-ary function

[edit]

The recursive definition of the Ackermann function can naturally be transposed to a term rewriting system (TRS).

The definition of the 2-ary Ackermann function leads to the obvious reduction rules[20][21]

Example

Compute

The reduction sequence is [n 3]

Leftmost-outermost (one-step) strategy:             Leftmost-innermost (one-step) strategy:
         
         
         
         
         
         

To compute one can use a stack, which initially contains the elements .

Then repeatedly the two top elements are replaced according to the rules[n 4]

Schematically, starting from :

WHILE stackLength <> 1
{
   POP 2 elements;
   PUSH 1 or 2 or 3 elements, applying the rules r1, r2, r3
}

The pseudocode is published in Grossman & Zeitman (1988).

For example, on input ,

the stack configurations     reflect the reduction[n 5]
         
         
         
         
         
         
         
         
         
         
         
         
         
         

Remarks

  • The leftmost-innermost strategy is implemented in 225 computer languages on Rosetta Code.
  • For all the computation of takes no more than steps.[22]
  • Grossman & Zeitman (1988) pointed out that in the computation of the maximum length of the stack is , as long as .

    Their own algorithm, inherently iterative, computes within time and within space.

Computation by TRS, based on iterated 1-ary function

[edit]

The definition of the iterated 1-ary Ackermann functions leads to different reduction rules

As function composition is associative, instead of rule r6 one can define

Like in the previous section the computation of can be implemented with a stack.

Initially the stack contains the three elements .

Then repeatedly the three top elements are replaced according to the rules[n 4]

Schematically, starting from :

WHILE stackLength <> 1
{
   POP 3 elements;
   PUSH 1 or 3 or 5 elements, applying the rules r4, r5, r6;
}

Example

On input the successive stack configurations are

The corresponding equalities are

When reduction rule r7 is used instead of rule r6, the replacements in the stack will follow

The successive stack configurations will then be

The corresponding equalities are

Remarks

  • On any given input the TRSs presented so far converge in the same number of steps. They also use the same reduction rules (in this comparison the rules r1, r2, r3 are considered "the same as" the rules r4, r5, r6/r7 respectively). For example, the reduction of converges in 14 steps: 6 × r1, 3 × r2, 5 × r3. The reduction of converges in the same 14 steps: 6 × r4, 3 × r5, 5 × r6/r7. The TRSs differ in the order in which the reduction rules are applied.
  • When is computed following the rules {r4, r5, r6}, the maximum length of the stack stays below . When reduction rule r7 is used instead of rule r6, the maximum length of the stack is only . The length of the stack reflects the recursion depth. As the reduction according to the rules {r4, r5, r7} involves a smaller maximum depth of recursion,[n 6] this computation is more efficient in that respect.

Computation by TRS, based on hyperoperators

[edit]

As Sundblad (1971) — or Porto & Matos (1980) — showed explicitly, the Ackermann function can be expressed in terms of the hyperoperation sequence:

or, after removal of the constant 2 from the parameter list, in terms of Buck's function

Buck's function ,[10] a variant of Ackermann function by itself, can be computed with the following reduction rules:

Instead of rule b6 one can define the rule

To compute the Ackermann function it suffices to add three reduction rules

These rules take care of the base case A(0,n), the alignment (n+3) and the fudge (-3).

Example

Compute

using reduction rule :[n 5]     using reduction rule :[n 5]
         
         
         
         
         
         
                   
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         

The matching equalities are

  • when the TRS with the reduction rule is applied:

  • when the TRS with the reduction rule is applied:

Remarks

  • The computation of according to the rules {b1 - b5, b6, r8 - r10} is deeply recursive. The maximum depth of nested s is . The culprit is the order in which iteration is executed: . The first disappears only after the whole sequence is unfolded.
  • The computation according to the rules {b1 - b5, b7, r8 - r10} is more efficient in that respect. The iteration simulates the repeated loop over a block of code.[n 7] The nesting is limited to , one recursion level per iterated function. Meyer & Ritchie (1967) showed this correspondence.
  • These considerations concern the recursion depth only. Either way of iterating leads to the same number of reduction steps, involving the same rules (when the rules b6 and b7 are considered "the same"). The reduction of for instance converges in 35 steps: 12 × b1, 4 × b2, 1 × b3, 4 × b5, 12 × b6/b7, 1 × r9, 1 × r10. The modus iterandi only affects the order in which the reduction rules are applied.
  • A real gain of execution time can only be achieved by not recalculating subresults over and over again. Memoization is an optimization technique where the results of function calls are cached and returned when the same inputs occur again. See for instance Ward (1993). Grossman & Zeitman (1988) published a cunning algorithm that computes within time and within space.

Huge numbers

[edit]

To demonstrate how the computation of results in many steps and in a large number:[n 5]

Table of values

[edit]

Computing the Ackermann function can be restated in terms of an infinite table. First, place the natural numbers along the top row. To determine a number in the table, take the number immediately to the left. Then use that number to look up the required number in the column given by that number and one row up. If there is no number to its left, simply look at the column headed "1" in the previous row. Here is a small upper-left portion of the table:

Values of A(mn)
n
m
0 1 2 3 4 n
0 1 2 3 4 5
1 2 3 4 5 6
2 3 5 7 9 11
3 5 13 29 61 125
4 13 65533 265536 – 3





5 65533

6
m

The numbers here that are only expressed with recursive exponentiation or Knuth arrows are very large and would take up too much space to notate in plain decimal digits.

Despite the large values occurring in this early section of the table, some even larger numbers have been defined, such as Graham's number, which cannot be written with any small number of Knuth arrows. This number is constructed with a technique similar to applying the Ackermann function to itself recursively.

This is a repeat of the above table, but with the values replaced by the relevant expression from the function definition to show the pattern clearly:

Values of A(mn)
n
m
0 1 2 3 4 n
0 0+1 1+1 2+1 3+1 4+1 n + 1
1 A(0, 1) A(0, A(1, 0))
= A(0, 2)
A(0, A(1, 1))
= A(0, 3)
A(0, A(1, 2))
= A(0, 4)
A(0, A(1, 3))
= A(0, 5)
A(0, A(1, n−1))
2 A(1, 1) A(1, A(2, 0))
= A(1, 3)
A(1, A(2, 1))
= A(1, 5)
A(1, A(2, 2))
= A(1, 7)
A(1, A(2, 3))
= A(1, 9)
A(1, A(2, n−1))
3 A(2, 1) A(2, A(3, 0))
= A(2, 5)
A(2, A(3, 1))
= A(2, 13)
A(2, A(3, 2))
= A(2, 29)
A(2, A(3, 3))
= A(2, 61)
A(2, A(3, n−1))
4 A(3, 1) A(3, A(4, 0))
= A(3, 13)
A(3, A(4, 1))
= A(3, 65533)
A(3, A(4, 2)) A(3, A(4, 3)) A(3, A(4, n−1))
5 A(4, 1) A(4, A(5, 0)) A(4, A(5, 1)) A(4, A(5, 2)) A(4, A(5, 3)) A(4, A(5, n−1))
6 A(5, 1) A(5, A(6, 0)) A(5, A(6, 1)) A(5, A(6, 2)) A(5, A(6, 3)) A(5, A(6, n−1))

Properties

[edit]

General remarks

[edit]
  • It may not be immediately obvious that the evaluation of always terminates. However, the recursion is bounded because in each recursive application either decreases, or remains the same and decreases. Each time that reaches zero, decreases, so eventually reaches zero as well. (Expressed more technically, in each case the pair decreases in the lexicographic order on pairs, which is a well-ordering, just like the ordering of single non-negative integers; this means one cannot go down in the ordering infinitely many times in succession.) However, when decreases there is no upper bound on how much can increase — and it will often increase greatly.
  • For small values of m like 1, 2, or 3, the Ackermann function grows relatively slowly with respect to n (at most exponentially). For , however, it grows much more quickly; even is about 2.00353×1019728, and the decimal expansion of is very large by any typical measure, about 2.12004×106.03123×1019727.
  • An interesting aspect is that the only arithmetic operation it ever uses is addition of 1. Its fast growing power is based solely on nested recursion. This also implies that its running time is at least proportional to its output, and so is also extremely huge. In actuality, for most cases the running time is far larger than the output; see above.
  • A single-argument version that increases both and at the same time dwarfs every primitive recursive function, including very fast-growing functions such as the exponential function, the factorial function, multi- and superfactorial functions, and even functions defined using Knuth's up-arrow notation (except when the indexed up-arrow is used). It can be seen that is roughly comparable to in the fast-growing hierarchy. This extreme growth can be exploited to show that , which is obviously computable on a machine with infinite memory such as a Turing machine and so is a computable function, grows faster than any primitive recursive function and is therefore not primitive recursive.

Not primitive recursive

[edit]

The Ackermann function grows faster than any primitive recursive function and therefore is not itself primitive recursive.

Proof sketch:

Primitive recursive functions are built from basic functions using composition and primitive recursion, and all grow within a certain rate. We define, constructively, a hierarchy of total functions by:

where denotes -fold iteration of on input .[23] This hierarchy grows strictly faster with increasing , and every primitive recursive function is eventually bounded above by some . This can be shown by structural induction on the definitions of primitive recursive functions.

However, the Ackermann function eventually exceeds every ; for every , there exists such that for all sufficiently large . Thus, grows faster than any primitive recursive function and is therefore not primitive recursive.

Inverse

[edit]

Since the function f(n) = A(n, n) considered above grows very rapidly, its inverse function, f−1, grows very slowly. This inverse Ackermann function f−1 is usually denoted by α. In fact, α(n) is less than 5 for any practical input size n, since A(4, 4) is on the order of .

This inverse appears in the time complexity of some algorithms, such as the disjoint-set data structure and Chazelle's algorithm for minimum spanning trees. Sometimes Ackermann's original function or other variations are used in these settings, but they all grow at similarly high rates. In particular, some modified functions simplify the expression by eliminating the −3 and similar terms.

A two-parameter variation of the inverse Ackermann function can be defined as follows, where is the floor function:

This function arises in more precise analyses of the algorithms mentioned above, and gives a more refined time bound. In the disjoint-set data structure, m represents the number of operations while n represents the number of elements; in the minimum spanning tree algorithm, m represents the number of edges while n represents the number of vertices. Several slightly different definitions of α(m, n) exist; for example, log2 n is sometimes replaced by n, and the floor function is sometimes replaced by a ceiling.

Other studies might define an inverse function of one where m is set to a constant, such that the inverse applies to a particular row.[24]

The inverse of the Ackermann function is primitive recursive, since it is graph primitive recursive, and it is upper bounded by a primitive recursive function.[25]

Usage

[edit]

In computational complexity

[edit]

The Ackermann function appears in the time complexity of some algorithms,[26] such as vector addition systems[27] and Petri net reachability, thus showing they are computationally infeasible for large instances.[28]

The inverse of the Ackermann function appears in some time complexity results. For instance, the disjoint-set data structure takes amortized time per operation proportional to the inverse Ackermann function,[29] and cannot be made faster within the cell-probe model of computational complexity.[30]

In discrete geometry

[edit]

Certain problems in discrete geometry related to Davenport–Schinzel sequences have complexity bounds in which the inverse Ackermann function appears. For instance, for line segments in the plane, the unbounded face of the arrangement of the segments has complexity , and some systems of line segments have an unbounded face of complexity .[31]

As a benchmark

[edit]

The Ackermann function, due to its definition in terms of extremely deep recursion, can be used as a benchmark of a compiler's ability to optimize recursion. The first published use of Ackermann's function in this way was in 1970 by Dragoș Vaida[32] and, almost simultaneously, in 1971, by Yngve Sundblad.[14]

Sundblad's seminal paper was taken up by Brian Wichmann (co-author of the Whetstone benchmark) in a trilogy of papers written between 1975 and 1982.[33][34][35]

See also

[edit]

Notes

[edit]

References

[edit]

Bibliography

[edit]
[edit]
Revisions and contributorsEdit on WikipediaRead on Wikipedia
from Grokipedia
The Ackermann function is a recursive function in mathematics and computability theory, renowned as one of the simplest examples of a total computable function that grows faster than any primitive recursive function, thereby illustrating the boundaries between primitive recursion and general recursion. Originally introduced by German mathematician Wilhelm Ackermann in his 1928 paper "Zum Hilbertschen Aufbau der reellen Zahlen" as a three-argument function φ(m, n, p) defined recursively using auxiliary functions for iteration to demonstrate operations beyond primitive recursion in the context of Hilbert's program for the foundations of mathematics, it served as an early counterexample to the conjecture that all recursive functions are primitive recursive. A simplified and more commonly used two-argument version, often called the Ackermann–Péter function, was later formulated by Hungarian mathematician Rózsa Péter in her 1934 paper "Über den Zusammenhang der verschiedenen Begriffe der rekursiven Funktionen" to provide a clearer example of a function beyond primitive recursion while preserving Ackermann's intent. This version, defined for non-negative integers m and n, is:

A(0, n) = n + 1 A(m + 1, 0) = A(m, 1) A(m + 1, n + 1) = A(m, A(m + 1, n))

A(0, n) = n + 1 A(m + 1, 0) = A(m, 1) A(m + 1, n + 1) = A(m, A(m + 1, n))

The function's values escalate dramatically with increasing arguments, surpassing exponential growth early on—for example, A(1, n) = n + 2, A(2, n) = 2n + 3, A(3, n) = 2^(n + 3) - 3, and A(4, 2) = 2^65536 - 3, a number with 19,729 decimal digits that corresponds to tetration in Knuth's up-arrow notation as 2 ↑↑ 5 - 3. This hyperoperation-like behavior makes it a benchmark for testing the efficiency of recursive algorithms and programming language implementations, as even modest inputs like A(5, 1) yield computationally infeasible results on standard hardware. Beyond its foundational role in recursion theory, the Ackermann function has influenced fields such as proof theory, where it highlights the strength of systems like Peano arithmetic, and googology, the study of large numbers, due to its utility in defining hierarchies of fast-growing functions. Variants, including those by Raphael Robinson in 1963, further refine its structure for specific analytical purposes, but the Péter version remains the standard reference for illustrating non-primitive recursive computability.

Introduction and History

Overview

The Ackermann function stands as a foundational mathematical construct in recursion theory, defined through a recursive process that generates extraordinarily large integers even from modest input values. This function exemplifies the power and limitations of recursive definitions in computability, where its iterative structure leads to outputs that escalate far beyond everyday numerical scales, such as A(4, 2) = 2^{65536} - 3, a number with 19,729 digits that vastly exceeds the estimated 10^{80} atoms in the observable universe. Its significance lies in illustrating the boundaries of primitive recursive functions, a class of computable operations built from basic arithmetic using bounded recursion, which the Ackermann function surpasses by employing unbounded recursion. This distinction highlights how certain total functions, while fully computable, escape the constraints of primitive recursion, providing a concrete counterexample in theoretical computer science. The function is commonly expressed in its two-argument form, denoted A(m, n), where m and n are non-negative integers that control the levels of recursion and iteration, respectively. In computability theory, it serves as a total computable function—meaning it halts and produces a defined output for every input pair—yet remains non-primitive recursive, underscoring the hierarchy of recursive functions and the expressive limits of formal systems.

Historical Development

In the early 1920s, David Hilbert and his collaborators, including student Wilhelm Ackermann, advanced proof theory as part of Hilbert's program to establish the consistency of mathematics through finitary methods, emphasizing the study of recursive definitions to distinguish intuitive computability from more general recursion. Ackermann, working under Hilbert at the University of Göttingen, contributed to this effort by exploring functions that exceeded primitive recursive bounds while remaining total and computable. In 1928, Ackermann published a seminal three-argument recursive function in his paper "Zum Hilbertschen Aufbau der reellen Zahlen" within Mathematische Annalen, using it to exemplify a total recursive function beyond the scope of primitive recursion in the context of Hilbert's foundational framework. This function, defined via nested iterations, highlighted limitations in primitive recursive methods and supported Hilbert's finitist approach by demonstrating computability without impredicativity. Building on these ideas, Rózsa Péter independently developed a comparable rapidly growing two-argument function in her 1935 paper "Über den Zusammenhang der verschiedenen Begriffe der rekursiven Funktionen," published in Mathematische Annalen, to delineate the boundaries of primitive recursive functions and introduce non-primitive recursive examples. Péter's formulation simplified Ackermann's while preserving its growth properties, marking a key refinement in the analysis of recursive hierarchies during the foundational crisis of mathematics. The function evolved further in 1947 when Raphael M. Robinson presented a streamlined two-argument version in his article "Primitive Recursive Functions" in the Bulletin of the American Mathematical Society, adjusting initial conditions for elegance and proving its non-primitive recursiveness, which solidified it as the standard Ackermann function. Throughout the 20th century, subsequent interpretations linked these formulations to hyperoperations, framing the Ackermann function as a diagonalization over the hyperoperation sequence, thus connecting recursion theory to broader arithmetic hierarchies.

Definitions

Multi-argument Formulation

The multi-argument formulation of the Ackermann function originates from Wilhelm Ackermann's 1928 paper, where he introduced a three-argument recursive function φ(m, n, p) to exemplify a total recursive function that is not primitive recursive. Although the original definition involved higher-type recursion with auxiliary functions, a commonly used simplification for non-negative integers m, n, p is: ϕ(0,n,p)=n+p+1,ϕ(m+1,0,p)=ϕ(m,1,p),ϕ(m+1,n+1,p)=ϕ(m,ϕ(m+1,n,p),p).\begin{align*} \phi(0, n, p) &= n + p + 1, \\ \phi(m + 1, 0, p) &= \phi(m, 1, p), \\ \phi(m + 1, n + 1, p) &= \phi(m, \phi(m + 1, n, p), p). \end{align*} These equations establish base cases for m = 0 and handle the recursive nesting for higher m, where the computation of φ(m + 1, n + 1, p) invokes φ(m, ·, p) applied to an inner recursive call, creating deeply nested recursions that escalate in complexity with increasing m. For fixed small values of p, the function φ(m, n, p) reproduces familiar arithmetic operations: addition when p = 0, multiplication when p = 1, and exponentiation when p = 2, with higher p leading to more rapid growth through iterated applications. The widely used two-argument Ackermann function A(m, n) emerged as a simplification of this three-argument version. It is defined recursively as: A(0,n)=n+1,A(m+1,0)=A(m,1),A(m+1,n+1)=A(m,A(m+1,n)).\begin{align*} A(0, n) &= n + 1, \\ A(m + 1, 0) &= A(m, 1), \\ A(m + 1, n + 1) &= A(m, A(m + 1, n)). \end{align*} This formulation retains the nested recursive structure of φ, where each increment in m shifts the recursion to a higher level: A(1, n) yields multiplication-like behavior (n + 2), A(2, n) exponentiation-like (2n + 3), and A(3, n) tetration-like (2^{n+3} - 3), and higher m produce even faster-growing functions. The nesting in A(m + 1, n + 1) = A(m, A(m + 1, n)) embeds multiple evaluations of lower-level functions within higher ones, mirroring the hyperoperation hierarchy and demonstrating how the multi-argument setup generalizes to encode increasingly powerful operations through recursion depth.

Iterated Unary Formulation

The iterated unary formulation presents the Ackermann function as a hierarchy of unary functions αm:NN\alpha_m: \mathbb{N} \to \mathbb{N}, defined recursively by α0(n)=n+1\alpha_0(n) = n + 1 and αm+1(n)=αm(n+1)(n)\alpha_{m+1}(n) = \alpha_m^{(n+1)}(n), where f(k)(x)f^{(k)}(x) denotes the kk-fold iteration of the unary function ff applied to xx. This construction builds each subsequent function by applying the previous one a number of times that depends on the input nn, starting from nn itself, thereby encapsulating increasingly rapid growth through repeated composition. This unary hierarchy is equivalent to the multi-argument formulation A(m,n)A(m, n), in the sense that A(m,n)=αm(n)A(m, n) = \alpha_m(n) for all m,nNm, n \in \mathbb{N}. To see this, proceed by induction on mm. For the base case m=0m = 0, α0(n)=n+1=A(0,n)\alpha_0(n) = n + 1 = A(0, n) holds directly from the multi-argument base clause. Assume it holds for some m=km = k, so αk(n)=A(k,n)\alpha_k(n) = A(k, n). For m=k+1m = k+1, the definition αk+1(n)=αk(n+1)(n)\alpha_{k+1}(n) = \alpha_k^{(n+1)}(n) corresponds to iterating A(k,)A(k, \cdot) exactly n+1n+1 times starting at nn, which matches the recursive unfolding of A(k+1,n)A(k+1, n) via the clauses A(k+1,0)=A(k,1)A(k+1, 0) = A(k, 1) and A(k+1,y+1)=A(k,A(k+1,y))A(k+1, y+1) = A(k, A(k+1, y)), adjusted for the iteration count and initial value. For small values of mm, the unary functions admit closed forms that illustrate their growth. Specifically, α1(n)=2n+3\alpha_1(n) = 2n + 3, obtained by iterating the successor-like α0\alpha_0 exactly n+1n+1 times on nn, yielding n+(n+1)1+2n + (n+1) \cdot 1 + 2 after alignment with standard base adjustments. Similarly, α2(n)=2n+33\alpha_2(n) = 2^{n+3} - 3, arising from iterating the linear α1\alpha_1 n+1n+1 times on nn, which produces exponential growth via repeated doubling plus offsets. These examples highlight how the formulation layers simple operations into hyper-exponential behavior. This perspective underscores the Ackermann function's connection to transfinite recursion, as the hierarchy αm\alpha_m mirrors the fast-growing hierarchy of functions indexed by ordinals below ε0\varepsilon_0, where each αm\alpha_m corresponds to recursion along finite ordinals, extending primitive recursion to transfinite levels while remaining computable.

Hyperoperation Interpretation

The hyperoperation sequence provides a unified framework for extending basic arithmetic operations into an infinite hierarchy of increasingly powerful functions. Defined recursively, the hyperoperations Hk(a,b)H_k(a, b) begin with the successor function as H0(a,b)=b+1H_0(a, b) = b + 1, followed by addition H1(a,b)=a+bH_1(a, b) = a + b, multiplication H2(a,b)=a×bH_2(a, b) = a \times b, exponentiation H3(a,b)=abH_3(a, b) = a^b, tetration H4(a,b)=baH_4(a, b) = {^{b}a}, and higher operations such as pentation and beyond for k5k \geq 5, where each level iterates the previous one. This sequence, introduced by Reuben Goodstein in 1947, generalizes arithmetic progression by nesting operations to produce functions of rapidly increasing growth rates. The Ackermann function aligns closely with this hyperoperation hierarchy, offering an explicit diagonalization over the sequence for specific arguments. In the standard two-argument formulation A(m,n)A(m, n), the values correspond to hyperoperations applied with base 2 and adjusted arguments: A(m, n) = H_m(2, n + 3) - 3. This mapping positions the Ackermann function as a concrete realization of hyperoperations starting from successor, with each increment in mm elevating the operation level. Particularly notable is the case for m=4m = 4, where A(4,n)A(4, n) embodies tetration: A(4,n)=2(n+3)3A(4, n) = 2 \uparrow\uparrow (n + 3) - 3, using Knuth's up-arrow notation in which \uparrow\uparrow denotes iterated exponentiation (tetration). Here, 2k2 \uparrow\uparrow k stacks exponentiations of 2 to height k1k - 1, yielding values like A(4, 0) = 13 = 2^2^2^2 - 3 (with right-associativity) and exploding to immense scales for larger nn. Despite this alignment, the Ackermann function exhibits limitations relative to the full hyperoperation framework, as it fixes the base at 2 and applies a linear adjustment (n+33n + 3 - 3), effectively diagonalizing only a subset of the hierarchy rather than encompassing arbitrary bases or unadjusted heights. Consequently, while A(m,n)A(m, n) captures the essence of hyperoperations up to level mm, it grows more slowly than generalized hyperoperations like Hm(a,b)H_m(a, b) for a>2a > 2 or without offsets, highlighting its role as a primitive recursive diagonal rather than the complete hierarchy.

Evaluation

Small Values Table

The Ackermann function produces small, manageable values for low arguments but escalates dramatically as inputs increase, highlighting its non-primitive recursive nature. The table below enumerates A(m, n) for m ranging from 0 to 4 and n from 0 to 6, based on the standard two-argument formulation. For m ≤ 3, all values are explicitly computable as integers; for m = 4 and n ≥ 2, the results exceed practical numerical representation and are expressed in closed form with approximate scale indicators.
n \ m01234
0123513
12351365,533
2347292^{65,536} - 3 (19,729 digits)
345961^{6}2 - 3 (∼10^{19,728} digits)
45611125^{7}2 - 3 (incomprehensibly large)
56713253^{8}2 - 3 (incomprehensibly large)
67815509^{9}2 - 3 (incomprehensibly large)
These computations demonstrate the function's alignment with basic arithmetic operations for small m: successor for m=0, addition for m=1, multiplication for m=2, and exponentiation for m=3, transitioning to tetration (iterated exponentiation) at m=4. By A(4, 2), the value surpasses 10^{19,000}, rendering exact decimal expansion infeasible on conventional hardware, while higher entries like A(4, 3) involve towers of exponents that defy direct notation or storage. This swift escalation underscores why the Ackermann function serves as a benchmark for recursive growth beyond primitive recursion.

Computational Methods

The Ackermann function is most commonly evaluated using its standard recursive definition, which proceeds by structural induction on the first argument mm, with the base case m=0m = 0 yielding n+1n + 1, the case n=0n = 0 reducing to a call on m1m - 1, and the general case nesting a recursive call on n1n - 1 within another on m1m - 1. This approach leverages tail recursion in certain branches, such as the inner recursion on nn, allowing optimization to an iterative loop in functional languages that support tail-call elimination. However, the double recursion inherent in the definition leads to exponential call stack growth, causing stack overflow in naive implementations for values beyond small inputs like A(4,1)A(4, 1). To address recursion depth issues, iterative implementations replace recursive calls with explicit loops, particularly for fixed small mm, where the function corresponds to basic hyperoperations. For instance, A(0,n)A(0, n) is the successor function, implemented as a single increment; A(1,n)A(1, n) as addition via a loop adding 1, nn times; A(2,n)A(2, n) as multiplication via a nested loop simulating repeated addition; and A(3,n)A(3, n) as exponentiation via further nesting for repeated multiplication. These LOOP-program-style constructions build progressively toward the full Ackermann by composing bounded iterations for lower mm, though higher mm requires hybrid approaches combining loops with limited recursion or stack simulation to avoid overflow. In formal verification and automated reasoning, the Ackermann function is often handled via term rewriting systems (TRS), where reduction rules mirror the recursive cases for stepwise simplification. A standard 2-ary TRS uses the signature with constants 0, successor S, and binary Ackermann symbol A, with rules A(0,x)S(x)A(0, x) \to S(x), A(S(x),0)A(x,S(0))A(S(x), 0) \to A(x, S(0)), and A(S(x),S(y))A(x,A(S(x),y))A(S(x), S(y)) \to A(x, A(S(x), y)), enabling confluent normalization for ground terms. Equivalent iterated unary or hyperoperation-based TRS variants rewrite terms by unfolding to successor chains or Knuth up-arrow notation, facilitating proof of termination and complexity analysis through orderings like lexicographic path order. Practical computations for small values benefit from optimizations like memoization, caching intermediate results in a table indexed by (m,n)(m, n) to eliminate redundant subcomputations, as the function's tree of calls has significant overlap. Incrementalization techniques further enhance efficiency by updating only changed parts in recursive self-calls, yielding programs up to 30 times faster than naive recursion for feasible inputs, often via loop unrolling or dynamic programming.

Growth Rate Analysis

The Ackermann function demonstrates extraordinarily rapid growth, outpacing any primitive recursive function asymptotically. For any primitive recursive function f:NNf: \mathbb{N} \to \mathbb{N}, the diagonal values A(n,n)A(n, n) eventually exceed f(n)f(n) for sufficiently large nn, as formalized by the majorization relation where A(n,n)A(n, n) dominates all such ff. This property arises from the function's recursive structure, which allows it to iterate operations in a way that escapes the bounded recursion schema defining primitive recursiveness. In terms of asymptotic behavior, the growth escalates dramatically with the first argument mm. For fixed mm, A(m,n)A(m, n) aligns with increasingly powerful hyperoperations as nn grows, but the overall function A(m,n)A(m, n) transcends primitive recursive bounds when considering varying mm. Specifically, A(4,n)A(4, n) grows comparably to tetration, approximately 2(n+3)32 \uparrow\uparrow (n+3) - 3 in Knuth's up-arrow notation, representing iterated exponentiation towers of height linear in nn. This places the function beyond exponentiation (which corresponds roughly to A(3,n)2n+33A(3, n) \approx 2^{n+3} - 3) at m=3m=3, and beyond tetration at m=4m=4, embedding it within the hyperoperation hierarchy where each increment in mm advances to the next level of iterated operations. The explosive growth yields numbers vastly exceeding well-known large values. Such magnitudes highlight the function's role as a foundational benchmark in notations for enormous numbers, including extensions like Bowers' Exploding Array Function (BEAF) and the Subcubic Graph numbers (SCG(13) and beyond), which leverage or exceed Ackermann-level growth to define even larger constructs in combinatorial and googological contexts. As a diagonalization over the primitive recursive functions, the Ackermann function systematically constructs values that outgrow any fixed level of the primitive recursive hierarchy, leading to extensions in higher computability theory where analogous diagonal arguments yield uncomputably large growth rates. This diagonal nature underscores its significance in separating recursive from primitive recursive classes, with implications for understanding limits of computable growth.

Properties

Functional Characteristics

The Ackermann function A(m,n)A(m, n) is a total recursive function, defined for all natural numbers mm and nNn \in \mathbb{N}, with its recursive computation guaranteed to terminate for every input pair due to the well-founded nature of the underlying recursion on natural numbers. In general, the Ackermann function is not commutative, meaning A(m,n)A(n,m)A(m, n) \neq A(n, m) for most pairs (m,n)(m, n). For instance, under the standard definition, A(1,0)=3A(1, 0) = 3 while A(0,1)=2A(0, 1) = 2, illustrating the asymmetry. However, equality holds for specific low values, such as (0,0)(0, 0) where A(0,0)=1A(0, 0) = 1, (1,1)(1, 1) where A(1,1)=4A(1, 1) = 4, and (2,2)(2, 2) where A(2,2)=7A(2, 2) = 7; for small fixed mm, the function reduces to commutative operations like successor or addition, yielding limited symmetries in those cases. The Ackermann function exhibits extensional equivalence to certain fast-growing hierarchies, particularly corresponding to the ordinal ωω\omega^\omega level, where the diagonal A(n,n)A(n, n) aligns with fω(n)f_\omega(n) in the standard fast-growing hierarchy. This placement underscores its role among computable fast-growing functions, though uncomputable ones like the Busy Beaver function eventually surpass it in growth for large arguments.

Non-Primitive Recursiveness

Primitive recursive functions form the smallest class of total functions from natural numbers to natural numbers that includes the constant zero function, the successor function, and the projection functions (which select arguments), and is closed under the operations of composition and primitive recursion. Primitive recursion allows defining a function h(x,0)=f(x)h(x, 0) = f(x) and h(x,y+1)=g(x,y,h(x,y))h(x, y+1) = g(x, y, h(x, y)) for some previously defined functions ff and gg, corresponding intuitively to bounded for-loops with fixed nesting depth. The Ackermann function demonstrates non-primitive recursiveness by growing faster than any function obtainable through a fixed finite number of primitive recursions. In Wilhelm Ackermann's original 1928 formulation, a three-argument function ϕ(x,y,z)\phi(x, y, z) was defined recursively on zz: ϕ(x,y,0)=x+y\phi(x, y, 0) = x + y, ϕ(x,0,z+1)=α(x,z)\phi(x, 0, z+1) = \alpha(x, z), ϕ(x,y+1,z+1)=ϕ(x,ϕ(x,y,z+1),z)\phi(x, y+1, z+1) = \phi(x, \phi(x, y, z+1), z), where α(x,0)=0\alpha(x, 0) = 0, α(x,1)=1\alpha(x, 1) = 1, and α(x,z)=x\alpha(x, z) = x for z2z \geq 2. Ackermann argued that this function cannot be primitive recursive because, for any purported primitive recursive approximation with fixed recursion depth, the function's value at sufficiently large arguments exceeds the growth bound of that approximation, leading to a contradiction. A modern simplification to a two-argument form, introduced by Rózsa Péter in 1935, defines A(m,n)A(m, n) with base cases A(0,n)=n+1A(0, n) = n + 1 and A(m+1,0)=A(m,1)A(m+1, 0) = A(m, 1), and recursive case A(m+1,n+1)=A(m,A(m+1,n))A(m+1, n+1) = A(m, A(m+1, n)). The proof of non-primitive recursiveness proceeds by contradiction: assume AA is primitive recursive, so the diagonal f(n)=A(n,n)f(n) = A(n, n) is primitive recursive and thus majorized by some function with fixed primitive recursion nesting depth kk, equivalent to iterated exponentiation of height k+2k+2 (as in Kalmár elementary functions for small kk). However, f(n)f(n) grows like the nn-th hyperoperation applied to nn, outpacing any fixed-height iteration for n>kn > k, yielding a contradiction. This separation highlights that while all primitive recursive functions are total and computable (in the sense of general recursive functions via the μ\mu-operator), the converse does not hold; the Ackermann function is total recursive but not primitive recursive, delineating a fundamental boundary in recursion theory between these classes.

Inverse

Definition

The inverse Ackermann function, commonly denoted α(n)\alpha(n), is a slow-growing function that serves as a partial inverse to the rapidly growing Ackermann function A(m,n)A(m, n). The standard variant in theoretical computer science, known as the diagonal inverse, defines α(n)\alpha(n) as the smallest non-negative integer kk such that A(k,k)nA(k, k) \geq n, where the diagonal refers to evaluating the Ackermann function at equal arguments. This diagonal form often simplifies analysis in contexts like algorithm complexity, as it captures the function's extreme slowness in a single-variable setup. The inverse Ackermann function can also be characterized recursively through a hierarchy of inverse operations aligned with the Ackermann hierarchy. For instance, level-wise inverses are defined as αk(x)=min{n:Ak(n)x}\alpha_k(x) = \min \{ n : A_k(n) \geq x \} for each level k1k \geq 1, where AkA_k denotes the kk-th row of the Ackermann function, building up to the full α(n)\alpha(n) via minimization over kk. These recursive structures underscore α(n)\alpha(n)'s computability within primitive recursive bounds, contrasting sharply with the non-primitive recursive nature of the original Ackermann function. Both variants highlight α(n)\alpha(n)'s role as an inverse: while the Ackermann function A(m,n)A(m, n) outpaces any primitive recursive function in growth rate, its inverse α(n)\alpha(n) increases so gradually that it remains below 5 for all practically relevant values of nn up to enormous scales.

Asymptotic Behavior

The inverse Ackermann function α(n)\alpha(n) exhibits extraordinarily slow growth, rendering it effectively constant for all computationally relevant values of nn. For the standard diagonal inverse using the Péter Ackermann function, α(n)=3\alpha(n) = 3 for 8n618 \leq n \leq 61, α(n)=4\alpha(n) = 4 for 62nA(4,4)27362 \leq n \leq A(4,4) \approx 2 \uparrow\uparrow 7 - 3, and α(n)=5\alpha(n) = 5 only beyond that immense threshold up to A(5,5)A(5,5), which involves pentation. Note that in some computer science contexts, slightly modified Ackermann variants are used, leading to adjusted thresholds (e.g., α(n)=4\alpha(n) = 4 up to scales like 2(216+3)32 \uparrow\uparrow (2^{16} + 3) - 3), but the qualitative behavior of near-constancy remains the same. Asymptotically, α(n)logn\alpha(n) \sim \log^* n, where logn\log^* n denotes the iterated logarithm, representing the number of times the base-2 logarithm must be applied to nn to reduce it below a constant threshold (typically 1 or 2). However, in practice, α(n)\alpha(n) advances even more sluggishly than logn\log^* n due to the specific alignment with the Ackermann function's diagonal growth, where the functional iterations align with hyperoperation levels rather than pure logarithmic reductions. A proof of this slow growth proceeds by induction on the hyperoperation levels implicit in the Ackermann function's definition. The base cases for small kk verify that α(n)\alpha(n) stabilizes at low values for modest nn, such as α(n)=3\alpha(n) = 3 for n61n \leq 61. Assuming the induction hypothesis that α(m)k\alpha(m) \leq k for all mm below the threshold where the (k+1)(k+1)-th hyperoperation dominates, the next level requires nn to exceed the Ackermann value A(k,k)A(k, k), which grows beyond any fixed iteration of the previous level—ensuring the increment occurs only at exponentially larger scales. This inductive step confirms that each increase in α(n)\alpha(n) demands an escalation through the entire hyperoperation sequence, bounding the function tightly for practical domains. In comparison to other slow-growing functions, α(n)\alpha(n) increases more gradually than any logarithm iterated a fixed finite number of times (e.g., slower than loglogn\log \log n or logloglogn\log \log \log n), yet remains unbounded as nn \to \infty, eventually surpassing any constant but only after traversing incomprehensible magnitudes. This positions α(n)\alpha(n) as a canonical example of a function that is asymptotically negligible in complexity analyses while theoretically diverging.

Applications

Complexity Theory

The Ackermann function serves as a fundamental bound in defining complexity classes that extend beyond primitive recursive and elementary computations. The Ackermann class, often denoted as the set of problems solvable by deterministic Turing machines in time or space O(A(n, n)), where A(n, n) is the diagonal of the Ackermann function, captures computations that grow faster than any primitive recursive bound but remain within recursive functions. This class is equivalent to the union over all primitive recursive polynomials p of DTIME(F_ω(p(n))), where F_ω denotes the fast-growing hierarchy function at level ω, which coincides with the Ackermann function. Such classes are crucial for studying hierarchies in computational complexity that surpass polynomial or even exponential time. A key relation exists between the Ackermann function and elementary functions, which form the third level (ℰ³) of the Grzegorczyk hierarchy. Functions in ℰ³, known as Kalmár elementary functions, are computable in time bounded by iterated exponentials of fixed height, precisely upper-bounded by growth rates akin to A(3, n) ≈ 2↑↑(n + 3) − 3 in Knuth up-arrow notation. In contrast, the full Ackermann function A(m, n) for m ≥ 4 exceeds any fixed level of the Grzegorczyk hierarchy, defining non-elementary complexity classes that require hyper-exponential resources. This distinction highlights how A(3, n) marks the boundary for elementary time, while higher values of A(m, n) delineate super-elementary behaviors. The Ackermann function also facilitates advanced techniques in complexity theory, including its application in oracle Turing machines and relativization arguments. Oracle machines equipped with oracles allowing Ackermann-level computations can relativize results about primitive recursive separations, enabling proofs of hierarchy theorems in relativized worlds. Specifically, diagonalization over the Grzegorczyk hierarchy constructs the Ackermann function itself, and similar diagonalization in time complexity shows that TIME(A(n)) strictly contains the union of TIME(f(n)) over all primitive recursive f, establishing proper separations in non-elementary time classes. These connections underscore the Ackermann function's role in bounding resources for oracle-augmented models and proving structural properties of complexity hierarchies.

Discrete Geometry

The inverse Ackermann function α(n) plays a crucial role in the analysis of union-find data structures, which are fundamental to many algorithms in discrete geometry, such as dynamic maintenance of connectivity in point sets or incremental construction of geometric graphs. In these structures, path compression with union by rank achieves an amortized time complexity of O(α(n)) per operation, where α(n) is the smallest integer k such that the Ackermann function A(k, 3) ≥ n; this bound effectively eliminates extra logarithmic factors beyond linear time in nearly all practical scenarios. This efficiency is particularly valuable in geometric applications, where union-find operations manage mergers and queries in evolving structures like Voronoi diagrams or arrangements, ensuring that the overall algorithm remains quasi-linear despite the super-exponential growth of the underlying Ackermann function. In higher-dimensional order types, Ackermann-like growth emerges in the combinatorial complexity of arrangements, where the number of regions or cells defined by hyperplane or pseudoline arrangements can exhibit rapid escalation as dimensionality increases, though practical constructions leverage inverse Ackermann bounds to achieve efficient enumeration. For instance, randomized incremental algorithms for building arrangements in d dimensions rely on union-find to track conflicts and adjacencies, yielding total time complexities of O(n^{d/2} α(n)) for n objects, which captures the subtle overhead from path compression in maintaining the order type's topological structure. This integration highlights how the slow growth of α(n) tames the otherwise explosive proliferation of regions, enabling computational feasibility in problems like motion planning or visibility decompositions in higher dimensions. Variants of Szemerédi's theorem in multidimensional settings invoke Ackermann hierarchies to quantify bounds on arithmetic progressions within geometric configurations, such as subsets of the integer lattice. In the proof of the multidimensional Szemerédi theorem, the regularity lemma for hypergraphs produces partition sizes that ascend levels in the Ackermann hierarchy with increasing progression length k, leading to quantitative bounds of the form exp_k (log n / log log n) or higher, where exp_k denotes iterated exponentials akin to Ackermann levels. These hierarchy-based estimates are essential for geometric applications, like analyzing progression-free sets in grids, where the theorem ensures that dense point sets in Z^d contain k-term progressions, with proof complexities reflecting the non-primitive recursive nature of the Ackermann function. In geometric set theory, particularly Vapnik-Chervonenkis (VC) theory applied to range spaces, the Ackermann function indirectly influences bounds on shattering dimensions through its inverse in epsilon-net constructions for geometric objects. For range spaces of constant VC dimension, such as halfspaces or balls in Euclidean space, the minimal epsilon-net size is Θ( (1/ε) log(1/ε) ), but lower bounds for certain low-dimensional geometric families, such as axis-parallel rectangles in the plane, reach Ω(α(1/ε)), involving the inverse Ackermann function α to capture the overhead in shattering large point sets. This connection underscores the role of fast-growing hierarchies in limiting the expressive power of geometric hypothesis classes, ensuring learnability while bounding the combinatorial explosion in shattered subsets.

Benchmarking Computations

The Ackermann function is frequently employed as a stress test for programming languages, compilers, and runtime environments to evaluate their handling of deep recursion and stack management. Computations of values like A(4,1), which equals 65,533, or A(4,2), which equals 2^{65536} - 3, demand exceptionally high stack depths in naive recursive implementations, often exceeding default limits and causing stack overflows. This makes it an effective benchmark for assessing recursion optimization techniques, such as tail-call optimization, and the overall robustness of a language's call stack. Historical benchmarks have highlighted the Ackermann function's utility in testing recursion handling in functional languages like Haskell and Scheme. In Haskell, optimized implementations using techniques like continuation-passing style (CPS) can compute A(3,11) in seconds, while non-optimized recursive versions may take minutes or fail due to stack exhaustion. Similarly, Scheme implementations in Lisp dialects, which guarantee proper tail-call optimization per the language standard, can handle larger arguments efficiently for many recursive functions. In contrast, Python's default recursion limit of 1,000 frames restricts it to smaller inputs like A(3,4) = 125, beyond which sys.setrecursionlimit() must be invoked to avoid RuntimeError, though this risks system instability.
Language/CompilerImplementationRunning Time for A(3, n) (approx.)
C (gcc)Recursive3.76 seconds
C (gcc -O4)Optimized0.35 seconds
Java (HotSpot)Recursive2.35 seconds
These results, from early 2010s benchmarks, illustrate how compiler optimizations can dramatically reduce computation time for A(3, n) where n ≈ 12, emphasizing the function's role in measuring recursive efficiency. In modern contexts, the Ackermann function benchmarks performance in emerging platforms like WebAssembly (Wasm), where recursive implementations reveal performance gaps compared to native code, often due to limited inlining and optimization support. Benchmarks show that certain optimizations, such as function inlining, can lead to slowdowns in Wasm runtimes, highlighting areas for improvement in browser-based computing. GPU adaptations remain exploratory, focusing on parallelizing hyperoperations for larger arguments, though the inherently sequential nature limits scalability. Variants using μ-recursive definitions provide a framework for testing the function's totality in formal verification systems. These implementations express the Ackermann function via primitive recursive operations plus the minimization operator (μ), which searches for the smallest index satisfying a condition, allowing simulation on Turing-complete models to confirm computability without primitive recursion. Such encodings are used in proof assistants like Coq to verify that the function halts for all inputs, distinguishing it from non-total functions.

References

  1. -Sch.pdf
Add your contribution
Related Hubs
User Avatar
No comments yet.