2014-11-27 12 views
3

Я полный новичок в Prolog. Я пытаюсь выяснить проблему, когда мне нужно проверить, существует ли путь между ребрами. Я закончил с ациклическим графовым кодом для циклического кода, который меняет бесконечный цикл.Поиск пути по маршруту пролога с циклическим путем

path(Start, End) :- edge(Start, End). 
path(Start, End) :- edge(Start, Z), path(Z, End). 

мне нужно обрабатывать этот случай, определив новый предикат: new_path (Start, End, путь) который должен устранить бесконечный цикл. Пожалуйста, дайте мне знать, как это сделать.

ответ

1

Попробуйте

path(Start, End) :- 
    closure(edge, Start, End). 

использованием this definition for closure/3

+0

Эй, спасибо, но это возможно сделать без закрытия0, где я могу определить свой собственный функтор, как путь. Еще раз спасибо за ваш вклад. –

1

Вы должны отслеживать, какие узлы, которые вы посетили, как вы идете, используя пролога список как стек LIFO. Что-то в этом стихе:

path(A , Z , P) :-   % to find a path from A to Z 
    traverse(A , Z , [] , P) , % take a walk, visiting A to see if we can get to Z, seeding the visited list with the empty string. 
    reverse(P,Path)    % once we find a path, let's reverse it, since it's in LIFO order. 
    .       % That's all there is to it, really. 

traverse(Z , Z , V , [Z|V])  % if current node is the destination node, we've arrived. 
    .        % - just push the destination vertice onto the visited list and unify that with the path 
traverse(A , Z , V , P) :-  % Otherwise... 
    edge(A , Z) ,     % - if the current node is directly connected to the destination node, 
    traverse(Z , Z , [A|V] , P) % - go visit the destination, marking the current node as visited 
    .        % 
traverse(A, Z , V , P) :-  % Otherwise... 
    A \= Z, 
    edge(A , B) ,     % - if the current node is connected to a node 
    B \= Z ,      % - that is not the destination node, and 
    unvisited([A|V],B) ,   % - we have not yet visited that node, 
    traverse(B , Z , [A|V] , P) % - go visit the intermediate node, marking the current node as visited. 
    .        % Easy! 

unvisited([] , _) .     % We succeed if the visited list is empty. 
unvisited([A|_] , A) :- ! , fail .  % We fail deterministically if we find the node in the visited list. 
unvisited([_|L] , A) :- unvisited(L,A) . % otherwise, we keep looking.