2017-01-25 26 views
2

我有以下設置的事實:如何根據他們所在的線路獲取所有電臺列表?

線路名稱:

line(ecLine). 
line(wcLine). 
line(mLine). 
line(gwLine). 
line(swLine). 

站名和線路的各個列表:

station(london,  [ecLine, wcLine, mLine, gwLine, swLine]). 
station(bristol,  [gwLine, wcLine]). 
station(rugby,  [wcLine]). 
station(birmingham, [wcLine]). 
station(crewe,  [wcLine]). 
station(liverpool, [wcLine]). 
station(manchester, [wcLine, mLine]). 
station(carlisle,  [wcLine]). 
station(glasgow,  [wcLine]). 
station(edinburgh, [wcLine]). 
station(leicester, [mLine]). 
station(sheffield, [mLine]). 
station(peterborough, [ecLine]). 
station(york,   [ecLine]). 
station(newcastle, [ecLine]). 
station(edinburgh, [ecLine]). 
station(oxford,  [ecLine]). 

站相鄰:

adjacent(london,  bristol). 
adjacent(london,  oxford). 
adjacent(london,  rugby). 
adjacent(london,  leicester). 
adjacent(london,  peterborough). 
adjacent(bristol,  birmingham). 
adjacent(rugby,  birmingham). 
adjacent(birmingham, crewe). 
adjacent(rugby,  crewe). 
adjacent(crewe,  liverpool). 
adjacent(crewe,  manchester). 
adjacent(crewe,  carlisle). 
adjacent(manchester, carlisle). 
adjacent(carlisle,  glasgow). 
adjacent(carlisle,  edinburgh). 
adjacent(leicester, sheffield). 
adjacent(sheffield, manchester). 
adjacent(peterborough, york). 
adjacent(york,   newcastle). 
adjacent(newcastle, edinburgh). 

並遵循以下規則:

規則,使相鄰關係雙向的:

twoWay(X, Y) :- adjacent(X, Y); adjacent(Y, X). 

而我的規則,返回站對於給定的線路名的列表:

line(Line, StationList) :- 
    findall(Station, 
     (line(Line), 
     station(Station, ListOfLines), 
     member(Line, ListOfLines) 
     ), 
     StationList). 

這工作得很好,當線路名在查詢中給出如下:

?- line(mLine, LineList). 
LineList = [london,manchester,leicester,sheffield]. 

但是,如果我不給線路名稱的規則'線',它會返回fo llowing:

?- line(Line, StationList). 
StationList = [london,peterborough,york,newcastle,edinburgh,oxford,london,bristol|...]. 

不退還所有站,因爲它太大,無法寫入控制檯 - 在這一點上,我還以爲是讓所有站到一個列表。但是,如果我重寫序言的answer_write_options如下:

set_prolog_flag(answer_write_options,[max_depth(0)]). 

這是發生了什麼:

?- line(Line, StationList). 
StationList = [london,peterborough,york,newcastle,edinburgh,oxford, 
       london,bristol,rugby,birmingham,crewe,liverpool, 
       manchester,carlisle,glasgow,edinburgh,london,manchester, 
       leicester,sheffield,london,bristol,london,oxford]. 

它不僅給所有電臺,但他們中的一些是重複的。

簡而言之:鑑於上述所有事實,是否可以編寫一個規則,返回每行的名稱,然後是該行的列表,最好採用以下格式(我可以容忍任何格式,但這是我的偏好):

Line = ecLine 
LineList = [london,peterborough,york,newcastle,edinburgh,oxford] 

Line = mLine 
LineList = [london,manchester,leicester,sheffield] 

Line = ... 

等等。

在此先感謝。

回答

2

只需實例Lineline/1第一:

line(Line,StationList) :- 
    line(Line), %ground Line with a valid line 
    findall(Station,(station(Station,Lines),member(Line,Lines)),StationList).

如果我有兩個未初始化變量查詢:

?- line(Line,StationList). 
Line = ecLine, 
StationList = [london, peterborough, york, newcastle, edinburgh, oxford] ; 
Line = wcLine, 
StationList = [london, bristol, rugby, birmingham, crewe, liverpool, manchester, carlisle, glasgow|...] ; 
Line = mLine, 
StationList = [london, manchester, leicester, sheffield] ; 
Line = gwLine, 
StationList = [london, bristol] ; 
Line = swLine, 
StationList = [london]. 

或用Line固定:

?- line(wcLine,StationList). 
StationList = [london, bristol, rugby, birmingham, crewe, liverpool, manchester, carlisle, glasgow|...]. 

或用StationList

?- line(Line,[london]). 
Line = swLine. 

或者最後用兩個:

?- line(wcLine,[london]). 
false. 

?- line(swLine,[london]). 
true. 

通過調用line(Line)結果是,從現在開始Line接地:所以例如Line = gwLine,然後你運行像查詢:

findall(Station,(station(Station,Lines),member(gwLine,Lines)),StationList). 

哪一個 - 就像你已經找到你自己 - 找到所有在Lines列表上映射的站點,其中gwLinemember/2的。然後將它們放入StationList,因此可以返回。

+0

哇,這是一個非常快速和工作的答案!你能向我解釋它是如何工作的嗎?謝謝! – SomeProlog

+0

@SomeProlog:更新了一些解釋,但實際上並沒有太多要說的。 –

+0

感謝您的編輯,我現在明白了!謝謝! – SomeProlog

相關問題