我是 Prolog 的新手,我对一段代码有一些可能很简单的问题。这是上周五出现的现实世界问题,相信我这不是 CS 作业。
我们想打印名片,而这些名片只能打印 900 张卡片(100 张,每张 9 张)。任何人的卡片都不应该分布在几个块上。人们订购了不同数量的卡片,例如:
% "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).
我将以下定义放在一起以找到合适的 900 张名片块:
block(0,[]).
block(N,[H|T]) :-
braucht(H,Nh),
% \+(member(H,T)),
D is N - Nh,
D >= 0,
block(D,T).
这会生成一个很好的人块列表,这些人的卡片可以放在 900 张卡片块上。但是如果我激活注释行“\+member....”并且只给我一个“false”,它就会停止工作。但我需要确保没有人在那个街区得到超过一次。我在这里做错了什么?
最佳答案
看来你要实现的是设置一个约束,使得H
不会出现在列表的尾部T
中。但是,当您调用 T
时, member/2
仍然未绑定(bind),因此 member(H, T)
将成功,因此 \+ member(H,T)
将失败。
如果您不想使用约束编程,而是使用纯 Prolog,您应该使用另一个方向的检查,并检查 H
是否已经存在于已聚合到该点的人员列表中。就像是:
block(0, List, List).
block(N, Rest, List) :-
braucht(H, Nh),
\+(memberchk(H, Rest)), % will fail when H is already in Rest
D is N-Nh,
D >= 0,
block(D, [H|Rest], List).
谓词
block/3
可以从谓词 block/2
调用:block(N, List) :-
block(N, [], List).
关于prolog - 打印名片 - 一种背包任务,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8779115/