

Beware this little predicate Unexpected result for predicate nb_setarg/3
?- functor(A, array, 5), forall( arg(Index, A, foo), nb_setarg(Index, A, bar)). A = array(_16050, _16052, _16054, _16056, _16058).
The above is expected as backtracking occurs to before the position where array
at position Index is set to foo
, rolling back the nb_setarg/3 effect by rolling back the arg/3 effect.
However:
?- A=array(_,_,_,_,_), forall( arg(Index, A, foo), nb_setarg(Index, A, bar)). A = array(bar, bar, bar, bar, bar).
This is actually a problem with SWI-Prolog (8.3.14). It shouldn't work.
This one doesn't do "dual assignment" and so come out right, consistently:
?- A=array(_,_,_,_,_), forall( between(1,5,Index), nb_setarg(Index, A, bar)). A = array(bar, bar, bar, bar, bar).
?- functor(A, array, 5), forall( between(1,5,Index), nb_setarg(Index, A, bar)). A = array(bar, bar, bar, bar, bar).
Basically, do not backtrack to before where you started using `nb_*` and only use the `nb_*` predicates on the same location.