我正在探索像这样的约束依赖结构:
assign(X,Y) :-
X in 1..5,
((X mod 2 #= 1) #=> Y in 2..3),
((X mod 2 #= 0) #=> Y #= 5).
我正在寻找的是X
和Y
的域尽可能稀疏的表示 - 在这种情况下,它将是{{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的机制和局限性知之甚少,我能从中学到什么资源吗?我已经知道约束编程,弧一致性等的基础知识。
答案 0 :(得分:1)
要保持clpfd枚举谓词(例如indomain/1
,label/1
,labeling/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.