I want to implement a tracing predicate that outputs which predicate is being “currently resolved” from within any predicates that get called during its resolution.
To do this I am trying to find a way to set global state to a value only:
- during execution of a predicate
or - during any of the children called to “prove” it.
Here’s an example that uses an unimplemented setGlobalDuringPredicate/2 predicate as an example:
:- dynamic(globalValue/1).
globalValue(none).
writeGlobal(Tag) :-
globalValue(X),
writeln(value(Tag, X)).
parentPredicate :-
% Unclear how to implement setGlobalDuringPredicate
% so that I get the output below
setGlobalDuringPredicate(value1, childPredicate),
writeGlobal(parentPredicate).
childPredicate :-
writeGlobal(childPredicate).
?- parentPredicate.
value(childPredicate, value1)
value(parentPredicate, none)
I tried implementing setGlobalDuringPredicate using setup_call_cleanup. It almost worked. The problem was that cleanup is only called after all backtracking is done in call. So if childPredicate and parentPredicate were written so that execution backtracks once it would execute like this:
:- dynamic(globalValue/1).
globalValue(none).
setGlobalDuringPredicate(Value, Goal) :-
setup_call_cleanup(
(
globalValue(PreviousValue),
retractall(globalValue(_)),
assert(globalValue(Value))
),
(
Goal
),
(
retractall(globalValue(_)),
assert(globalValue(PreviousValue))
)
).
writeGlobal(Tag) :-
globalValue(X),
writeln(value(Tag, X)).
parentPredicate :-
% Unclear how to implement setGlobalDuringPredicate
% so that I get the output below
setGlobalDuringPredicate(value1, childPredicate),
writeGlobal(parentPredicate),
fail.
backtrack(a).
backtrack(b).
childPredicate :-
backtrack(X),
writeln(X),
writeGlobal(childPredicate).
?- parentPredicate.
a
value(childPredicate,value1)
value(parentPredicate,value1) % not what I want. I want `none`
b
value(childPredicate,value1)
value(parentPredicate,none)
false.
Is there a way to get the behavior I want (outside of making every predicate take an argument where I pass along the “current predicate”)?