5

我正在尝试使用 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 总是失败,使用 forall 总是成功,没有任何限制。

就这个循环而言,Schedule 是全局的,目的是使用序列化来约束它的 starttime 元素。OTOH、HisSchedule、Sts 和 Dus 取决于特定的人。所以我认为我需要 foreach 来让 Schedule 开心,但为了让 HisSchedule 等开心。那是问题吗?如果是这样,我该如何解决?

4

2 回答 2

8

一些 Prolog 系统提供了forall/2内置功能,它严重依赖非单调结构,并且从未设计为与约束协作。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),
   ...
于 2014-11-15T15:26:22.627 回答
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。

于 2014-11-16T07:18:16.523 回答