Я схожу с ума от этого...
Как я уже упоминал выше, есть некоторые различия между Прологом на Java и Прологом через SWI.
В настоящее время я использую этот код:
% this data is from original Prolog Dijkstra' algorithm implementation
:- dynamic(best_so_far/2).
findPath([Goal | Rest], Goal, Temp, Temp, [Goal | Rest]) :-
!.
findPath([A | Rest], Goal, Cost, Temp, Path) :-
path(A, B, C),
\+ member(B, Rest),
NewCost is Temp + C,
best_so_far(Limit, _),
NewCost < Limit,
findPath([B, A | Rest], Goal, Cost, NewCost, Path).
% ?- searchPath(aberdeen, glasgow, L, P).
%
searchPath(Start, Goal, BestLen, BestPath) :-
retract_all(best_so_far(_, _)),
asserta(best_so_far(50, [])),
findPath([Start], Goal, Cost, 0, Path),
% if we get here, it's because a lower Cost exists
retract_all(best_so_far(_,_)),
asserta(best_so_far(Cost, Path)),
fail
;
best_so_far(BestLen, BestPath).
retract_all(Term):-
retract(Term),fail.
retract_all(_).
Запрашивая результат в SWI Prolog, я получу ответ через 0,016 секунды. Java требуется 15 секунд для того же результата!
Более того и даже хуже: в какой-то момент gnu prolog дает совершенно другой результат.
Вот некоторая схема Java:
From 190 to 221
pathList: [221, 191, 190]
distance: 2
From 191 to 221
pathList: [221, 251, 252, 253, 223, 193, 194, 195, 196, 197, 198, 199, 169, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123, 122, 121, 151, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191]
distance: 43
From 190 to 221
pathList: [221, 191, 190]
distance: 2
Вы можете ясно видеть, что есть путь от 191 до 221. Но вместо того, чтобы вернуть этот результат (pathList: [221,191]
), я получаю совершенно другой путь, ведущий назад, откуда пришел мой призрак. Выполнение запроса searchPath(191,221, Distance, Path)
в SWI Prolog (мгновенно) возвращает
7 ?- searchPath(191,221, Cost, Path).
Cost = 1,
Path = [221, 191].
Еще раз: я использую тот же самый код. Я скопировал и вставил его, чтобы убедиться. И я передаю правильные аргументы (поэтому я их распечатываю).
Я действительно не знаю, как вас отблагодарить (особенно CapelliC). Я уверен, что вы и так потратили на меня слишком много времени. Но я определенно не в себе.
Изменить: подумал, что было бы полезно увидеть мой код Java:
private int decideHunterMovement() {
// term which contains the result of the prolog method
VariableTerm pathTerm = new VariableTerm("Path");
VariableTerm distanceTerm = new VariableTerm("Distance");
Integer movement;
List<IntegerTerm> pathList = new LinkedList<IntegerTerm>();
// Create the arguments to the compound term which is the question
IntegerTerm hunterPosition = new IntegerTerm(hunter.getPosition());
IntegerTerm targetPosition = new IntegerTerm(pacman.getPosition()); // target for hunter is the pacman position
long time= System.nanoTime ();
Term[] arguments = { hunterPosition, targetPosition, distanceTerm, pathTerm};
// Construct the question
CompoundTerm goalTerm = new CompoundTerm(AtomTerm.get("searchPath"), arguments);
// Execute the goal and return the return code.
int rc;
System.out.println("From " + hunterPosition + " to " + targetPosition);
try{
// Create the answer
rc = interpreter.runOnce(goalTerm);
time = (System.nanoTime () - time) / 1000 / 1000;
System.out.println("Result in:" + time+ "ms");
// If it succeeded.
if (rc == PrologCode.SUCCESS || rc == PrologCode.SUCCESS_LAST){
// Get hold of the actual Terms which the variable terms point to
Term path = pathTerm.dereference();
Term distance = distanceTerm.dereference();
// Check it is valid
if (path != null){
if (path instanceof CompoundTerm){
// convert CompoundTerm to a Java LinkedList
convertToList((CompoundTerm) path, pathList);
if(VERBOSE_MODE){
System.out.println("pathList: " + pathList);
System.out.println("distance: " + (IntegerTerm) distance + "\n");
}
}else{
throw new NoAnswerException("PROLOG ERROR: Answer is not a CompundTerm: (" + path + ")");
}
}else{
throw new NoAnswerException("PROLOG ERROR: Answer null when it should not be null");
}
}else{
throw new NoAnswerException("PROLOG ERROR: Goal failed");
}
} catch (NoAnswerException e) {
e.printStackTrace();
} catch (PrologException e1) {
e1.printStackTrace();
}
movement = decideMovement(pathList);
return movement;
}
person
Markus
schedule
06.04.2013
g_assign/2
иg_read/2
. - person Daniel Lyons   schedule 05.04.2013