# Can this notation be computed in Mathematica?

I defined a notation as follows:

(a, b) = $$a^b$$,

(a, b(c)) = (a, b-1(c)) * (a+1, b(c-1)),

(a, b(0)) = (a, b), and (a, 1(c)) = (a, a(c-1)).

For c = 4, (a, b(c)) is already tedious to evaluate. I next defined (a, b(0,1)) to be equal to (a, b($$a^b$$)) and (a, b(c, 1)) as (a, b-1(c,1)) * (a+1, b(c-1,1). (2, 2(1,1)) is greater than $$10^{10000}$$, and has so far taken me over a week to evaluate as I only have formulas for (a, b(2)) and (a, b(3)). Can (a, b(c)) be programmed in Mathematica? Any help would be appreciated.

• How should be understand b-1(c) in your second definition? It seems that 1(c) is defined later as a(c-1), so should b-1(c) == b - a (c - 1)? Or should it be $(b-1) \times (c)$? You may also want to use some other operator that is not multiplication in your expressions in Mathematica, since things like 1(c) would automatically be simplified. Mar 24, 2021 at 16:43
• In any case, you'll probably need Nest or Fold. Mar 24, 2021 at 16:47

Roman's solution gets very slow as the value b or c increases. I use Memoization below to prevent recomputing values. We should also ensure b and c are positive integers to avoid infinite recursion. My improved version that does all that is here.

Clear[f];
f[a_, b_] := a^b;
f[a_, b_, 0] := a^b;
f[a_, 1, c_Integer?Positive] := f[a,1,c] = f[a,a,c-1]
f[a_, b_Integer?Positive, c_Integer?Positive] := f[a,b,c] = f[a,b-1,c]*f[a+1,b,c-1]

• Alternative to c_Integer?Positive is c_Integer/;c>0. Mar 25, 2021 at 14:39

You can write $$(a,b(c))$$ as f[a,b,c]:

f[a_, b_] = a^b;
f[a_, b_, 0] = f[a, b];
f[a_, 1, c_] := f[a, a, c - 1]
f[a_, b_, c_] := f[a, b - 1, c]*f[a + 1, b, c - 1]


examples:

f[1, 2, 3]
(*    15552    *)

f[3, 2, 1]
(*    432    *)

f[4, 4, 4]
(*    19393983827718432382942097517695828647998395142202754928834510298705433141104807237509816216475619585550730636347520400973355250128278033815331515175151864224862276548634782796395405263354886224119286448795750466960120269181334154615594100146469053340917944759980663872462182165749651283641595899665986474356606642225885307385859438341031898136637724087018412941823577813683669698799074676100519019046540622228028082879315049653248249344010970369039835332134345637888000000000000000000000000000000000000000000000000000000    *)

• Can you tell me why it's appropiate here to use = (Set) instead of := (SetDelayed) for your first/second line? I always use SetDelayed whenever I have an argument (like a_) but without a good reason. Mar 25, 2021 at 16:28
• @AccidentalTaylorExpansion I don't see a reason to delay these assignments, so why delay them? For the second line, for example, an immediate assignment means the right-hand side is evaluated at definition time to $a^b$; if you delay this assignment, then any time we use it we are effectively launching another lookup to f[a,b] which yields a^b which yields $a^b$; this seems unreasonable/excessively complex to me. Mar 25, 2021 at 17:26
• Thanks that makes sense Mar 25, 2021 at 19:12
• As mentioned in the documentation for Set under "Possible Issues" is the example x=5; f[x_]=x^2; f[2] which returns 25. The issue is "In the presence of global variables, pattern variables may show unexpected behavior" which illustrates the need for SetDelayed. Mar 27, 2021 at 20:32
• @Somos you're technically right but pointing out a deeper problem. Defining global variables and thus messing up a local scope is one of the reasons why global variables are considered bad style. Another reason is code testability. Mar 29, 2021 at 5:44