SWI Prolog - 在广度优先搜索中使用assertz()和retract()

问题描述 投票:0回答:1

我正在尝试使用assertz()和retract()在SWI Prolog中编写广度优先搜索。但我遇到了一些问题,希望得到一些指导。我猜我正在做一些愚蠢的事情。

:- dynamic paths/1.

bfs_solve(Solution) :-
  initial_state(Start),
  assertz(paths([[Start]])),
  breadthfirst(Solution).

breadthfirst([Node | Path]) :-
  retract(paths([[Node | Path] | _])),
  goal(Node).

breadthfirst(Solution) :-
  retract(paths([Path | RestPaths])),
  extend(Path, NewPaths),
  conc(RestPaths, NewPaths, Paths1),
  assertz(paths(Paths1)),
  breadthfirst(Solution).

extend([Node | Path], NewPaths) :-
  bagof([NewNode, Node | Path],
  (s(Node, NewNode), \+ member(NewNode, [Node | Path])),
  NewPaths),
  !.

extend(Path, []).

initial_state([1, 2, 3, 4, 5]).
goal([0, 0, 0, 0, 0]).

% Function 's' is not detailed here as it is irrelevant to this problem

member(X, [X | Tail]).
member(X, [Head | Tail]) :-
  member(X, Tail).

conc([], L, L).
conc([X | L1], L2, [X | L3]) :-
  conc(L1, L2, L3).

问题是,一旦目标检查发生在

breadthfirst/1
中,它就会从数据库中撤回初始状态,因此当它到达
breadthfirst/1
的第二个定义时(调用
extend/2
函数的地方) ,没有什么可以收回,导致执行停止。

我在这里缺少什么?

谢谢!

prolog breadth-first-search swi-prolog
1个回答
0
投票

如果您将对assert*和retract*的调用包装在几个实现队列的谓词中,您可能能够找出错误。排队需要什么?

  • 初始化一个空队列
  • 推到后面
  • 从前面弹出

(是不是也需要能推到前面,或者看上面而不弹出?)

我假设你想保持这个状态和全局? (为什么要使用数据库?)在这种情况下,您可以选择调用您的队列

queue/1
,然后:

:- dynamic queue/1.

empty_queue :-
    retractall(queue(_)).

push_back(Back) :-
    assertz(queue(Back)).

pop_front(Front) :-
    once(queue(F0)), % first fact matched to a free variable
    once(retract(queue(F0))), % retract exactly once the matched fact
    Front = F0.

一个简单的测试,我压入[a,b,c],弹出两次,所以应该是'a',然后是'b',并打印队列的其余部分,应该是[c]:

?- empty_queue,
   push_back(a),
   push_back(b),
   push_back(c),
   pop_front(X0),
   pop_front(X1),
   forall(queue(A), format("~w~n", [A])).
c
X0 = a,
X1 = b.

(整个队列位于输出的第一行)

为了表明我们只弹出顶部:

?- empty_queue,
   push_back(a),
   push_back(b),
   push_back(a),
   pop_front(X),
   forall(queue(A), format("~w~n", [A])).
b
a
X = a.

所以它似乎有效。

© www.soinside.com 2019 - 2024. All rights reserved.