2014-12-05 91 views
0

序言問題: 剛開始學習序言,這是我們給出的練習測驗之一。查詢規則的序言順序

考慮:

avenger(thor). 
avenger(captainAmerica). 
sibling(thor,loki). 
asgardian(thor). 
asgardian(X) :- sibling(Y,X),asgardian(Y). 
train1(X,Y) :- avenger(X),!,avenger(Y). 
train2(X,Y) :- avenger(X),X\=Y,avenger(Y). 

名單由以下查詢返回的所有答案。

train2(A, captainAmerica). %returns A=thor. 
train2(captainAmerica, A). %returns false. 

我的問題是關於第二個查詢。爲什麼這不會返回A = thor。 ? 我搞砸了一下週圍,如果我TRAIN2改變

train2(X,Y) :- avenger(X),avenger(Y),X\=Y. 

當我運行第二個查詢,我得到

A=thor. 

爲什麼在查詢規則的順序事項這裏會快速的解釋太棒了。謝謝。

+0

請參閱[此答案](http://stackoverflow.com/a/8523825/772868)。所以要麼使用'dif/2'或['iso_dif/2'](http://stackoverflow.com/a/20238931/772868) – false 2014-12-05 15:18:04

回答

2

\=是一個奇怪的謂詞......它說,「如果統一的兩個論點成功,失敗;如果統一失敗,成功」。所以,隨着一個自由變量與一個原子的統一總是成功的,它就會失敗。

一旦Y已經被統一爲thorcaptainAmericathor統一的失敗,所以X \= Y成功。

無論如何,你不應該在這種情況下使用\=。相反,使用dif/2。嘗試將謂詞定義爲:

train3(X, Y) :- 
    dif(X, Y), 
    avenger(X), 
    avenger(Y). 

以幾種方式比其他兩種更好。您可以通過dif/2搜索其他問題。

0

\=/2標準謂詞在其參數不統一時爲真。因此,它要求綁定兩個參數(即不是變量)纔有意義。您的解決方案:

train2(X,Y) :- avenger(X), avenger(Y), X \= Y. 

是正確的,因爲這兩個程序調用到avenger/1謂詞確保雙方XY將調用\=/2謂語前充分實例化。

正如鮑里斯在他的回答中解釋的那樣,使用dif/2謂詞的替代方法,具有使上述子句中的目標順序不相關的優點。但是有一個警告。謂詞不是標準謂詞,並不是所有的Prolog實現都提供它。

+0

很久以前,有一個涉及'dif/2'的熱烈討論:http:// stackoverflow.com/questions/13757261/using-or-dif。我留下的印象是這是一個事實標準。當談到實施之間的差異時,你當然比大多數人知道得更多。 – 2014-12-05 15:19:54

+0

支持'dif/2'作爲內置謂詞的主要Prolog實現包括B-Prolog,SWI-Prolog和YAP。 ECLiPSe和SICStus Prolog支持它作爲圖書館謂詞。主要的Prolog實現(當前)不支持它,包括GNU Prolog和XSB。其他不太流行的Prolog實現也不支持它。因此,我不會把它分類爲事實上的標準謂詞。希望這會改變。 – 2014-12-05 15:39:34

+1

請參閱[prolog-dif](http://stackoverflow.com/tags/prolog-dif/info)以獲取直接和間接支持'dif/2'的系統列表。如果他們知道的話,請添加更多的系統。任何符合ISO的系統都可以提供['iso_dif/2'](http://stackoverflow.com/a/20238931/772868)這是一種安全的近似方法,它不具有'(\ =)/ 2'邏輯缺陷和'(\ ==)/ 2'。 – false 2014-12-06 23:02:35