Write clean code

Most novices try to write a single rule using a long and complicated control structure that produces the desired answer. The rule typically doesn't work, so they start adding additional control structures and conditions to fix the corner cases. Suprisingly quickly, it gets very difficult to read the rule. Recognise this? You need to write monolitic queries in query languages such as SQL or SPARQL. Prolog allows for composing rules from simpler ones. Use composition!

First of all, make sure your program consists of small predicates, where the body (the part after the :- operator) is typically a simple sequence (conjunction) of sub-queries (goals). In particular

Following the above guidelines (1) makes your program easier to read, (2) makes it easier to formulate new queries (code reuse) and (3) makes the program easier to debug.

My query still gives the wrong result (or false)

If the answer is wrong, you may consider tracing the execution of the query. To start debugging at a particular place in the source, set a breakpoint by clicking a line number in the gutter of the editor. To trace from the beginning, use the menu Solutions -> Debug (trace). Note that you can add a (conditional) call to trace/0 anywhere in the program to start debugging at that point.

In trace mode, you single-step through the execution of the program. The SWISH debugger only shows calls appearing in the current source files; details for called predicates are hidden. The following buttons are displayed below the port

Continue without debugging. Execution will stop on completion, reaching a breakpoint or error. Breakpoints may be set and cleared before using this button.

Advance a single step. If possible, go into the next rule.

Advance a single step. Step over the next rule.

Complete execution of this rule, stopping in the parent
This is Prolog's secret weapon: if you are at the end (Exit Fail or Exception), you can go back to the beginning and now use instead of to get more details.

Abort executing this query.

Note that the nice small predicates not only makes reading and reusing your code easy, but also facilitates hierarchical debugging by first stepping over () all details and as soon as a goal gives an unexpected result, retry () and step into () the rule.

My query raises an error

If your query contains an error, such as dividing by zero or adding a number to an atom, Prolog will raise an exception. SWISH tries to start the tracer as soon as possible. Unfortunately, Prolog optimization sometimes causes that it cannot stop right there or that much of the execution context is not available. In that case, run the query in debug mode as illustrated below.

?- debug, goal.

That should stop at the error location. If you wonder about the context, use the Step Out () button to get to a higher level and Retry () to follow the execution that leads to the error in detail ().