[英]Prolog does not end calculation?
This is rather a technical question I think, I am trying to write a program that will find me all sub-sets of size K of the integers 1,2,...,N. 我认为这是一个技术问题,我正在尝试编写一个程序,该程序将为我找到所有大小为K的子集,整数1,2,...,N。
In here I've asked about a sub-set function that I'm using. 在这里,我询问了我正在使用的子集功能。 The fixed version is:
固定版本为:
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).
Later I wrote two functions to help me find the last element in a set and the sub-set of all element except the last (because [A|Rest]
means A
is the first and Rest
is from number 2 to last, but I'd like the opposite - having the last elements and all the elements from the first to the one before the last). 后来我写了两个函数来帮助我找到集合中的最后一个元素以及除最后一个元素之外的所有元素的子集(因为
[A|Rest]
表示A
是第一个元素,而Rest
是从2到最后一个元素,但是我d则相反-具有最后一个元素以及从第一个到最后一个之前的所有元素)。 The functions are: 这些功能是:
lastOf(A,[A]).
lastOf(A,[B|R]):-
lastOf(A,R).
subLast([],[X]).
subLast([A|R1],[A|R2]):-
subLast(R1,R2).
Now I wrote a function that creates a list of the first N
natural numbers: 现在,我编写了一个函数,该函数创建了前
N
自然数的列表:
setOf(0,[]).
setOf(N,Nums):-
lastOf(N,Nums),
N>0, N1 is N-1,
subLast(NeoNums,Nums),
setOf(N1, NeoNums).
To combine all the above I have: 结合以上所有内容,我可以:
choose(K,N,X):-
setOf(N,Y),
subs(K,X,Y).
Running it, for example on 2
and 4
, I get: 运行它,例如在
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
These are all the correct outputs, but the problem is that after every time I press enter for a (possible) next answer, I get the next one, apart from the last, in which I have to forcefully abort, as it seems like the programs gets stuck in an infinite loop of some sort. 这些都是正确的输出,但是问题在于,每次按Enter输入(可能的)下一个答案后,除最后一个答案外,我都会得到下一个答案,在该答案中,我不得不强行中止,就像程序陷入某种无限循环中。
Can anyone assist? 有人可以协助吗?
I'm using SWI-Prolog. 我正在使用SWI-Prolog。
If you're using SWI-Prolog , you can also use clpfd ! 如果您使用的是SWI-Prolog ,也可以使用clpfd ! Here's a clpfd variant of
choose/3
: 这是select
choose/3
的clpfd变体:
:- use_module(library(clpfd)).
choose(K,N,Zs) :-
length(Zs,K),
Zs ins 1..N,
chain(Zs,#<),
labeling([],Zs).
That's it! 而已! And here's the query you gave in the question:
这是您在问题中提供的查询:
?- 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
The setOf
is the problem here. setOf
是这里的问题。 More specifically - lastOf
, which is generating an infinite number of possible lists ending with N
. 更具体地说
lastOf
,它生成无限数量的以N
结尾的可能列表。 Anyway, setOf can be implemented much easier and in much more readable way (and which is terminating): 无论如何,setOf可以更轻松,更易读的方式实现(并且终止):
setOf(0, []).
setOf(N, [N|T]) :-
N > 0,
N1 is N-1,
setOf(N1, T).
This is if you don't care about the reverse order of the numbers. 这是如果您不关心数字的倒序。 Otherwise by introducing a helper predicate:
否则,通过引入一个辅助谓词:
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).
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.