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”)?