我有以下功能。
当我用final_filter([(2, 2)], R)
调用它时,会打印很多" 2 2"对。当我评论get_all_sums(S, _)
时,它可以正常工作,但是如果我单独测试get_all_sums(4, R)
。我的工作也很好,可能是什么问题?
get_all_sums_R(NR, IT, []):- IT > NR - 2.
get_all_sums_R(NR, IT, R):-
A is IT,
B is NR-IT,
A >= B,
NEXT_IT is IT + 1,
get_all_sums_R(NR, NEXT_IT, R_NEXT),
append([(A, B)], R_NEXT, R).
get_all_sums_R(NR, IT, R):-
A is IT,
B is NR-IT,
A < B,
NEXT_IT is IT + 1,
get_all_sums_R(NR, NEXT_IT, R).
get_all_sums(NR, R):-get_all_sums_R(NR, 2, R).
get_all_divisors(X, IT, []):-IT > X/2.
get_all_divisors(X, IT, R):-
IT =< X/2,
TMP_RES is mod(X, IT),
TMP_RES =:= 0,
NEXT_IT is IT + 1,
get_all_divisors(X, NEXT_IT, R_NEXT),
append([IT], R_NEXT, R).
get_all_divisors(X, IT, R):-
IT =< X/2,
NEXT_IT is IT + 1,
get_all_divisors(X, NEXT_IT, R).
get_all_products_R([], _, []).
get_all_products_R([H|L], NR, R):-
A is H,
B is NR/H,
A >= B,
get_all_products_R(L, NR, NEXT_R),
append([(A, B)], NEXT_R, R).
get_all_products_R([H|L], NR, R):-
A is H,
B is NR/H,
A < B,
get_all_products_R(L, NR, R).
get_all_products(NR, R):-
get_all_divisors(NR, 2, R_LEFT),
get_all_products_R(R_LEFT, NR, R).
single_element([_]).
final_filter([(A, B)|_], _):-
write(A),
P is A*B,
S is A+B,
get_all_products(P, PRODUCTS),
get_all_sums(S, _),
write(A),write(' '), write(B), write('\n'),
not(single_element(PRODUCTS)).
答案 0 :(得分:3)
这里的中心误解是Prolog中的终止意味着什么。也就是说,通用终止。感兴趣的查询如下:
?- get_all_sums(4,R).
R = [ (2, 2)]
Prolog的顶级shell为您提供第一个答案。但是通过输入; 或 SPACE 可以获得更多。所以当向您展示第一个答案/解决方案时,Prolog还没有完成。事实上:
?- get_all_sums(4,R).
R = [ (2, 2)] ;
R = [ (2, 2), (3, 1)] ;
R = [ (2, 2), (3, 1), (4, 0)] ;
R = [ (2, 2), (3, 1), (4, 0), (5, -1)] ;
R = [ (2, 2), (3, 1), (4, 0), (5, -1), (6, -2)] ;
R = [ (2, 2), (3, 1), (4, 0), (5, -1), (6, -2), (7, -3)] ;
R = [ (2, 2), (3, 1), (4, 0), (5, -1), (6, -2), (7, -3), (8, -4)] ;
R = [ (2, 2), (3, 1), (4, 0), (5, -1), (6, -2), (7, -3), (8, -4), (9, -5)] ...
你真的想要列举所有负数吗?对我来说看起来无穷无尽!
但是,让我们专注于非终止财产......
也许系统会在8个解决方案后停止?有没有更好的方法 当然?只需&#34;关闭&#34;解决方案的显示如下:
?- get_all_sums(4,R), false.
现在我们不再对解决方案/答案感到烦恼,我们可以专注于终止属性。我将进一步增加这些目标
false
以及更多进入您的计划,以本地化不终止的实际原因。生成的程序称为故障切片。无论我如何添加false
目标,它总是认为:如果失败切片没有终止,那么原始程序也不会终止。经过一番尝试,我得到了:
get_all_sums_R(NR, IT, []):- false, IT > NR - 2. get_all_sums_R(NR, IT, R):- NR = 4, A is IT, B is NR-IT, A >= B, NEXT_IT is IT + 1, get_all_sums_R(NR, NEXT_IT, R_NEXT), false,append([(A, B)], R_NEXT, R).get_all_sums_R(NR, IT, R):- false,A is IT,B is NR-IT,A < B,NEXT_IT is IT + 1,get_all_sums_R(NR, NEXT_IT, R). get_all_sums(NR, R):-get_all_sums_R(NR, 2, R), false. ?- get_all_sums(4, R), false.
所以这个小的剩余部分负责不终止。为了解决这个问题,你必须在这里添加一些目标。确定:NR = 4
,A
增加1,B
减1。只要A >= B
,这个循环就会继续。
您可能想要添加剪切或once/1
。但是这个
只引导你从一个虫子到另一个虫子。更好地解决上述问题。