我正在尝试编译SWI-Prolog程序但继续获取test is always true, var (sum) error on line 7
。我无法弄清楚这意味着什么。有人可以帮忙吗?这是一个我希望最终解决拉丁方的程序。谢谢。
:- use_module(library(clpfd)).
magic_counter(Count) :-
findall(a, magic_1(_Soln), As),
length(As, Count).
magic_1(Soln) :-
Row1 = [W1, W2, W3],
Row2 = [X1, X2, X3],
Row3 = [Y1, Y2, Y3],
Row1 ins 1..3,
Row2 ins 1..3,
Row3 ins 1..3,
Sum #= 6,
all_different(Row1),
all_different(Row2),
all_different(Row3),
all_different([W1,X1,Y1]),
all_different([W2,X2,Y2]),
all_different([W3,X3,Y3]),
W1 + W2 + W3 #= Sum,
X1 + X2 + X3 #= Sum,
Y1 + Y2 + Y3 #= Sum,
W1 + X1 + Y1 #= Sum,
W2 + X2 + Y2 #= Sum,
W3 + X3 + Y3 #= Sum,
append(Row1,Row2,Row12),
append(Row12,Row3,Soln),
labeling([], Soln).
答案 0 :(得分:4)
如果一行由1
和3
之间的三个整数组成,并且这些整数必须是不同的,那么这一行的总和必须是6
(根据定义)。因此,声明这样的行的总和等于6
是一个空闲约束。同样的推理适用于你声明类似的不相交约束的'列'。
编辑:尽管上述推理是正确的,但这不是警告的来源。 Carlo是对的,它只取决于约束库重写约束的方式。
test1:-
L = [X],
L ins 1..2,
Y #= 2,
X #= Y.
test2:-
L = [X],
L ins 1..2,
X #= 2.
test1/0
会发出警告,test2/0
没有。不过,我发现很难理解为什么首先发出警告,即背后的理性是什么。例如,这里是test1/0
的扩展(注意我的评论):
:- use_module(library(clpfd)).
test1:-
A=[D],
A ins 1..2,
(
integer(B)
->
(
var(2)
->
2 is B
;
true
->
B=:=2
;
C is B,
clpfd:clpfd_equal(C, 2)
)
;
true
->
(
var(B) % This does not throw a warning.
->
B is 2
;
C is 2,
clpfd:clpfd_equal(B, C)
)
;
clpfd:clpfd_equal(B, 2)
),
(
integer(D)
->
(
var(B) % This throws a "Test is always true" warning.
->
B is D
;
integer(B)
->
D=:=B
;
E is D,
clpfd:clpfd_equal(E, B)
)
;
integer(B)
->
(
var(D)
->
D is B
;
E is B,
clpfd:clpfd_equal(D, E)
)
;
clpfd:clpfd_equal(D, B)
).
答案 1 :(得分:4)
这是一个警告,而不是错误。
我在SWI-Prolog邮件列表上再次发布了一个针对此问题的请求,因为一些现有代码在对邮件进行细化后开始提出此警告。 Here是Jan的答案。
我认为您可以忽略该警告,或禁用它,但这似乎不可取。