prolog - 将命令纳入谓词解析

标签 prolog clpfd

查看以下目标(我使用 swi-prolog 和 Markus Triska 的 clpfd):

result(Input,Result) :-
    Input #> 10,
    Result=decline.
result(Input,Result) :-
    Input in 0..20,
    Result=offer.

可能的查询如下所示:

?- result(15,B).
B = decline ;
B = offer.

我想添加订单或某种解决方案优先级。 如果“decline”是 Input=15 的有效响应,则不应再考虑第二个目标,因此只有 B=decline 是解决方案,而 >B=报价

我知道我可以添加 !/0 但反过来就行不通了。给我这个谓词的所有可能的答案。

考虑到此示例,Result=offer 应该仅对于 Input 0..10 为 true,否则应触发更高的优先拒绝目标。

当我尝试考虑谓词内的顺序时,我是否认为太势在必行?

最佳答案

这里有几个问题,让我们首先从最明显的问题开始:

建模问题

您有一个关系( result/2 可能不是最好的名字),并且该关系应该在 decline 时建模当 offer应该是真的。在阅读你的程序之前,我更喜欢问Prolog:

?- result(X, decline), result(X, offer).
   X in 11..20
;  false.

因此,对于从 11 到 20 的值,您的关系是不明确的。如果你想做出决定,那就先修复这个关系。实际上,我会从

  • 关系的更好名称,表明它是一个关系
  • 没有祈使句(例如 Input 或祈使句)
  • 更紧凑的配方,不需要那么多(=)/2你的计划中的目标。相反,你可以这样写:
heigth_decision(I, decline) :-
   I #< 10.

CLP 中的答案和成功与解决方案

还有另一个更根本的问题。这实际上要严重得多,因为到目前为止给出的所有 SO 答案都完全忽略了这一方面。它涉及答案和成功的概念,另一方面涉及解决方案的概念。

当您在 Prolog 中提出查询时,您得到的就是答案。这样的答案可能包含解决方案,例如答案 L = [_,_]其中包含无限多个解。或者答案可能只包含一个解决方案,如 Decision = decline 。但是,如果您使用像 library(clpfd) 这样的约束,那么两者之间还有更多的内容。 .

您现在可以获得有限多个解决方案:

?- abs(X) #< 3.
   X in -2..2.

或者无穷多个:

?- X #> Y.
   Y#=<X+ -1.

但是您也可以获得完全相同的一种解决方案,但它看起来并不像一个:

?- 2^X #= 1.
   2^X#=1.

所以,重申一下:我们这里只有一个整数解,但对于 Prolog 来说这太复杂了。我们得到的答案是:是的,这都是真的,只要所有这些细则都是真的

更糟糕的是,有时我们得到的答案不包含任何解决方案。

?- X^X#=0.
   X^X#=0.

如果 Prolog 足够聪明,它会回答 false 。但它不可能总是那么聪明,仅仅因为你可以轻松地提出无法判定的问题。这样的答案有时被称为不一致。德国的概念 Scheinlösung(~假解决方案,但负面含义较少)更好地传达了这个想法。

所以答案可能包含解决方案,但有些答案根本不包含解决方案。因此,目标的成功并不能视为解决方案的存在!也就是说,如果将成功视为解决方案,则所有建议某种提交(如 (;)/2 – if-then-else、once/1 或 !/0)的 SO 答案都是不正确的。要看到这一点,请尝试使用:

?- X^X#=0, result(X,decline).
   X in 11..sup, X^X#=0
;  false.
?- X^X#=0, result(X,offer).
   X in 0..20, X^X#=0.

那么你现在怎么能确定任何事情呢?

  • 目标的失败是值得信赖的。

  • 您可以尝试labeling/2 ,但这仅适用于有限域。

  • 您可以使用call_residue_vars/2copy_term/3确定是否存在“徘徊”的约束

  • 不幸的是,您不能完全依赖 SWI 的顶层,它隐藏了与答案中的变量无关的约束。只有 SICStus 能够正确显示它们。

关于prolog - 将命令纳入谓词解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13515161/

相关文章:

prolog - 从 prolog 中的函数返回一个值

prolog - 操作 Prolog 代码输出

Clojure core.logic CLP(FD) 投影 FD 变量

list - 列表 ECLiPSe clp 上的简单算术约束

list - 从列表中的一个索引元素删除到另一个索引元素

prolog - 如何在序言中轮换列表?

module - 如何在存在 meta_predicate 声明的情况下编写 rec/3 代码?

prolog - 了解N皇后问题的CLP(FD)Prolog代码

prolog - 无限循环的树方法

numbers - Prolog 中的数字和