Can someone please explain the Prolog logical view about assert and retract in details?
For example in code below, in the first run Prolog returns true and in subsequent runs returns false. I don't know why because of Prolog logical view when asserta(nextBound(100)) satisfies, nice(X) is still frozen with values when it started so this change should be ignore and nextbound(100) must be false.
nextBound(10000).
nice(X) :-
asserta(nextBound(100)),
retract(nextBound(10000)),
nextBound(100).
You can do a
traceto determine what happens:You can see that, in the first case, first the
nextBound(100)fact is successfully asserted (for the 1st time). Then, theretract(nextBound(10000))succeeds becausenextBound(10000).is a fact which exists in the data. Following that, the querynextBound(100)succeeds because two steps before this fact was asserted into the data.On the second execution of
nice(_),nextBound(10000)doesn't exist because it was retracted in the first execution, and the code doesn't re-assert it. So, in the second execution ofnice(_),retract(nextBound(10000))fails because the factnextBound(10000)doesn't exist and the entire second execution ofnice(_)fails at that point since backtracking overassertaandretractdo not re-execute and produce additional results.A listing shows that now there are two
nextBound(100)facts, since we've asserted one in each of the two runs ofnice(_), and nonextBound(10000)since it was retracted in the first run ofnice(_):The logical update view, as stated in the SWI documentation, says, Starting with SWI-Prolog 3.3.0 we adhere to the logical update view, where backtrackable predicates that enter the definition of a predicate will not see any changes (either caused by
assert/1orretract/1) to the predicate.In other words, the logical update view prevents the predicate from dynamically changing itself while it's executing. That's not the scenario here.
In fact, it's critical in Prolog that, during the execution of a predicate, if you assert a fact at one point in the predicate, that result must be visible in it immediately, or the predicate may not be able to function properly. There are many many common library predicates that rely on this behavior.