【问题标题】:Labeling in Prolog constraint programmingProlog约束规划中的标签
【发布时间】:2016-10-27 17:52:32
【问题描述】:

我是 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

【问题讨论】:

  • 请显示您实际输入的内容。当我尝试它时,我没有得到任何解决方案,而不是出现错误。
  • 那是我实际输入的。一个错误是当我放置标签(Vars)并通过杂货店(V)执行时。
  • 如何输入label(Vars)很重要。您应该输入 grocery(Vars), label(Vars).(注意第一次通话后的逗号)。这就是我用你的代码运行的,没有得到错误,但没有得到任何解决方案。如果您输入带有句点的grocery(Vars).,然后输入label(Vars).,那么label(Vars) 对前面查询中的Vars 一无所知。它们是分开的。

标签: prolog clpfd instantiation-error


【解决方案1】:

您面临两个我想单独讨论的问题

实例化错误

正如你所说,我们得到:

?- 杂货店(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)。 错误

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

如果您希望在这种情况下解决方案,则必须更改剩余程序的部分以纠正公式中的错误。

有关此方法的更多信息,请参阅

【讨论】:

    猜你喜欢
    • 2016-09-27
    • 1970-01-01
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-12
    相关资源
    最近更新 更多