2017-07-07 157 views
1

我在序言这里的一个问题是代码:逻辑在序言语言

sound(time1). 
sound(time2). 

sun(time3). 

relax(X):- 
    not(sound(X)), 
    !, 
    sun(X). 
relax(_):- 
    sun(_). 

现在我的跑步 - relax(T)。当我运行relax(F)时,我会变得真实。为什么会发生?

还有一个问题,为什么relax(time4)。也变得虚假?我想我错过了一些东西。 非常感谢!

回答

2

relax(T)relax(F)都给出相同结果的事实是正常的:大写标识符是变量。所以两个查询在语义上是相同的:你用一个不接地的变量进行查询。我们为什么得到true.?如果查询relax(T),Prolog将首先调用relax(X)的第一个子句。

第一个子句有一个以not(sound(X))开头的正文。所以我们实际上查询not(sound(T))。不被否定为有限失败原理:Prolog将旨在“证明”sound(T),如果失败(它无法找到满足该查询的方法)。

所以现在Prolog的查询sound(T)此查询满足:的确,sound(time1)满足此查询,因为Prolog的原因,现在T = time1。因此not(sound(T))false,因此Prolog回溯。

现在Prolog会尝试下一个子句:relax(_) :- sun(_)._是一个“通配符”或“不关心”变量。此外,如果您在同一个子句中使用多个_,那么与不是有关。所以你基本上说:一切都是relax/1,因为至少有一个sun/1。所以现在Prolog会查询sun(_)。此查询成功:sun(time3)是一个有效的候选人,因为_ = time3。这意味着relax(_)成功。我们没有改变变量T(或F),所以Prolog只能说这个查询是true

现在,如果我们查询relax(time4),这是一个不同的故事。 Prolog将再次尝试满足relax/1的第一个子句。这通过呼叫not(sound(time4))再次完成。但请注意,time4是一个常数。而在Prolog 中所有常量都不相同:所以time1time4不能统一。

所以现在Prolog的第一个旨在统一sound(time1)(第一款为sound/1)与sound(time4),但由于time1time4是不同的,失败。接下来它的目标是统一sound(time2)sound/1的第二个子句)与sound(time4),但是再次没有运气。现在没有sound/1的条款了。所以Prolog放弃并认为not(sound(time4))是真实的。

这意味着Prolog将继续在relax/1的第一个子句的正文中。下一个陈述是在Prolog中的!,即“cut”。这意味着,对于这个分支点,Prolog应该不再考虑其余的子句。所以从现在开始,忽略relax/1的第二个子句。接下来遇到sun(X)。所以现在Prolog会打电话给sun(time4),并且是为了满足这个。它的目标是与sun/1的第一个(也是唯一)条款统一起来:sun(time3)。但如前所述,time3time4不统一。因此,这失败了。由于Prolog不能采用relax/1(由于削减(!))的第二个子句,因此它已经用尽了所有选项,并且确定查询relax(time4)false

+0

非常感谢你! 多一个小问题。如果剪辑在这样的句子末尾:放松(X): - not(sound(X)),sun(X),!。 有关time4的答案是一样的吗?我认为在那里放置切割标志有什么意义?我认为,在我们得到真实(声音(X))后,我们将停止并发送真实信号。希望你能理解我 – user4485863