I am trying to write breadth-first search in SWI Prolog using assertz() and retract(). I am having some issues though and I was hoping for some guidance. My guess is I'm doing something stupid.
:- 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).
The problem is that as soon as the goal check happens in breadthfirst/1
, it retracts the initial state from the database, so by the time it gets to the second definition of breadthfirst/1
(where the extend/2
function is called), there is nothing left to retract, causing execution to stop.
What am I missing here?
Thanks!