我试图在prolog中定义一个函数,它接受形式组合的参数(3,[a,b,c,d],L),结果返回
L=a,b,c
L=a,b,d
L=a,c,d
L=b,c,d
我的实施如下:
combination(K,argList,L):-
unknown(X,argList,Y),
Z is select(X,argList),
length(Z,K),
L is Z,
combination(K,Z,L).
unknown(X,[X|L],L).
unknown(X,[_|L],R) :- unknown(X,L,R).
未知谓词的行为如下: ![在此输入图像说明] [1]
请帮忙。
答案 0 :(得分:0)
使用您对unknown/3
的定义时想到的最简单的解决方案是:
combination(0, _, []) :-
!.
combination(N, L, [V|R]) :-
N > 0,
NN is N - 1,
unknown(V, L, Rem),
combination(NN, Rem, R).
unknown(X,[X|L],L).
unknown(X,[_|L],R) :-
unknown(X,L,R).
说明:combination/3
的第二个子句试图从列表L
中选择一个元素,谓词unknown/3
以线性方式执行,返回余数{{1} }。一旦从列表Rem
中选择的元素数超过L
,就会触发基本情况(N
的第一个子句),终止分支。请注意,combination/3
的定义依赖于combination/3
的非确定性特性,它为选择备用列表元素留下了选择点。
答案 1 :(得分:0)
出于某种原因,我接受了一个挑战,提出了一个组合/ 3谓词,这没有留下最后的选择点。如果不使用sharky解决方案进行修改,我们就会得到以下行为:
?- combination(2,[a,b,c],X).
X = [a, b] ;
X = [a, c] ;
X = [b, c] ;
No
此要求有点符合Gertjan van Noord member / 2技巧的精神。但是我们宁愿通过计算给定列表的长度来解决这个问题:
:- use_module(library(basic/lists)).
% combination(+Integer, +List, -List)
combination(0, _, []) :- !.
combination(N, L, [A|R]) :-
M is N-1,
length(L, K),
J is K-N,
unknown(J, A, L, H),
combination(M, H, R).
% unknown(+Integer, -Elem, +List, -List)
unknown(0, X, [X|L], L) :- !.
unknown(_, X, [X|L], L).
unknown(N, X, [_|L], R) :-
M is N-1,
unknown(M, X, L, R).
上述谓词仍然不是最优的,我们只能计算一次长度。但是它显示了我们删除了多余的选择点的位置。现在,谓词运行如下:
Jekejeke Prolog 4, Runtime Library 1.4.1 (August 20, 2019)
(c) 1985-2019, XLOG Technologies GmbH, Switzerland
?- combination(2,[a,b,c],X).
X = [a, b] ;
X = [a, c] ;
X = [b, c]