Как вы интерпретируете отрицательные уровни в Mathematica?

Я пытаюсь получить более глубокое понимание того, как выражения Mathematica представлены внутри, и озадачен логикой команды Level в Mathematica. Если у нас есть следующий ввод:

In[1]:= a = z*Sin[x + y] + z1*Cos[x1 + y1]

Out[1]= z1 Cos[x1 + y1] + z Sin[x + y]

In[2]:= FullForm[a]

Out[2]= Plus[Times[z1,Cos[Plus[x1,y1]]],Times[z,Sin[Plus[x,y]]]]

In[3]:= TreeForm[a]

Получаем следующее дерево:

tree form of expression a, above

Если мы попросим Mathematica вернуться только на уровень 4, мы получим:

In[4]:= Level[a,{4}]
Out[4]= {x1,y1,x,y}

Я понимаю, что мы находимся на 4 уровня от "стебля" (оператор "Плюс" на уровне 0). На самом деле, я думаю, я понимаю, что положительные индексы всегда относятся к исходной позиции дерева. (Надеюсь, я прав?)

В отличие от этого, когда вы запрашиваете отрицательный уровень, нет общей точки отсчета (например, стебель выше), потому что разные ветки дерева имеют разную длину. Итак, если вы попросите Mathematica предоставить только уровень -1, мы получим:

In[6]:= Level[a,{-1}]
Out[6]= {z1,x1,y1,z,x,y}

Я был удивлен этим выходом, когда я догадался, что мне нужно вернуться {x1, y1, x, y} (без z1 и z). Но хорошо, если я попытаюсь понять это, я беру -1, чтобы обозначить "конец каждой ветки". Если это так, то я ожидаю, что Level[a,{-2}] вернется:

{z1*Cos[x1+y1],z*Sin[x+y],x1+y1,x+y}

Но это не то, что я верну, Mathematica дает:

In[8]:= Level[a,{-2}]
Out[8]= {x1+y1,x+y}

Итак, теперь я смущен и не вижу последовательного способа понять выход отрицательных уровней.

Есть ли последовательный, более простой способ понять эту тему? Есть ли определенный "правильный" способ, которым я должен читать структуру дерева?

Извините за "длинный вопрос", но я надеюсь, вы понимаете, о чем я прошу.

Ответ 1

Если вы посмотрите docs, они скажут:

Отрицательный уровень -n состоит из всех частей expr с глубиной n.

Таким образом, отрицательные уровни не рассчитываются из контрольной точки, а определяются на основе глубины подвыражений. z1*Cos[x1+y1] имеет глубину 4, поэтому он не возвращается, когда вы запрашиваете Level[..., {-2}].