2012-04-12 77 views
2

我試圖使用約束X不是列表中的值。使用in_set/2約束

SICStus Prolog manual

?X in_set +FDSet 

我無法弄清楚如何將列表轉換爲FDSet,雖然。 我有一個整數列表[2,3,8,9],我想限制變量X的域不在列表中。我怎麼做?謝謝。

回答

4

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. 
+0

那麼:\({2} \/{3} \/{8} \/{9})中的X' – false 2015-08-04 10:19:36

0

我實現了一個喜歡在這裏..

/** 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). 
+2

這是* generate-and-test *,並且放棄約束的力量。 「in/2」的意思是確定性地聲明一個變量的域。您應該確定性地將列表轉換爲域表達式,然後發佈單一的「in/2」約束來充分受益於CLP(FD)約束,而不是回溯(使用'member/2')。 – mat 2015-08-03 18:51:21

+0

嗯,聽起來不錯!我會看看我是否可以實現這種方式。感謝您的建議。 – 2015-08-05 11:48:17