This predicate allows you to make several predicates over integers deterministic while preserving their generality and completeness. For example:
n_factorial(N, F) :-
zcompare(C, N, 0),
n_factorial_(C, N, F).
n_factorial_(=, _, 1).
n_factorial_(>, N, F) :-
F #= F0*N, N1 #= N - 1,
n_factorial(N1, F0).
This version is deterministic if the first argument is instantiated, because first argument indexing can distinguish the two different clauses:
?- n_factorial(30, F). F = 265252859812191058636308480000000.
The predicate can still be used in all directions, including the most general query:
?- n_factorial(N, F). N = 0, F = 1 ; N = F, F = 1 ; N = F, F = 2 .