在序言中获取单例警告(面额更改)

Getting Singleton Warning in prolog (denomination change)

我正在编写序言谓词来打印给定值的可能更改, 在 运行 上显示 X2 是单例变量的警告。 X 是给定值,T 是可用面额列表,L 是结果列表。

例如change(100,[1,2,5,10],L).

change(X,T,L) :-
    change1(X,T,[],L).
change1(X,[H|T],AC,L):-
    X > 0,
    X >= H,
    X2 is X-1,
    change1(X2,T,[H|AC],L);
    change1(X2,[H|T],[H|AC],L);
    change1(X,T,AC,L).
change1(0,_,AC,AC).
change1(X,[],_,_):-X \= 0,false.

您收到 单例 警告,因为逗号 , 的优先级高于 ;,因此代码的有效分组是:

change1(X,[H|T],AC,L):-
    (   X > 0,
        X >= H,
        X2 is X-1,
        change1(X2,T,[H|AC],L)
    )
    ;   change1(X2,[H|T],[H|AC],L)
    ;   change1(X,T,AC,L).

(注意括号)将 change1(X2,[H|T],[H|AC],L) 与可能实例化 X2 的任何查询隔离开来。所以 X2 在这种情况下是单例的。你的意思可能是:

change1(X,[H|T],AC,L):-
    X > 0,
    X >= H,
    X2 is X-1,
    (   change1(X2,T,[H|AC],L)
    ;   change1(X2,[H|T],[H|AC],L)
    ;   change1(X,T,AC,L)
    ).

使用!

:- use_module([library(clpfd),library(lists)]).
:- set_prolog_flag(toplevel_print_anon, false).

我们这样定义change_/4

change_(Total, Units, Amounts, Zs) :-
   same_length(Units, Amounts),
   Units   ins 1..sup,
   Amounts ins 0..sup,
   scalar_product(Units, Amounts, #=, Total),
   append( [Total|Units],Amounts, Zs).

示例查询:

?- change_(100, [1,2,5,10], Amounts, _Zs), labeling([], _Zs).
  Amounts = [0,0,0,10]
; Amounts = [0,0,2,9]
; Amounts = [0,0,4,8]
...