让我们有以下假设场景……一个 5x5 的网格,让我们说 3 个数字。我们要定义对位置的约束。在 CLP 中,我们通常用整数定义约束,所以这是一种方法:
... Fig1X #\= 2, Fig1Y #\= 3, ....
即我们对每个 X 和 Y 位置都有单独的变量。有没有办法定义基于整数的结构化变量的约束。例如:
.... Fig1 #\= (2,4) ...
该场景仅用于说明。
我主要对您如何处理结构化变量感兴趣,是否有标准做法。
特别是与您的示例中的几何任务有关,至少有以下完全不同的概念方法:
geost/N
:这些约束为推理多维对象提供了一种专用的迷你语言。这是一种非常强大且灵活的方法,可在 SICStus Prolog 和其他一些约束系统中使用。X #= 2 #==> Y #\= 4
等于2,则Y
不能为 4。X
因此,(X,Y)
自动不同于(2,4)
。table/2
等)让您显式枚举允许的元组集或其补集。fd_relation/2
这些方法会带来不同的后果和权衡。我个人的喜好和建议大致体现在上面的顺序上。但是,根据当前的情况,一种方法可能比其他方法具有显着优势。
CSP 中的建模部分有时被称为一门艺术而不是一门科学,因为有很多不同的可能性可供选择,而且还不清楚哪种模型是最好的,也因为有很多权衡——例如便利性、便携性、可扩展性、速度、内存等——涉及。
在像您这样的情况下,“结构化变量”具有仅包含数字字段的固定结构,您不需要“结构化变量”的概念。从概念上讲,您只使用数字元组(或数字变量)。
有时这些元组最好表示为列表,因为这样您就可以直接应用将列表作为参数的全局约束。例如,要限制一个点[X,Y]
不在对角线上,你可以写
alldifferent([X,Y])
或使用表格约束将其约束到给定的一组坐标:
table([[X,Y]], [[1,2],[2,4],[3,1],[4,3]])
在其他情况下,最好使用具有描述性仿函数的结构,例如point(X,Y)
or rect(X1,Y1,X2,Y2)
,然后编写相应的约束包装器,例如
points_differ(point(X,Y), point(V,W)) :-
X#\=V or Y#\=W.
或者
rect_contains_point(rect(I,J,K,L), point(PI,PJ)) :-
I #=< PI, PI #=< K,
J #=< PJ, PJ #=< L.