Prolog - 总结数字

时间:2014-06-02 12:38:37

标签: numbers prolog sum

我是prolog的新手。我在互联网上找到了广泛的第一个搜索程序,即搜索城市之间的路线。我想扩展程序来存储和计算距离。但我无法弄明白该怎么做。

原始代码:

move(loc(omaha), loc(chicago)).
move(loc(omaha), loc(denver)).
move(loc(chicago), loc(denver)).
move(loc(chicago), loc(los_angeles)).
move(loc(chicago), loc(omaha)).
move(loc(denver), loc(los_angeles)).
move(loc(denver), loc(omaha)).
move(loc(los_angeles), loc(chicago)).
move(loc(los_angeles), loc(denver)).

bfs(State, Goal, Path) :-
    bfs_help([[State]], Goal, RevPath), reverse(RevPath, Path).

bfs_help([[Goal|Path]|_], Goal, [Goal|Path]).
bfs_help([Path|RestPaths], Goal, SolnPath) :-
    extend(Path, NewPaths),
    append(RestPaths, NewPaths, TotalPaths),
    bfs_help(TotalPaths, Goal, SolnPath).

extend([State|Path], NewPaths) :-
    bagof([NextState,State|Path],
          (move(State, NextState), not(member(NextState, [State|Path]))),
          NewPaths), !.
extend(_, []).

输出:

1 ?- bfs(loc(omaha), loc(chicago), X).
X = [loc(omaha), loc(chicago)] ;
X = [loc(omaha), loc(denver), loc(los_angeles), loc(chicago)] ;
false.

我试过这个:

bfs(A,B,Path,D) :-
   bfs(A,B,Path),
   path_distance(Path,D).

path_distance([_], 0).
path_distance([A,B|Cs], S1) :-
   move(A,B,D),
   path_distance(Cs,S2),
   S1 is S2+D.

bfs(A,B, Path) :-
    bfs_help([[A]], B, RevPath), reverse(RevPath, Path).

bfs_help([[Goal|Path]|_], Goal, [Goal|Path]).
bfs_help([Path|RestPaths], Goal, SolnPath) :-
    extend(Path, NewPaths),
    append(RestPaths, NewPaths, TotalPaths),
    bfs_help(TotalPaths, Goal, SolnPath).

extend([State|Path], NewPaths) :-
    bagof([NextState,State|Path],
          (move(State, NextState,_), not(member(NextState, [State|Path]))),
          NewPaths), !.
extend(_, []).

输出

5 ?- bfs(loc(omaha), loc(chicago), X,D).
false.

我想要的是什么:

1 ?- bfs(loc(omaha), loc(chicago), X, D).
X = [loc(omaha), loc(chicago)] ;
D = 1
X = [loc(omaha), loc(denver), loc(los_angeles), loc(chicago)] ;
D = 6
false.

请有人帮我解决这个问题! 抱歉我的英文。

1 个答案:

答案 0 :(得分:2)

定义关系path_distance/2似乎最便宜。那不是最优雅的方式, 但它应该符合你的目的:

bfs(A,B,Path,D) :-
   bfs(A,B,Path),
   path_distance(Path,D).

path_distance([_], 0).
path_distance([A,B|Cs], S1) :-
   move(A,B,D),
   path_distance([B|Cs],S2),
   S1 is S2+D.

您可能还会重新考虑bfs/3。查询

?- bfs(A,B, Path).

给出了相当奇怪的结果。

现在使用move/2move/3。因此:

move(A,B) :-
   move(A,B,_).

move(loc(omaha), loc(chicago),1).
move(loc(omaha), loc(denver),2).
move(loc(chicago), loc(denver),1).
move(loc(chicago), loc(los_angeles),2).
move(loc(chicago), loc(omaha),1).
move(loc(denver), loc(los_angeles),2).
move(loc(denver), loc(omaha),1).
move(loc(los_angeles), loc(chicago),2).
move(loc(los_angeles), loc(denver),3).