Next: Manipulation of FDs as
Up: Some Advice on FUF
Previous: Expression of Negative Constraints
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: Manipulation of FDs as
Up: Some Advice on FUF
Previous: Expression of Negative Constraints
Michael Elhadad - elhadad@cs.bgu.ac.il