Search code examples
prologclpfd

Getting Singleton Warning in prolog (denomination change)


I was writing a prolog predicate to print possible changes for given value, on running it shows a warning that X2 is a singleton variable. X is the given value, T is given List of available denominations and L is the resulting List.

e.g: 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.

Solution

  • You're getting a singleton warning because the comma , has higher precedence than ;, so the effective grouping of your code is:

    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).
    

    (note the parentheses) which isolates change1(X2,[H|T],[H|AC],L) from any queries that might instantiate X2. So X2 is singleton in that context. You probably meant:

    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)
        ).