2017-04-16 77 views
1

我有一個簡單的序言程序,試圖確定誰相信基於信任規則和知道規則的人。這是規則中的序言規則

know(joe,jack). 
know(joe,sue). 
know(joe,betty). 
know(sue,betty). 
know(jack,betty). 
know(bill,betty). 

knows(X,Y):- know(X,Y);know(Y,X). 

trust(jack,joe). 
trust(bill,joe). 
trust(betty,jack). 

知道規則是對稱的和傳遞,以及信託規則由

Person X trusts Y if and only if 
-X inherently trusts Y, or 
-X knows two DIFFERENT people who trust Y. 

信託定義不再是對稱的,而不是傳遞。

我不知道如何做規則內的規則,並且變量似乎在搞亂我,因爲在試圖只有2個變量作爲參數,但在規則中使用4。任何幫助將不勝感激,謝謝。

+2

首先,只有一個小提示:爲了表示這兩個術語是*不同*,可以使用謂詞'dif/2'。有關更多信息,請參閱[tag:prolog-dif]。在規則體中只有一些變量出現在頭部是完全可以的。事實上,這是一個相當典型的例子。關鍵是要以聲明的方式思考它,即使用所需的任何附加變量來描述必須爲參數保留的約束。 – mat

+0

@mat我創建了這個規則,但由於某種原因它導致了無限循環。信任(X,Y): - dif(A,B),知道(X,A),信任(A,Y),知道(X,B),信任(B,Y)。任何想法,爲什麼會這樣? – Johnny

回答

2

你的問題以某種方式暗示着你認爲你必須在謂詞的頭部存在謂詞的主體中的所有變量。這不是必需的。說我想找到的數人,有人在我們的問題定義知道:

?- bagof(X, knows(betty, X), Xs), length(Xs, N). 

你也許真的只是想知道,貝蒂知道4人,但頂層會寫的人的名單貝蒂知道反正。因此,你把它放在一個斷言:

knows_count(X, N) :- 
    bagof(Y, knows(X, Y), Ys), 
    length(Ys, N). 

所以,現在你只能看到你需要看到什麼:

?- knows_count(betty, N). 
N = 4. 

?- knows_count(X, N). 
X = betty, N = 4 ; 
X = bill, N = 1 ; 
X = jack, N = 2 ; 
X = joe, N = 3 ; 
X = sue, N = 2. 

你現在已經「隱藏」的人在knows_count/2體內的列表。

要定義的trusts/2第二種情況下,你可以這樣做:

trusts(X, Y) :- 
    knows(X, A), trust(A, Y), ... % and so on 

正如指出的@mat,現在你需要做的就是確保所有的人都爲之「X知道」在謂詞的主體中不是同一個人。請參閱link in the comment by @mat或僅搜索Stackoverflow的[prolog] dif

+0

我試過這樣做,並沒有取得任何進展。不管我做什麼,我最終都會遇到一個無限循環,因爲Prolog不夠聰明,不能自行循環。我試圖理解你的第一個例子問題與信任問題的關係,但我無法弄清楚。 – Johnny

+0

@Johnny最重要的是:你需要一個不是遞歸的'trusts/2'中的一個子句,並且只根據事實'trust/2'定義;其他條款將根據「知識/ 2」和事實「信任/ 2」來定義,我猜。那並且使用'dif/2'來確保必須不同的變量是不同的。 – 2017-04-21 18:34:34

+0

@Johnny我注意到我其實犯了一個嚴重的錯誤(現在編輯!)在上面的小代碼片段中:我使用'trusts/2'而不是'trust/2',所以實際上謂詞是遞歸定義的,即使你明確地在你的問題中表示「信任」傳遞的關係....對不起,浪費你的時間:-( – 2017-04-21 18:40:13