2010-10-11 3 views
3

Я создаю деревья s-выражений для проблемы генетического программирования и нуждаюсь в изменении частей деревьев в процессе эволюции. Я наткнулся на функцию Clojure zipper, которая кажется, что она должна быть идеальной, но для жизни я не могу понять, как ее использовать.Как отформатировать дерево так, чтобы оно работало с молнией 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) 

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

ответ

3

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

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

+ .  3 
    - 1 2 

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

+0

Спасибо за это объяснение, это очистило меня. Я не думаю, что мне нужно пересечь дерево в том порядке, в котором оно выполнено, поэтому я, вероятно, все еще могу использовать Zipper. –

1

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

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

 
user=> (-> zipped zip/down zip/right zip/down zip/node) 
clojure.core/-