我使用CLP(FD)和SWI-Prolog编写了一个CSP程序.
我认为当我在谓词中使用mod运算符时,我需要改进约束的写法#\/.
一个简短的例子:
:- use_module(library(clpfd)).
constr(X,Y,Z) :-
X in {1,2,3,4,5,6,7},
Y in {3,5,7},
Z in {1,2},
((X #= 3)) #==> ((Y mod 3 #= 0) #\/ (Y mod 7 #= 0)),
((Z #= 1)) #<==> ((Y mod 3 #= 0) #\/ (Y mod 7 #= 0)).
Run Code Online (Sandbox Code Playgroud)
如果我打电话constr(3,Y,Z).,我得到Z #= 1或Z #= 2.这是因为mod仍然需要评估一些中间变量(相对于表达式).
当然理想只是获得Z #= 1.
怎么可以这样做?
我知道如果我写的话
((X #= 3)) #==> ((Z #= 1)),
((Z #= 1)) …Run Code Online (Sandbox Code Playgroud) 我的问题与这个(现在已有1年历史)关于CLP(FD)计划中的具体化问题的帖子有关:链接
我提供给SWI引擎的prolog文件是基于用户可以使用另一个应用程序添加/编辑/删除的一些数据(即之后调用引擎的相同数据),即时编写的.
我想检测一些特殊情况来动态重写约束,以帮助"引擎"找到最小的可能域.一个例子 :
constr(X,Y,Z) :-
X in {1,2,3,4,5,6,7},
Y in {3,5,7},
Z in {1,2},
((X #= 3)) #==> ((Y mod 3 #= 0) #\/ (Y mod 7 #= 0)),
((Z #= 1)) #<==> ((Y mod 3 #= 0) #\/ (Y mod 7 #= 0)).
Run Code Online (Sandbox Code Playgroud)
如果我打电话constr(3,Y,Z).,我得到Z #= 1或Z #= 2.
一种解决方案是自动替换最后两行
((X #= 3)) #==> T,
((Z #= 1)) #<==> T,
T #<==> ((Y mod 3 #= 0) #\/ (Y mod 7 #= …Run Code Online (Sandbox Code Playgroud)