In
computability theory
Computability theory, also known as recursion theory, is a branch of mathematical logic, computer science, and the theory of computation that originated in the 1930s with the study of computable functions and Turing degrees. The field has since e ...
, a primitive recursive function is roughly speaking a function that can be computed by a
computer program
A computer program is a sequence or set of instructions in a programming language for a computer to execute. Computer programs are one component of software, which also includes documentation and other intangible components.
A computer progra ...
whose
loops are all
"for" loops (that is, an upper bound of the number of iterations of every loop can be determined before entering the loop). Primitive recursive functions form a strict
subset
In mathematics, Set (mathematics), set ''A'' is a subset of a set ''B'' if all Element (mathematics), elements of ''A'' are also elements of ''B''; ''B'' is then a superset of ''A''. It is possible for ''A'' and ''B'' to be equal; if they are ...
of those
general recursive functions that are also
total functions.
The importance of primitive recursive functions lies in the fact that most computable functions that are studied in
number theory (and more generally in mathematics) are primitive recursive. For example,
addition
Addition (usually signified by the Plus and minus signs#Plus sign, plus symbol ) is one of the four basic Operation (mathematics), operations of arithmetic, the other three being subtraction, multiplication and Division (mathematics), division. ...
and
division, the
factorial
In mathematics, the factorial of a non-negative denoted is the product of all positive integers less than or equal The factorial also equals the product of n with the next smaller factorial:
\begin
n! &= n \times (n-1) \times (n-2) \t ...
and
exponential function, and the function which returns the ''n''th prime are all primitive recursive. In fact, for showing that a computable function is primitive recursive, it suffices to show that its
time complexity is bounded above by a primitive recursive function of the input size. It is hence not that easy to devise a
computable function that is ''not'' primitive recursive; some examples are shown in section below.
The set of primitive recursive functions is known as
PR in
computational complexity theory.
Definition
A primitive recursive function takes a fixed number of arguments, each a
natural number (nonnegative integer: ), and returns a natural number. If it takes ''n'' arguments it is called ''n''-
ary ARY may stand for:
* Abdul Razzak Yaqoob, a Pakistani expatriate businessman
* Andre Romelle Young, real name of Dr. Dre
* Ary and the Secret of Seasons, an action adventure video game
* ARY Digital, a Pakistani television network
* ARY Digital Net ...
.
The basic primitive recursive functions are given by these
axiom
An axiom, postulate, or assumption is a statement that is taken to be true, to serve as a premise or starting point for further reasoning and arguments. The word comes from the Ancient Greek word (), meaning 'that which is thought worthy or f ...
s:
More complex primitive recursive functions can be obtained by applying the
operation
Operation or Operations may refer to:
Arts, entertainment and media
* ''Operation'' (game), a battery-operated board game that challenges dexterity
* Operation (music), a term used in musical set theory
* ''Operations'' (magazine), Multi-Man ...
s given by these axioms:
The primitive recursive functions are the basic functions and those obtained from the basic functions by applying these operations a finite number of times.
Examples
Addition
A definition of the 2-ary function
, to compute the sum of its arguments, can be obtained using the primitive recursion operator
. To this end, the well-known equations
:
are "rephrased in primitive recursive function terminology": In the definition of
, the first equation suggests to choose
to obtain
; the second equation suggests to choose
to obtain
. Therefore, the addition function can be defined as
. As a computation example,
:
Doubling
Given
, the 1-ary function
doubles its argument,
.
Multiplication
In a similar way as addition, multiplication can be defined by
. This reproduces the well-known multiplication equations:
:
and
:
Predecessor
The predecessor function acts as the "opposite" of the successor function and is recursively defined by the rules
and
. A primitive recursive definition is
. As a computation example,
:
Truncated subtraction
The limited subtraction function (also called "
monus", and denoted "
") is definable from the predecessor function. It satisfies the equations
:
Since the recursion runs over the second argument, we begin with a primitive recursive definition of the reversed subtraction,
. Its recursion then runs over the first argument, so its primitive recursive definition can be obtained, similar to addition, as
. To get rid of the reversed argument order, then define
. As a computation example,
:
Converting predicates to numeric functions
In some settings it is natural to consider primitive recursive functions that take as inputs tuples that mix numbers with
truth values (that is ''t'' for true and ''f'' for false), or that produce truth values as outputs. This can be accomplished by identifying the truth values with numbers in any fixed manner. For example, it is common to identify the truth value ''t'' with the number 1 and the truth value ''f'' with the number 0. Once this identification has been made, the
characteristic function of a set ''A'', which always returns 1 or 0, can be viewed as a predicate that tells whether a number is in the set ''A''. Such an identification of predicates with numeric functions will be assumed for the remainder of this article.
Predicate "Is zero"
As an example for a primitive recursive predicate, the 1-ary function
shall be defined such that
if
, and
, otherwise. This can be achieved by defining
. Then,
and e.g.
.
Predicate "Less or equal"
Using the property
, the 2-ary function
can be defined by
. Then
if
, and
, otherwise. As a computation example,
:
Predicate "Greater or equal"
Once a definition of
is obtained, the converse predicate can be defined as
. Then,
is true (more precisely: has value 1) if, and only if,
.
If-then-else
The 3-ary if-then-else operator known from programming languages can be defined by
. Then, for arbitrary
,
:
and
:
.
That is,
returns the then-part,
, if the if-part,
, is true, and the else-part,
, otherwise.
Junctors
Based on the
function, it is easy to define logical junctors. For example, defining
, one obtains
, that is,
is true
if, and only if, both
and
are true (
logical conjunction of
and
).
Similarly,
and
lead to appropriate definitions of
disjunction and
negation
In logic, negation, also called the logical complement, is an operation that takes a proposition P to another proposition "not P", written \neg P, \mathord P or \overline. It is interpreted intuitively as being true when P is false, and false ...
:
and
.
Equality predicate
Using the above functions
,
and
, the definition
implements the equality predicate. In fact,
is true if, and only if,
equals
.
Similarly, the definition
implements the predicate "less-than", and
implements "greater-than".
Other operations on natural numbers
Exponentiation and
primality test
A primality test is an algorithm for determining whether an input number is prime. Among other fields of mathematics, it is used for cryptography. Unlike integer factorization, primality tests do not generally give prime factors, only stating whet ...
ing are primitive recursive. Given primitive recursive functions ''e'', ''f'', ''g'', and ''h'', a function that returns the value of ''g'' when ''e''≤''f'' and the value of ''h'' otherwise is primitive recursive.
Operations on integers and rational numbers
By using
Gödel numbering
In mathematical logic, a Gödel numbering is a function that assigns to each symbol and well-formed formula of some formal language a unique natural number, called its Gödel number. The concept was developed by Kurt Gödel for the proof of ...
s, the primitive recursive functions can be extended to operate on other objects such as integers and
rational numbers. If integers are encoded by Gödel numbers in a standard way, the arithmetic operations including addition, subtraction, and multiplication are all primitive recursive. Similarly, if the rationals are represented by Gödel numbers then the
field operations are all primitive recursive.
Some common primitive recursive functions
:The following examples and definitions are from Kleene (1952) pp. 223–231 — many appear with proofs. Most also appear with similar names, either as proofs or as examples, in Boolos-Burgess-Jeffrey 2002 pp. 63–70; they add the logarithm lo(x, y) or lg(x, y) depending on the exact derivation.
In the following we observe that primitive recursive functions can be of four types:
# ''functions'' for short: "number-theoretic functions" from to ,
# ''predicates'': from to truth values ,
# ''propositional connectives'': from truth values to truth values ,
# ''representing functions'': from truth values to . Many times a predicate requires a representing function to convert the predicate's output to (note the order "t" to "0" and "f" to "1" matches with ~sg( ) defined below). By definition a function φ(x) is a "representing function" of the predicate P(x) if φ takes only values 0 and 1 and produces ''0'' when P is true".
In the following the mark " ' ", e.g. a', is the primitive mark meaning "the successor of", usually thought of as " +1", e.g. a +1 =
def a'. The functions 16-20 and #G are of particular interest with respect to converting primitive recursive predicates to, and extracting them from, their "arithmetical" form expressed as
Gödel numbers.
:# Addition: a+b
:# Multiplication: a×b
:# Exponentiation: a
b
:# Factorial a! : 0! = 1, a'! = a!×a'
:# pred(a): (Predecessor or decrement): If a > 0 then a-1 else 0
:# Proper subtraction a ∸ b: If a ≥ b then a-b else 0
:# Minimum(a
1, ... a
n)
:# Maximum(a
1, ... a
n)
:# Absolute difference: , a-b , =
def (a ∸ b) + (b ∸ a)
:# ~sg(a): NOT
ignum(a) If a=0 then 1 else 0
:# sg(a): signum(a): If a=0 then 0 else 1
:# a , b: (a divides b): If b=k×a for some k then 0 else 1
:# Remainder(a, b): the leftover if b does not divide a "evenly". Also called MOD(a, b)
:# a = b: sg , a - b , (Kleene's convention was to represent ''true'' by 0 and ''false'' by 1; presently, especially in computers, the most common convention is the reverse, namely to represent ''true'' by 1 and ''false'' by 0, which amounts to changing sg into ~sg here and in the next item)
:# a < b: sg( a' ∸ b )
:# Pr(a): a is a prime number Pr(a) =
def a>1 & NOT(Exists c)
1 a :# pi: the i+1-st prime number
:# (a)i: exponent of pi in a: the unique x such that pix, a & NOT(pix', a)
:# lh(a): the "length" or number of non-vanishing exponents in a
:# lo(a, b): (logarithm of a to base b): If a, b > 1 then the greatest x such that bx , a else 0
: ''In the following, the abbreviation x =def x1, ... xn; subscripts may be applied if the meaning requires.''
* #A: A function φ definable explicitly from functions Ψ and constants q1, ... qn is primitive recursive in Ψ.
* #B: The finite sum Σy ψ(x, y) and product Πyψ(x, y) are primitive recursive in ψ.
* #C: A ''predicate'' P obtained by substituting functions χ1,..., χm for the respective variables of a predicate Q is primitive recursive in χ1,..., χm, Q.
* #D: The following ''predicates'' are primitive recursive in Q and R:
::* NOT_Q(x) .
::* Q OR R: Q(x) V R(x),
::* Q AND R: Q(x) & R(x),
::* Q IMPLIES R: Q(x) → R(x)
::* Q is equivalent to R: Q(x) ≡ R(x)
* #E: The following ''predicates'' are primitive recursive in the ''predicate'' R:
::* (Ey)y R(x, y) where (Ey)y denotes "there exists at least one y that is less than z such that"
::* (y)y R(x, y) where (y)y denotes "for all y less than z it is true that"
::* μyy R(x, y). The operator μyy R(x, y) is a ''bounded'' form of the so-called minimization- or mu-operator: Defined as "the least value of y less than z such that R(x, y) is true; or z if there is no such value."
* #F: Definition by cases: The function defined thus, where Q1, ..., Qm are mutually exclusive ''predicates'' (or "ψ(x) shall have the value given by the first clause that applies), is primitive recursive in φ1, ..., Q1, ... Qm:
:: φ(x) =
::* φ1(x) if Q1(x) is true,
::* . . . . . . . . . . . . . . . . . . .
::* φm(x) if Qm(x) is true
::* φm+1(x) otherwise
* #G: If φ satisfies the equation:
:: φ(y,x) = χ(y, COURSE-φ(y; x2, ... xn ), x2, ... xn then φ is primitive recursive in χ. The value COURSE-φ(y; x2 to n ) of the course-of-values function encodes the sequence of values φ(0,x2 to n), ..., φ(y-1,x2 to n) of the original function.
Use in first-order Peano arithmetic
In first-order Peano arithmetic
In mathematical logic, the Peano axioms, also known as the Dedekind–Peano axioms or the Peano postulates, are axioms for the natural numbers presented by the 19th century Italian mathematician Giuseppe Peano. These axioms have been used nearly u ...
, there are infinitely many variables (0-ary symbols) but no k-ary non-logical symbols with k>0 other than S, +, *, and ≤. Thus in order to define primitive recursive functions one has to use the following trick by Gödel.
By using a Gödel numbering for sequences, for example Gödel's β function, any finite sequence of numbers can be encoded by a single number. Such a number can therefore represent the primitive recursive function until a given n.
Let ''h'' be a 1-ary primitive recursion function defined by:
:
:
where C is a constant and ''g'' is an already defined function.
Using Gödel's β function, for any sequence of natural numbers (k0, k1, ..., kn), there are natural numbers b and c such that, for every i ≤ n, β(b, c, i) = ki. We may thus use the following formula to define ''h''; more precisely, ''m''=''h''(''n'') is a shorthand for the following:
: