如何缩短以下程序?

时间:2013-05-12 17:07:31

标签: prolog clpfd sicstus-prolog

我想缩短以下程序。只需成像就有数十个变量,而不只是XY。问题是我需要分别为每个变量定义域。我不喜欢它,因为它使我的程序更长,更不透明。

输入:

?- Dom1 in 0..2, Dom2 in 0..2, global_cardinality([X,Y], [0-Dom1,1-Dom2]), labeling([],[X,Y]).

结果:

X = 0,
Y = 0,
Dom1 = 2,
Dom2 = 0 ? ;
X = 0,
Y = 1,
Dom1 = 1,
Dom2 = 1 ? ;
X = 1,
Y = 0,
Dom1 = 1,
Dom2 = 1 ? ;
X = 1,
Y = 1,
Dom1 = 0,
Dom2 = 2 ? ;
no

起初我以为我会通过写作来解决它:

?- Dom1 in 0..2, global_cardinality([X,Y], [0-Dom1,1-Dom1]), labeling([],[X,Y]).  

但是它没有用,因为Dom1用一个值统一(这是clpfd中发生的事情的正确术语吗?),因此唯一的结果是:

X = 0,      
Y = 1,
Dom1 = 1 ? ;
X = 1,
Y = 0,
Dom1 = 1 ? ;
no

谢谢!

2 个答案:

答案 0 :(得分:3)

假设L = [X1,...,Xn]并且您希望每个变量都在1..10。

备选方案1,仅适用于间隔:

?- domain(L, 1, 10).

备选方案2,适用于非间隔的域:

?- (foreach(X,L) do X in 1..10).

答案 1 :(得分:2)

我无法理解你的用例。你所追求的结果似乎与

相同
?- [X,Y] ins 0..1, labeling([], [X,Y]).
X = Y, Y = 0 ;
X = 0,
Y = 1 ;
X = 1,
Y = 0 ;
X = Y, Y = 1.

您的解释

  

它不起作用,因为Dom1用一个值统一(...)

我似乎很清楚。由于Dom1表示密钥的“出现次数”,并且有2个变量具有2个可能的值('keys'0,1),因此Dom1必须为1.