Получить элементы из списка списков - PullRequest
3 голосов
/ 20 марта 2012

возможно ли получить все элементы из списка списков в Прологе?

Что-то вроде: у нас есть getElements ([[[a, b, [c]], d, e], f, g, [h, [i, j]]], S) и результатis: S = [a, b, c, d, e, f, g, h, i, j] ...

Спасибо за помощь.

Ответы [ 2 ]

5 голосов
/ 20 марта 2012

Вы запросили все элементы списка списков.То есть для [[1,2,3],[4]] это будет список [1,2,3,4].Однако для [[[1],[3]]] это будет список [[1],[3]], поскольку [1] и [3] являются элементами.По этой причине, flatten/2 неверно, и вы получите [1,3] в качестве ответа.Кроме того, для 1 это дает [1] ...

Вот решение с использованием :

seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).

seqq([]) --> [].
seqq([Es|Ess]) --> seq(Es), seqq(Ess).

?- phrase(seqq([[[1],[3]]]), Xs).
Xs = [[1],[3]].

?- phrase(seqq(1), Xs).
false.

Это решение теперь работает и для таких случаев, какследующее:

?- phrase(seqq([S1,S2]), [1,2]).
S1 = [],
S2 = [1,2] ;
S1 = [1],
S2 = [2] ;
S1 = [1,2],
S2 = [] ;
false.

, тогда как flatten/2 совершенно неверно:

?- flatten([S1,S2],[1,2]).
S1 = 1,
S2 = 2.
3 голосов
/ 20 марта 2012

В SWI-Prolog (и, возможно, других) вы можете использовать flatten/2:

?- flatten([[[a,b,[c]],d,e],f,g,[h,[i,j]]], S).
S = [a, b, c, d, e, f, g, h, i|...].

Обратите внимание, что страница руководства SWI-Prolog для flatten/2 включает следующее утверждение:

Окончание необходимости сглаживания / 3 часто указывает, как и добавление / 3 для добавления двух списков, плохой дизайн.

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

Я уверен, что будет дан лучший ответ.

...