是否可以从 Prolog 的列表中获取所有元素?
类似的东西:我们有 getElements([[[a,b,[c]],d,e],f,g,[h,[i,j]]],S) 结果是:S = [a ,b,c,d,e,f,g,h,i,j] ...
感谢帮助。
您要求提供列表列表的所有元素。也就是说,[[1,2,3],[4]]
这将是 list [1,2,3,4]
。但是,因为[[[1],[3]]]
这将是列表[[1],[3]]
,因为[1]
和[3]
是元素。出于这个原因,flatten/2
它给你[1,3]
一个答案是不正确的。此外,因为1
它给[1]
...
这是使用dcg的解决方案:
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.
在 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
包括以下语句:
最终需要 flatten/3 通常表明,例如 append/3 用于附加两个列表,这是一个糟糕的设计。
但是,该页面没有说明是否有另一个本地谓词来替换它。
我相信会提供更好的答案。