New undo/1

I think the new undo/1 is a great feature to have! Alllows much cleaner code when we need side-effects. I had a question, in the test code you have:

test(error, throws(x)) :-
    (   undo(throw(x)),
        fail
    ;   ok                              % true is a VMI
    ).

why does it make a difference to have ok vs true?

Wow!.. Is undo/1 already available in SWI?
All I see is rdf_edit:undo/1

-D

See ADDED: undo/1 to schedule goals to be called on backtracking. · SWI-Prolog/swipl-devel@2c2acdd · GitHub

git source for now, i guess it will be in next development release.

True doesn’t create a call and goals registered with undo/1 are executed on the next call port. So, the undo happens, but not in the test body context but right after getting back into the test wrapper where the exception is no longer caught.

2 Likes

B.t.w. when I was documenting this I wanted to refer to the SICStus compatibility. It appears SICStus dropped (deprecated?) undo/1 from SICStus 4. Going through some of the comments about using undo/1 in a constraint context it seems SICStus did actually call the goal while unwinding the trail. That is quite different from SWI-Prolog at the moment: the goal is copied, scheduling its execution for later. That limits its usability to dealing with otherwise non-backtrackable data such as the clause DB, foreign structures, external databases, etc.

I don’t really see the point why one would want undo/1 to poke around in the already backtrackable constraint store. Maybe it made/makes sense in SICStus. Executing the goal in the middle of the trail rewinding is interesting as it avoids copying. I have little clue on how to implement that though

Just in case, if my posts are not related to this undo/1 thread… we can remove these posts and move to a new thread?

That seems to me the most useful purpose. Like you, I don’t see why would it be used with already backtrackable structures, but I don’t have deep knowledge about these matters…