If you want to run some goal in an "isolated context":
\+ \+ Goal
The above really makes clear that you are only interested in whether Goal will succeed or fail and that any bindings shall be trashed and have no influence on further computation; (except for any side-effects generated when proving Goal, which are forever inscribed in the Universe and cannot be rolled back).
f(1,2). ?- A=2, ( \+ \+ f(X,A) ), format("X is now ~q\n", [X]). X is now _7808 A = 2.
Especially useful if you want to isolate your debugging printouts lest they change something due to small detail:
ddd_isolate(X) :- debug(topic,"X is ~q\n",[X]), (X= -> % ERROR: = instead of == debug(topic,"X is the empty list\n",) ; true). test(X) :- debug(topic), % switch on debug printing for topic "topic" debug(topic,"X before: ~q\n",[X]), \+ \+ ddd_isolate(X), debug(topic,"X after: ~q\n",[X]).
Yes, it works:
?- test(12). % X before: 12 % X is 12 % X after: 12 true. ?- test(). % X before:  % X is  % X is the empty list % X after:  true. ?- test(X). % X before: _5354 % X is _5354 % X is the empty list % X after: _5354 % changes have been erased true.