是否有可能从Prolog中的列表列表中获取所有元素?
类似于:我们有getElements([[[[a,b,[c]],d,e],f,g,[h,[i,j]]],S),结果为:S = [a,b,c,d,e,f,g,h,i,j] ......
感谢您的帮助。
答案 0 :(得分:5)
您询问了列表列表的所有元素。也就是说,对于[[1,2,3],[4]]
,这将是列表[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.
答案 1 :(得分:3)
在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|...].
请注意,the SWI-Prolog manual page for flatten/2
包含以下声明:
结束需要flatten / 3经常表示,就像附加/ 3附加两个列表一样,设计不好。
但是,该页面并未说明是否有另一个本机谓词来替换它。
我确定会提供更好的答案。