Как мне отформатировать дерево, чтобы оно работало с молнией Clojure?

Я создаю деревья s-выражений для проблемы генетического программирования, и мне нужно изменить части деревьев в процессе эволюции. Я столкнулся с функцией молнии Clojure, которая, кажется, должна быть идеальной, но я не могу понять, как ее использовать.

Например, скажем, я создаю молнию с

(def zipped (zip/seq-zip `(+ (- 1 2) 3)))

Я понимаю, что это представляет дерево с + в корне, которое выглядит так:

   +
 -   3
1 2

Моя молния, однако, не согласна с этим: если я попрошу первый узел с (-> zipped zip/down zip/node) это дает мне + (что правильно) но это (-> zipped zip/down zip/down) не берет меня -вместо этого он возвращает nil, В самом деле, (-> zipped zip/down zip/rights) дает остальную часть дерева как братьев и сестер справа от корня, что подсказывает мне, что у меня вообще нет дерева:

user> (-> zipped zip/down zip/rights)
((clojure.core/- 1 2) 3)

Я почти уверен, что правильно представляю свои деревья, потому что когда я их выполняю, я получаю правильный ответ. Молния ожидает другого макета?

2 ответа

Решение

Проблема в том, что здесь есть две разные идеи дерева. Ваше дерево представляет собой график того, как значения просачиваются через оценку, но LISP думает о списках списков и использует префиксную нотацию:

'(+ (- 1 2) 3) также (list + (list - 1 2) 3), что на самом деле это дерево:

+  .     3
   - 1 2

(-> zipped down node) дает вам первый элемент, +, атом.(-> zipped down down) таким образом, вы получаете ноль, потому что первый элемент, +, является атомом.(-> zipped down right down node) дает вам знак минус, который вы хотите, потому что это первый элемент второго элемента выражения.

Дерево не так, как вы его изобразили. Корневой узел имеет 3 детей: +, (- 1 2), а также 3, Когда вы делаете down от корневого узла, по умолчанию это самый левый дочерний элемент, поэтому вы видите +,

Чтобы добраться до - вам нужно позвонить:

user => (-> zip zip/down zip/right zip/down zip/node)
clojure.core/-
Другие вопросы по тегам