next up previous contents
Next: Manipulation of FDs as Up: Some Advice on FUF Previous: Expression of Negative Constraints

Control

The overall flow of control of FUF is quite complex, and the trace messages do not make it very easy to follow. Before going on and suffering through the zillions of lines produced by the trace system, try to understand analytically what could go wrong - recheck the syntax of your fd and grammar, and recheck the structure of your FD and the structure your grammar builds. Only when this fails should you try to read the trace messages to understand what went wrong on a particular input. You should proceed in the following order:

1.
Identify that there is a bug: do (trace-off) and (trace-bp). This will emit a dot every 10 backtracking points (10 is the default) and indicate how much effort FUF has invested on your input. For example, when dealing with SURGE, a clause that takes more than 300 backtracking points (30 dots on the screen) is either very complicated or contains a bug. When you think there is a bug, interrupt the unifier (generally use control-C).    

2.
Monitor the speed of appearance of the dots. In general, FUF operates in two modes: ``forward'' and ``backward''. Forward mode is when the grammar is traversed as expected, and every new feature falls into place. Backward mode is after the occurrence of the first unexpected failure. The unifier starts backtracking and tries every other branch in an unexpected manner. In general, these tried branches fail very quickly. So in backward mode, backtracking dots tend to be emitted much more quickly than in forward mode. When the dots start piling up, it's a good sign that FUF has entered backward mode, and that a bug has been found.

3.
Once you suspect there is a bug, identify the first unexpected failure. The first attempt to do that is to set (trace-on) and (trace-level 30). This will print the most obvious candidates. If this does not work, basically, you're in trouble, and finding the bug will take time (sorry! I'm in the middle of the implementation of a graphical debugger for FUF which should help you beyond this stage).      

4.
The next step is to gradually lower the trace-level until you get a good understanding of where in the grammar is the source of the bug - moving to values 20, 15, 12, 10, 5 and 0 (trying trace-level 0 on a full grammar without disabling most of the tracing flags is a sign of desperation).  

5.
Once the approximate location of the problem is identified in the grammar, enable only the relevant tracing flags (those defined in the grammar around the problematic spot). This is achieved by using the functions (trace-disable-all) (trace-enable-alt <name-of-suspected-alt>).    

6.
From then on, try to understand what's happening. I find it convenient to run FUF within an Emacs buffer and to use the editor to search through the trace messages printed by FUF.  

7.
If you enable all tracing flags and set trace-level to 0 and you still cannot find a tracing message identifying a failure (of the form ``FAIL in ...'') this can be due to 2 problems:
(a)
Either the failure is occurring in a region of the grammar which does not contain tracing flags. In this case, set (trace-alts) and check the messages ``fail in alt :anonymous''.    

(b)
Or the failure is due to a missing cat in the grammar. Often if you unify ((cat xxx)) with a grammar that has no branch for xxx, there is no failure message produced. Check your cats often.  

The main points you should be looking for when debugging are:

         


next up previous contents
Next: Manipulation of FDs as Up: Some Advice on FUF Previous: Expression of Negative Constraints
Michael Elhadad - elhadad@cs.bgu.ac.il