在Prolog的clpfd中枚举域

时间:2015-03-16 22:46:46

标签: prolog clpfd

我正在探索像这样的约束依赖结构:

assign(X,Y) :- 
    X in 1..5, 
    ((X mod 2 #= 1) #=> Y in 2..3), 
    ((X mod 2 #= 0) #=> Y #= 5).

我正在寻找的是XY的域尽可能稀疏的表示 - 在这种情况下,它将是{{1 }}。

这样做的一种方法是检测X in {1,3,5} and Y in {2,3} or X in {2,4} and Y = 5左侧的所有变量,枚举所有值并收集并合并在一起,类似于#=>,但也许有更有效的方式?

我在尝试?- assign(X, Y), findall(X-D, (indomain(X),fd_dom(Y,D)), C), do stuff with C时也遇到了错误:当我在label([X,Y])的域上添加另一个约束时,参数没有被充分实例化。

我应该何时会发生此错误?我觉得我对clpfd的机制和局限性知之甚少,我能从中学到什么资源吗?我已经知道约束编程,弧一致性等的基础知识。

1 个答案:

答案 0 :(得分:1)

要保持clpfd枚举谓词(例如indomain/1label/1labeling/2等)来自永远投掷实例化错误,只需确保在执行任何枚举谓词之前,已为所有变量分配了一些有限

那么如何直接将你写的内容翻译成代码?

assign(X,Y) :- X in 1\/3\/5, Y in 2..3.     %    X in {1,3,5} and Y in {2,3} 
assign(X,Y) :- X in 2..4,    Y in 5.        % or X in {2,4}   and Y = 5

一个简单的查询(使用SWI-Prolog):

?- assign(X,Y), labeling([],[X,Y]).
  X = 1, Y = 2
; X = 1, Y = 3
; X = 3, Y = 2
; X = 3, Y = 3
; X = 5, Y = 2
; X = 5, Y = 3
; X = 2, Y = 5
; X = 3, Y = 5
; X = 4, Y = 5.