我正在使用CLPFD,但似乎无法摆脱错误:
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR: [16] throw(error(instantiation_error,_9234))
ERROR: [12] clpfd:drep_to_domain(_9270..15,_9266) at /usr/lib/swi-prolog/library/clp/clpfd.pl:3652
ERROR: [11] clpfd:clpfd_in(_9302,_9308..15) at /usr/lib/swi-prolog/library/clp/clpfd.pl:1608
ERROR: [10] computeShapeBelow([[circle|...],6|...],[[diamond|...],_9370|...])
下面是我的程序,对我来说很明显,来自nth0 / 3的Dim1和Dim2导致Prolog引发此错误。我该如何解决?我找不到使用CLPFD在StackOverflow上应用我在这里看到的解决方案的方法
:- use_module(library(clpfd)).
computeShapeBelow(Shape1,Shape2) :-
nth0(2,Shape1,Location1),
nth0(2,Shape2,Location2),
nth0(1,Shape1,Dim1),
nth0(1,Shape2,Dim2),
nth0(0,Location1,Xcord1),
nth0(0,Location2,Xcord2),
nth0(1,Location1,Ycord1),
nth0(1,Location2,Ycord2),
XlowerLimit1 #= Dim1,
XupperLimit1 #= 20-Dim1,
YlowerLimit1 #= Dim1,
YupperLimit1 #= 15-Dim1,
XlowerLimit2 #= Dim2,
XupperLimit2 #= 20-Dim2,
YlowerLimit2 #= Dim2,
YupperLimit2 #= 15-Dim2,
Ycord1 in YlowerLimit1..YupperLimit1,
Ycord2 in YlowerLimit2..YupperLimit2,
Xcord1 in XlowerLimit1..XupperLimit1,
Xcord2 in XlowerLimit2..XupperLimit2,
Ycord2 #> Ycord1+Dim2+Dim1,
labeling([min(Xcord1),
min(Ycord2),
max(Xcord2),
max(Ycord2)],
[Xcord1,Ycord1,Xcord2,Ycord2]).
修改
listing(computeShapeBelow)
产生以下内容。
computeShapeBelow(A, B) :-
nth0(2, A, C),
nth0(2, B, D),
nth0(1, A, E),
nth0(1, B, J),
nth0(0, C, Q),
nth0(0, D, R),
nth0(1, C, O),
nth0(1, D, P),
( integer(E)
-> F=E
; clpfd:clpfd_equal(F, E)
),
( integer(E)
-> G is 20-E
; clpfd:clpfd_equal(G, 20-E)
),
( integer(E)
-> H=E
; clpfd:clpfd_equal(H, E)
),
( integer(E)
-> I is 15-E
; clpfd:clpfd_equal(I, 15-E)
),
( integer(J)
-> K=J
; clpfd:clpfd_equal(K, J)
),
( integer(J)
-> L is 20-J
; clpfd:clpfd_equal(L, 20-J)
),
( integer(J)
-> M=J
; clpfd:clpfd_equal(M, J)
),
( integer(J)
-> N is 15-J
; clpfd:clpfd_equal(N, 15-J)
),
clpfd:clpfd_in(O, H..I),
clpfd:clpfd_in(P, M..N),
clpfd:clpfd_in(Q, F..G),
clpfd:clpfd_in(R, K..L),
( integer(P)
-> ( integer(O),
integer(J),
integer(E)
-> P>=O+J+E+1
; S=P,
clpfd:clpfd_geq(S, O+J+E+1)
)
; integer(O),
integer(J),
integer(E)
-> S is O+J+E+1,
clpfd:clpfd_geq(P, S)
; clpfd:clpfd_geq(P, O+J+E+1)
).
答案 0 :(得分:2)
此错误的原因是您在(in)/2
中使用变量作为域边界。
作为显示问题的最小示例,请考虑:
?- Var in X..Y. ERROR: Arguments are not sufficiently instantiated
对于(in)/2
,域必须为 ground 。不允许仅使用部分实例化的域。
对此具体问题可能的解决方法是使用诸如(#>)/2
等的算术约束,而不是(in)/2
。例如:
my_in(Var, Lower, Upper) :- Lower #=< Var, Var #=< Upper.
如果您在代码中使用该谓词而不是(in)/2
,则问题将消失。我只想弄清楚如何使用谓词。
但是,其他问题将会出现。我认为应该在一个新问题中分别讨论它们。