2012-04-12 79 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