2015-02-09 110 views
-1

知識庫走出一個無限循環的序言中我使用:如何使用蓄電池

connected(1,2). 
connected(3,4). 
connected(5,6). 
connected(7,8). 
connected(9,10). 
connected(12,13). 
connected(13,14). 
connected(15,16). 
connected(17,18). 
connected(19,20). 
connected(4,1). 
connected(6,3). 
connected(4,7). 
connected(6,11). 
connected(14,9). 
connected(11,15). 
connected(16,12). 
connected(14,17). 
connected(16,19). 

的問題,我試圖解決:

假設你添加「連接(4,3)「緊接事實 」連接(3,4)「。運行查詢? - 路徑(3,2)產生一個循環 並且不終止。使用累加器修改路徑/ 2以存儲 已經訪問的點,以便在計算路徑時不會再次訪問相同點 。然後再次運行查詢? - 路徑(3,2)。

我在這裏遇到的麻煩是我對Prolog很新,我沒有實際使用過累加器(據我所知),因此我不確定如何進行。如果任何人都可以向我解釋我必須採取的步驟,那就太好了。

此外,我看到很多「/ 2」之後的東西 - 任何解釋,這一般意味着什麼?

乾杯。

+1

你應該顯示你的'path/2':它看起來是被定義的,但它不在你的問題中。 「'/ 2」代表仿函數的_arity_(參見這裏:http:// www。swi-prolog.org/pldoc/man?section=glossary)。而且,如果你使用「prolog accumulator」,你會得到相當多的關於這個話題的信息。 – 2015-02-09 13:07:48

+0

請參閱[這些答案](http://stackoverflow.com/search?q=%5Btransitive-closure%5D+%5Bprolog%5D+closure0) – false 2015-02-09 17:36:55

回答

0

您沒有顯示path/2的定義。但是,練習中最常見的問題是,要保留已經訪問過的節點列表(如connected/2中定義的連接所隱含定義的)(可能在列表中爲您的「累加器」)。每當你考慮是否應該關注連接時,你應該檢查迄今爲止的路徑(你的累加器)是否已經包含該節點。這樣你將避免(無限)循環。

這幾乎是你的家庭作業聲明已經說了。

沒有代碼,這個答案不是很有用,但是你也不提供任何代碼。

0

/表示法用於每個謂詞的arity。例如,path/2指示path需要2個參數,例如,

path(EdgeA, EdgeB) :- connected(EdgeA, EdgeB). 
path(EdgeA, EdgeB) :- connected(EdgeA, Other), connected(Other, EdgeB). 

累加器只是一個額外的參數,在滿足目標後更新,作爲中間步驟。這通常是一個列表。假設您要構建一個range/2謂詞,其謂詞參數爲X,並生成一個從1X(不使用內置的between謂詞)的整數列表。

在這裏,您將使用累加器來存儲在運行查詢時在範圍[1..X]中生成的每個數字。例如: -

range(X, Y) :- range(X, [], Y). 

range(X, Acc, Z) :- X > 0, NewX is X - 1, range(NewX, [X|Acc], Z). 
range(X, Acc, Acc) :- X = 0. 

生成調用輔助謂詞range/3時預先計劃Acc新號碼。 Acc是一個經典的累加器,以列表的形式列出您「積累」的內容。您可以在每次解析目標時從圖形中累積邊數,並在每個步驟檢查您要跟隨的邊是否已經在累加器中,而不是數字。