我試圖使用約束X
不是列表中的值。使用in_set/2約束
?X in_set +FDSet
我無法弄清楚如何將列表轉換爲FDSet,雖然。 我有一個整數列表[2,3,8,9]
,我想限制變量X
的域不在列表中。我怎麼做?謝謝。
我試圖使用約束X
不是列表中的值。使用in_set/2約束
?X in_set +FDSet
我無法弄清楚如何將列表轉換爲FDSet,雖然。 我有一個整數列表[2,3,8,9]
,我想限制變量X
的域不在列表中。我怎麼做?謝謝。
從documentation來看,list_to_fdset/2
怎麼樣?您可以翻譯爲FDSet
,然後構建其補充,然後發佈in_set/2
。如果您的版本沒有list_to_fdset/2
,則可以輕鬆地將列表轉換爲正常的域表達式,然後發佈取消約束的in/2
。在你的榜樣,那麼您需要交:
#\ X in {2}\/{3}\/{8}\/{9}
,你只需要描述的列表和由單身的域表達,這是很容易的關係:
list_domain([I|Is], Dom) :-
foldl(integer_domain_, Is, {I}, Dom).
integer_domain_(I, D0, D0 \/ {I}).
查詢示例:
?- list_domain([1,2,3], Dom).
Dom = {1}\/{2}\/{3}.
?- list_domain([1,2,3], Dom), X in Dom.
Dom = {1}\/{2}\/{3},
X in 1..3.
我實現了一個喜歡在這裏..
/** Constraint domain to memebers of a list (of numbers only) **/
domain_list_constraint(_, []) :- !.
domain_list_constraint(DomainVar, List) :- member(E, List),
(atom(E)->atom_number(E, I),
DomainVar #= I;
DomainVar #= E).
這是* generate-and-test *,並且放棄約束的力量。 「in/2」的意思是確定性地聲明一個變量的域。您應該確定性地將列表轉換爲域表達式,然後發佈單一的「in/2」約束來充分受益於CLP(FD)約束,而不是回溯(使用'member/2')。 – mat 2015-08-03 18:51:21
嗯,聽起來不錯!我會看看我是否可以實現這種方式。感謝您的建議。 – 2015-08-05 11:48:17
那麼:\({2} \/{3} \/{8} \/{9})中的X' – false 2015-08-04 10:19:36