如果我在第3行中取消“中止”,程序会在屏幕上生成所需输出的近似值,例如:
?- biggest_denom(37,P).
Pay with 25 ; remainder =12
Pay with 10 ; remainder =2
Pay with 1 ; remainder =1
Pay with 1 ; remainder =0
Finish
% Execution Aborted
?-
然而,我想要'purer'return-solutions-when-hit-decmicon或return-as-list变体。 (“追踪。”似乎没有提供任何线索)。
我能得到的最好(第3行中的'abort'没有被删除)是:
?- biggest_denom(13,P).
Pay with 10 ; remainder =3
Pay with 1 ; remainder =2
Pay with 1 ; remainder =1
Pay with 1 ; remainder =0
Finish
P = 10 ;
Pay with 5 ; remainder =8
Pay with 5 ; remainder =3
Pay with 1 ; remainder =2
Pay with 1 ; remainder =1
Pay with 1 ; remainder =0
Finish
P = 5 ;
Pay with 1 ; remainder =7
Pay with 5 ; remainder =2
Pay with 1 ; remainder =1
Pay with 1 ; remainder =0
Finish
P = 5 ;
Pay with 1 ; remainder =6
Pay with 5 ; remainder =1
Pay with 1 ; remainder =0
Finish
P = 5 ;
Pay with 1 ; remainder =5
Pay with 5 ; remainder =0
Finish
P = 5 ;
Pay with 1 ; remainder =4
Pay with 1 ; remainder =3
Pay with 1 ; remainder =2
Pay with 1 ; remainder =1
Pay with 1 ; remainder =0
Finish
P = 5 %IT GOES ON AND ON LIKE THIS!! XXXXXXXXXXXXX
这是我的代码:
%XXXXXXXXXXXXX no change given XXXXXXXXXXXXXXXXXXXXXXXXXXXX
accept([100,50,25,10,5,1]). %pre-sorted (listing from big to small)
biggest_denom( 0 , _ ) :- writeln('Finish'). %,abort. %please STOP!!! horrible!
biggest_denom( N , D ) :-
N \= 0 ,
accept(X) ,
member(D,X) ,
D =< N ,
Remainder is N-D ,
write('Pay with ') ,
write(D) ,
write(' ; remainder =') ,
writeln(Remainder) ,
%Remainder \= 0 , %gives more output, for some reason, not less
biggest_denom(Remainder,D2)
.
pay( N ) :- %print list of denoms which adds up to N ; will use findall
writeln('not yet implemented') .
非常感谢任何建议!
答案 0 :(得分:0)
你应该让顶级成员为你写作。你也可以删除accept/1
中的列表并将它们作为事实。
accept(100).
accept(50).
accept(25).
accept(10).
accept(5).
accept(1).
return_change(N, C) :- integer(N), N > 0,
return_change_1(N, C).
return_change_1(0, []) :- !.
return_change_1(N, [X-R|Change]) :-
accept(X),
X =< N,
R is N - X,
return_change_1(R, Change).
这实际上就是你需要做的一切。
?- return_change(37, C), !.
C = [25-12, 10-2, 1-1, 1-0].
或者,如果你坚持输出:
?- return_change(37, C), !, forall(member(P-R, C), format("Pay with ~d ; remainder ~d~n", [P, R])).
Pay with 25 ; remainder 12
Pay with 10 ; remainder 2
Pay with 1 ; remainder 1
Pay with 1 ; remainder 0
C = [25-12, 10-2, 1-1, 1-0].
删除查询中的剪切以获得更多解决方案。
正如@mat指出的那样,使用谓词foo, !
可以更优雅地表达来电once/1
,如下所示:once(foo)