I am new to Prolog and I have some probably simple issue with a piece of code. This is a real world problem that arose last Friday and believe me this is not a CS Homework.
We want to print business cards and these can only be printed in blocks of 900 cards (100 sheets with 9 cards per sheet). The cards for anybody should not be distributed over several blocks. People ordered different amount of cards, E.G:
% "braucht" is german and means "needs"
braucht(anton,400).
braucht(berta,200).
braucht(claudia,400).
braucht(dorothee,100).
braucht(edgar,200).
braucht(frank,400).
braucht(georg,100).
I put together the following definition to find an appropriate block of 900 business cards:
block(0,[]).
block(N,[H|T]) :-
braucht(H,Nh),
% \+(member(H,T)),
D is N - Nh,
D >= 0,
block(D,T).
This produces a nice list of blocks of people whose cards fit together on a 900 cards block. But it stops working if I activate the commented line “\+member….” and just gives me a “false”. But I need to assure that nobody is getting more than once on that block. What am I doing wrong here?
It seems that what you want to achieve is to set a constraint that
Hdoes not appear in the tailTof the list. However,Tis still unbound when you callmember/2, so thatmember(H, T)will succeed and hence\+ member(H,T)will fail.If you don’t want to use Constraint Programming, but use pure Prolog instead, you should use the check in the other direction and check whether
His already present in the list of people that has been aggregated up to that point. Something like:The predicate
block/3can be called from a predicateblock/2: