Details
The function fun must be specified as a rule: head[var]→form[var, head], where var and head are free symbols for the integer domain and range of a recursive function in some particular form. Both var and head[var] are assumed to take on integer values, usually positive.
The
inits must also be specified as a rule or as a list of rules of the form:
conditioni[
var] →
vali. When an integer value
m is assigned to
var, each
conditioni[
m] is checked by
TrueQ. When one
conditioni[
m] evaluates to
True, the function value is set as
head[
m]=
vali.
The initial value
vali can also be a function of
var, i.e.
conditioni[
var] →
vali[
var], in which case a
True conditioni[
m] leads to the assignment
head[
m]=
vali[
m].
For example,
fun=f[n]→f[n-1]+f[n-2] is the form of a typical linear recurrence with
head=f,
var=n, and
form=Function[#2[#1-1]+#2[#1-2]]. The
Fibonacci numbers have a special initial condition,
inits={
n<=1→n}, where
condition=Function[#1<=1] with
val=n. The initial condition can also be written as
inits={n==0→0,n==1→1}, with two
conditioni and two
vali variables.
Linear recurrences such as
Fibonacci are relatively easy examples. Their values can be easily computed by
RecurrenceTable or RecursiveFunction. This resource RecursiveFunction can additionally compute values of nestedly recursive functions, where
RecurrenceTable fails with an error message.
Nestedly recursive functions are recursive functions where the right-hand-side of fun contains a term like head[…] that again contains one or more instances of head[…] somewhere in its argument pattern. For example, the Hofstadter G function is defined by fun=f[n]→n-f[f[n-1]] with inits={n==0→0}.
The option
Method can be set to either "Stack" or "SelfReferential". The default "Stack" method never experiences difficulties with
$RecursionLimit. The "SelfReferential" method can typically compute the same data in shorter time, but might encounter
TerminatedEvaluation via
$RecursionLimit.
To avoid runaway iterations, it is generally assumed that evaluation of
f[
n] does not depend on any
f[
m] satisfying
0<n<m. If and when this condition becomes invalid, a
Failure object is thrown. This pragmatic feature is nice to have when exploring function spaces.