swi prolog程序“未更改”未正确返回面额
如果我取消第3行中的“中止”,程序将在屏幕上生成所需输出的近似值,例如:swi prolog程序“未更改”未正确返回面额,prolog,Prolog,如果我取消第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 ?- 但是,我希望在按分号或按列表变量返回时使用“更纯”的返回解决方案。查出似乎没有提供任何线索 第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
?-
但是,我希望在按分号或按列表变量返回时使用“更纯”的返回解决方案。查出似乎没有提供任何线索
第3行中的“中止”没有取消,我能得到的最好结果是:
?- 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') .
任何建议都将不胜感激 你应该让高层为你写作。您还可以去掉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), !, 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!可以使用谓词one/1更优雅地表达,如下所示:oncefo@mat Yes,这是故意的。错误的做法是更改谓词的名称。是的,这个程序有类似的版本,要求以所有可能的方式支付或返回更改,但今天我只是在寻找一个最明显的解决方案,我认为,这就是Boris的代码似乎一直在做的事情。感谢所有人,尤其是鲍里斯!!!once/1是提交第一个解决方案的一个优雅的替代方案。
?- 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].