[英]Prolog: foreach or forall for constraint solving?
我正在嘗試使用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等開心。 那是問題嗎? 如果是這樣,我該如何解決?
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),
...
我這樣修好了:
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。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.