我试图使用约束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