在Prolog中访问BFS,为什么该程序不';不行?

在Prolog中访问BFS,为什么该程序不';不行?,prolog,Prolog,我从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

我从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.
正如您所看到的,当它尝试扩展不是目标节点的当前节点(在本例中是目标节点)时,问题似乎发生了。扩展节点意味着从路径头列表(候选路径列表)中删除第一条路径,并且由于该路径中的元素,因此创建一个名为NewPath的新列表,其中包含这些节点的所有一步邻居节点

然后,使用conc/2谓词构建一个新的路径1候选路径列表,将该列表放置在路径列表(没有头部的候选路径的旧列表)的末尾新路径列表

然后在此新列表上执行breadthfirst(路径1

当它尝试扩展当前节点时,问题似乎出现了,因为extends/2谓词似乎工作不好(事实上,NewPath apper void):

有关更多信息,我在查阅程序时收到以下错误消息:

[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.
为什么??你有办法解决这个问题吗?

第47行

not member(NewNode,[Node|Path]) 
not( member(NewNode,[Node|Path]) )
是无效语法。必须是两者之一

\+ member(NewNode,[Node|Path])

在线47

not member(NewNode,[Node|Path]) 
not( member(NewNode,[Node|Path]) )
是无效语法。必须是两者之一

\+ member(NewNode,[Node|Path])