2013-09-07 3 views
1

J'ai essayé de résoudre ce problème depuis un moment, mais je ne suis pas vraiment sûr de la façon de procéder.Suppression des listes dans les listes de mon code prologue

Par exemple, disons que j'ai cet « arbre » dans ma base de données:

tree4(b(b(l(Apple),l(Banana)), b(l(Orange), l(Pear)))). 

Je veux être en mesure d'interroger la base de données afin de récupérer les informations dans chaque l() et de le présenter en une liste. Jusqu'à présent, je l'ai fait:

leaves(l(X), L) :- 
    L = X. 
leaves(b(X,Y), L) :- 
    leaves(X, A), 
    leaves(Y, B), 
    L = [A, B]. 

Je requête alors la base de données et il me donne ceci:

?- tree4(T), leaves(T, L). 
T = b(b(l(1), l(2)), b(l(3), l(4))), 
L = [[1, 2], [3, 4]]. 

Le problème avec ce code est qu'il génère plusieurs listes nichés dans mon original. Y a-t-il un autre moyen d'y parvenir? Toute aide serait grandement appréciée!

Répondre

1

Vous pouvez éviter le coût du append/3 prédicat en utilisant un accumulateur pour collecter les feuilles pendant la traversée de l'arbre:

leaves(Tree, Leaves) :- 
    leaves(Tree, [], Leaves). 

leaves(l(Leaf), Leaves, [Leaf| Leaves]). 
leaves(b(Left,Right), Leaves0, Leaves) :- 
    leaves(Right, Leaves0, Leaves1), 
    leaves(Left, Leaves1, Leaves). 

Utilisation de votre exemple d'appel:

?- leaves(b(b(l(1), l(2)), b(l(3), l(4))), Leaves). 
Leaves = [1, 2, 3, 4]. 
+0

Merci Paulo (+1). J'allais en fait rendre une autre solution sans "append". Tu m'as battu. :) J'apprends toujours à ne pas penser d'abord en termes de prédicats intégrés. – lurker

+0

Merci pour l'aide de vous deux, pense que je comprends le brouillard de celui-ci! –

0

En supposant que votre mise en œuvre Prolog a un prédicat append, vous pouvez le faire:

leaves(l(X), [X]). 

leaves(b(X,Y), L) :- 
    leaves(X, A), 
    leaves(Y, B), 
    append(A, B, L). 

Alors leaves retournera toujours une liste à plat, même s'il y a juste un. Cela suppose également que votre arbre est strictement binaire, comme vous l'avez décrit.

2

Comme vous décrivant une liste (dans ce cas: de feuilles), envisager d'utiliser un DCG:

leaves(l(L))  --> [L]. 
leaves(b(B1,B2)) --> leaves(B1), leaves(B2). 

Exemple requête (en utilisant des atomes au lieu de variables tree4/1):

?- tree4(Tree), phrase(leaves(Tree), Leaves). 
Tree = b(b(l(apple), l(banana)), b(l(orange), l(pear))), 
Leaves = [apple, banana, orange, pear]. 
0

Juste un rappel flatten/2, un builtin pratique:

?- leaves(b(b(l(1), l(2)), b(l(3), l(4))), L), flatten(L, F). 
L = [[1, 2], [3, 4]], 
F = [1, 2, 3, 4]. 

Comme vous pouvez le voir la documentation, son utilisation est déconseillée et vous avez déjà reçu beaucoup de bons conseils qui permettent de l'éviter.

Questions connexes