【问题标题】:Prolog list recursionProlog列表递归
【发布时间】:2016-12-13 02:03:03
【问题描述】:

我的谓词的目标是:

?- line_terminal_stations(east_london, StartsAt, EndsAt).
StartsAt = shoreditch
EndsAt = new_cross

以下是我目前所拥有的,递归按预期工作并逐步创建线路上的站点列表。

line_terminal_stations(LineName, StationX, StationY):-
    next_station(LineName, StationX, StationY, []).

next_station(LineName, StationX, StationY, V) :-

    link(StationX, StationY, LineName),
    next_station(LineName, StationY, _, [StationX | V]).

但是,一旦找到最终站,谓词就会失败并开始“撤消”列表。而当 link/3 失败时,我想结束递归,以便提取列表的第一个和最后一个站点。

链接示例/3:

link(shoreditch, whitechapel, east_london).
link(whitechapel, shadwell, east_london).

贯穿示例:

line_terminal_stations(east_london, StartsAt, EndsAt).

Redo: (9) link(_G3031, _G3032, east_london) ? creep
Exit: (9) link(whitechapel, shadwell, east_london) ? creep
Call: (9) next_station(east_london, shadwell, _G3128, [whitechapel]) ? creep
Call: (10) link(shadwell, _G3127, east_london) ? creep
Exit: (10) link(shadwell, wapping, east_london) ? creep
Call: (10) next_station(east_london, wapping, _G3131, [shadwell, whitechapel]) ? creep
Call: (11) link(wapping, _G3130, east_london) ? creep
Exit: (11) link(wapping, rotherhithe, east_london) ? creep
Call: (11) next_station(east_london, rotherhithe, _G3134, [wapping, shadwell, whitechapel]) ? creep
Call: (12) link(rotherhithe, _G3133, east_london) ? creep
Exit: (12) link(rotherhithe, surrey_docks, east_london) ? creep
Call: (12) next_station(east_london, surrey_docks, _G3137, [rotherhithe, wapping, shadwell, whitechapel]) ? creep
Call: (13) link(surrey_docks, _G3136, east_london) ? creep
Exit: (13) link(surrey_docks, new_cross_gate, east_london) ? creep
Call: (13) next_station(east_london, new_cross_gate, _G3140, [surrey_docks, rotherhithe, wapping, shadwell, whitechapel]) ? creep
Call: (14) link(new_cross_gate, _G3139, east_london) ? creep
Fail: (14) link(new_cross_gate, _G3139, east_london) ? creep
Fail: (13) next_station(east_london, new_cross_gate, _G3140, [surrey_docks, rotherhithe, wapping, shadwell, whitechapel]) ? creep
Redo: (13) link(surrey_docks, _G3136, east_london) ? creep
Exit: (13) link(surrey_docks, new_cross, east_london) ? creep
Call: (13) next_station(east_london, new_cross, _G3140, [surrey_docks, rotherhithe, wapping, shadwell, whitechapel]) ? creep
Call: (14) link(new_cross, _G3139, east_london) ? creep
Fail: (14) link(new_cross, _G3139, east_london) ? creep
Fail: (13) next_station(east_london, new_cross, _G3140, [surrey_docks, rotherhithe, wapping, shadwell, whitechapel]) ? creep
Fail: (12) next_station(east_london, surrey_docks, _G3137, [rotherhithe, wapping, shadwell, whitechapel]) ? creep
Fail: (11) next_station(east_london, rotherhithe, _G3134, [wapping, shadwell, whitechapel]) ? creep
Fail: (10) next_station(east_london, wapping, _G3131, [shadwell, whitechapel]) ? creep
Fail: (9) next_station(east_london, shadwell, _G3128, [whitechapel]) ? creep

【问题讨论】:

  • 能否添加链接/3 和一些示例数据?

标签: prolog


【解决方案1】:

一种代码更改最少的方法是:

link(shoreditch, whitechapel, east_london).
link(whitechapel, shadwell, east_london).

line_terminal_stations(LineName, First, Last):-
    next_station(LineName, _, _, [], Stations),
    Stations = [Last|_],
    last(Stations, First).

next_station(LineName, StationX, StationY, V, [StationX|V]) :-
\+ link(StationX, StationY, LineName).

next_station(LineName, StationX, StationY, V, Stations) :-
    link(StationX, StationY, LineName),
    next_station(LineName, StationY, _, [StationX | V], Stations).

测试运行:

[debug]  ?- line_terminal_stations(east_london, StartsAt, EndsAt).
StartsAt = shoreditch,
EndsAt = shadwell 

但就目前而言,link/3 需要按照正确的顺序才能首先找到真正的起始站。即您可以回溯并找到不同的起点:

[debug]  ?- line_terminal_stations(east_london, StartsAt, EndsAt).
StartsAt = shoreditch,
EndsAt = shadwell ;
StartsAt = whitechapel,
EndsAt = shadwell 

【讨论】:

  • 跟踪您提出的更改,我现在明白我错过了什么,感谢!
【解决方案2】:

但是你需要递归吗?

如果线不是环,您可以简单地将StartAt 设置为起点,但不是终点,EndAt 是终点,但不是起点。

我是说

line_terminal_stations(Line, StartsAt, EndsAt) :-
  link(StartsAt, _, Line),
  \+ link(_, StartsAt, Line),
  link(_, EndsAt, Line),
  \+ link(EndsAt, _, Line).

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多