2017-03-22 33 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'目标中使用某些故障安全选项吗? –