从Prolog的列表中选择N个元素

4
我正在尝试编写一个 Prolog 断言(SWI),可以从列表中选择 N 个元素,如下所示:
selectn(+N,?Elems,?List1,?List2)是真的,当 List1<\/em> 删除所有 Elems<\/em> 后结果为 List2<\/em>。
selectn(N,Lps,L1s,[]) :- length(L1s,L), N >= L, permutation(L1s,Lps).
selectn(0,[],L1s,Lps) :- permutation(L1s,Lps).
selectn(N,[E|Es],L1s,L2s) :- 
    select(E,L1s,L0s),
    N0 is N-1,
    selectn(N0,Es,L0s,L2s).

我的问题是,在某些情况下,我会得到重复的结果,但我不知道如何避免它们:
?- findall(L,selectn(2,Es,[a,b,c],L),Ls),length(Ls,Solutions).
Ls = [[c], [b], [c], [a], [b], [a]],
Solutions = 6.

这不是作业,但如果您能像对待作业一样帮助我,我也会感到高兴。
1个回答

4
这可能能回答你的问题(尽管我不理解你的第一个从句 selectn/4,排列已经通过“嵌套”select/3完成)。
selectn(0, [], Rest, Rest).
selectn(N, [A|B], C, Rest) :-
    append(H, [A|T], C),
    M is N-1,
    selectn(M, B, T, S),
    append(H, S, Rest).

产量
?- findall(L,selectn(2,Es,[a,b,c],L),Ls),length(Ls,Solutions).
Ls = [[c], [b], [a]],
Solutions = 3.

感谢您的回复@CapelliC!这确实帮了我很多。然而,使用您的代码时,排列组合并不是由您建议的任何selectn/4完成的,导致在查询selectn(3,[c,a,b],[a,b,c,d],[d]).selectn(0,[a,b],[b,a]).时失败,当然这是因为重复项没有被视为答案。 - Carles Araguz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接