0


0

Рутина пролога

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

traceroute(_,L) :- member((A,A),L).
traceroute(N,L) :-
   predecessor(N,P),
   append(N,L,L1),
   traceroute(P,L1).

Когда я запускаю traceroute (placeA, Y) ., он возвращает эти данные .. Y = [(_G575, _G575) | _G579] .

В основном, для первой строки traceroute я пытаюсь завершить рекурсию, если какой-либо участник сам по себе является предшественником. Вторая часть должна пройти через все узлы и добавить их в список (L).

Узлы хранятся как [(placeA, placeB), (placeB, placeC)], а список должен храниться как [placeA, placeB, placeC]

Я не могу понять, почему я получаю эти результаты.

1 Answer


2


Решение, которое выглядит следующим образом (когда оно неверно), обычно означает, что вы не нашли (то есть, создали экземпляр) термин где-то там, где вы должны иметь.

Я не совсем уверен, как должен работать ваш код, но похоже, что ваша главная проблема в том, что вы передаете непеременная переменная для второго аргумента traceroute.

В вызове члена, поскольку L - неосновная, вы фактически просите пролог вернуть элемент формы (A, A), который является элементом полностью необоснованного списка. Хотя это не имеет особого смысла, бывают случаи, когда подобные вещи полезны, поэтому пролог послушно соблюдает и при возврате генерирует списки увеличенной длины (поскольку вы нигде не указали длину) nonground переменные, которые имеют элемент (A, A) в какой-то момент. ie:

?- traceroute(placeA, Y).
Y = [ (_G271, _G271)|_G275] ;
Y = [_G274, (_G271, _G271)|_G278] ;
Y = [_G274, _G277, (_G271, _G271)|_G281] ;
Y = [_G274, _G277, _G280, (_G271, _G271)|_G284] ;

Вам нужно либо передать значение для Y, которое является наземным, либо дополнительно ограничить значения, которые оно принимает внутри вашего предиката, или, возможно, даже оба.

Также, хотя второе предложение на самом деле не выполняется, у вас есть похожая проблема: L, который снова является nonground, добавляется к N, чтобы получить L1, который также является nonground. Так как этот предикат делает это рекурсивно, окончательный список всегда будет кратким.