我已经从Ivan Bratko的书中采用了实现BFS访问算法的程序:“人工智能编程”。
我的逻辑非常明确(我已经评论了代码行及其含义),但不起作用。
我的代码是:
s(a, b).
s(b, c).
s(c, d).
s(a, d).
% GOAL: il raggiungimento del nodo d:
goal(d).
/* solve(Start, Solution): Solution is a path (in reverse order) from Start to a goal it is TRUE
if it is TRUE breadthfirst(Paths, Solution) (it is TRUE if some path from a candidate set of paths Paths
can be extended to a goal nod. Solution is such an extended path
*/
solve(Start, Solution) :- breadthfirst([[Start]], Solution).
/* breadthfirst([Path1, Path2, ...], Solution) it is TRUE if:
Solution is an extension to a goal of one of the paths in the Paths list of candidates paths
SET CANDIDATES PATH RAPPRESENTATIONS: The set will be represented as a list of paths, and each path will
be a list of nodes in the inverse order; that is, the head will be the most recently generated node, and
the last element of the list will be the start node of the search
*/
/* BASE CASE: If the HEAD of the FIRST PATH (in Paths list) is a GOAL then this path is a Solution of the problem
*/
breadthfirst([[Node|Path]|_], [Node|Path]) :- goal(Node).
/* GENERAL CASE: Otherwise (if the head of the first path is not a goal node) remove the first path from the
candidates set and generate the set of all possible one-step extensions of this paths, add this set of
extension at the end of the candidate set, and execute breath-first search on this updated set
*/
breadthfirst([Path|Paths], Solution) :-
/* Remove the first path from the Paths list and extends it (generate the set of
all possible one-step extensions of this paths that is NewPaths list */
extend(Path, NewPaths),
/* Paths1 = [Paths|NewPaths] */
conc(Paths, NewPaths, Paths1),
/* Execute BFS on Paths1 */
breadthfirst(Paths1, Solution).
/* extended/2 predicate take a Path that is a list of node and generate the set of all possible one-step
extensions of this paths
*/
extend([Node|Path], NewPaths) :- bagof([NewNode, Node|Path],
(s(Node, NewNode), not member(NewNode,[Node|Path]) ),
NewPaths),
!.
extend(Path, []). % bagof failed: Node has no successor
conc([],L,L).
conc([X|L1],L2,[X|L3]) :- conc(L1,L2,L3).
问题在于,当我尝试执行查询时,它总是以FALSE响应我(如果存在从起始节点X到另一个音符Y的路径)
例如(做一些情况)我有:
[trace] ?- solve(a,Solution).
Call: (6) solve(a, _G367) ? creep
Call: (7) breadthfirst([[a]], _G367) ? creep
Call: (8) goal(a) ? creep
Fail: (8) goal(a) ? creep
Redo: (7) breadthfirst([[a]], _G367) ? creep
Call: (8) extend([a], _G443) ? creep
Exit: (8) extend([a], []) ? creep
Call: (8) conc([], [], _G444) ? creep
Exit: (8) conc([], [], []) ? creep
Call: (8) breadthfirst([], _G367) ? creep
Fail: (8) breadthfirst([], _G367) ? creep
Fail: (7) breadthfirst([[a]], _G367) ? creep
Fail: (6) solve(a, _G367) ? creep
false.
正如您所看到的那样,当它尝试扩展不是目标节点的当前节点(在本例中为a)时,似乎会出现问题。扩展节点意味着从路径列表的头部(候选路径列表)中删除第一条路径,并且由于此路径中的元素,创建一个名为NewPath的新列表,其中包含这些节点的所有一步邻居节点。
然后,使用 conc / 2 谓词,它会在路径列表的末尾构建一个新的 Paths1 候选路径列表(没有头部的候选路径的旧列表) NewPaths 列表
然后在这个新列表上执行breadthfirst( Paths1 )
当它尝试扩展当前节点时似乎会出现问题,因为似乎 extends / 2 谓词不能很好地工作(事实上NewPath apper void):
extend([Node|Path], NewPaths) :- bagof([NewNode, Node|Path],
(s(Node, NewNode), not member(NewNode,[Node|Path]) ),
NewPaths),
!.
有关详细信息,请参阅我的程序时收到以下错误消息:
[debug] ?- consult(bfs).
ERROR: /home/andrea/Documenti/prolog/lezione10/bfs.pl:47:62: Syntax error: Operator expected
Warning: /home/andrea/Documenti/prolog/lezione10/bfs.pl:51:
Singleton variables: [Path]
% bfs compiled 0.00 sec, 160 bytes
true.
为什么呢?你有什么想法来解决这个问题吗?
答案 0 :(得分:4)
第47行
not member(NewNode,[Node|Path])
语法无效。它必须是
\+ member(NewNode,[Node|Path])
或
not( member(NewNode,[Node|Path]) )