2010-10-11 4 views
3

Je crée des arbres de s-expressions pour un problème de programmation génétique, et j'ai besoin de modifier des parties des arbres pendant le processus d'évolution. Je suis tombé sur la fonction Clojure zipper qui semble être parfaite, mais pour la vie de moi je n'arrive pas à comprendre comment l'utiliser.Comment formater un arbre pour qu'il fonctionne avec la fermeture à glissière de Clojure?

Par exemple, supposons que je crée une fermeture éclair avec

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

Je comprends que cela représente un arbre avec + à la racine, qui ressemble à ceci:

+ 
- 3 
1 2 

Ma fermeture à glissière, bien , n'est pas d'accord avec ceci: Si je demande le premier noeud avec (-> zipped zip/down zip/node) il me donne + (ce qui est correct) mais (-> zipped zip/down zip/down) ne me prend pas à -, à la place il renvoie nil. En effet, (-> zipped zip/down zip/rights) donne le reste de l'arbre comme frères et soeurs à droite de la racine, ce qui me suggère que je n'ai pas un arbre du tout:

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

Je suis sûr que je représente ma arbres correctement parce que quand je les exécute, j'obtiens la bonne réponse. Est-ce que la fermeture éclair attend une mise en page différente?

Répondre

3

Le problème est qu'il ya deux idées différentes d'arbres qui se passe ici. Votre arbre est un graphique de la façon dont les valeurs filtrent à travers l'évaluation, mais LISP pense à des listes de listes, et en utilisant la notation de préfixe:

'(+ (- 1 2) 3) est aussi (liste + (liste - 1 2) 3), qui est en fait cet arbre:

+ .  3 
    - 1 2 

(-> zipped down node) vous donne le premier élément, +, un atome. (-> zipped down down) vous donne donc zéro car le premier élément, +, est un atome. (-> zipped down right down node) vous donne le signe moins que vous voulez parce que c'est le premier élément du deuxième élément de l'expression.

+0

Merci pour cette explication, cela a éclairci les choses pour moi. Je ne pense pas avoir besoin de traverser l'arbre dans l'ordre dans lequel il est exécuté, donc je peux probablement utiliser Zipper. –

1

L'arbre n'est pas la façon dont vous l'avez schématisé. Le nœud racine a 3 enfants: +, (- 1 2) et 3. Lorsque vous faites down à partir du nœud racine, il est par défaut à l'enfant le plus à gauche, d'où la raison +.

Pour accéder à la - que vous auriez besoin d'appeler:

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