General Recursive Function: Difference between revisions

From BusyBeaverWiki
Jump to navigation Jump to search
JLM (talk | contribs)
→Primitive Recursive Functions: Define the 'R' operator.
HelpMe (talk | contribs)
elaborate
 
(107 intermediate revisions by 5 users not shown)
Line 5: Line 5:
'''BBµ'''(n) is a [[Busy Beaver function]] for GRFs:<math display="block">BB \mu (n) = \max \{ f() | f \in \text{GRF}_0 , |f| = n \}</math>
'''BBµ'''(n) is a [[Busy Beaver function]] for GRFs:<math display="block">BB \mu (n) = \max \{ f() | f \in \text{GRF}_0 , |f| = n \}</math>


where <math>f \in GRF_k</math> means that <math>f: \N^k \rightharpoonup \N</math> is a k-ary GRF and <math>|f|</math> is the "structural size" of ''f'' (defined below). In other words, it is the largest number computable via a 0-ary function (a constant) with a limited "program" size. It is more akin to the traditional [[Sigma score]] for a Turing machine rather than the Step function in the sense that it maximizes over the produced value, not the number of steps needed to reach that value.
where <math>f \in GRF_k</math> means that <math>f: \N^k \rightharpoonup \N</math> is a k-ary GRF and <math>|f|</math> is the "structural size" of ''f'' (the number of atoms and combinators in the definition, [[General Recursive Function#Size|see details below]]). In other words, it is the largest number computable via a 0-ary function (a constant) with a limited "program" size. It is more akin to the traditional [[Sigma score]] for a Turing machine rather than the Step function in the sense that it maximizes over the produced value, not the number of steps needed to reach that value.


== Definition ==
== Definition ==
Line 20: Line 20:
===== Combinators =====
===== Combinators =====


* Composition: <math>\forall k,m \in \N, \forall h \in GRF_m, \forall g_1, \dots g_m \in GRF_k, C(h, g_1, \dots g_m) \in GRF_k</math> is the composition or substitution of the gs into h <math>C(h, g_1, \dots g_m)(x_1, \dots x_k) = h(g_1(x_1, \dots x_k), \dots g_m(x_1, \dots x_k))</math>
* Composition: <math>\forall k,m \in \N, \forall h \in GRF_m, \forall g_1, \dots g_m \in GRF_k, C^k(h, g_1, \dots g_m) \in GRF_k</math> is the composition or substitution of the ''g''s into ''h'': <math>C^k(h, g_1, \dots g_m)(x_1, \dots x_k) = h(g_1(x_1, \dots x_k), \dots g_m(x_1, \dots x_k))</math>
* Primitive Recursion: <math>\forall k \in \N, \forall g \in GRF_k, \forall h \in GRF_{k+2}, R(g, h) \in GRF_{k+1}</math> is primitive recursion using g as the base case and h as the inductive step.
* Primitive Recursion: <math>\forall k \in \N, \forall g \in GRF_k, \forall h \in GRF_{k+2}, R^{k+1}(g, h) \in GRF_{k+1}</math> is primitive recursion using ''g'' as the base case and ''h'' as the inductive step.
* Minimization / Unlimited Search: <math>\forall k \in \N, \forall f \in GRF_{k+1}, M(f) \in GRF_k</math> is the µ-operator which allows unlimited search.
* Minimization / Unlimited Search: <math>\forall k \in \N, \forall f \in GRF_{k+1}, M^k(f) \in GRF_k</math> is the µ-operator which allows unlimited search.
The arity superscripts for C, R and M are redundant (except for <math>C^k(h)</math>) and so are sometimes omitted below.


=== Primitive Recursive Functions ===
=== Size ===
The size of a GRF is the number of atoms and combinators in the definition:
 
* <math>|Z^k| = |P^k_i| = |S| = 1</math>
* <math>|C(h, g_1, \cdots, g_m)| = 1 + |h| + |g_1| + \cdots + |g_m|</math>
* <math>|R(g, h)| = 1 + |g| + |h|</math>
* <math>|M(f)| = 1 + |f|</math>
 
=== Primitive Recursion ===
<math>R</math> models a typical iterative function definition over ℕ.
<math>R</math> models a typical iterative function definition over ℕ.


Line 30: Line 39:


Iterative case (for <math>x_1 > 0</math>): <math>R^k(g, h)(x_1, x_2, ..., x_k) = h(x_1-1, v, x_2, x_3, ..., x_k)</math> where <math>v = R(g, h)(x_1-1, x_2, x_3, ..., x_k)</math>.
Iterative case (for <math>x_1 > 0</math>): <math>R^k(g, h)(x_1, x_2, ..., x_k) = h(x_1-1, v, x_2, x_3, ..., x_k)</math> where <math>v = R(g, h)(x_1-1, x_2, x_3, ..., x_k)</math>.
''R'' can be recursively evaluated following its definition directly or it can be simulated as a bounded <code>for</code> loop like this python code:<pre>
# f = R(g,h)
def f(n, *xs):
  acc = g(*xs)
  for k in range(n):
    acc = h(k, acc, *xs)
  return acc
</pre>The iterative function ''h'' is passed two synthetic args in the front: (''k'') iteration number (0-indexed) and (''acc'') "accumulator" from previous iterations.
Both the base and iterative cases can be parameterized by values <math>x_2, x_3, ..., x_k</math>.


<math>R</math> can be recursively evaluated following its definition directly.  Or it can be iterated over its first argument, starting with 0 (and thus a call to <math>g</math>), then 1, 2, 3, etc. until <math>x_1</math> is reached, each time calling <math>h</math> with the iteration count for its first argument and the result of the prior call for its second.
If you restrict functions to only those constructible with Z, S, P, C, R (no M) then this defines the Primitive Recursive Functions, a subset of the General Recursive Functions that always halt.


=== Minimization ===
=== Minimization ===
<math>M^k(f) \triangleq \min \{i \in \N: f(i, x_1, ..., x_k) = 0\}</math>
<math>M^k(f)(x_1, ..., x_k) \triangleq \min \{i \in \N: f(i, x_1, ..., x_k) = 0\}</math>


In computational language, when M is evaluated it can be considered to calculate <math>f(0, x_1, ..., x_k)</math>, then <math>f(1, x_1, ..., x_k)</math>, then <math>f(2, x_1, ..., x_k)</math>, etc. until one of the calls to <math>f</math> returns 0.  It returns the value for the first argument which first gave a result of 0.  If no first argument causes <math>f</math> to return 0, <math>M(f)</math> doesn't return.
In computational language, when ''M(f)'' is evaluated it can be considered to calculate <math>f(i, x_1, ..., x_k)</math> with <math>i=0</math>, then <math>i=1</math>, then <math>i=2</math> etc. until one of the calls to <math>f</math> returns 0, at which point it returns the value of <math>i</math> which first gave a result of 0.  If no first argument causes <math>f</math> to return 0, <math>M(f)</math> doesn't return (this is the only way for a GRF to not halt).  


== Macros ==
== Macros ==
In order to improve readability we define the following macros. For all <math>f \in GRF_1</math>
In order to improve readability we define the following macros. For all <math>f \in GRF_2, g \in GRF_1</math>
{| class="wikitable"
{| class="wikitable"
|+
|+
Line 48: Line 67:
!Size
!Size
!Function
!Function
|-
|Plus constant
|<math>Plus[n]</math>
|1
|<math>\begin{array}{lcl}
  Plus[1]    & :=  & S \\
  Plus[n+1]  & :=  & C(S, Plus[n])
\end{array}</math>
|<math>2n-1</math>
|<math>\lambda x. x+n</math>
|-
|-
|Constant
|Constant
Line 69: Line 78:
|<math>\lambda x_1 \dots x_k. n</math>
|<math>\lambda x_1 \dots x_k. n</math>
|-
|-
|Iteration
|Plus constant
|<math>Rep[f,n]</math>
|<math>Plus[n]</math>
|1
|<math>Rep[f,n] := R(K^0[n], C(f, P^2_2))</math>
|<math>|f| + 2n + 4</math>
|<math>\lambda x. f^x(n)</math>
|-
|Ackermann iteration
|<math>Ack[n,f]</math>
|1
|1
|<math>\begin{array}{lcl}
|<math>\begin{array}{lcl}
   Ack[0,f]    & :=  & f \\
   Plus[1]    & :=  & S \\
   Ack[n+1,f]  & :=  & Rep[Ack[n,f],1]
   Plus[n+1]  & :=  & C(S, Plus[n])
\end{array}</math>
\end{array}</math>
|<math>6n + |f|</math>
|<math>2n-1</math>
|
|<math>\lambda x. x+n</math>
|-
|Addition
|Add
|2
|<math>Add := R(P^1_1, C(S, P^3_2))</math>
|5
|<math>\lambda xy. x+y</math>
|-
|-
|Knuth base 2 up-arrows
|Triangular numbers
|<math>Knuth2[n]</math>
|<math>Tri</math>
|1
|1
|<math>\begin{array}{lcl}
|<math>Tri := R(Z^0, R(S, C(S, P^3_2)))</math>
  Knuth2[0]   & := & Rep[Plus[2],0] \\
|7
  Knuth2[n+1]  & :=  & Rep[Knuth2[n],1]
|<math>\lambda x. \frac{x(x+1)}{2}</math>
\end{array}</math>
|-
|<math>6n+7</math>
|Iteration
|<math>\lambda x. 2 \uparrow^n x</math>
|<math>RepSucc[g]</math>
|2
|<math>RepSucc[g] := R(S, C(g, P^3_2))</math>
|<math>|g| + 4</math>
|<math>\lambda x\ y. g^x(y+1)</math>
|-
|Iteration on first arg
|<math>RepFirst[f]</math>
|2
|<math>RepFirst[f] := R^2(S, R^3(f, P^4_2))</math>
|<math>|f| + 4</math>
|<math>\lambda x\ y. (\lambda z. f(z, y))^x (y+1)</math>
|-
|Diagonalization & Iteration
|<math>DiagRep[f]</math>
|2
|<math>DiagRep[f] := R(S, C(f, P^3_2, P^3_2))</math>
|<math>|f| + 5</math>
|<math>\lambda x\ y. (\lambda z. f(z,z))^x (y+1)</math>
|-
|-
|Polygonal
|Diagonalization
|<math>Poly[n]</math>
|<math>DiagS[f]</math>
|1
|1
|<math>Poly[n] := R(Z^0, R(S, C(Plus[n], P^3_2)))</math>
|<math>DiagS[f] := C(f, S, S)</math>
|<math>2n+5</math>
|<math>|f| + 3</math>
|<math>\lambda x. \frac{n}{2} x(x-1) + x</math>
|<math>\lambda x. f(x+1, x+1)</math>
|-
|-
| rowspan="2" |Ackermann iteration
|<math>AckDiag2[n,f]</math>
|2
|<math>\begin{array}{lcl}
  AckDiag2[0,f]    & :=  & RepSucc[f] \\
  AckDiag2[n+1,f]  & :=  & DiagRep[AckDiag2[n,f]]
\end{array}</math>
|<math>5n + 4 + |f|</math>
|
|
|<math>Tri</math>
|-
|<math>AckDiag[n,f]</math>
|1
|1
|<math>Tri := Poly[1]</math>
|<math>AckDiag[n,f] := DiagS[AckDiag2[n,f]]</math>
|<math>7</math>
|<math>5n + 7 + |f|</math>
|<math>\lambda x. \frac{x(x+1)}{2}</math>
|-
|
|
|<math>Square</math>
|1
|<math>Square := Poly[2]</math>
|<math>9</math>
|<math>\lambda x. x^2</math>
|}
|}


== Champions ==
== Champions ==
We divide the champions tables up by enumeration categories. Starting from the simplest functions and moving to the most general.
=== Composition Functions ===
The simplest category are PRFs without Recursion. In other words, only atoms and Composition. All composition functions are equivalent to either <math>Plus[n]</math>, <math>C(Plus[n], P_i^k)</math> or <math>K^k[n] = C(Plus[n], Z^k)</math>. For BBµ, the only options are <math>K^0[n]</math> which is size 2n+1. These can be trivially extended to <math>C^0(K^0[n])</math> of size 2n+2. So this proves that <math>BB\mu(2n+1), BB\mu(2n+2) \ge n</math>. These are the best known champions up to size 13.
=== Primitive Recursive Functions ===
We get considerably more complexity by allowing all Primitive Recursive Functions (PRFs). But PRFs are still all guaranteed to be total, are decidable and are all dominated by Ackermann growth functions. They are convenient to enumerate since none diverge, so any holdouts that remain when running limited computations must eventually halt. All PRF champions up to size 13 are simple composition functions as mentioned above. PRFs with R begin at size 14.
The size 21-24 PRF champions are also currently full GRF champions, although it seems likely that M(PRF) will surpass these values, it just hasn't been run out that far yet.
{| class="wikitable"
{| class="wikitable"
!n
!n
!BBµ(n)
!Max Score
!Champion
!Champions
!Champion Found
!Champion Found
!Holdouts Proven
!# Holdouts
|-
|-
|1
|13
|= 0
|= 6
|<math>Z^0</math>
|<code>K[6]</code>
|
|
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1447693296322215976 8 Dec 2025] By hand
|0
|-
|14
|= 7
|<code>C(DiagS[RepSucc[S]], K[2])</code>
<code>C(DiagS[RepSucc[Plus[2]]], K[1])</code>
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1492246885329670184 10 Apr 2026]
|0
|-
|-
|2
|15
|= 0
|= 7
|<math>M(Z^1), M(P^1_1), C(Z^0)</math>
|<code>K[7]</code>
|
|
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1447693296322215976 8 Dec 2025] By hand
|0
|-
|16
|= 10
|<code>C(DiagS[RepSucc[Plus[2]]], K[2])</code>
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1492394919728517160 11 Apr 2026]
|0
|-
|17
|= 15
|<code>C(DiagS[DiagRep[RepSucc[S]]], K[1])</code>
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1492990073820545125 12 Apr 2026]
|0
|-
|18
|= 21
|<code>C(DiagS[RepSucc[Tri]], K[1])</code>
<code>C(DiagS[RepFirst[RepSucc[Plus[2]]]], K[1])</code>
|Jacob Mandelson [https://discord.com/channels/960643023006490684/1447627603698647303/1492021428546179182 9 Apr 2026]
|0
|-
|19
|= 39
|<code>C(DiagS[DiagRep[RepSucc[S]]], K[2])</code>
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1492997385247264941 12 Apr 2026]
|0
|-
|20
|= 1540
|<code>C(DiagS[RepSucc[Tri]], K[2])</code>
|Jacob Mandelson 9 Apr 2026
|0
|-
|21
|= 8,589,934,591
|<code>C(DiagS[RepFirst[DiagRep[RepSucc[S]]]], K[1])</code>
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1505396390665130035 16 May 2026]
|0
|-
|-
|3
|22
|= 1
|<math>\approx 10^{10^{69}}</math>
|<math>K^0[1]</math>
|<code>C(DiagS[RepFirst[RepSucc[Tri]]], K[1])</code>
|
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1506168696605904946 17 May 2026]
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1447693296322215976 8 Dec 2025] By hand
|Deciders: [https://discord.com/channels/960643023006490684/1447627603698647303/1507804514650947654 11]
All decided by hand
|-
|-
|4
|23
|= 1
|<math>> 10^{10^{463}}</math>
|<math>C^0(K^0[1])</math>
|<code>C(DiagS[DiagRep[RepSucc[Tri]]],K[1])</code>
|
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1519532827186565314 24 Jun 2026]
|Jacob Mandelson [https://mandelson.org/grf/ 3 Apr 2026]
|[https://discord.com/channels/960643023006490684/1447627603698647303/1518981870254297138 129]
|-
|-
|5
|24
|= 2
|<math>> 2^{2^{2^{2^{2^{20}}}}}</math>
|<math>K^0[2]</math>
|<code>C(DiagS[RepFirst[RepSucc[Tri]]], K[2])</code>
|
|Shawn Ligocki 17 May 2026
|Jacob Mandelson [https://mandelson.org/grf/ 3 Apr 2026]
|Not yet enumerated
|}
 
=== M(PRF) ===
We get another level of complexity by allowing Minimization, but only at the very top level. In other words, all of these GRF are M(f) for some PRF f. We call this M(PRF) or <code>min_prf</code>. This is a convenient set to explore because (1) it is Turing complete, (2) it is a smaller domain and easier to enumerate than full GRF, (3) all small known champions are of this form.
 
All M(PRF) champions up to size 13 are simple composition functions as mentioned above.
{| class="wikitable"
!n
!Max Score
!Champions
!Champion Found
!# Holdouts
|-
|-
|6
|12
|= 2
|= 5
|<math>C^0(K^0[2])</math>
|<code>C(K[5])</code>
|
|
|Jacob Mandelson [https://mandelson.org/grf/ 3 Apr 2026]
|0
|-
|-
|7
|13
|= 3
|= 6
|<math>K^0[3]</math>
|<code>K[6]</code>
|
|
|Jacob Mandelson [https://mandelson.org/grf/ 3 Apr 2026]
|Deciders: 15
All proven by hand
|-
|-
|2k+1
|14
|≥ k
|≥ 32
|<math>K^0[k]</math>
|<math>M^{0}(C^{1}(R^{2}(P^{1}_{1}, R^{3}(P^{2}_{1}, C^{4}(R^{2}(P^{1}_{1}, P^{3}_{1}), P^{4}_{2}, P^{4}_{1}))), P^{1}_{1}, S))</math><math>M^{0}(C^{1}(R^{2}(S, R^{3}(P^{2}_{1}, C^{4}(R^{2}(P^{1}_{1}, P^{3}_{1}), P^{4}_{2}, P^{4}_{1}))), P^{1}_{1}, P_1^1))</math>
|
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1499223592263745617 29 Apr 2026]
|
|109
|-
|-
|15
|15
|≥ 7
|≥ 32
|<math>K^0[7]</math>
|C^0(size 14 champ)
|
|
|
|589
|-
|16
|≥ 47
|<math>M(C(R(S, R(P^2_1, R(P^3_2, C(R(S, P^3_1), P^5_3, P^5_2)))), P^1_1, S))</math>
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1501347538287067267 5 May 2026]
|3,430
|-
|-
|17
|17
|≥ 10
|≥ 58,471
|<math>C(Tri, K^0[4])</math>
|<code>M(C(R(P(1,1),R(R(S,R(R(S,R(Z2,P(4,1))),P(4,2))),P(4,2))),S,P(1,1)))</code>
|Shawn Ligocki 9 Dec 2025
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1521327240732737536 29 Jun 2026]
|19,862
|-
|18
|
|
|
|
|93,738
|-
|-
|19
|19
|≥ 16
|<math>C(Square, K^0[4])</math>
|Shawn Ligocki 9 Dec 2025
|
|
|
|
|1,419,487
|-
|-
|21
|20
|≥ 25
|
|<math>C(Square, K^0[5])</math>
|
|Shawn Ligocki 9 Dec 2025
|
|
|7,508,624
|}
=== Full GRF ===
The final level is full GRF where Minimization is allowed at any level. The only champions currently at this level are hand-constructed GRF designed to surpass [[Graham's number]].
{| class="wikitable"
!n
!BBµ(n)
!Champion
!Champion Found
!# Holdouts
|-
|-
|23
|93
|≥ 36
|<math>>f_{\omega+1}(f_\omega(2 \uparrow\uparrow\uparrow 2 \uparrow\uparrow\uparrow 6)) \gg \text{Graham's number}</math>
|<math>C(Square, K^0[6])</math>
|Graham() from [https://github.com/sligocki/etc/blob/main/gen_rec/mgrf/goodstein.mgrf goodstein.mgrf]
|Shawn Ligocki 9 Dec 2025
|Racheline and Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1506295959049474068 19 May 2026]
|
|
|-
|-
|25
|...
|≥ 256
|
|<math>C(Rep[Square,2], K^0[3])</math>
|
|Shawn Ligocki 9 Dec 2025
|
|
|
|-
|-
|27
|98
|≥ 359,026,206
|<math>> f_\omega^{f_\omega^3(3)}(3) \gg \text{Graham's number}</math>
|<math>C(Rep[Rep[Tri,2],0], K^0[3])</math>
|Graham() from [https://github.com/sligocki/etc/blob/main/gen_rec/mgrf/ack_worm.mgrf ack_worm.mgrf]
|Shawn Ligocki 9 Dec 2025
|Shawn Ligocki 17 May 2026
|
|
|}
== Analysis of Champions ==
=== BBµ(14) ≥ 32 ===
This is the smallest non-trivial champion:<pre>
Expression: M(C(R(P(1,1), R(P(2,1), C(R(P(1,1), P(3,1)), P(4,2), P(4,1)))), P(1,1), S))
Arity: 0 | Size: 14 | GRF
=== Sub-expressions ===
a := R(P(1,1), P(3,1))    [arity 2, size 3, PRF, used={1,2}]
  a(0, y) = y
  a(x, _) = x-1
b := R(P(2,1), C(a, P(4,2), P(4,1)))    [arity 3, size 8, PRF, used={1,2}]
    if 0 ≤ x ≤ y: b(x,y) = y-x
    if y+1 ≤ x ≤ 2y+1: b(x,y) = 2y+1-x
  b(x, y) = (y+1) 2^k - 1 - x  (where k is minimal such that this is ≥ 0)
c := R(P(1,1), b)    [arity 2, size 10, PRF, used={1,2}]
  def c(x, y):
    acc = y
    for i in range(x):
      acc = b(i,acc)
    return acc
=== Root ===
d := M(C(c, P(1,1), S))    [arity 0, size 14]
  def d():
    for n in 0..:
      acc = n+1
      for i in range(n):
        while acc < i:
          acc = 2*acc + 1
        acc -= i
      if acc == 0:
        return n
  d() = 32
</pre>This GRF subtracts numbers 0 to n-1 from accumulator starting at n+1 with a slightly complex underflow condition (what to do when the number goes negative). It repeats this on increasing n until this process happens to hit exactly 0. It appears to be chaotic. It can be parameterized in a couple of ways by swapping S <-> P(1,1). This parameterization seems to get the luckiest and make it up to n=32 before halting. The other co-champion has the exact same behavior, just by switching when we do S vs P(1,1) for the base case.
== Cryptids ==
So far all [[Cryptids]] have been constructed by hand; no GRFs found in the wild have been categorized as Cryptids yet.
{| class="wikitable"
|+Hand Constructed Cryptids
!Size
!Problem
!Authors
!Ref
|-
|49
|[[wikipedia:Brocard's_problem|Brocard's problem]]
|aparker, star and Shawn 3 May 2026
|[https://github.com/sligocki/etc/blob/main/gen_rec/mgrf/brocard.mgrf brocard.mgrf] [https://discord.com/channels/960643023006490684/1447627603698647303/1500605707748245524 Discord]
|-
|56
|5x+1 trajectory of 7
|Shawn Ligocki 2 May 2026
|[https://github.com/sligocki/etc/blob/main/gen_rec/mgrf/collatz.mgrf collatz.mgrf]
|-
|81
|Erdős ternary conjecture
|Shawn Ligocki 28 Apr 2026
|[https://github.com/sligocki/etc/blob/main/gen_rec/mgrf/erdos.mgrf erdos.mgrf]
|-
|139
|Antihydra-like problem
|Jacob Mandelson 8 Apr 2026
|[https://discord.com/channels/960643023006490684/1447627603698647303/1491642156295913482 Orig (size 141)] [https://discord.com/channels/960643023006490684/1447627603698647303/1494889866704588983 Size 139]
|}
There is also a size 133 GRF that searches for counterexamples to Fermat's Last Theorem, halting iff it ever found one (however, since FLT has been [https://www.jstor.org/stable/2118559 proven], this GRF can be shown to be non-terminating, and is therefore not considered a Cryptid): [https://github.com/sligocki/etc/blob/main/gen_rec/mgrf/fermat.mgrf fermat.mgrf]
== Notable GRF ==
=== Unsolved GRFs ===
* Size 16: <code>M(C(R(S, R(C(S, P(2,1)), C(R(P(1,1), P(3,1)), P(4,2), P(4,1)))), P(1,1), S))</code>[https://discord.com/channels/960643023006490684/1447627603698647303/1501444301245382707 Discord] [https://discord.com/channels/960643023006490684/1447627603698647303/1504211320864505947 Discord]
** It is known that if this function returns a value, it must be greater than 499 quadrillion. [https://discord.com/channels/960643023006490684/1447627603698647303/1546666535911821413 Discord]
=== Solved GRFs ===
==== Hardest Size 12 ====
This is subjective of course, but it seems like the hardest size 12 M(PRF) holdout is <code>M(R(C(S, Z0), R(S, R(R(S, P(3,1)), P(4,2)))))</code>. Proving it seems requires noticing the pattern that d(x) = x-2 for all x ≥ 3 and proving that it inductively follows that pattern for all future values.<sup>[https://discord.com/channels/960643023006490684/1447627603698647303/1508151420258484354]</sup><pre>
Expression: M(R(C(S, Z0), R(S, R(R(S, P(3,1)), P(4,2)))))
Arity: 0 | Size: 12 | GRF
=== Sub-expressions ===
a := R(S, P(3,1))    [arity 2, size 3, PRF, used={1,2}]
  a(0, y) = 1 + y
  a(x, _) = x-1
b := R(a, P(4,2))    [arity 3, size 5, PRF, used={1,2,3}]
  b(_, 0, z) = 1 + z
  b(_, y, _) = y-1
c := R(S, b)    [arity 2, size 7, PRF, used={1,2}]
  c(x, y) = (1 + y - x) %< (2 + y)
d := R(C(S, Z0), c)    [arity 1, size 11, PRF, used={1}]
  d(0) = 1
  d(1) = 2
  d(2) = 2
  d(x) = x - 2
=== Root ===
M(d)    [arity 0, size 12]
  = ∞
</pre>
==== Hardest Size 13 (Triangular Divisibility) ====
Likewise, it seems like the hardest size 13 M(PRF) holdout is <code>M(C(R(S, R(P(2,1), R(R(P(2,2), P(4,1)), P(5,2)))), P(1,1), P(1,1)))</code> which halts iff there exists some n ≥ 1 such that n+2 divides <math>Tri(n) = \frac{n(n+1)}{2}</math>. There is no such n,<sup>[https://discord.com/channels/960643023006490684/1447627603698647303/1527405134857113650]</sup> therefore this GRF diverges, but this requires reasoning about divisibility and modular arithmetic.
==== Tetrahedral Divisibility ====
The GRF <math>M^{0}(C^{1}(R^{2}(S, R^{3}(P^{2}_{1}, R^{4}(P^{3}_{1}, R^{5}(R^{4}(P^{3}_{3}, P^{5}_{1}), P^{6}_{2})))), S, S))</math> (Size 15) halts iff there exists some n ≥ 1 such that n+3 divides <math>Tetr(n) = \frac{n(n+1)(n+2)}{6}</math>.<sup>[https://discord.com/channels/960643023006490684/960643023530762341/1500584497542987776]</sup> aparker<sup>[https://discord.com/channels/960643023006490684/960643023530762341/1500587569514283098]</sup> and star<sup>[https://discord.com/channels/960643023006490684/960643023530762341/1500595210919346337]</sup> proved that there is no such n, therefore this GRF diverges.
==== Chaotic size 15 ====
<pre>
Expression: M(C(R(P(1,1), R(R(S, P(3,1)), R(R(P(2,2), P(4,1)), P(5,2)))), S, P(1,1)))
Arity: 0 | Size: 15 | GRF
=== Sub-expressions ===
a := R(S, P(3,1))    [arity 2, size 3, PRF, used={1,2}]
  a(0, y) = 1 + y
  a(x, _) = x-1
b := R(P(2,2), P(4,1))    [arity 3, size 3, PRF, used={1,3}]
  b(0, _, z) = z
  b(x, _, _) = x-1
c := R(b, P(5,2))    [arity 4, size 5, PRF, used={1,2,4}]
  c(_, 0, _, w) = w
  c(_, y, _, _) = y-1
d := R(a, c)    [arity 3, size 9, PRF, used={1,2,3}]
  d(x, 0, z) = (1 + z - x) %< (1 + z)
  d(x, y, z) = (y - x - 1) %< (1 + z)
e := R(P(1,1), d)    [arity 2, size 11, PRF, used={1,2}]
M(C(e, S, P(1,1)))    [arity 0, size 15]
</pre>(where <code>a %< b</code> is <code>a</code> if a ≥ 0 and <code>a % b</code> if a < 0)
Racheline proved this diverges.<sup>[https://discord.com/channels/960643023006490684/1447627603698647303/1508961266490937536]</sup> The key here is that <code>e(n+1, n) = d(n, y, n)</code> for some y (the last step of the recursion) and for all y <code>d(n, y, n) ≠ 0</code> since:<pre>
d(n, 0, n) = 1
d(n, y+1, n) = y+1
</pre>
== Macro Bounds ==
Let <math>C = \frac{1}{\log_{10}(2)} \approx 3.32</math>
=== AckDiag[k, S] ===
Let <math>AS_k(n) := DiagRep^k[RepSucc[S]](n,n) = AckDiag[k,S](n-1)</math>
* <math>AS_0(n) = S^n(n+1) = 2n+1</math>
* <math>AS_1(n) = AS_0^n(n+1) = (n+2) 2^n - 1</math>
* <math>AS_1(n) > C \cdot 10^{n/C}</math> (for <math>n \ge 2</math>)
* <math>AS_2(n) = AS_1^n(n+1) > C \cdot (10 \uparrow)^n \left( \frac{n+1}{C} \right) > 10 \uparrow\uparrow n \left[ \uparrow \frac{n+1}{C} \right]</math> (for <math>n \ge 2</math>)
* <math>AS_k(n) = AS_{k-1}^n(n+1) > (10 \uparrow^{k-1})^n (n+1)</math> (for <math>k \ge 3</math> and <math>n \ge 1</math>)
=== AckDiag[k, Tri] ===
Let <math>AT_k(n) := DiagRep^k[RepSucc[Tri]](n,n) = AckDiag[k,Tri](n-1)</math>
* <math>Tri(n) = \frac{n(n+1)}{2} > \frac{1}{2} n^2</math>
* <math>AT_0(n) = Tri^n(n+1) > 2 \left( \frac{n+1}{2} \right)^{2^n}</math>
* <math>AT_0(2) = 21</math>, <math>AT_0(3) = 1540</math>, <math>AT_0(4) > 10^{7.42}</math>
* <math>AT_0(n) > C 10^{10^{\left(\frac{n-1}{C}\right)}} + 1</math> (for <math>n \ge 5</math>)
* <math>AT_1(n) = AT_0^n(n+1) > C (10 \uparrow)^{2n-2} \left( \frac{AT_0(n+1)}{C} \right)</math>
* <math>AT_1(2) > 10^{10^{AT_0(3) / C}} > 10^{10^{463}}</math>, <math>AT_1(3) > 10^{10^{10^{10^{AT_0(4) / C}}}} > 10 \uparrow\uparrow 5</math>
* <math>AT_1(n) > 10 \uparrow\uparrow 2n</math> (for <math>n \ge 4</math>)
* <math>AT_2(n) = AT_1^n(n+1) > (10 \uparrow\uparrow)^{n-1} (AT_1(n+1))</math>
* <math>AT_2(2) = AT_1^2(3) > AT_1(10 \uparrow\uparrow 5) > 10 \uparrow\uparrow 10 \uparrow\uparrow 5</math>, <math>AT_2(3) = AT_1^3(4) > 10 \uparrow\uparrow 10 \uparrow\uparrow 10 \uparrow\uparrow 8</math>
* <math>AT_2(n) > 10 \uparrow\uparrow\uparrow (n+1)</math> (for <math>n \ge 4</math>)
* <math>AT_3(n) = AT_2^n(n+1) > (10 \uparrow\uparrow\uparrow)^{n-1} (AT_2(n+1))</math>
* <math>AT_3(2) = AT_2^2(3) > AT_2(10 \uparrow\uparrow\uparrow 3) > 10 \uparrow\uparrow\uparrow 10 \uparrow\uparrow\uparrow 3</math>
== Pairing Functions ==
In order to do arbitrary computation, GRF need to be able to store arbitrary data into a single integer (since the R combinator only passes a single accumulator). There are many ways to do that and the Graham champions above accomplish it via custom binary encodings. But the traditional way to store arbitrary data into an integer is to use a [[wikipedia:Pairing_function|pairing function]]. Thus there is value in finding small pairing/unpairing functions.
We define two APIs here for pairing functions:
# A triple of GRF <code>Pair</code>, <code>Left</code>, <code>Right</code> such that for all a,b: <code>Left(Pair(a,b)) = a</code> and <code>Right(Pair(a,b)) = b</code>
# A GRF <code>Pair</code> and GRF Macro <code>LRCall[f]</code> such that for all a,b,f: <code>LRCall[f](Pair(a,b)) = f(a,b)</code>
The smallest known pairing functions are:
{| class="wikitable"
|+Smallest Pairing Functions
!Macro
!arity
!Definition
!Size
!Function
|-
|<math>Pair</math>
|2
|<math>Pair := C(AddS, C(Tri, Add), P^2_1)</math>
|20
|<math>\lambda xy. \frac{(x+y)(x+y+1)}{2} + x + 1</math>
|-
|<math>Left</math>
|1
|<math>Left := C(RMonus, C(TriP, InvTriCeil), Pred)</math>
|38
|<math>Left(Pair(x,y)) = x</math>
|-
|<math>Right</math>
|1
|<math>Right := C(RMonus, P^1_1, C(Tri, InvTriCeil))</math>
|36
|<math>Right(Pair(x,y)) = y</math>
|-
|<math>LRCall[f^2]</math>
|1
|<math>LRCall[f] := C(LRpart3[f], InvTriCeil, P^1_1)</math>
|<math>59 + |f|</math>
|<math>LRCall[f](Pair(x,y)) = f(x,y)</math>
|}
Where these are based on the following definitions:
{| class="wikitable"
|+Macros
!
!Macro
!arity
!Definition
!Size
!Function
|-
| rowspan="3" |Addition
|Add
|2
|<math>Add := R(P^1_1, C(S, P^3_2))</math>
|5
|<math>\lambda xy. x+y</math>
|-
|AddXA
|3
|<math>AddXA := R(P^2_1, C(S, P^4_2))</math>
|5
|<math>\lambda xyz. x+y</math>
|-
|AddS
|2
|<math>AddS := R(S, C(S, P^3_2))</math>
|5
|<math>\lambda xy. x+y+1</math>
|-
|[[wikipedia:Primitive_recursive_function#Predecessor|Predecesor]]
|Pred
|1
|<math>Pred := R(Z^0, P^2_1)</math>
|3
|<math>\lambda x. x \dot - 1</math>
|-
|[[wikipedia:Monus#Natural_numbers|Monus]]
|RMonus
|2
|<math>RMonus := R(P^1_1, C(Pred, P^3_2))</math>
|7
|<math>\lambda xy. y \dot - x</math>
|-
|-
|29
| rowspan="3" |Triangular numbers
|<math>> 10 \uparrow\uparrow 3.9 </math>
|Tri
|<math>C(Rep[Rep[Tri,2],0], K^0[4])</math>
|1
|Shawn Ligocki 9 Dec 2025
|<math>Tri := R(Z^0, AddS)</math>
|
|7
|<math>\lambda x. \frac{x(x+1)}{2}</math>
|-
|-
|31
|TriP
|<math>> 10 \uparrow\uparrow 5.9 </math>
|1
|<math>C(Rep[Rep[Tri,2],0], K^0[5])</math>
|<math>TriP := R(Z^0, Add)</math>
|Shawn Ligocki 9 Dec 2025
|7
|
|<math>TriP(x+1) = Tri(x)</math>
|-
|-
|33
|TriPXA
|<math>> 10 \uparrow\uparrow 7.9 </math>
|2
|<math>C(Rep[Rep[Tri,2],0], K^0[6])</math>
|<math>TriPXA := R(Z^1, AddXA)</math>
|Shawn Ligocki 9 Dec 2025
|7
|
|<math>TriPXA(x,y) = TriP(x)</math>
|-
|-
|35
| rowspan="2" |Inverting Tri
|<math>\ge 2 \uparrow\uparrow\uparrow 4</math>
|RMonusTri
|<math>C(Knuth2[3], K^0[4])</math>
|2
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1447633458510692385 8 Dec 2025]
|<math>RMonusTri := C(RMonus, C(Tri, P^2_1), P^2_2)</math>
|
|18
|<math>\lambda xy. y \dot - Tri(x)</math>
|-
|-
|37
|InvTriCeil
|<math>\ge 2 \uparrow\uparrow\uparrow 5</math>
|1
|<math>C(Knuth2[3], K^0[5])</math>
|<math>InvTriCeil := M(RMonusTri)</math>
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1447633458510692385 8 Dec 2025]
|19
|
|<math>\lambda y. \min \{x | Tri(x) \ge y \}</math>
|-
|-
|39
| rowspan="5" | Combined LRCall
|<math>\ge 2 \uparrow\uparrow\uparrow 6</math>
|RightPiece
|<math>C(Knuth2[3], K^0[6])</math>
|3
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1447633458510692385 8 Dec 2025]
|<math>RightPiece := R(P^2_2, C(Pred, P^4_2))</math>
|
|7
|<math>\lambda xyz. z \dot - x</math>
|-
|-
|6k+17
|LeftPiece
|<math>\ge 2 \uparrow^k 4</math>
|3
|<math>C(Knuth2[k], K^0[4])</math>
|<math>LeftPiece := C(RMonus, C(S, P^3_2), P^3_1)</math>
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1447633458510692385 8 Dec 2025]
|12
|
|<math>\lambda xyz. x \dot - (y+1)</math>
|-
|LRpart1[f]
|3
|<math>LRpart1[f] := C(f, LeftPiece, RightPiece)</math>
|<math>20 + |f|</math>
|<math>\lambda xyz. f(x \dot - (y+1), z \dot - x)</math>
|-
|-
|6k+19
|LRpart2[f]
|<math>\ge 2 \uparrow^k 5</math>
|3
|<math>C(Knuth2[k], K^0[5])</math>
|<math>LRpart2[f] :=  C(LRpart1[f], P^3_3, P^3_1, AddXA)</math>
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1447633458510692385 8 Dec 2025]
|<math>28 + |f|</math>
|
|<math>\lambda xyz. f(z \dot - (x+1), x+y\dot - z)</math>
|-
|-
|6k+21
|LRpart3[f]
|<math>\ge 2 \uparrow^k 6</math>
|2
|<math>C(Knuth2[k], K^0[6])</math>
|<math>LRpart3[f] := C(LRpart2[f], TriPXA, P^2_1, P^2_2)</math>
|Shawn Ligocki [https://discord.com/channels/960643023006490684/1447627603698647303/1447633458510692385 8 Dec 2025]
|<math>38 + |f|</math>
|
|<math>\lambda xy. f(y\dot - (TriP(x)+1), TriP(x)+x\dot - y)</math>
|}
|}


[[Category:functions]]
[[Category:functions]]

Latest revision as of 17:25, 6 October 2026

General recursive functions (GRFs), also called µ-recursive functions or partial recursive functions, are the collection of partial functions ℕk⇀ℕ that are computable. This definition is equivalent using any Turing complete system of computation. See Wikipedia:general recursive function for background.

Historically it was defined as the smallest class of partial functions ℕk⇀ℕ that is closed under composition, recursion, and minimization, and includes zero, successor, and all projections (see formal definitions below). In the rest of this article, this is the formulation that we focus on exclusively. In this way, it can be considered to be a Turing complete model of computation. In fact, it is one of the oldest Turing complete models, first formalized by Kurt Gödel and Jacques Herbrand in 1933, 3 years before λ-calculus and Turing machines.

BBµ(n) is a Busy Beaver function for GRFs:BBμ(n)=max⁡{f()|f∈GRF0,|f|=n}

where f∈GRFk means that f:ℕk⇀ℕ is a k-ary GRF and |f| is the "structural size" of f (the number of atoms and combinators in the definition, see details below). In other words, it is the largest number computable via a 0-ary function (a constant) with a limited "program" size. It is more akin to the traditional Sigma score for a Turing machine rather than the Step function in the sense that it maximizes over the produced value, not the number of steps needed to reach that value.

Definition

Structure

Define GRFk inductively based on the following construction rules, start with Atoms and combine them using Combinators.

Atoms
  • Zero: ∀k∈ℕ,Zk∈GRFk is the constant 0 function Zk(x1,…,xk)=0
  • Successor: S∈GRF1 is the successor function S(x)=x+1
  • Projection: ∀1≤i≤k∈ℕ,Pik∈GRFk is a projection function Pik(x1,…xk)=xi
Combinators
  • Composition: ∀k,m∈ℕ,∀h∈GRFm,∀g1,…gm∈GRFk,Ck(h,g1,…gm)∈GRFk is the composition or substitution of the gs into h: Ck(h,g1,…gm)(x1,…xk)=h(g1(x1,…xk),…gm(x1,…xk))
  • Primitive Recursion: ∀k∈ℕ,∀g∈GRFk,∀h∈GRFk+2,Rk+1(g,h)∈GRFk+1 is primitive recursion using g as the base case and h as the inductive step.
  • Minimization / Unlimited Search: ∀k∈ℕ,∀f∈GRFk+1,Mk(f)∈GRFk is the µ-operator which allows unlimited search.

The arity superscripts for C, R and M are redundant (except for Ck(h)) and so are sometimes omitted below.

Size

The size of a GRF is the number of atoms and combinators in the definition:

  • |Zk|=|Pik|=|S|=1
  • |C(h,g1,⋯,gm)|=1+|h|+|g1|+⋯+|gm|
  • |R(g,h)|=1+|g|+|h|
  • |M(f)|=1+|f|

Primitive Recursion

R models a typical iterative function definition over ℕ.

Base case: Rk(g,h)(0,x2,x3,...,xk)=g(x2,x3,...,xk)

Iterative case (for x1>0): Rk(g,h)(x1,x2,...,xk)=h(x1−1,v,x2,x3,...,xk) where v=R(g,h)(x1−1,x2,x3,...,xk).

R can be recursively evaluated following its definition directly or it can be simulated as a bounded for loop like this python code:

# f = R(g,h)
def f(n, *xs):
  acc = g(*xs)
  for k in range(n):
    acc = h(k, acc, *xs)
  return acc

The iterative function h is passed two synthetic args in the front: (k) iteration number (0-indexed) and (acc) "accumulator" from previous iterations.

Both the base and iterative cases can be parameterized by values x2,x3,...,xk.

If you restrict functions to only those constructible with Z, S, P, C, R (no M) then this defines the Primitive Recursive Functions, a subset of the General Recursive Functions that always halt.

Minimization

Mk(f)(x1,...,xk)≜min⁡{i∈ℕ:f(i,x1,...,xk)=0}

In computational language, when M(f) is evaluated it can be considered to calculate f(i,x1,...,xk) with i=0, then i=1, then i=2 etc. until one of the calls to f returns 0, at which point it returns the value of i which first gave a result of 0. If no first argument causes f to return 0, M(f) doesn't return (this is the only way for a GRF to not halt).

Macros

In order to improve readability we define the following macros. For all f∈GRF2,g∈GRF1

Macro arity Definition Size Function
Constant Kk[n] k Kk[0]:=ZkKk[n]:=C(Plus[n],Zk) 2n+1 λx1…xk.n
Plus constant Plus[n] 1 Plus[1]:=SPlus[n+1]:=C(S,Plus[n]) 2n−1 λx.x+n
Addition Add 2 Add:=R(P11,C(S,P23)) 5 λxy.x+y
Triangular numbers Tri 1 Tri:=R(Z0,R(S,C(S,P23))) 7 λx.x(x+1)2
Iteration RepSucc[g] 2 RepSucc[g]:=R(S,C(g,P23)) |g|+4 λx y.gx(y+1)
Iteration on first arg RepFirst[f] 2 RepFirst[f]:=R2(S,R3(f,P24)) |f|+4 λx y.(λz.f(z,y))x(y+1)
Diagonalization & Iteration DiagRep[f] 2 DiagRep[f]:=R(S,C(f,P23,P23)) |f|+5 λx y.(λz.f(z,z))x(y+1)
Diagonalization DiagS[f] 1 DiagS[f]:=C(f,S,S) |f|+3 λx.f(x+1,x+1)
Ackermann iteration AckDiag2[n,f] 2 AckDiag2[0,f]:=RepSucc[f]AckDiag2[n+1,f]:=DiagRep[AckDiag2[n,f]] 5n+4+|f|
AckDiag[n,f] 1 AckDiag[n,f]:=DiagS[AckDiag2[n,f]] 5n+7+|f|

Champions

We divide the champions tables up by enumeration categories. Starting from the simplest functions and moving to the most general.

Composition Functions

The simplest category are PRFs without Recursion. In other words, only atoms and Composition. All composition functions are equivalent to either Plus[n], C(Plus[n],Pik) or Kk[n]=C(Plus[n],Zk). For BBµ, the only options are K0[n] which is size 2n+1. These can be trivially extended to C0(K0[n]) of size 2n+2. So this proves that BBμ(2n+1),BBμ(2n+2)≥n. These are the best known champions up to size 13.

Primitive Recursive Functions

We get considerably more complexity by allowing all Primitive Recursive Functions (PRFs). But PRFs are still all guaranteed to be total, are decidable and are all dominated by Ackermann growth functions. They are convenient to enumerate since none diverge, so any holdouts that remain when running limited computations must eventually halt. All PRF champions up to size 13 are simple composition functions as mentioned above. PRFs with R begin at size 14.

The size 21-24 PRF champions are also currently full GRF champions, although it seems likely that M(PRF) will surpass these values, it just hasn't been run out that far yet.

n Max Score Champions Champion Found # Holdouts
13 = 6 K[6] 0
14 = 7 C(DiagS[RepSucc[S]], K[2])

C(DiagS[RepSucc[Plus[2]]], K[1])

Shawn Ligocki 10 Apr 2026 0
15 = 7 K[7] 0
16 = 10 C(DiagS[RepSucc[Plus[2]]], K[2]) Shawn Ligocki 11 Apr 2026 0
17 = 15 C(DiagS[DiagRep[RepSucc[S]]], K[1]) Shawn Ligocki 12 Apr 2026 0
18 = 21 C(DiagS[RepSucc[Tri]], K[1])

C(DiagS[RepFirst[RepSucc[Plus[2]]]], K[1])

Jacob Mandelson 9 Apr 2026 0
19 = 39 C(DiagS[DiagRep[RepSucc[S]]], K[2]) Shawn Ligocki 12 Apr 2026 0
20 = 1540 C(DiagS[RepSucc[Tri]], K[2]) Jacob Mandelson 9 Apr 2026 0
21 = 8,589,934,591 C(DiagS[RepFirst[DiagRep[RepSucc[S]]]], K[1]) Shawn Ligocki 16 May 2026 0
22 ≈101069 C(DiagS[RepFirst[RepSucc[Tri]]], K[1]) Shawn Ligocki 17 May 2026 Deciders: 11

All decided by hand

23 >1010463 C(DiagS[DiagRep[RepSucc[Tri]]],K[1]) Shawn Ligocki 24 Jun 2026 129
24 >2222220 C(DiagS[RepFirst[RepSucc[Tri]]], K[2]) Shawn Ligocki 17 May 2026 Not yet enumerated

M(PRF)

We get another level of complexity by allowing Minimization, but only at the very top level. In other words, all of these GRF are M(f) for some PRF f. We call this M(PRF) or min_prf. This is a convenient set to explore because (1) it is Turing complete, (2) it is a smaller domain and easier to enumerate than full GRF, (3) all small known champions are of this form.

All M(PRF) champions up to size 13 are simple composition functions as mentioned above.

n Max Score Champions Champion Found # Holdouts
12 = 5 C(K[5]) 0
13 = 6 K[6] Deciders: 15

All proven by hand

14 ≥ 32 M0(C1(R2(P11,R3(P12,C4(R2(P11,P13),P24,P14))),P11,S))M0(C1(R2(S,R3(P12,C4(R2(P11,P13),P24,P14))),P11,P11)) Shawn Ligocki 29 Apr 2026 109
15 ≥ 32 C^0(size 14 champ) 589
16 ≥ 47 M(C(R(S,R(P12,R(P23,C(R(S,P13),P35,P25)))),P11,S)) Shawn Ligocki 5 May 2026 3,430
17 ≥ 58,471 M(C(R(P(1,1),R(R(S,R(R(S,R(Z2,P(4,1))),P(4,2))),P(4,2))),S,P(1,1))) Shawn Ligocki 29 Jun 2026 19,862
18 93,738
19 1,419,487
20 7,508,624

Full GRF

The final level is full GRF where Minimization is allowed at any level. The only champions currently at this level are hand-constructed GRF designed to surpass Graham's number.

n BBµ(n) Champion Champion Found # Holdouts
93 >fω+1(fω(2↑↑↑2↑↑↑6))≫Graham's number Graham() from goodstein.mgrf Racheline and Shawn Ligocki 19 May 2026
...
98 >fωfω3(3)(3)≫Graham's number Graham() from ack_worm.mgrf Shawn Ligocki 17 May 2026

Analysis of Champions

BBµ(14) ≥ 32

This is the smallest non-trivial champion:

Expression: M(C(R(P(1,1), R(P(2,1), C(R(P(1,1), P(3,1)), P(4,2), P(4,1)))), P(1,1), S))
Arity: 0 | Size: 14 | GRF

=== Sub-expressions ===

a := R(P(1,1), P(3,1))    [arity 2, size 3, PRF, used={1,2}]
  a(0, y) = y
  a(x, _) = x-1

b := R(P(2,1), C(a, P(4,2), P(4,1)))    [arity 3, size 8, PRF, used={1,2}]
    if 0 ≤ x ≤ y: b(x,y) = y-x
    if y+1 ≤ x ≤ 2y+1: b(x,y) = 2y+1-x
  b(x, y) = (y+1) 2^k - 1 - x  (where k is minimal such that this is ≥ 0)

c := R(P(1,1), b)    [arity 2, size 10, PRF, used={1,2}]
  def c(x, y):
    acc = y
    for i in range(x):
      acc = b(i,acc)
    return acc

=== Root ===
d := M(C(c, P(1,1), S))    [arity 0, size 14]
  def d():
    for n in 0..:
      acc = n+1
      for i in range(n):
        while acc < i:
          acc = 2*acc + 1
        acc -= i
      if acc == 0:
        return n
  d() = 32

This GRF subtracts numbers 0 to n-1 from accumulator starting at n+1 with a slightly complex underflow condition (what to do when the number goes negative). It repeats this on increasing n until this process happens to hit exactly 0. It appears to be chaotic. It can be parameterized in a couple of ways by swapping S <-> P(1,1). This parameterization seems to get the luckiest and make it up to n=32 before halting. The other co-champion has the exact same behavior, just by switching when we do S vs P(1,1) for the base case.

Cryptids

So far all Cryptids have been constructed by hand; no GRFs found in the wild have been categorized as Cryptids yet.

Hand Constructed Cryptids
Size Problem Authors Ref
49 Brocard's problem aparker, star and Shawn 3 May 2026 brocard.mgrf Discord
56 5x+1 trajectory of 7 Shawn Ligocki 2 May 2026 collatz.mgrf
81 Erdős ternary conjecture Shawn Ligocki 28 Apr 2026 erdos.mgrf
139 Antihydra-like problem Jacob Mandelson 8 Apr 2026 Orig (size 141) Size 139

There is also a size 133 GRF that searches for counterexamples to Fermat's Last Theorem, halting iff it ever found one (however, since FLT has been proven, this GRF can be shown to be non-terminating, and is therefore not considered a Cryptid): fermat.mgrf

Notable GRF

Unsolved GRFs

  • Size 16: M(C(R(S, R(C(S, P(2,1)), C(R(P(1,1), P(3,1)), P(4,2), P(4,1)))), P(1,1), S))Discord Discord
    • It is known that if this function returns a value, it must be greater than 499 quadrillion. Discord

Solved GRFs

Hardest Size 12

This is subjective of course, but it seems like the hardest size 12 M(PRF) holdout is M(R(C(S, Z0), R(S, R(R(S, P(3,1)), P(4,2))))). Proving it seems requires noticing the pattern that d(x) = x-2 for all x ≥ 3 and proving that it inductively follows that pattern for all future values.[1]

Expression: M(R(C(S, Z0), R(S, R(R(S, P(3,1)), P(4,2)))))
Arity: 0 | Size: 12 | GRF

=== Sub-expressions ===

a := R(S, P(3,1))    [arity 2, size 3, PRF, used={1,2}]
  a(0, y) = 1 + y
  a(x, _) = x-1

b := R(a, P(4,2))    [arity 3, size 5, PRF, used={1,2,3}]
  b(_, 0, z) = 1 + z
  b(_, y, _) = y-1

c := R(S, b)    [arity 2, size 7, PRF, used={1,2}]
  c(x, y) = (1 + y - x) %< (2 + y)

d := R(C(S, Z0), c)    [arity 1, size 11, PRF, used={1}]
  d(0) = 1
  d(1) = 2
  d(2) = 2
  d(x) = x - 2

=== Root ===
M(d)    [arity 0, size 12]
  = ∞

Hardest Size 13 (Triangular Divisibility)

Likewise, it seems like the hardest size 13 M(PRF) holdout is M(C(R(S, R(P(2,1), R(R(P(2,2), P(4,1)), P(5,2)))), P(1,1), P(1,1))) which halts iff there exists some n ≥ 1 such that n+2 divides Tri(n)=n(n+1)2. There is no such n,[2] therefore this GRF diverges, but this requires reasoning about divisibility and modular arithmetic.

Tetrahedral Divisibility

The GRF M0(C1(R2(S,R3(P12,R4(P13,R5(R4(P33,P15),P26)))),S,S)) (Size 15) halts iff there exists some n ≥ 1 such that n+3 divides Tetr(n)=n(n+1)(n+2)6.[3] aparker[4] and star[5] proved that there is no such n, therefore this GRF diverges.

Chaotic size 15

Expression: M(C(R(P(1,1), R(R(S, P(3,1)), R(R(P(2,2), P(4,1)), P(5,2)))), S, P(1,1)))
Arity: 0 | Size: 15 | GRF

=== Sub-expressions ===

a := R(S, P(3,1))    [arity 2, size 3, PRF, used={1,2}]
  a(0, y) = 1 + y
  a(x, _) = x-1

b := R(P(2,2), P(4,1))    [arity 3, size 3, PRF, used={1,3}]
  b(0, _, z) = z
  b(x, _, _) = x-1

c := R(b, P(5,2))    [arity 4, size 5, PRF, used={1,2,4}]
  c(_, 0, _, w) = w
  c(_, y, _, _) = y-1

d := R(a, c)    [arity 3, size 9, PRF, used={1,2,3}]
  d(x, 0, z) = (1 + z - x) %< (1 + z)
  d(x, y, z) = (y - x - 1) %< (1 + z)

e := R(P(1,1), d)    [arity 2, size 11, PRF, used={1,2}]
M(C(e, S, P(1,1)))    [arity 0, size 15]

(where a %< b is a if a ≥ 0 and a % b if a < 0) Racheline proved this diverges.[6] The key here is that e(n+1, n) = d(n, y, n) for some y (the last step of the recursion) and for all y d(n, y, n) ≠ 0 since:

d(n, 0, n) = 1
d(n, y+1, n) = y+1

Macro Bounds

Let C=1log10(2)≈3.32

AckDiag[k, S]

Let ASk(n):=DiagRepk[RepSucc[S]](n,n)=AckDiag[k,S](n−1)

  • AS0(n)=Sn(n+1)=2n+1
  • AS1(n)=AS0n(n+1)=(n+2)2n−1
  • AS1(n)>C⋅10n/C (for n≥2)
  • AS2(n)=AS1n(n+1)>C⋅(10↑)n(n+1C)>10↑↑n[↑n+1C] (for n≥2)
  • ASk(n)=ASk−1n(n+1)>(10↑k−1)n(n+1) (for k≥3 and n≥1)

AckDiag[k, Tri]

Let ATk(n):=DiagRepk[RepSucc[Tri]](n,n)=AckDiag[k,Tri](n−1)

  • Tri(n)=n(n+1)2>12n2
  • AT0(n)=Trin(n+1)>2(n+12)2n
  • AT0(2)=21, AT0(3)=1540, AT0(4)>107.42
  • AT0(n)>C1010(n−1C)+1 (for n≥5)
  • AT1(n)=AT0n(n+1)>C(10↑)2n−2(AT0(n+1)C)
  • AT1(2)>1010AT0(3)/C>1010463, AT1(3)>10101010AT0(4)/C>10↑↑5
  • AT1(n)>10↑↑2n (for n≥4)
  • AT2(n)=AT1n(n+1)>(10↑↑)n−1(AT1(n+1))
  • AT2(2)=AT12(3)>AT1(10↑↑5)>10↑↑10↑↑5, AT2(3)=AT13(4)>10↑↑10↑↑10↑↑8
  • AT2(n)>10↑↑↑(n+1) (for n≥4)
  • AT3(n)=AT2n(n+1)>(10↑↑↑)n−1(AT2(n+1))
  • AT3(2)=AT22(3)>AT2(10↑↑↑3)>10↑↑↑10↑↑↑3

Pairing Functions

In order to do arbitrary computation, GRF need to be able to store arbitrary data into a single integer (since the R combinator only passes a single accumulator). There are many ways to do that and the Graham champions above accomplish it via custom binary encodings. But the traditional way to store arbitrary data into an integer is to use a pairing function. Thus there is value in finding small pairing/unpairing functions.

We define two APIs here for pairing functions:

  1. A triple of GRF Pair, Left, Right such that for all a,b: Left(Pair(a,b)) = a and Right(Pair(a,b)) = b
  2. A GRF Pair and GRF Macro LRCall[f] such that for all a,b,f: LRCall[f](Pair(a,b)) = f(a,b)

The smallest known pairing functions are:

Smallest Pairing Functions
Macro arity Definition Size Function
Pair 2 Pair:=C(AddS,C(Tri,Add),P12) 20 λxy.(x+y)(x+y+1)2+x+1
Left 1 Left:=C(RMonus,C(TriP,InvTriCeil),Pred) 38 Left(Pair(x,y))=x
Right 1 Right:=C(RMonus,P11,C(Tri,InvTriCeil)) 36 Right(Pair(x,y))=y
LRCall[f2] 1 LRCall[f]:=C(LRpart3[f],InvTriCeil,P11) 59+|f| LRCall[f](Pair(x,y))=f(x,y)

Where these are based on the following definitions:

Macros
Macro arity Definition Size Function
Addition Add 2 Add:=R(P11,C(S,P23)) 5 λxy.x+y
AddXA 3 AddXA:=R(P12,C(S,P24)) 5 λxyz.x+y
AddS 2 AddS:=R(S,C(S,P23)) 5 λxy.x+y+1
Predecesor Pred 1 Pred:=R(Z0,P12) 3 λx.x−˙1
Monus RMonus 2 RMonus:=R(P11,C(Pred,P23)) 7 λxy.y−˙x
Triangular numbers Tri 1 Tri:=R(Z0,AddS) 7 λx.x(x+1)2
TriP 1 TriP:=R(Z0,Add) 7 TriP(x+1)=Tri(x)
TriPXA 2 TriPXA:=R(Z1,AddXA) 7 TriPXA(x,y)=TriP(x)
Inverting Tri RMonusTri 2 RMonusTri:=C(RMonus,C(Tri,P12),P22) 18 λxy.y−˙Tri(x)
InvTriCeil 1 InvTriCeil:=M(RMonusTri) 19 λy.min⁡{x|Tri(x)≥y}
Combined LRCall RightPiece 3 RightPiece:=R(P22,C(Pred,P24)) 7 λxyz.z−˙x
LeftPiece 3 LeftPiece:=C(RMonus,C(S,P23),P13) 12 λxyz.x−˙(y+1)
LRpart1[f] 3 LRpart1[f]:=C(f,LeftPiece,RightPiece) 20+|f| λxyz.f(x−˙(y+1),z−˙x)
LRpart2[f] 3 LRpart2[f]:=C(LRpart1[f],P33,P13,AddXA) 28+|f| λxyz.f(z−˙(x+1),x+y−˙z)
LRpart3[f] 2 LRpart3[f]:=C(LRpart2[f],TriPXA,P12,P22) 38+|f| λxy.f(y−˙(TriP(x)+1),TriP(x)+x−˙y)