使用(nb_)设置/3与gnu.Java中的prolog



我目前正试图使用prolog退出java使用gnu。序言(http://www.gnu.org/software/gnuprologjava/) .

感谢CapelliC的巨大帮助,我现在有一个prolog程序,它完美地满足了我的目的。问题是gnu。prolog不支持reverse/2,也不支持nb_setarg/3。Java将抛出一个错误:

Exception in thread "Game" java.lang.IllegalArgumentException: The goal is not currently active

这不是一个大问题实现reverse/2对我自己,但我不知道如何取代nb_setarg/3 (setarg/3也不工作)

下面是我的prolog代码:
findPath(_Limit, [Goal | Rest], Goal, Temp, Temp, [Goal | Rest]) :- !.
findPath(Limit, [A | Rest], Goal, Cost, Temp, Path) :-
    path(A,B,C),
    +member(B, Rest),
    NewCosts is (Temp + C),
    NewCosts < Limit,
    findPath(Limit, [B, A | Rest], Goal, Cost, NewCosts, Path).
searchPath(Start, Goal, Path_to_goal) :-
    S = path_len([], 50),
    repeat,
    arg(2, S, Limit),
    (   findPath(Limit, [Start], Goal, Cost, 0, Path)
    ->  (   Cost < Limit
        ->  nb_setarg(1, S, Path),
        nb_setarg(2, S, Cost),
        fail
        )
    ;   true
    ),
    arg(1, S, Rev),
    reverse(Rev, Path_to_goal).

我试图从SWI Prolog中使用JPL,但由于几个异常指出,Eclipse无法正确找到库,所以我无法运行它。我总是得到以下异常之一:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no jpl in java.library.path

UnsatisfiedLinkError: D:Program FilesPrologbinjpl.dll: Can't find dependent libraries
SWI-Prolog: [FATAL ERROR:
    Could not find system resources]

即使遵循这个和这个指南,我还是不能解决我的问题。在Windows(32位)和Ubuntu(64位)上都不能。

你有一个解决方案,我如何才能得到JPL运行或如何能够使用nb_setarg/3 ?到现在为止,我花了一天半的时间没有任何结果。很沮丧…

我很抱歉,但我建议使用GProlog设置作为替代SWI-Prolog nb_setarg是错误的。现在我用一种更简单和(我希望)更有效的方式重新编写了代码,可以在任何ISO Prolog下工作。

% this data is from original Prolog Dijkstra' algorithm implementation
:- initialization( consult(salesman) ).
:- dynamic(best_so_far/2).
path(X,Y,Z) :- dist(X, Y, Z).
path(X,Y,Z) :- dist(Y, X, Z).
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) :-
    retractall(best_so_far(_, _)),
    asserta(best_so_far(1000000, [])),
    findPath([Start], Goal, Cost, 0, Path),
    % if we get here, it's because a lower Cost exists
    retractall(best_so_far(_, _)),
    asserta(best_so_far(Cost, Path)),
    fail
    ;
    best_so_far(BestLen, BestPath).

如果你想要紧一点,有一个非常简单的启发式应该适用:即使findPath贪婪,选择第一个成本较低的分支。可以使用setof+member…

我要疯了…

正如我上面已经提到的,Java中的Prolog和通过SWI实现的Prolog之间存在一些差异。

我正在使用这个代码:

% 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

可以清楚地看到,有一条路径从191221。但不是返回这个结果(pathList: [221,191]),我得到了一个完全不同的路径,从我的鬼来的地方向后。在SWI Prolog中运行查询searchPath(191,221, Distance, Path)(立即)返回

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;
    }

相关内容

  • 没有找到相关文章

最新更新