您面临两个我想分别讨论的问题:
实例化错误
正如你提到的,我们得到:
?- 杂货店(Vs),标签(Vs)。
错误:参数没有充分实例化
标记要求要标记的变量都具有有限域。在您的情况下,label/1
会引发实例化错误,因为某些变量的域仍然是无限的:
?- 杂货店([A,B,C,D])。
A inf.. -1\/1..sup ,
100*A#=_9006,
_9006 inf.. -100\/100..sup,
_9006+_9084+_9078+_9072#=711,
_9006*_9084#=_9102,
_9084 inf.. -100\/100..sup,
100*B#=_9084,
_9102 inf.. -1\/1..sup,
_9102*_9078#=_9222,
_9078 inf.. -100\/100..sup,
100*C#=_9078,
C inf.. -1\/1..sup ,
_9222 在 -71100000000.. -1\/1..71100000000,
_9222*_9072#=71100000000,
_9072 在 -71100000000.. -100\/100..71100000000,
100*D#=_9072,
D 在 -711000000.. -1\/1..711000000,
B inf.. -1\/1..sup。
纠正这个问题的唯一机会是创建一个合适的程序专业化,其中变量以有限域结束。写[Vs]
而不是Vs
显然没有解决办法:
?- 杂货店(Vs),标签([Vs])。
错误:类型错误:预期为“整数”,找到“[_8206,_9038,_8670,_8930]”(列表)
这是因为label/1
要求它的参数是有限域变量的列表,而不是列表的 列表。
合适的专业化示例可能是:
?- 杂货店(Vs),Vs ins 0..sup,标签(Vs)。
假的。
生成的程序没有解决方案,但至少我们知道它肯定没有解决方案,因为没有更多的实例化错误。
没有解决方案
因此,我们遇到了第二个相当独立的问题:为什么这个结果程序没有解决方案?
使用像 Prolog 这样的逻辑编程语言的一个主要优点是它支持声明式调试方法的应用,例如 GUPU中所示。
就像在 GUPU 中一样,使用以下定义来概括客场目标:
:- op(950,fy, *).
*_.
例如,我们可以概括掉程序的最后一个目标:
杂货店(Vars):-
变量 = [A,B,C,D],
X #= 100 * A,
Y #= 100 * B,
Z #= 100 * C,
W #= 100 * D,
X+Y+Z+W #= 711,
* X*Y*Z*W #= 71100000000。
结果程序显然比原始程序更通用,因为我们已经从一个纯单调的Prolog 程序中删除了一个约束。
现在,我们仍然得到前面的查询:
?- 杂货店(Vs),Vs ins 0..sup,标签(Vs)。
假的。
现在我们知道:即使是更通用的程序也没有解决方案。
如果您希望在这种情况下得到解决方案,您将不得不更改剩余程序的部分内容以纠正公式中的错误。
有关此方法的更多信息,请参阅程序切片和逻辑纯度。