所以我对Prolog很新,需要一些帮助。我正在尝试列出像[[1,2,3],[4,5,6],[7,8]]
这样的列表,并创建一个像[2,3,5,6,8]
这样的列表,所以除了每个列表的第一个之外,基本上所有值都放入一个新列表中。我明白了:
test5(X,[[_|X]|_]).
test5(X,[_|A]) :- test5(X,A).
每次按Enter键时,会返回[2,3]
然后再返回[5,6]
然后返回[8]
。我不确定如何让它们一次运行并将它们放入列表中。我尝试以不同的方式使用追加,但我无法使其工作。有关如何实现这一点的任何想法?谢谢!
答案 0 :(得分:2)
你有一个共同的谓词flatten/2
,几乎完成了这项任务:
?- flatten([[1,2,3],[4,5,6],[7,8]], L).
L = [1, 2, 3, 4, 5, 6, 7, 8].
有many implementations of flatten/2
available,只是google it。
如果你知道列表列表没有嵌套,你应该使用append/2
。
然后,您需要在追加之前删除每个列表的第一个元素:
list_tail([_|T], T).
然后:
?- maplist(list_tail, [[1,2,3],[4,5,6],[7,8]], T), append(T, L).
T = [[2, 3], [5, 6], [8]],
L = [2, 3, 5, 6, 8].
仔细观察上面链接的append/2
的实现可能是一个很好的练习。如果定义发生微小变化(字面意思是删除1个字符并添加5个字符),它将执行删除并在同一步骤中追加,而不会遍历原始列表两次。
修改强>
那么为什么当第一个参数不是一个正确的列表时,@repeat's initial solution不会终止,但第二个参数是一个正确的列表呢?
nt_tails_append([[_|T]|Ls], As) :-
append(T, Ws, As),
nt_tails_append(Ls, Ws).
这是因为当nt_tails_append/2
的第一个参数是一个自由变量时,上面append/3
的前两个参数也是变量。当我们在这种模式下调用append/3
时,根据定义我们得到:
?- append(A, B, L).
A = [],
B = L .
换句话说,第二个和第三个参数现在是统一的。使用nt_tail_append/2
的定义,这意味着递归调用获得与原始调用相同的第二个参数,并将新的自由变量作为第一个参数。当然,这是一个无限循环。
(很明显,如果你想看看上面链接的append/2
的定义,你会看到第一个参数must_be
和list
。)
这有什么帮助?
tails_append(Ls, As) :-
maplist(list_tail, Ls, T),
append(T, As).
list_tail([_|T], T).
定义maplist
的方式,所有列表参数都将实例化为正确的列表。因此,您可以安全地使用append/3
(此处,用于append/2
的定义。)
答案 1 :(得分:1)
以下是使用append/3
:
lists_concatenatedTails([],[]). lists_concatenatedTails([[_|Xs0]|Xss],Ys) :- append(Xs0,Ys0,Ys), lists_concatenatedTails(Xss,Ys0).
示例查询:
?- lists_concatenatedTails([[1,2,3],[4,5,6],[7,8]], Xs). Xs = [2, 3, 5, 6, 8].
请注意@Boris建议的代码(使用list_tail/2
,maplist/3
,append/2
)也会为以下查询提供答案:
?- maplist(list_tail,Xss,Yss), append(Yss,[1,2,3]).
Xss = [[_G97, 1, 2, 3]], Yss = [[1, 2, 3]] ;
Xss = [[_G97], [_G106, 1, 2, 3]], Yss = [[], [1, 2, 3]] ;
Xss = [[_G97, 1], [_G106, 2, 3]], Yss = [[1], [2, 3]] ;
Xss = [[_G97, 1, 2], [_G106, 3]], Yss = [[1, 2], [3]] ;
Xss = [[_G97, 1, 2, 3], [_G106]], Yss = [[1, 2, 3], []] ;
Xss = [[_G97], [_G106], [_G115, 1, 2, 3]], Yss = [[], [], [1, 2, 3]] ...
这并不是普遍终止的 - 我们也不期望它:解决方案集的大小是无限的,在这种情况下,它只能被无限的答案序列所覆盖。
在以下等效查询中lists_concatenatedTails/2
"循环"马上:
?- lists_concatenatedTails(Lss,[1,2,3]).
% not a single answer within finite time
只有在立即限制Lss
的长度时,才能实现公平的枚举:
?- length(Lss,_), lists_concatenatedTails(Lss,[1,2,3]).
Lss = [[_G23, 1, 2, 3]] ;
Lss = [[_G26], [_G29, 1, 2, 3]] ;
Lss = [[_G26, 1], [_G32, 2, 3]] ;
Lss = [[_G26, 1, 2], [_G35, 3]] ;
Lss = [[_G26, 1, 2, 3], [_G38]] ;
Lss = [[_G29], [_G32], [_G35, 1, 2, 3]] ...