Estimated hours taken: 40
Branches: main
This is the second part of a change to support term dependency analysis
in the declarative debugger. A `mark' command is implemented for the
term browser, which allows a particular subterm to be selected and
returned from the browser. The declarative debugger interprets this as
a suspicious subterm, and tries to find a child or sibling node from which
this subterm comes. This is used to determine the next question to be
asked of the oracle.
browser/browse.m:
Update the browser interface to allow for marked subterms being
returned from the browser.
Implement and document the mark command.
Rewrite run_command as a switch instead of a chain of if-then-elses.
This forces all unimplemented commands to be explicitly listed,
and gives better error checking.
browser/browser_info.m:
Add a maybe_mark field to the browser_info. It is initially `no',
but is updated when the mark command is given.
browser/declarative_analyser.m:
Select which child or sibling node to ask about next by searching
for the origin of the suspicious subterm. If the subterm has mode
`out' we act as if the oracle had answered no, and if the subterm
has mode `in' we act as if the oracle had answered yes. In future
we may not wish to presume this -- we do so now mainly to keep the
analysis algorithm simpler.
browser/declarative_debugger.m:
Add a functor for suspicious subterms to the decl_answer type.
browser/declarative_oracle.m:
Accommodate the changed answer type. The oracle does not try to
store information about suspicious subterms in the knowledge base,
because in principle this could lead to infinite loops (although
currently this wouldn't be a problem since we don't ever use the
information to move upward in the tree, so no cycle could be
formed).
browser/declarative_user.m:
Accommodate the changed answer type, and interpret marked terms
from the browser as suspicious subterms.
browser/parse.m:
Add the new command.
browser/program_representation.m:
Add a procedure to convert the browser's list(dir) to a term_path.
Change atomic_goal_rep_is_call/2 so it fails for special predicates,
which was originally intended.
trace/mercury_trace_browse.c:
Ignore the extra argument -- marked terms are not currently used in
the main debugger.
tests/debugger/declarative/Mmakefile:
tests/debugger/declarative/input_term_dep.*:
tests/debugger/declarative/output_term_dep.*:
tests/debugger/declarative/special_term_dep.*:
New test cases.
Estimated hours taken: 80
This is the first part of a change to support term dependency analysis
in the declarative debugger. A method is added to the mercury_edt
typeclass which finds the origin of a selected subterm in an EDT node,
somewhere in the body of the call or in the body of the parent. The
other parts of the change required before this can be useful are to
modify the search strategy (in browser/declarative_analyser.m) to make
use of the new information, and to modify the user interface to allow
a subterm to be selected. They will be committed as separate changes.
The typeclass method first traverses one or more contours, matching the
contour events up with goals in a procedure representation. This matching
process requires a left to right traversal, because we need to know which
disjunct/arm/branch was taken before we can match subgoals, and the
DISJ/SWTCH/THEN/ELSE events which tell us this information occur at the
left edge of the subgoals to which they apply. But we must always start
from the right hand side of the contour being traversed, so this means
that a right to left traversal is required before the matching can start.
Using the contour matched up with the atomic goals, we track the location
of a subterm by looking at which variables are bound, while scanning right
to left along the contour. Because this must happen after the matching,
this must be a separate right to left traversal than the earlier one.
Therefore the algorithm implemented here requires two passes over the
contours in order to find the origin of the selected subterm.
browser/declarative_execution.m:
Add a maybe(goal_rep) to call nodes in the annotated trace. This
is `no' if the relevant module was compiled below trace level `rep'.
trace/mercury_trace_declarative.c:
If the information is available, fill in the goal_rep when
constructing call nodes.
browser/declarative_analyser.m:
Add the new method to the mercury_edt typeclass.
browser/declarative_debugger.m:
Implement the new method. Update for the changed call nodes.
browser/program_representation.m:
Add a version of goal_paths to be used by the declarative debugger,
and a predicate to parse these from goal_path_strings. Add the
types arg_pos and term_path to represent a subterm of a call or exit.
browser/program_representation.m:
compiler/prog_rep.m:
No longer store conjunctions in reverse order in the goal_rep; we now
store them in the same order as in the HLDS.
Although we search conjunctions in reverse order, we need to match
them up with contour events before doing that. This can only be
done in the forwards direction, so it turns out that there is no
advantage in storing them in reverse order.
compiler/hlds_goal.m:
compiler/trace.m:
Add comments to the existing definitions of goal_path and
path_step_to_string.
Estimated hours taken: 2.5
Alter the `dd' command in mdb so that it does not assume that the answer
to the first question asked is `no'. The question is somewhat redundant,
since the only sensible answer is `no', but I find that it gives useful
feedback about the symptom that is being diagnosed, and it makes clearer
why the following questions are asked.
browser/declarative_analyser.m:
Start analysis with a list of suspects which contains only the
topmost node of the debugging tree.
browser/declarative_debugger.m:
If the answer to the first question is something other than `no',
then end the diagnosis and report that no bugs were found.
tests/debugger/declarative/*.{inp,exp,exp2}:
Update test cases to handle the extra question.
Estimated hours taken: 40
Implement the expanding of implicit subtrees in the declarative debugger.
When the maximum depth is reached by the front end, it now returns to
the back end a request for the missing subtree. If the back end receives
such a request, it restarts declarative debugging with a different
topmost call and a deeper depth bound.
The EDT instance needs to know when to request expansion, so CALL nodes
need a flag to indicate whether they were at the maximum depth. The
front end needs to be able to point out the bug and/or subtree to the
back end, so CALL, EXIT and FAIL nodes need to record the event number.
browser/declarative_execution.m:
- Store the event number in CALL, EXIT and FAIL nodes.
- Store a bool in CALL nodes which indicates whether the event
was at the maximum depth or not.
browser/declarative_debugger.m:
- Store the event number of the buggy event in the reported bug,
and pass this event number to the back end so it can go back
to that event.
- Add a case for expanding an implicit tree to the
diagnoser_response type, and handle this response properly.
- Export procedures to C that allow acces to the diagnoser_response
type.
- Accommodate the changes to the trace_node type.
browser/declarative_analyser.m:
- Store the list of previous prime suspects in the analyser state.
That way they don't have to be specially dealt with when
restarting analysis with an expanded subtree.
- When starting analysis, assume the top node is wrong; this
is not an unreasonable assumption, and the strategy works better
for the case when a subtree is expanded.
browser/declarative_user.m:
- Accommodate changes to the reported bug.
trace/mercury_trace_declarative.c:
- Change the depth step size to a reasonable number, now that
it works. This also has the effect of testing the change,
since some test cases go deeper than the new limit.
- Filter events outside the topmost call. Rather than keep
track of the minimum depth, we record the topmost call sequence
number and use a global to keep track of whether we have entered
or left this procedure.
- Factor out code in the existing mechanism for starting
declarative debugging, so that it can be used to re-start
debugging as well.
- Accommodate the changes to the trace_node type.
- Output error messages if declarative debugging fails to start
properly.
- Handle the reponse from the diagnoser, by jumping to the buggy
event (if a bug is found) or re-executing to expand a subtree
(if one is requested).
- Add a new checkpoint for events which are filtered out of
the annotated trace.
trace/mercury_trace_internal.c:
- Don't report error messages when declarative debugging fails
to start. Errors are now reported by the declarative debugger
before returning.
tests/debugger/declarative/*.inp:
tests/debugger/declarative/*.exp:
tests/debugger/declarative/*.exp2:
- Update to reflect the removed questions.
tests/debugger/declarative/Mmakefile:
tests/debugger/declarative/filter.m:
tests/debugger/declarative/filter.inp:
tests/debugger/declarative/filter.exp:
- New test case to cover the code which filters events which
are outside the topmost call.
Estimated hours taken: 10
Represent bugs directly rather than with edt nodes. This makes the
interface to the analyser more consistent: bugs are now handled
in much the same way as questions.
browser/declarative_analyser.m:
- In the mercury_edt/2 typeclass, change edt_root/3 to
edt_root_question/3 and add the method edt_root_e_bug/3.
- Add the type prime_suspect/1 which keeps track of the
evidence (oracle answers) which implicates a particular
edt node.
- Use the new bug representation.
browser/declarative_debugger.m:
browser/declarative_oracle.m:
- Move oracle_confirmation to declarative_debugger.m, and
rename it decl_confirmation.
browser/declarative_debugger.m:
- Change decl_bug/1 to decl_bug/0. Instead of a bug being
represented by an edt node, decl_bug now represents
directly the different sorts of bugs possible.
- Add an implementation for the new mercury_edt method.
browser/declarative_oracle.m:
browser/declarative_user.m:
- Update the confirmation to use the new types.
tests/debugger/declarative/*.{exp,exp2}:
- Update test results.
Estimated hours taken: 1
Make all the modules in the browser library sub-modules of
module `mdb', to avoid link errors when users use module names
such as `parse'.
browser/Mmakefile:
browser/browser_library.m:
browser/mdb.m:
Rename browser_library.m to mdb.m.
Change `:- import_module' declarations to
`:- include_module' declarations.
browser/Mmakefile:
Remove the special case rule for `mer_browser.init' --
it doesn't work when the file names are not the same
as the module name. Instead, the default rule for `mdb.init'
is used and the output is copied to `mer_browser.init'.
browser/.cvsignore:
Rename header files, etc.
browser/*.m:
Add a `mdb__' prefix to the names of modules in the browser library
in `:- module' and `:- import_module' declarations.
trace/*.c:
Rename the header files for the browser library in
`#include' statements.
tests/hard_coded/Mmakefile:
tests/hard_coded/parse.m:
tests/hard_coded/parse.exp:
Test case.
Estimated hours taken: 120
Implement the new architecture for the front end of the
declarative debugger. Disable declarative debugging if conservative
GC is not being used since this change relies on it. The benefits
of declarative debugging in non-GC grades are not worth the extra
maintenance required to support it, since even small examples require
a large amount of memory.
browser/declarative_analyser.m:
New module which handles the analysis of EDTs, which was
previously done in browser/declarative_debugger.m.
browser/declarative_debugger.m:
- Change the interface according to the new design.
- Export types of the form decl_*, rather than edt_*.
- Move the EDT analysis to the new module.
- Handle the interaction between the analyser and the oracle.
- Don't interact directly with the user, but go via the oracle.
- New diagnoser state type.
- Update the EDT instance to conform to the other changes.
browser/declarative_oracle.m:
- Replace oracle_answer type with oracle_response.
- Allow the oracle to work with a queue of questions rather
than one at a time.
- Add new predicates to manipulate the knowledge base.
browser/declarative_user.m:
- Export the user_state type.
- Handle some user commands in this module.
- Handle questions properly (apart from printing atoms).
browser/browser_library.m:
Add the new module.
trace/mercury_trace_declarative.c:
- Initialise the front end state just once per session.
- Make the step size much larger, since implicit subtrees
are not fully supported yet.
- Correct the types in a format specifier.
trace/mercury_trace_declarative.c:
trace/mercury_trace_internal.c:
trace/mercury_trace_internal.h:
- Disable declarative debugging unless conservative GC is used.