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 个获取答案集的规则:
Satisfy the rules of Π. In other words, believe in the head of a rule if you believe in its body.
Do not believe in contradictions.
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, H
到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 本身已完成,并向程序添加更多子句,以便其他查询也有意义。
假设我们有以下程序:
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 个获取答案集的规则:
Satisfy the rules of Π. In other words, believe in the head of a rule if you believe in its body.
Do not believe in contradictions.
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 statementp
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, H
到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 本身已完成,并向程序添加更多子句,以便其他查询也有意义。