如何在此图形路径查找器的Prolog中显示中间步骤?

时间:2016-10-13 10:55:53

标签: prolog prolog-toplevel

我在Prolog中创建了这个知识库,它反映了一个公共汽车公司的公共汽车往返地点,离开并到达设定时间:

connection(kerkrade, heerlen, 1100, 1200).
connection(kerkrade, bleijerheide, 1100, 1225).
connection(heerlen, kerkrade, 1115, 1230).
connection(heerlen, maastricht, 1230, 1330).
connection(maastricht, heerlen, 1430, 1530).
connection(maastricht, sittard, 1331, 1430).
connection(maastricht, sittard, 1345, 1445).
connection(sittard, maastricht, 1630, 1530).
connection(sittard, denbosch, 1530, 1700).
connection(denbosch, sittard, 1800, 1930).
connection(denbosch, amsterdam, 1000, 1330).

checkTime(X,Y,Z):-
    connection(X,Y,S,_),
    (Z =< S).

 aRoute(From, To, Time):-
    checkTime(From,To,Time).

testRoute(A,B,T):-
    walk(A,B,T,[]).


walk(A,B,Time,V) :-
    aRoute(A,X,Time),
    not(member(X,V)),
    (
        B = X;
        connection(A,X,_,S), walk(X,B,S,[A|V])
    ).

每当我向我的知识库询问两点之间是否有路线时,它会返回是否可能; truefalse

testRoute(kerkrade, sittard, 900).
true; (signifies that there are three routes, of which two are possible)
true;
false.

但是,这不是我想要的。在最好的情况下,我想显示用于在顶层中的两个点之间创建路径的连接,如下所示:

connection(kerkrade, heerlen, 1100, 1200)
connection(heerlen, maastricht, 1230, 1330)
/* and so on.. */

我该怎么做?我想我必须传递一个像X这样的变量以及我对testRoute的调用,以便它可以报告它的值。我在编写谓词时遇到了麻烦,因为我不确定在哪里放置它。我的想法是我必须向walk(A,B,Time,V)添加一个额外的参数,但我不知道在此之后我能做些什么才能报告路线的中间步骤。

2 个答案:

答案 0 :(得分:3)

您可以通过以下方式保留包含连接的列表:

 checkTime(X,Y,Z, connection(X,Y,S,W)):-
    connection(X,Y,S,W),
    (Z =< S).

 aRoute(From, To, Time,Head):-
    checkTime(From,To,Time,Head).

testRoute(A,B,T,L):-
    walk(A,B,T,[],L).


walk(A,B,Tijd,V,[Head|L]) :-
    aRoute(A,X,Tijd,Head),
    not(member(X,V)),
    (
        B = X,L=[];
        connection(A,X,_,S), walk(X,B,S,[A|V],L)
    ).

示例:

?- testRoute(kerkrade, sittard, 900,L).
L = [connection(kerkrade, heerlen, 1100, 1200), connection(heerlen, maastricht, 1230, 1330), connection(maastricht, sittard, 1331, 1430)] ;
L = [connection(kerkrade, heerlen, 1100, 1200), connection(heerlen, maastricht, 1230, 1330), connection(maastricht, sittard, 1345, 1445)] ;
false.

答案 1 :(得分:3)

  

我想显示用于创建两点之间路线的连接[...]我该怎么做?我想我必须传递一个像X这样的变量以及我对testRoute的调用,以便它可以报告它的值。

是:我想你必须为路径传递另一个变量

我提出以下解决方案

walk(Stop, Stop, _, ReverseRoute, DirectRoute):-
  reverse(ReverseRoute, DirectRoute).

walk(Start, Stop, TimeMin, ReverseRoute, DirectRoute) :-
  connection(Start, Mid, TimeStart, TimeArrival),
  TimeMin =< TimeStart,
  not(member(Mid, ReverseRoute)),
  walk(Mid, Stop, TimeArrival, [Mid | ReverseRoute], DirectRoute).

testRoute(Start, Stop, TimeStart, Route) :-
  walk(Start, Stop, TimeStart, [Start], Route).