我有以下几点事实:
行名称:
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].
但是,如果我没有为规则'行'提供行名称,则会返回以下内容:
?- line(Line, StationList).
StationList = [london,peterborough,york,newcastle,edinburgh,oxford,london,bristol|...].
它不会返回所有电台,因为它太大而无法写入控制台 - 此时我认为它将所有电台都放到一个列表中。但是,如果我按如下方式覆盖Prolog' 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 = ...
等等。
提前致谢。
答案 0 :(得分:2)
首先使用Line
首先实例化line/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
列表中映射的所有电台,其中gwLine
是member/2
。然后将它们放入StationList
并因此可以返回。