# How to randomly generate Tree or Nested List of Function in Mathematica?

In detail, I want to generate randomly something like
Divide[Add[X,Times[X,Y]],Times[X,3]]
or
{Divide,{Add,X,{Times{X,Y}}},{Times,X,3}}

(Specified Function(# of argument is from 2 to 5)) + Specified Symbol+Random Integer)
,but I don't know how to implement this. Are there any good example?

• TreeForm[(X + Y) (Z + W)]? Dec 4 '18 at 17:22
• No,I meant "Tree" is something like Func[X,Func2[Y]] ( Nested list of function?) Dec 4 '18 at 17:34
• I'm not sure I understand the question. Mathematica expressions are already trees. Look at ClearAll[x,y]; TreeForm[x + y]! Dec 4 '18 at 18:26
• Yes,Mathematica's expression is already tree. but I wanted to create "Tree" or "Expression" randomly for using meta-programming. For example, Tree(max-depth 2 & head is "Plus") is Plus[a1,a2]. I should have use something like "Nested Function" but "Tree", Anyway thanks! Dec 5 '18 at 9:32

## 3 Answers

This version is a bit more involved than the other answers given above, but it respects the condition on the arities of the functions.

ClearAll[plus, times, div, m, f, g, h];
m = 5;
f[a_, n_] := Symbol[FromCharacterCode[96 + n] <> ToString@a];
g[a_, n_] /; (n <= 1) := f[a, n];
g[a_, n_] := Replace[RandomChoice[{1, 2}], {1 -> f[a, n], 2 -> h[a + m + 1, n - 1]}];
h[a_, n_] /; (n <= 1) := g[a, n];
h[a_, n_] := Replace[RandomChoice[{
{plus, RandomInteger[{2, m}]}, {times, RandomInteger[{2, 5}]}, {div, 2}
}], {s_, t_} :> s @@ Map[g[a + #, n] &, Range@t]];
h[n_] := h[0, n];


Most of the awkwardness is due to the fact that the accumulator a tries to force the creation of a new symbol each time. You can test it as follows:

h[5] // FullForm
(*
plus[e1, times[d9, div[c17, plus[a31, a32, b27, a34]], d11, times[c19, plus[a33, a34, b29, a36]]], div[d10, plus[plus[b25, b26, b27, a34, b29], plus[b26, a33]]], e4]
*)

h[3] // FullForm
(* div[plus[a14, a15, b10, a17], c2] *)

B[B[A, A], B[A, A]] //. {B :> RandomChoice[{1, 1, 1, 1} -> {mult, div, add, sub}], A :> RandomChoice[{1, 1, 1, 1, 5} -> {mult[A, A], sub[A, A], div[A, A], add[A, A], RandomInteger[{1, 10}]}]}


I've made the initial condition non-trivial so that you'll always get a somewhat interesting result instead of, eg, just a number

add[add[add[2, 7], 7], div[mult[mult[2, 10], 5], add[div[add[1, 7], 10], 8]]]

Replace add, div, etc with Plus, Divide, ... for actual Mathematica expressions. As for variable argument lists, I'll leave that as an exercise for the reader!

The following example might show you a way forward. We define a recursive random function that builds a tree.

heads = {f, g};
factor = 0.9;
randomtree[mean_] := RandomChoice[heads]@@Table[randomtree[factor*mean],
RandomVariate[PoissonDistribution[mean]]]

randomtree[2.2]
(* g[
g[f[f[f[],
f[f[f[f[g[]], g[g[f[f[g[f[], f[]], g[]]], g[]], f[]]]]]]]]] *)