ASP中的否定如何理解为失败?

How to understand negation as failure in ASP?

假设我们有以下程序:

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

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

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).

我在 book from Gelfond 中读到它给出了 3 个获取答案集的规则:

  1. Satisfy the rules of Π. In other words, believe in the head of a rule if you believe in its body.

  2. Do not believe in contradictions.

  3. Adhere to the “Rationality Principle” which says: “Believe nothing you are not forced to believe.”

这里的规则:

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

我们得到了一个失败的否定not holiday(tomorrow)

如本书所示:

Symbol not is a new logical connective called default negation, (or negation as failure); not l is often read as “it is not believed that l is true.” Note that this does not imply that l is believed to be false. It is conceivable, in fact quite normal, for a rational reasoner to believe neither statement p nor its negation, ¬p.

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

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

假设我改为:

may_go_to_school(D) :- not holiday(D).

您期望得到哪些答案,即,它的型号是什么?实际给出的是什么?

关键问题是否定作为失败是直接实现,但没有完全理解我们在逻辑上用 ¬ 表示的意思。例如,D = hello 呢?

Can we just use classical negation?

好吧,看来我们做不到。问题是我们无法实现逻辑否定。主要思想是 Prolog 为您的程序理论生成一个模型(Herbrand 模型)。当我们添加否定时,程序的语义会发生变化,因此 Prolog 可能无法使用 sld 解析找到模型。所以否定作为失败的优点是我们可以有一个否定(不完全是逻辑否定)并且仍然没有像经典否定那样的程序语义问题。

你可以看看我的相关问题:Logical Negation in Prolog。这个问题问的和这个问题不完全一样,但是@j4n bur53 在他的回答中描述了为什么我们不能有逻辑否定。

可以在示例中也使用经典否定,但您随后需要假日谓词的供应否定信息。

要使用经典的否定,你需要切换谓词假期的边,也就是说你需要从G :- not A, HG, 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 本身已完成,并向程序添加更多子句,以便其他查询也有意义。