Prolog程序的意外行为

时间:2015-02-11 09:27:54

标签: algorithm prolog artificial-intelligence

我写了一个prolog程序来搜索无方向图(或迷宫)中的路径。

pway(a, b,10).
pway(b, e,10).
pway(b, c,10).
pway(d, e,10).
pway(c, d,10).
pway(e, f,10).
pway(g, e,10).

solve(X,X,T,N) :-
    write(T), N is 0. % do nothing
solve(X,Y,T,N) :-
    pway(X, Z,C),
    not(member(Z, T)),
    solve(Z, Y, [Z|T],M),
    N is M+C. % There is a pway from X to Z, new list has z as head.
solve(X,Y,T,N) :-
    pway(Z, X,C),
    not(member(Z, T)),
    solve(Z, Y, [Z|T],M),N is M+C. % same, just takes care of non-directedness

我打算将此程序用于以下查询:

?- solve(a,f,P,N). 

即。给我一条路径P从a到f的费用。

但这不符合预期。当我输入(P打算成为一个列表)时,

?- solve(e,b,P,N).
false. 

我弄错了。 (为什么??)

但是,当我进入时:

?- solve(e,b,[],N).
[b,e,f]
N = 30 ;
[b,c,d,e,f]
N = 50 ;
[b]
N = 10 ;
[b,e,d]
N = 30 ;
[b,c,d]
N = 30 ;
[b,e,g]
N = 30 ;
[b,c,d,e,g]
N = 50 ;
false.

我得到了结果。实际上,我从不想在prolog程序本身中使用write命令,只要输入第一个查询(返回false),我就应该得到相同的结果。 我无法识别错误。

感谢任何帮助。感谢。

1 个答案:

答案 0 :(得分:1)

这是因为#3参数不是#1和#2中两个节点之间的路径,正如您所期望的那样。如果您在#3中传递变量,则目标not(member(Z, T))始终会失败,因此solve/3也会失败。

从你所说的话来看,你想做的事情可能是这样的。

solve(X,Y,T,N) :- solve(X,Y,[],N,T).

solve(X,X,T,0,T).

solve(X,Y,T,N,O) :-
    pway(X, Z,C),
    \+ member(Z, T),
    solve(Z, Y, [Z|T],M,O),
    N is M+C.

solve(X,Y,T,N,O) :-
    pway(Z, X,C),
    \+ member(Z, T),
    solve(Z, Y, [Z|T],M,O),N is M+C.