Prolog:foreach还是forall用于约束求解?

时间:2014-11-15 14:06:37

标签: lambda prolog constraint-programming clpfd resource-scheduling

我正在尝试使用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等开心。那是问题吗?如果是这样,我该如何解决?

2 个答案:

答案 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。