I have some code that uses when/2 to allow “bi-directional” predicates. When the computation is finished, there shouldn’t be an “frozen” goals, so I do something like this (the actual code is more complex, but I think this captures the gist of it):
pred(X,Y) :- maplist(pred_on_subterm, X, Y), ( term_attvars((X,Y), ) -> true ; instantiation_error((X,Y)) ). ... pred_on_subterm(A, B) :- when((nonvar(A);nonvar(B)), pred_on_subterm_impl(A, B))
But alternatively, I could wrap the call with call_residue_vars/2.
All potential “frozen” variables should be reachable from the top-level
Y, so I think the effect of both term_attvars/2 and call_residue_vars/2 would be the same but term_attvars/2 should be faster. Is this a correct understanding?