2016-10-13 4 views
3

Я создал эту базу знаний в Прологе, которая отражает автобусную компанию WTH автобусов, идущих от и к местам, в результате чего и прибывать в установленное время:Как я могу показать промежуточные шаги в 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]) 
    ). 

Всякий раз, когда я спрашиваю мою базу знаний, если есть маршрут между две точки, он возвращает, возможно ли это; true или false:

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), но после этого я не знаю, что я могу с ним сделать, чтобы он сообщал о промежуточных шагах маршрута.

ответ

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. 
+0

Ваш ответ работал безупречно, спасибо! Что делает 'L = []' точно? Оценивает ли он равенство между пустым списком и L? – Zimano

+0

Или он объединяет L с пустым списком? – Zimano

+0

Он объединяет L с пустым списком с момента создания главы списка и заканчивается там, так что хвост списка должен быть пустым (нет других элементов для добавления). – coder

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