The McCarthy 91 function is a recursive function, defined by the computer scientist John McCarthy as a test case for formal verification within computer science.
The McCarthy 91 function is defined as
M(n)=\begin{cases} n-10,&ifn>100\\ M(M(n+11)),&ifn\le100 \end{cases}
The results of evaluating the function are given by M(n) = 91 for all integer arguments n ≤ 100, and M(n) = n - 10 for n > 100. Indeed, the result of M(101) is also 91 (101 - 10 = 91). All results of M(n) after n = 101 are continually increasing by 1, e.g. M(102) = 92, M(103) = 93.
The 91 function was introduced in papers published by Zohar Manna, Amir Pnueli and John McCarthy in 1970. These papers represented early developments towards the application of formal methods to program verification. The 91 function was chosen for being nested-recursive (contrasted with single recursion, such as defining
f(n)
f(n-1)
It is easier to reason about tail-recursive control flow, this is an equivalent (extensionally equal) definition:
Mt(n)=Mt'(n,1)
Mt'(n,c)=\begin{cases} n,&ifc=0\\ Mt'(n-10,c-1),&ifn>100andc\ne0\\ Mt'(n+11,c+1),&ifn\le100andc\ne0 \end{cases}
This is an equivalent mutually tail-recursive definition:
Mmt(n)=Mmt'(n,0)
Mmt'(n,c)=\begin{cases} Mmt''(n-10,c),&ifn>100\\ Mmt'(n+11,c+1),&ifn\le100 \end{cases}
Mmt''(n,c)=\begin{cases} n,&ifc=0\\ Mmt'(n,c-1),&ifc\ne0 \end{cases}
Example A:
M(99) = M(M(110)) since 99 ≤ 100 = M(100) since 110 > 100 = M(M(111)) since 100 ≤ 100 = M(101) since 111 > 100 = 91 since 101 > 100
Example B:
M(87) = M(M(98)) = M(M(M(109))) = M(M(99)) = M(M(M(110))) = M(M(100)) = M(M(M(111))) = M(M(101)) = M(91) = M(M(102)) = M(92) = M(M(103)) = M(93) .... Pattern continues increasing till M(99), M(100) and M(101), exactly as we saw on the example A) = M(101) since 111 > 100 = 91 since 101 > 100
Here is an implementation of the nested-recursive algorithm in Lisp:
Here is an implementation of the nested-recursive algorithm in Haskell:
Here is an implementation of the nested-recursive algorithm in OCaml:
Here is an implementation of the tail-recursive algorithm in OCaml:
Here is an implementation of the nested-recursive algorithm in Python:
Here is an implementation of the nested-recursive algorithm in C:
Here is an implementation of the tail-recursive algorithm in C:
int mc91taux(int n, int c)
Here is a proof that the McCarthy 91 function
M
M'
M'(n)=\begin{cases} n-10,&ifn>100\\ 91,&ifn\le100 \end{cases}
For n > 100, the definitions of
M'
M
M
For n ≤ 100, a strong induction downward from 100 can be used:
For 90 ≤ n ≤ 100,
M(n) = M(M(n + 11)), by definition = M(n + 11 - 10), since n + 11 > 100 = M(n + 1) This can be used to show M(n) = M(101) = 91 for 90 ≤ n ≤ 100: M(90) = M(91), M(n) = M(n + 1) was proven above = … = M(101), by definition = 101 − 10 = 91
M(n) = M(101) = 91 for 90 ≤ n ≤ 100 can be used as the base case of the induction.
For the downward induction step, let n ≤ 89 and assume M(i) = 91 for all n < i ≤ 100, then
M(n) = M(M(n + 11)), by definition = M(91), by hypothesis, since n < n + 11 ≤ 100 = 91, by the base case.
This proves M(n) = 91 for all n ≤ 100, including negative values.
Donald Knuth generalized the 91 function to include additional parameters.[1] John Cowles developed a formal proof that Knuth's generalized function was total, using the ACL2 theorem prover.[2]