List 如何根据站点所在的线路获取所有站点列表?

List 如何根据站点所在的线路获取所有站点列表?,list,prolog,List,Prolog,我有以下事实: 行名称: 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(birming

我有以下事实:

行名称:

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].
set_prolog_flag(answer_write_options,[max_depth(0)]).
但如果我没有为规则“line”指定行名称,它将返回以下内容:

?- line(Line, StationList).
StationList = [london,peterborough,york,newcastle,edinburgh,oxford,london,bristol|...].
它不会返回所有电台,因为它太大,无法写入控制台-此时,我认为它将所有电台放入一个列表中。但是,如果我覆盖Prolog的
应答\u写入\u选项
,如下所示:

?- line(mLine, LineList).
LineList = [london,manchester,leicester,sheffield].
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].
它不仅给出了所有的电台,而且还重复了其中的一些电台

简言之:考虑到上述所有事实,是否可以编写一条规则,返回每一行的名称以及该行中的站点列表,最好采用以下格式(我可以接受任何格式,但这是我的首选):

等等


提前感谢。

首先用
行/1
实例化

line(Line,StationList) :-
    line(Line), %ground Line with a valid line
    findall(Station,(station(Station,Lines),member(Line,Lines)),StationList).
或使用
固定:

?- line(wcLine,StationList).
StationList = [london, bristol, rugby, birmingham, crewe, liverpool, manchester, carlisle, glasgow|...].
或使用
站列表

?- 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).

就像你自己已经发现的那样,它会在
行列表中找到所有映射的电台,其中
gwLine
是的
成员/2
。然后将它们放入
统计列表
,然后可以返回。

哇,这是一个非常快速有效的答案!你能给我解释一下它是怎么工作的吗?谢谢@SomeProlog:更新了一些解释,但真的没什么好说的。谢谢你的编辑,我现在明白了!非常感谢。