How to find unexpected choicepoints?

As seen, there are a large number of ways to get more info. My personal solution is typically

?- gspy(suspect_pred).
?- go.

As the debugger hits suspect_pred, use s (skip) to jump to the end and examine the choice points in the top-right window. You can click on these to see the source location. You can also use u (up) to get to the caller of the open choice point (etc).

If you have a predicate that is most of the time deterministic but under some circumstances not, the rdet or cleanup/2 tricks can help you to fine the problematic case and start the debugger only in that case. I don’t recall using that. But then, experienced Prolog programmers do not make determinism mistakes very often :slight_smile:

Note that there are a number of cases. Fighting determinism this way makes most sense for recursive code that mostly has a procedural flavor. Here, non-determinism kills LCO (Last Call Optimization) making your code a lot slower and using a lot more memory.

In the typical case where a set of predicates define a logic formula that specify valid solutions, backtracking is typically desired. Using cuts to avoid exploring parts of the search space is typically better avoided. Adding additional constraints keeps the logical reading while the semantics of the code with cuts is often hard to grasp. If performance and/or multiple solutions is an issue here, you have some options. Ordering, stratification, distinct/1,2, order_by/3 may help. Tabling can be attractive as it avoids multiple solution, repeated computation of the same goal, deals with cycles and negation.

edit especially for numerical problems, constraints as e.g., library(clpfd) can solve the problem.

3 Likes