1

我对Prolog 语言中的否定作为失败有一个小问题:

这是一个比实际更理论的问题,因为我清楚这个例子是如何工作的。

所以我有以下Prolog程序:

/* Fatti che specificano quali esseri sono degli animali: */
animal(cat).
animal(dog).
animal(frog).
animal(horse).
animal(viper).
animal(boa).
animal(python).

/* Fatti che specificano quali esseri sono dei serpenti: */
snake(viper).
snake(boa).
snake(python).

/* X è un serpente, fallisce ed impedisce il backtracking quindi
   il predicato likes(mary,X) risulta essere falso: */
likes(mary,X) :- snake(X),
                 !,
                 fail.

/* Se X è un animale allora a mary piace: */
likes(mary, X) :- animal(X).

在 Prolog 中,我不能简单地说:“玛丽爱所有动物,但不是蛇” ,我必须这样表述:“如果 X 是一条蛇,那么玛丽不爱它。否则,如果X 它是一种动物,玛丽喜欢它”

根据规则,先例程序正是这样做的:

likes(mary,X) :- snake(X),
                 !,
                 fail.

Prolog 检查 X 是否是一条蛇,强制执行切割以避免回溯并强制谓词失败。

通过这种方式,如果snake(X)程序TRUE强制头部前导的失败likes(mary,X)和强加回溯避免了执行程序中其他规则的可能性(答案是真的,因为蛇也是动物)

我的问题是:在我看来,Prolog 的这种使用超出了逻辑和声明范式,并且在某种程度上属于某种程序范式

因为:

  1. 我必须强加 2 谓词的顺序(所以在某种程度上我是说:如果第一个失败,请尝试第二个)。
  2. 但我更想说的是:如果第一个规则匹配(X 它是一条蛇),则执行强制失败并且不强制回溯。

在我看来,这似乎更接近于程序意义,而不是经典逻辑意义......

是那个吗?是不是在这些情况下,Prolog 使用程序行为来克服逻辑的限制?

4

2 回答 2

4

我不同意“逻辑的限制”。

同样是

likes(mary,X) :- not(snake(X)) , animal(X).

因为 Prolog 使用深度优先搜索,所以可以以更短的方式表示某些内容,然后取决于深度优先搜索回溯算法。

x :- a, !, b.
x :- c.
x :- d.

是相同的

x :- a, b.
x :- not(a), c.
x :- not(a), d.
于 2013-04-08T16:26:46.790 回答
0

使用 cut (!) 的程序大部分时间都对目标和子句的顺序很敏感,而不仅仅是它们的终止,因此它们通常不是声明性的。

否定作为失败 (\+) 以某种方式封装了切割。它由大多数 Prolog 系统定义甚至实现如下:

\+ X :- X, !, fail.
\+ _ .

尽管它暗示了逻辑意义和声明性,但作为失败的否定仍然对目标的排序很敏感。这是一个例子。假设我们有以下数据库:

p(a).
q(b,c).

然后以下查询产生 X=a 作为解决方案:

?- p(X), \+ q(X,Y).
X = a.

但是如果连词 (,)/2 的参数换边,就会得到不同的结果:

?- \+ q(X,Y), p(X).
false.

因此,作为失败的否定本身并不是声明性的。对于论点的基本术语流,作为失败的否定在存在量词中偷偷摸摸。所以表格的查询:

 ?- A(X), \+ B(X,Y).

本质上它的含义是它量化了否定中的新变量 Y:

 ?- A(X), ~ exists Y B(X,Y).

所以在上面切换合取的例子中,否定中的新变量集作为失败发生变化,这就是为什么得到不同的解决方案。

再见

于 2015-11-13T17:38:06.537 回答