Lambda 序言:foreach还是forall用于约束求解?

Lambda 序言:foreach还是forall用于约束求解?,lambda,prolog,constraint-programming,clpfd,resource-scheduling,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

我正在尝试使用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,它总是成功而不受任何约束


就这个循环而言,调度是全局的,其目的是使用序列化的方法约束它的starttime元素。奥托,他的时间表,Sts和DU取决于特定的人。所以我想我需要每个人都让自己的日程安排愉快,但对于所有人来说,都要让自己的日程安排愉快。这就是问题所在吗?如果是这样的话,我该如何修复它呢?

对于所有/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
是非常有问题的,对于所有/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.
如果有的话,正确答案应该是1..5中的
I

要解决此问题,请首先将关系数据转换为列表:

   ...,
   setof(P, isa(P, person), Ps),
   maplist(perperson(P,Global),Ps),
   ...

我自己把它修好了,就像这样:

  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编写。

注意,
forall/2
谓词的标准定义是:
forall(Generator,Test):-\+(Generate,\+Test)
。使用否定(作为失败)可能是查询成功而不受任何约束的原因。谢谢。只是出于兴趣,你知道关于如何与中电进行资源规划的好材料吗?我担心的是,我考虑在假期或其他高优先级任务周围拆分任务,并表示工人更改主题时所丢失的时间。在这一点上,不再有简单的开始、持续时间和结束。@AdrianMay:可能从使用
findall/3
开始,而不是使用
setof/3
意味着解决方案序列中的意外更改可能会改变问题的解决方式。
…,地图列表(Schedule+\Per^(包括…,人员),…
默认情况下,变量是``的局部变量,您需要声明那些不是。