[英]Prolog does not end calculation?
我認為這是一個技術問題,我正在嘗試編寫一個程序,該程序將為我找到所有大小為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
是從2到最后一個元素,但是我d則相反-具有最后一個元素以及從第一個到最后一個之前的所有元素)。 這些功能是:
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。
如果您使用的是SWI-Prolog ,也可以使用clpfd ! 這是select choose/3
的clpfd變體:
:- 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
setOf
是這里的問題。 更具體地說lastOf
,它生成無限數量的以N
結尾的可能列表。 無論如何,setOf可以更輕松,更易讀的方式實現(並且終止):
setOf(0, []).
setOf(N, [N|T]) :-
N > 0,
N1 is N-1,
setOf(N1, T).
這是如果您不關心數字的倒序。 否則,通過引入一個輔助謂詞:
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.