Re: freeze/2 and nb_setarg/3 interaction
Jan Wielemaker <[email protected]> Mon, 14 Apr 2014 22:23:24 +0200
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <[email protected]> |
On 14-04-14 22:13, Michael Hendricks wrote: > Thanks Michael. That example and thread pointed me in a helpful direction. > This seems to be because the unification "H=a" is still trailed. On > backtracking that unification is undone which makes H unbound again. > > I've modified your broken2 example by adding an extra choicepoint to make > this apparent: > > broken3 :- > X = [H|_], > ( H = a, > (nb_setarg(1, X, b); true), > writeln(X), > fail > ; writeln(X) > ). > > ?- broken3. > [b|_G1940] > [b|_G1940] > [_G1939|_G1940] > true. Never realised that. So, the sequence of unifying a variable argument of a compound and then using nb_setarg/3 undoes all bindings on backtracking to before the unification. The same will happen for setarg/3 followed by nb_setarg/3. I guess that is something that just needs to be documented. It is unclear what the `right' action is in the first place (after all, the unification or backtrackable assignment assumes the old state is restored on backtracking). Even if we would like the nb_* version to be permanent, there is no realistic way to implement that: the nb_* predicate would have to analyse the trail and choicepoints to see whether there is any trailing on that location after the term was created. Cheers --- Jan