Prolog不结束计算?

Prolog不结束计算?,prolog,clpfd,Prolog,Clpfd,这是一个相当技术性的问题,我想,我正在写一个程序,可以找到所有大小为K的整数1,2,…,N的子集 在本文中,我询问了我正在使用的一个子集函数。固定版本为: subs(0,[],X). subs(N,[A|R1],[A|R2]):- N>0, N1 is N-1, subs(N1,R1,R2). subs(N,[A|R1],[B|R2]):- N>0, subs(N,[A|R1],R2). 后来,我编写了两个函数来帮助我找到集合中的最后一个元素和除最后一

这是一个相当技术性的问题,我想,我正在写一个程序,可以找到所有大小为K的整数1,2,…,N的子集

在本文中,我询问了我正在使用的一个子集函数。固定版本为:

subs(0,[],X).
subs(N,[A|R1],[A|R2]):-
   N>0,
   N1 is N-1,
   subs(N1,R1,R2).
subs(N,[A|R1],[B|R2]):-
   N>0,
   subs(N,[A|R1],R2).
后来,我编写了两个函数来帮助我找到集合中的最后一个元素和除最后一个元素之外的所有元素的子集(因为
[a | Rest]
意味着
a
是第一个,而
Rest
是从第二位到最后一位,但我希望相反——拥有最后一个元素和从第一位到最后一位的所有元素). 功能包括:

lastOf(A,[A]).
lastOf(A,[B|R]):-
   lastOf(A,R).

subLast([],[X]).
subLast([A|R1],[A|R2]):-
   subLast(R1,R2).
现在,我编写了一个函数,用于创建第一个
N
自然数的列表:

setOf(0,[]).
setOf(N,Nums):-
   lastOf(N,Nums),
   N>0, N1 is N-1,
   subLast(NeoNums,Nums),
   setOf(N1, NeoNums).
要结合以上所有内容,我有:

choose(K,N,X):-
   setOf(N,Y),
   subs(K,X,Y).
例如,在
2
4
上运行它,我得到:

?-choose(2,4,X).
X = [1, 2] ;
X = [1, 3] ;
X = [1, 4] ;
X = [2, 3] ;
X = [2, 4] ;
X = [3, 4] ;

abort
% Execution Aborted
14 ?- ERROR: Stream user_input:6:143 Syntax error: Unexpected end of clause
这些都是正确的输出,但问题是,每次我按enter键获得(可能的)下一个答案后,我都会得到下一个答案,除了最后一个答案外,我必须强制中止,因为程序似乎陷入某种无限循环中

有人能帮忙吗


我正在使用SWI Prolog。

这里的问题是
集合。更具体地说-
lastOf
,它生成无限多可能的列表,以
N
结尾。无论如何,setOf可以更容易地实现,并且以更易读的方式实现(即终止):

这是如果你不在乎数字的倒序。否则,通过引入辅助谓词:

setOf(N, X) :- range(1, N, X).
% range(LowerBound, UpperBound, ResultList)
range(L, L, [L]).
range(L, U, [L|T]) :-
   L < U,
   L1 is L + 1,
   range(L1, U, T).
setOf(N,X):-范围(1,N,X)。
%范围(下限、上限、结果列表)
范围(L,L,[L])。
范围(L,U[L|T]):-
L
如果您正在使用,也可以使用!下面是
choose/3
的一个变体:

:- use_module(library(clpfd)).

choose(K,N,Zs) :-
   length(Zs,K), 
   Zs ins 1..N,
   chain(Zs,#<),
   labeling([],Zs).
你没有收到关于“单例变量”的警告吗?你为什么不把它修好?
:- use_module(library(clpfd)).

choose(K,N,Zs) :-
   length(Zs,K), 
   Zs ins 1..N,
   chain(Zs,#<),
   labeling([],Zs).
?- choose(2,4,Zs).
Zs = [1,2] ;
Zs = [1,3] ;
Zs = [1,4] ;
Zs = [2,3] ;
Zs = [2,4] ;
Zs = [3,4].              % the goal `choose(2,4,Zs)` terminates