#prolog #instantiation-error
#пролог #создание экземпляра-ошибка
Вопрос:
node(1,22,44).
node(2,43,53).
node(3,23,12).
distance(Id1,Id2,D) :-
node(Id1,X1,Y1),
node(Id2,X2,Y2),
D is sqrt((X2-X1)^2 (Y2-Y1)^2).
distancePath([X,Y],D) :-
distance(X,Y,D).
distancePath([H,X|T],Distance) :-
distancePath([X|T],Rest),
distance(H,X,D),
Aux is Rest D,
Distance is Distance Aux.
У меня какая-то проблема с distancePath, потому что, когда я запускаю distancePath([1,2,3],Distance).
, он выдает мне «Ошибка создания экземпляра в аргументе 2 из (is) / 2», может кто-нибудь мне помочь?
Ответ №1:
Distance is Distance Aux.
не имеет особого смысла. Переменные неизменяемы, это означает, что после установки переменная сохранит то же значение в этой ветви оценки пролога. Кроме того, Distance
не ограничено, отсюда и ошибка.
На самом деле у вас уже есть значение для Distance
: это Aux
так как это расстояние для Rest
списка плюс расстояние D
:
distancePath([X,Y], D) :-
distance(X,Y,D).
distancePath([H,X|T], Aug) :-
distancePath([X|T],Rest),
distance(H,X,D),
Aux is Rest D.
Затем это дает нам:
?- distancePath([1,2,3], D).
D = 68.4652982294199 ;
false.
Однако вышеприведенное не очень эффективно: оно не использует хвостовую рекурсию, и, кроме того, вы выполняете распаковку конструктора cons несколько раз. Вы можете использовать вспомогательный предикат для повышения эффективности:
distancePath([X|T], Result) :-
distancePath(T, X, 0, Result).
distancePath([], _, D, D).
distancePath([J|T], I, Di, Do) :-
distance(I, J, Dd),
D2 is Di Dd,
distancePath(T, J, D2, Do).