You are getting a smaller leaf count than expected because the expression is evaluating before the leaves are counted. To get the leaf count of the unevaluated expression, used Unevaluated:
In[1]:= LeafCount[Unevaluated[ThreeFive[n_Integer] /; n > 0 := Floor[n/15]]]
Out[1]= 16
LeafCount does not hold its arguments, so LeafCount[ThreeFive[...] := ...]
is equivalent to LeafCount[Null]
:
In[2]:= FullForm[ThreeFive[n_Integer] /; n > 0 := Floor[n/15]]
Out[2]//FullForm= Null
In[3]:= LeafCount[ThreeFive[n_Integer] /; n > 0 := Floor[n/15]]
Out[3]= 1
In[4]:= LeafCount[Null]
Out[4]= 1
The first Possible Issue example is a red herring, LeafCount[Sqrt[x]]
gives LeafCount[Power[x, Rational[1, 2]]]
not because of FullForm
, but because Sqrt evaluated. LeafCount[Unevaluated[Sqrt[x]]]
gives 2
as expected.
For some atomic expressions (i.e. rational and complex numbers), LeafCount treats the atom as a compound expression according to its FullForm:
In[5]:= AtomQ[1/2]
Out[5]= True
In[6]:= FullForm[1/2]
Out[6]//FullForm= Rational[1, 2]
In[7]:= LeafCount[1/2]
Out[7]= 3
That explains why LeafCount[n/15]
gives 5
(Times[Rational[1, 15], n]
) rather than 3
(Times[1/15, n]
).
Setting the issue of FullForm aside, LeafCount gives the number of leaves in the tree of all subexpressions (including heads), not in the tree of heads (as used by TreeForm). These are the "Subexpressions" and "Heads" structures in ExpressionTree, respectively:
ExpressionTree[f[a[b]][c, d], "Subexpressions"]
ExpressionTree[f[a[b]][c, d], "Heads"]
Currently, neither ExpressionTree or TreeForm directly give trees corresponding to the FullForm of rationals and complexes, but it can be done:
In[1]:= tree = ExpressionTree[n/15 + 2/3 I, "Atoms"]
In[2]:= positions = TreePosition[tree, _Rational | _Complex, {-1}]
Out[2]= {{2}, {3, 2}}
In[3]:= SetAttributes[atomTree, HoldFirst];
atomTree[fullForm_] := ExpressionTree[Unevaluated[fullForm], "Atoms"]
In[5]:= rules = Map[
pos |-> pos ->
TreeExtract[tree, pos,
leaf |->
ToExpression[ToString[FullForm[TreeData[leaf]]], StandardForm,
atomTree]], positions]
In[6]:= TreeReplacePart[tree, rules]
In[7]:= Length[TreeLeaves[%]]
Out[7]= 11
In[8]:= LeafCount[n/15 + 2/3 I]
Out[8]= 11
ExpressionTree[ThreeFive ...]
andExpressionTree[Floor[n/15]]
. You can see that your definition of function gets evaluated (!) and returns "nothing" (or something like this, I am not sure), therefore only one leaf. Try withHold
:LeafCount[Hold[ThreeFive[...] := ...]]
, which will give you 17 leafs (one of them beingHold
itself). $\endgroup$