Prolog 约束规划中的标记

Labeling in Prolog constraint programming

我是 Prolog 的新手,目前正在研究一个简单的约束规划问题。所以我有四个实数 A、B、C、D 和 属性 这样 A+B+C+d = ABC*D = 7.11 由于使用整数更容易,我尝试了以下实现:

   :- use_module(library(clpfd)).
   grocery(Vars):-
      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.

由于上面的答案会部分解决,所以我尝试将关键字 label(Vars) 放在末尾。但这导致我执行 grocery(V) 产生

ERROR: Arguments are not sufficiently instantiated.

虽然grocery([V])会给我一个false。谁能告诉我如何做标签?谢谢

编辑:我之前没有调用库 clpfd

你面临两个问题,我想单独讨论

实例化错误

如您所述,我们得到:

?- grocery(Vs), label(Vs).
ERROR: Arguments are not sufficiently instantiated

标注要求被标注的变量都具有有限域。在你的例子中,label/1 抛出一个 因为一些变量的域仍然是 infinite:

?- grocery([A,B,C,D]).
A in inf.. -1\/1..sup,
100*A#=_9006,
_9006 in inf.. -100\/100..sup,
_9006+_9084+_9078+_9072#=711,
_9006*_9084#=_9102,
_9084 in inf.. -100\/100..sup,
100*B#=_9084,
_9102 in inf.. -1\/1..sup,
_9102*_9078#=_9222,
_9078 in inf.. -100\/100..sup,
100*C#=_9078,
C in inf.. -1\/1..sup,
_9222 in -71100000000.. -1\/1..71100000000,
_9222*_9072#=71100000000,
_9072 in -71100000000.. -100\/100..71100000000,
100*D#=_9072,
D in -711000000.. -1\/1..711000000,
B in inf.. -1\/1..sup.

纠正这个问题的唯一机会是创建一个合适的 专业化 程序,其中变量以有限域结束。写成[Vs]而不是Vs显然是没有办法的:

?- grocery(Vs), label([Vs]).
ERROR: Type error: `integer' expected, found `[_8206,_9038,_8670,_8930]' (a list)

这是因为 label/1 要求其参数是有限域变量的列表,不是 列表的列表.

合适 专业化的示例可以是:

?- grocery(Vs), Vs ins 0..sup, label(Vs).
false.

生成的程序无解,但至少我们知道它肯定无解,因为没有更多的实例化错误。

无解

因此我们得到了第二个,而不是独立问题:为什么这个结果程序没有解决方案?

使用像 Prolog 这样的逻辑编程语言的一个主要优点是它可以应用 声明式调试 方法,例如 GUPU[=84] =].

就像在 GUPU 中一样,使用以下定义来 概括掉 个目标:

:- op(950,fy, *).

*_.

例如,我们可以概括掉你程序的最后一个目标:

grocery(Vars):-
        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 程序。

现在,对于前面的查询,我们仍然得到:

?- grocery(Vs), Vs ins 0..sup, label(Vs).
false.

而现在我们知道:即使是更一般的程序也没有解决方案。

如果您希望在这种情况下得到解决方案,您将不得不更改剩余程序的部分以更正公式中的错误.

有关此方法的详细信息,请参阅 and