2015-10-15 96 views
2

我有一個這樣的數據庫:遞歸Prolog中查詢

traject(departure,arrive,transport). 

traject(London,Paris,train). 
traject(Paris,Madrid,train). 
traject(Madrid,Lisbon,bus). 
traject(Madrid,Berlin,plane). 
traject(Berlin,Prague,bus). 

我有規則:

connection(Departure,Arrrive):-traject(Departure,Arrive,Transport). 
connection(Departure,Arrrive):-traject(Departure,X,Transport),traject(X,Arrive). 

這條規則我知道如果我問查詢連接(巴黎,里斯本)例如答案是肯定的。

哪有我制定了一個規則和/或查詢在那裏我可以回答這個問題:

A)transport(Paris,Lisbon)

,答案應該來:火車和公共汽車

B)traject_between(Paris,Lisbon)

並且答案應該出現:馬德里

+0

Prolog原子需要以小寫字母開頭。 'traject(London,Paris,train).'與traject(_,_,train)相同。' – dasblinkenlight

+0

你應該嘗試獨立解決這個問題,這並不難。 – dasblinkenlight

回答

2

要使原子名稱以大寫字母開頭,請使用單引號:traject('London', 'Paris', train)

我更喜歡在代碼使用短,暗示性的變量名,使它更容易在精神上和視覺跟蹤(當然情況因人而異):

connect(D,A):- traject(D,A,T). 

後來你說你想看到的交通工具,那麼爲什麼你在這裏忽略它嗎?將其更改爲

connect(D,A,T):- traject(D,A,T). 
connect(D,A,T):- traject(D,X,T1), traject(X,A,T2). 

您現在有兩個傳輸,第二種情況。以某種方式將它們組合在一起!一個提示:什麼類型的數據可以容納兩個和一個條目呢?你也必須改變第一個條款,以保持一致。

現在新的問題是,你忽略航點,X。另一個相關的問題是你在旅途中只做了兩條腿,但如果你需要三條或更多條腿呢?

遞歸將有助於解決這兩個問題:

connect(D,A, Xs,Ts):- traject(D,A,T), Xs = ... , Ts = ... . 
connect(D,A, Xs,Ts):- traject(D,X,T), 
         connect(X,A, Xs2,Ts2), % <---- recursion! 
         Xs = ... , 
         Ts = ... . 

相反的...,懂事的東西必須出現。 connect(D,A, Xs,Ts)意味着,D eparture和A rrival通過列表連接012路沿點Xs,使用運輸類型Ts。因此,如果DA僅由一個traject(D,A,Transport)弧直接連接,則航點列表是什麼?什麼是運輸類型的列表? ---否則,如果我們能夠從DX在一個步驟中使用一種類型的運輸T的走了,XA與使用傳輸類型Ts2航點Xs2列表相連,什麼是航點的完整列表?什麼是運輸類型的完整列表?

完成此操作後,您可以很容易地定義所要求的兩個謂詞,因爲信息已經存在,在此謂詞connect/4謂詞(.../4表示它有4個參數)。

+0

謝謝您的答案尼斯。我試圖使用你提出的規則,但在Prolog中我很新,你是指通過在點上填寫缺少的代碼是什麼意思?我雖然不需要使用連詞... 我想問什麼樣的問題,以便知道我需要在2個或更多城市之間運輸什麼? 再次感謝您的提前..我是一個菜鳥在Prolog和需要了解它... – cdiogo7