7

假设我们有以下程序:

human(socrates).
day(tomorrow).
die(X) :- human(X).
may_go_to_school(Y) :- day(Y), 
                       not holiday(Y).

如果我们运行 clgo 来获取程序的答案集,我们得到

Answer: 1
human(socrates) day(tomorrow) die(socrates) may_go_to_school(tomorrow)

我们知道grounder会先将所有变量实例化为常量,所以grounder之后的程序是:

human(socrates).
day(tomorrow).
die(socrates) :- human(socrates).
may_go_to_school(tomorrow) :- day(tomorrow), 
                              not holiday(tomorrow).

我在Gelfond 的书中读到它给出了 3 条规则来获取答案集:

  1. 满足Π的规则。换句话说,如果你相信规则的主体,就相信它的头部。

  2. 不要相信矛盾。

  3. 坚持“理性原则”,即“什么都不相信,你不是被迫相信”。</p>

在规则中:

may_go_to_school(tomorrow) :- day(tomorrow), 
                              not holiday(tomorrow).

我们被否定为失败not holiday(tomorrow)

如本书所示:

符号not是一个新的逻辑连接词,称为默认否定,(或否定为失败);not l 通常被解读为“不相信 l 是真的”。请注意,这并不意味着 l 被认为是错误的。p一个理性的推理者既不相信陈述也不相信它的否定,这是可以想象的,实际上是很正常的¬p

那么根据规则 1,我应该相信believe in the head of a rule if you believe in its body身体not holiday(tomorrow).,因为我既不相信holiday(tomorrow).也不相信¬holiday(tomorrow).

根据答案,我应该相信¬holiday(tomorrow).

  • 那么为什么我们需要这种否定作为失败呢?
  • 我们可以只使用经典否定吗?
4

3 回答 3

5

我们可以只使用经典否定吗?

Well it seems we can't. The problem is that we can't implement logical negation. The main idea is that Prolog generates a model (Herbrand model) for your program-theory. When we add negation, semantics of the program change so that Prolog may not be able to find a model using sld resolution. So negation as failure has the advantage that we can have a negation (not exactly logical negation) and still not having problems with program semantics like we had with classical negation.

You can take a look in my relevant question: Logical Negation in Prolog. This question does not ask exactly the same thing as this question, but @j4n bur53 in his answer describes why we can't have logical negation.

于 2018-10-24T08:22:29.163 回答
5

假设我改写:

may_go_to_school(D) :-不是假期(D)。

您期望得到哪些答案,即,这个模型是什么?实际上给出了什么?

关键问题是否定作为失败是直接实现的,但不能完全理解我们在逻辑上的意思。例如,怎么样D = hello

于 2018-10-24T07:36:49.617 回答
1

也可以在示例中使用经典否定,但您需要为假期谓词提供否定信息。

要使用古典否定,您需要切换谓词holiday 的两侧,即您需要从G :- not A, Hto G, A :- H,即将它移动到头部,这是一个古典声音转换。结果是一个分离子句:

may_go_to_school(Y), holiday(Y) :- day(Y).

要在此处提供负面信息,最简单的方法是提供约束:

:- holiday(tomorrow).

您现在可以在没有任何默认否定的情况下运行 ASP 程序,因为您使用了经典否定并提供了否定信息。以下是将其转换为使用安全前向链接的 Jekejeke Prolog ASP 的方法:

:- reexport(library(minimal/asp)).

:- forward may_go_to_school/2.

choose([day(tomorrow)]) <= posted(init).
choose([may_go_to_school(Y), holiday(Y)]) <= posted(day(Y)).
fail <= posted(holiday(tomorrow)).

这是一个运行示例。此处的约束有助于在当前查询中不生成第二个模型:

Jekejeke Prolog 4, Runtime Library 1.4.1 (August 20, 2019)
(c) 1985-2019, XLOG Technologies GmbH, Switzerland

?- post(init), listing(may_go_to_school/1).
may_go_to_school(tomorrow).

Yes ;
No

更彻底的建模将考虑 may_go_to_school/1 本身已完成,并向程序添加更多子句,以便其他查询也有意义。

于 2019-10-11T18:52:54.633 回答