2017-03-22 35 views
1

我想製作一個Prolog控制檯應用程序,該應用程序顯示給定(用戶輸入)位置的任何事件的場地名稱和租金。到目前爲止,我已經能夠創建給定(用戶輸入)位置的場所列表。序言:在事實中使用列表的元素

我的代碼如下。

listing(venue_location). 
listing(venue_seating). 
listing(venue_overhead). 

venue_location(washington_party_hall1, washington). 
venue_location(washington_party_hall2, washington). 
venue_location(newyork_party_hall1, newyork). 
venue_location(newyork_party_hall2, newyork). 

venue_capacity(washington_party_hall1,300). 
venue_capacity(washington_party_hall2,450). 
venue_capacity(newyork_party_hall1, 340). 
venue_capacity(newyork_party_hall2,500). 

venue_rent(washington_party_hall1,1350). 
venue_rent(washington_party_hall2,1200). 
venue_rent(newyork_party_hall1,1500). 
venue_rent(newyork_party_hall2,1000). 

main:- 
    write("Enter a location"),nl,write("->"), 
    read(Loc), 
    findall(X,venue_location(X,Loc),Venues), 
    write(Venues). 

這給出了以下的輸出:

Enter a location 
->washington. 
[washington_party_hall1,washington_party_hall2] 
true. 

有一種使用在venue_rent其實venues列表讓每一個列表元素的租金的方法嗎? 我想與他們在這樣的租金,以顯示這些場所的名稱:

washington_party_hall1 1350 
washington_party_hall2 1200 

回答

2

你知道,如果你有一個給定的地點,說Venue,你可以從你的事實得到租金:

?- Venue = washington_party_hall1, venue_rent(Venue, Rent). 
Rent = 1350 

如果你想要得到的租金都在列表Venues場館,你可以使用member/2

?- Venues = [washington_party_hall1,washington_party_hall2], member(Venue, Venues), venue_rent(Venue, Rent). 

這就是你想要的基本查詢結構。現在,如果你想要寫的東西到終端在一個不錯的格式,你可以使用一個故障驅動循環,這是顯示的項目在一個格式化的方式列表中的常見方式:

write_venue_rents(Venues) :- 
    member(Venue, Venues), 
    venue_rent(Venue, Rent), 
    write(Venue), write(' '), write(Rent), nl, 
    fail. 

這不給你對齊的列,但你明白了。您可以查看Prolog的格式化選項和謂詞,將輸出格式化爲您的口味。

另一種方法是使用maplist/2

% Write out the rent for a given venue 
write_venue_rent(Venue) :- 
    venue_rent(Venue, Rent), 
    write(Venue), write(' '), write(Rent), nl. 

% Write out the rent for a list of venues 
write_venue_rents(Venues) :- 
    maplist(write_venue_rent, Venues). 

我覺得maplist/2版本更優雅。

+1

我正在尋找像'maplist/2'一樣的東西。你能提供一些很好的文檔來展示這個謂詞的例子嗎?我可能不得不經常使用這個謂詞。 –

+0

@AhashanAlamSojib不幸的是,我還沒有發現任何帶有示例的好的在線文檔。但它非常簡單。 'maplist'通過一個或多個列表迭代目標,普遍期望列表的長度都是相同的。參數的數量有一些限制。例如,你可以使用「call(goal(a),b)'等於'call(goal(a,b))'這一事實。因此,'maplist(foo(X,Y),L1,L2)'簡單地爲'L1'的每個元素'E1'和''L2'的'E2'調用'foo(X,Y,E1,E2)'。 – lurker

+1

如果'maplist/2'的給定目標對某些列表元素失敗,它會停止該過程嗎?我可以在'maplist/2'目標中使用某些故障安全選項嗎? –