2017-07-07 154 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