简体   繁体   English

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

[英]Prolog: foreach or forall for constraint solving?

I'm attempting project scheduling with SWI prolog and CLP. 我正在尝试使用SWI prolog和CLP进行项目调度。 I managed to support sequential dependencies but I'm struggling with avoiding double booking people. 我设法支持顺序依赖,但我正在努力避免双重预订人。

I have a list called Schedule containing elements like [taskname, starttime] where starttime is a free variable for the constraint solver. 我有一个名为Schedule的列表,其中包含[taskname,starttime]等元素,其中starttime是约束求解器的自由变量。 They're already constrained by sequential dependencies. 它们已经受到顺序依赖性的限制。

I'm trying to write a loop like this to rule out double bookings: 我正在尝试编写一个这样的循环来排除双重预订:

  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)
  )),

With foreach it always fails and with forall it always succeeds without constraining anything. 随着foreach它总是失败和forall它总是成功而不会约束任何东西。

Schedule is global as far as this loop is concerned, and the purpose is to constrain its starttime elements using serialized. 就这个循环而言,Schedule是全局的,目的是使用序列化来约束其starttime元素。 OTOH, HisSchedule, Sts and Dus depend on the particular person. OTOH,HisSchedule,Sts和Dus取决于特定的人。 So I think I need foreach to make Schedule happy but forall to make HisSchedule etc happy. 所以我认为我需要foreach让Schedule快乐,但是要让HisSchedule等开心。 Is that the problem? 那是问题吗? And if so how do I fix it? 如果是这样,我该如何解决?

The forall/2 built-in is offered by some Prolog systems, it relies heavily on non-monotonic constructs, and was never designed to collaborate with constraints. forall/2内置由一些Prolog系统提供,它在很大程度上依赖于非单调构造,并且从未被设计为与约束协作。 Same is true for foreach/2 which attempts to be a bit smarter. 对于试图更聪明的foreach/2也是如此。

Answers, solutions, constraints 答案,解决方案,约束

So, what is the big, fundamental problem here? 那么,这里最大的根本问题是什么? A lot of Prolog received its current form when constraints were not widely known. 当约束不为人所知时,很多Prolog都收到了它目前的形式。 Many constructs thus take success of a goal as a yes as ultimate truth. 因此,许多结构将目标的成功视为最终真理。 But with constraints, things are a bit different. 但是受限制,事情会有所不同。 A succeeding goal produces an answer which now may contain no solution at all! 一个接下来的目标产生一个答案 ,现在可能根本没有解决方案! For this reason success is not what it used to be. 因此,成功与以往不同。 Here is an example using SICStus: 以下是使用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

Answers may now contain no solution at all, in other words, they may be false. 答案现在可能根本没有解决方案,换句话说,它们可能是错误的。

In your example include/3 is highly problematic, as is forall/2 . 在你的例子中, include/3非常有问题,就像forall/2 Ah, and also setof/3 gets crazy with constraints: 啊,而且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.

If at all, the correct answer would be I in 1..5 . 如果有的话,正确答案是I in 1..5

To solve this problem, first transform the relational data into lists: 要解决此问题,请首先将关系数据转换为列表:

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

I fixed it myself like this: 我这样修好了:

  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).

For some reason I couldn't write nodoublebookings as a lambda. 出于某种原因,我无法将nodoublebookings写成lambda。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM