4

我对 CLP 在 Prolog 中的工作方式感到非常困惑。不仅我发现很难看到好处(我确实在特定情况下看到了它,但发现很难概括这些好处),而且更重要的是,我几乎无法弥补如何正确编写递归谓词。以下哪项是 CLP(R) 方式中的正确形式?

factorial(0, 1).
factorial(N, F):- {
  N > 0,
  PrevN = N - 1,
  factorial(PrevN, NewF),
  F = N * NewF}.

或者

factorial(0, 1).
factorial(N, F):- {
  N > 0,
  PrevN = N - 1,
  F = N * NewF},
  factorial(PrevN, NewF).

换句话说,我不确定何时应该在约束之外编写代码。对我来说,第一种情况似乎更合乎逻辑,因为PrevNNewF属于约束。但如果这是真的,我很想知道在哪些情况下在递归函数的约束之外使用谓词是有用的。

4

1 回答 1

5

您的帖子中有几个重叠的问题和问题,可能太多了,无法在一个帖子中连贯地解决您完全满意的问题。

因此,我想先说明一些一般原则,然后在此基础上对您发布的代码进行一些具体的评论。

首先,我想谈谈我认为在您的情况下最重要的问题:

LP ⊆ 中电

这仅仅意味着 CLP 可以被视为逻辑编程 (LP)的超集。是否应将其视为适当的超集,或者实际上是否将它们视为表示同一概念更有意义,这是有争议的。在我个人看来,没有约束的逻辑编程比约束更难理解,也更难用。考虑到即使是第一个 Prolog 系统也有一个约束dif/2,而且基本的内置谓词 (=)/2完全符合“约束”的概念,如果边界存在的话,对我来说至少有点人为,这表明:

LP ≈ CLP

尽管如此,使用 CLP(任何类型)时的关键概念是约束可用作 谓词,并像所有其他谓词一样在 Prolog 程序中使用。

因此,无论您是否有目标,factorial(N, F)或者{ N > 0 }至少在原则上是相同的概念:两者都意味着某事 成立

请注意语法:CLP(ℛ) 约束的形式{ C }为 ,它采用 {}(C)前缀表示法。

请注意,目标factorial(N, F)不是CLP(ℛ) 约束以下也不是:

?- {阶乘(N,F)}。
错误:未处理的异常:type_error({factorial(_3958,_3960)},...)

因此,{ factorial(N, F) }也不是 CLP(ℛ) 约束

因此,您的第一个示例已经无法单独工作。(此外,您在子句 head: 中有语法错误factorial (,因此它也根本无法编译。)

当您学习使用约束求解器时,请查看它提供的谓词。例如,CLP(ℛ) 提供{}/1了一些其他谓词,并且有一个专用的语法来说明关于浮点数的关系(在这种情况下)。

其他约束求解器提供自己谓词来描述其各自领域的实体。例如,CLP(FD) 提供(#=)/2了一些其他谓词来推理整数dif/2让你推理任何Prolog 术语。等等。

从程序员的角度来看,这与使用 Prolog 系统的任何其他谓词完全相同无论是内置的还是源自库。原则上,都是一样的:

像这样的目标list_length(Ls, L)可以理解为:“列表的长度 Ls是 L。”

类似的目标{ X = A + B }可以理解为:数字X等于和 的总和。例如,如果您使用 CLP(Q),很明显我们在这种情况下讨论的是有理数。AB

在您的第二个示例中,子句的主体是形式的连词(A, B),其中A是 CLP(ℛ) 约束,并且B是形式的目标factorial(PrevN, NewF)

重点是:CLP(ℛ) 约束也是一个目标!一探究竟:

?- write_canonical({a,b,c})。
{','(a,','(b,c))}
真的。

因此,您只是使用{}/1from library(clpr),这是它导出的谓词之一。

你是对的,PrevN属于NewF 约束。但是,factorial(PrevN, NewF)它不是CLP(ℛ) 实现的用于对浮点数进行推理的迷你语言的一部分。因此,您不能将此目标拉入特定于 CLP(ℛ) 的部分。

从程序员的角度来看,CLP 的一个主要吸引力在于它完全无缝地融入了“正常”逻辑编程,以至于实际上几乎无法将其与它区分开来:约束只是谓词,写下来就像所有其他目标。

是否将库谓词标记为“约束”几乎没有什么区别:所有谓词都可以视为约束,因为它们只能约束答案,永远不要放松它们。

请注意,您发布的两个示例都是递归的!这完全没问题。事实上,递归谓词很可能是您将来使用约束的大多数情况。

但是,对于factorial的具体情况,Prolog 系统的CLP(FD)约束可能更合适,因为它们完全致力于对 integers进行推理。

于 2017-01-10T10:09:36.837 回答