我正在尝试使用SWI prolog和CLP进行项目调度。我设法支持顺序依赖,但我努力避免双重预订人。
我有一个名为Schedule的列表,其中包含[taskname,starttime]等元素,其中starttime是约束求解器的自由变量。他们已经受到顺序依赖的约束。
我试图写一个这样的循环来排除双重预订:
forall /* or maybe foreach*/ (isa(P,person), (
% Filter scheduled tasks on that person...
include(\[T,S]^(assigned(T,P)), Schedule, HisSchedule),
% Present what serialized expects..
maplist(\[T,S]^S^true, HisSchedule, Sts),
% duration is just user-defined data...
maplist(\[T,S]^D^(duration(T,D)), HisSchedule, Dus),
% Hit it...
serialized(Sts, Dus)
)),
对于foreach来说,它始终失败,并且随着它的成功而不会限制任何事情。
就此循环而言,Schedule是全局的,目的是使用序列化约束其starttime元素。 OTOH,HisSchedule,Sts和Dus取决于特定的人。所以我认为我需要foreach让Schedule快乐,但是要让HisSchedule等开心。那是问题吗?如果是这样,我该如何解决?
答案 0 :(得分:8)
forall/2
内置由一些Prolog系统提供,它在很大程度上依赖于非单调构造,并且从未设计为与约束协作。 foreach/2
也是如此,它试图更聪明一些。
那么,这里最大的根本问题是什么?当约束不为人所知时,很多Prolog都收到了它目前的形式。因此,许多结构将目标的成功视为最终真理。但是受限制,事情会有所不同。后续目标产生答案,现在可能根本没有解决方案!因此,成功与以往不同。以下是使用SICStus的示例:
| ?- asserta(clpfd:full_answer).
yes
| ?- X mod 2 #= 1.
clpfd:(X mod 2#=1),
X in inf..sup ?
yes
| ?- X mod 2 #= 1, X mod 2 #= 0.
clpfd:(X mod 2#=0),
clpfd:(X mod 2#=1),
X in inf..sup ? ;
no
| ?- X mod 2 #= 1, X mod 2 #= 0, X in 0..9.
no
答案现在可能根本没有解决方案,换句话说,它们可能是错误的。
在您的示例include/3
中,问题很严重,forall/2
也是如此。啊,而setof/3
也因约束而疯狂:
| ?- setof(t, (I in 1..3 ; I in 3..5 ), _). % SICStus
yes
?- setof(t, (I in 1..3 ; I in 3..5 ),_). % SWI
I = 3.
如果,则正确答案为I in 1..5
。
要解决此问题,请先将关系数据转换为列表:
...,
setof(P, isa(P, person), Ps),
maplist(perperson(P,Global),Ps),
...
答案 1 :(得分:2)
我自己修理了这个:
findall(Per, isa(Per,person), People),
maplist(nodoublebookings(Schedule),People),
nodoublebookings(Schedule, Per):-
include(\[T,S]^(assigned(T,Per)), Schedule, HisSchedule),
maplist(\[T,S]^S^true, HisSchedule, Sts),
maplist(\[T,S]^D^(duration(T,D)), HisSchedule, Dus),
serialized(Sts, Dus).
出于某种原因,我无法将nodoublebookings写成lambda。