因此,在 dfs_start/3 中,您希望引用在 dfs/4 中探索过的所有节点,但 dfs/4 没有引用这些节点的参数。因此,您应该引入一个可用于此的附加参数:
dfs_start(InititalState, Goal, Es, Solution) :-
dfs([InititalState], [], Es, Goal, Solution).
dfs([H|_], Es0, Es, Goal, H) :- call(Goal, H), reverse(Es0, Es).
dfs([H|T], Es0, Es, Goal, Solution):-
findall(X, (arc(H, X),
\+ member(X, Es0),
\+ member(X, [H|T]) ), Children),
append(Children, T, OpenList),
dfs(OpenList, [H|Es0], Es, Goal, Solution).
示例查询:
?- dfs_start(a, goal, Path, Solution).
Path = [a, b, c, k, f, l, d],
Solution = g ;
false.
编辑:从您的评论中,我现在看到您想要什么。这很简单:只需按照到达的方式关联到打开列表中的每个节点:
dfs_start(Start, Goal, Path, Solution) :-
dfs([Start-[]], [], Goal, Path, Solution).
dfs([H-Path0|_], _, Goal, Path, H) :- call(Goal, H), reverse([H|Path0], Path).
dfs([H-Path0|T], Es, Goal, Path, Solution):-
findall(X-[H|Path0], (arc(H, X),
\+ member(X, Es),
\+ member(X-_, [H-_|T]) ), Children),
append(Children, T, OpenList),
dfs(OpenList, [H|Es], Goal, Path, Solution).
示例查询:
?- dfs_start(a, goal, Path, Solution).
Path = [a, d, g],
Solution = g ;
false.
还要考虑深度优先搜索在 Prolog 中通过内置的时间回溯提供,因此虽然有时将其明确化(例如,作为更高级搜索策略的起点)可能有用,但您也可以使用:
dfs_start(Start, Goal, Path) :- phrase(dfs(Start, [], Goal), Path).
dfs(Node, _, Goal) --> [Node], { call(Goal, Node) }.
dfs(Node0, Es, Goal) --> [Node0],
{ arc(Node0, Node1), \+ member(Node1, Es) },
dfs(Node1, [Node0|Es], Goal).
示例查询:
?- dfs_start(a, goal, Path).
Path = [a, d, g] ;
false.