[m-rev.] For review: Allow mdprof tools to use program representation information

Paul Bone pbone at csse.unimelb.edu.au
Wed Aug 27 22:41:40 AEST 2008


For review by Zoltan.
If you're unable to review this by Friday morning, I will commit it then
for post review, since I'll be working on this next on Friday.  Thanks.

Estimated Hours Taken: 10
Branches: main

Modify the deep profiling tools, in particular mdprof_cgi, to make use of
program representation files, and begin implementing the procrep coverage
report.

The mdprof coverage report is incomplete, however it is convenient to post
this for review now.  Currently it can display a pretty-printed procrep
structure without coverage annotations.

mdbcomp/program_representation.m:
	Modified program representation data structures to allow goals to be
	annotated with another type.

deep_profiler/query.m:
	Create new deep profiling command, to display a coverage-annotated
	procedure representation.
	Support use of program representation information by new-style report
	generating code.
	Centralised command parsing to code within this module.
	Created constants for strings shared between cmd_to_string and
	string_to_maybe_cmd.

deep_profiler/report.m:
	Add new report, report_procrep_coverage_dump.
	Modified the proc_static dump report to include the number of coverage
	points in the proc_static.

deep_profiler/create_report.m:
	create_report now accepts an optional program representation structure,
	making it possible for report generation code to use the program
	representation structure.
	Support the new procrep coverage report, which is incomplete.
	Modify the proc static dump report, to display the number of coverage
	points within a proc_static structure.

deep_profiler/display.m:
	Introduce display_verbatim, a new display element that is able to display
	verbatim text, such as source code.

deep_profiler/display_report.m:
	Add support for displaying the new mdbcomp_coverage report.
	Modify the proc static dump display to show the number of coverage points,
	conforming to a change in report.m

deep_profiler/html_format.m:
	Support the display_verbatim element.
	Use query_to_string from query.m to create the query part of a URL.
	Conform to changes in deep_profiler/query.m

deep_profiler/startup.m:	
	Modify read_and_startup to also read the program representation data if
	available.

deep_profiler/mdprof_cgi.m:
	Use string_to_maybe_query from query.m to parse a query string.
	Renamed some variables.
	Modified command-loop to pass program representation between commands.

deep_profiler/program_representation_utils.m:
	A new module to hold utilities from working with program representation
	data.
	Pretty printing code from mdprof_procrep has been moved here and modified
	to output a cord of strings rather than write to standard output.

deep_profiler/mdprof_feedback.m:
deep_profiler/mdprof_test.m:
	Conform to changes in query.m

deep_profiler/mdprof_procrep.m:
	Move proc_rep pretty-printing code to program_representation_utils.m

browser/declarative_tree.m:
	Conform to changes in mdbcomp/program_representation.m


Index: browser/declarative_tree.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/browser/declarative_tree.m,v
retrieving revision 1.57
diff -u -p -r1.57 declarative_tree.m
--- browser/declarative_tree.m	13 Aug 2008 07:38:08 -0000	1.57
+++ browser/declarative_tree.m	27 Aug 2008 12:39:17 -0000
@@ -1237,7 +1237,7 @@ next_goal_generates_internal_event([goal
 
 match_goal_to_contour_event(Store, Goal, Path, GoalPaths, Contour, MaybeEnd,
         ArgNum, TotalArgs, HeadVars, AllTraced, Primitives0) = MaybePrims :-
-    Goal = goal_rep(GoalExpr, _),
+    Goal = goal_rep(GoalExpr, _, _),
     (
         GoalExpr = conj_rep(Conjs),
         add_paths_to_conjuncts(Conjs, Path, 1, ConjPaths),
Index: deep_profiler/create_report.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/create_report.m,v
retrieving revision 1.7
diff -u -p -r1.7 create_report.m
--- deep_profiler/create_report.m	25 Aug 2008 07:19:39 -0000	1.7
+++ deep_profiler/create_report.m	27 Aug 2008 12:39:17 -0000
@@ -16,13 +16,17 @@
 :- module create_report.
 :- interface.
 
-:- import_module report.
+:- import_module maybe.
+:- import_module mdbcomp.
+:- import_module mdbcomp.program_representation.
 :- import_module profile.
 :- import_module query.
+:- import_module report.
 
 %-----------------------------------------------------------------------------%
 
-:- pred create_report(cmd::in, deep::in, deep_report::out) is det.
+:- pred create_report(cmd::in, deep::in, maybe_error(prog_rep)::in, 
+    deep_report::out) is det.
 
 %-----------------------------------------------------------------------------%
 
@@ -31,6 +35,7 @@
 :- import_module apply_exclusion.
 :- import_module measurement_units.
 :- import_module measurements.
+:- import_module program_representation_utils.
 :- import_module top_procs.
 
 :- import_module array.
@@ -48,7 +53,7 @@
 
 %-----------------------------------------------------------------------------%
 
-create_report(Cmd, Deep, Report) :-
+create_report(Cmd, Deep, MaybeProgRep, Report) :-
     (
         Cmd = deep_cmd_quit,
         Msg = string.format("Shutting down deep profile server for %s.",
@@ -85,6 +90,18 @@ create_report(Cmd, Deep, Report) :-
             MaybeTopProcsReport),
         Report = report_top_procs(MaybeTopProcsReport)
     ;
+        Cmd = deep_cmd_procrep_coverage(PSPtr),
+        (   
+            MaybeProgRep = ok(ProgRep),
+            generate_procrep_coverage_dump_report(Deep, ProgRep, PSPtr,
+                MaybeProcrepCoverageReport)
+        ;
+            MaybeProgRep = error(Error),
+            MaybeProcrepCoverageReport = 
+                error("No procedure representation information: " ++ Error) 
+        ),
+        Report = report_procrep_coverage_dump(MaybeProcrepCoverageReport)
+    ;
         Cmd = deep_cmd_proc(PSPtr),
         create_proc_report(Deep, PSPtr, MaybeProcReport),
         Report = report_proc(MaybeProcReport)
@@ -511,9 +528,31 @@ create_proc_caller_cliques(Deep, CalleeP
     own_and_inherit_to_perf_row_data(Deep, CliqueDesc, Own, Desc,
         PerfRowData).
 
+%----------------------------------------------------------------------------%
+%
+% Code to generate the coverage annotated procedure representation report.
+%
+
+:- pred generate_procrep_coverage_dump_report(deep::in, prog_rep::in,
+    proc_static_ptr::in, maybe_error(procrep_coverage_info)::out) is det.
+
+generate_procrep_coverage_dump_report(Deep, ProgRep, PSPtr, MaybeReport) :-
+    ( valid_proc_static_ptr(Deep, PSPtr) ->
+        deep_lookup_proc_statics(Deep, PSPtr, PS),
+        ProcLabel = PS ^ ps_id,
+        ( progrep_search_proc(ProgRep, ProcLabel, ProcRep) ->
+            MaybeReport = ok(ProcRep)
+        ;
+            MaybeReport = 
+                error("Program Representation doesn't contain procedure")
+        )
+    ;
+        MaybeReport = error("Invalid proc_static index")
+    ).
+
 %-----------------------------------------------------------------------------%
 %
-% Code to build the dump reports.
+% Code to build the other dump reports.
 %
 
 :- pred create_proc_static_dump_report(deep::in, proc_static_ptr::in,
@@ -524,11 +563,14 @@ create_proc_static_dump_report(Deep, PSP
         deep_lookup_proc_statics(Deep, PSPtr, PS),
         % Should we dump some other fields?
         PS = proc_static(_ProcId, _DeclModule, RefinedName, RawName,
-            FileName, LineNumber, _InInterface, CallSites, _CoveragePoints,
+            FileName, LineNumber, _InInterface, CallSites, CoveragePoints,
             _IsZeroed),
-        array.max(CallSites, NumCallSites),
+        array.max(CallSites, MaxCallSiteIdx),
+        NumCallSites = MaxCallSiteIdx + 1,
+        array.max(CoveragePoints, MaxCoveragePointIdx),
+        NumCoveragePoints = MaxCoveragePointIdx + 1,
         ProcStaticDumpInfo = proc_static_dump_info(PSPtr, RawName, RefinedName,
-            FileName, LineNumber, NumCallSites),
+            FileName, LineNumber, NumCallSites, NumCoveragePoints),
         MaybeProcStaticDumpInfo = ok(ProcStaticDumpInfo)
     ;
         MaybeProcStaticDumpInfo = error("invalid proc_static index")
Index: deep_profiler/display.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/display.m,v
retrieving revision 1.8
diff -u -p -r1.8 display.m
--- deep_profiler/display.m	25 Aug 2008 07:19:39 -0000	1.8
+++ deep_profiler/display.m	27 Aug 2008 12:39:17 -0000
@@ -63,6 +63,11 @@
             )
     ;       display_table(
                 table
+            )
+    ;       display_verbatim(
+                % A string to be displayed verbatim.  It should be displayed
+                % with a fixed with font and line breaks should be honoured.
+                string
             ).
 
 %-----------------------------------------------------------------------------%
Index: deep_profiler/display_report.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/display_report.m,v
retrieving revision 1.10
diff -u -p -r1.10 display_report.m
--- deep_profiler/display_report.m	25 Aug 2008 07:19:39 -0000	1.10
+++ deep_profiler/display_report.m	27 Aug 2008 12:39:17 -0000
@@ -35,7 +35,10 @@
 
 :- implementation.
 
+:- import_module mdbcomp.
+:- import_module mdbcomp.program_representation.
 :- import_module measurement_units.
+:- import_module program_representation_utils.
 
 :- import_module array.
 :- import_module assoc_list.
@@ -112,6 +115,16 @@ report_to_display(Deep, Prefs, Report) =
             Display = display(no, [display_heading(Msg)])
         )
     ;
+        Report = report_procrep_coverage_dump(MaybeProcrepCoverageInfo),
+        (
+            MaybeProcrepCoverageInfo = ok(ProcrepCoverageInfo),
+            display_report_procrep_coverage_info(ProcrepCoverageInfo,
+                Display)
+        ;
+            MaybeProcrepCoverageInfo = error(Msg),
+            Display = display(no, [display_text(Msg)])
+        )
+    ;
         Report = report_proc_static_dump(MaybeProcStaticDumpInfo),
         (
             MaybeProcStaticDumpInfo = ok(ProcStaticDumpInfo),
@@ -974,6 +987,21 @@ make_proc_callers_link(Prefs, Label, PSP
     Cmd = deep_cmd_proc_callers(PSPtr, CallerGroups, BunchNum, ContourExcl),
     Link = deep_link(Cmd, yes(Prefs), Label, link_class_control),
     Item = display_link(Link).
+            
+%-----------------------------------------------------------------------------%
+%
+% Code to display procrep_coverage dumps 
+%
+
+:- pred display_report_procrep_coverage_info(procrep_coverage_info::in,
+    display::out) is det.
+
+display_report_procrep_coverage_info(ProcrepCoverageInfo, Display) :-
+    Title = "Procrep coverage dump",
+    print_proc_to_strings(ProcrepCoverageInfo, ProcRepStrings),
+    string.append_list(list(ProcRepStrings), ProcRepString),
+    Display = display(yes(Title), [display_verbatim(ProcRepString)]).
+    
 
 %-----------------------------------------------------------------------------%
 %
@@ -987,16 +1015,17 @@ make_proc_callers_link(Prefs, Label, PSP
 
 display_report_proc_static_dump(ProcStaticDumpInfo, Display) :-
     ProcStaticDumpInfo = proc_static_dump_info(PSPtr, RawName, RefinedName,
-        FileName, LineNumber, NumCallSites),
+        FileName, LineNumber, NumCallSites, NumCoveragePoints),
     PSPtr = proc_static_ptr(PSI),
     string.format("Dump of proc_static %d", [i(PSI)], Title),
 
     Values =
-        [("Raw name:"               - td_s(RawName)),
-        ("Refined name:"            - td_s(RefinedName)),
-        ("File name:"               - td_s(FileName)),
-        ("Line number:"             - td_i(LineNumber)),
-        ("Number of call sites:"    - td_i(NumCallSites))],
+        [("Raw name:"                   - td_s(RawName)),
+        ("Refined name:"                - td_s(RefinedName)),
+        ("File name:"                   - td_s(FileName)),
+        ("Line number:"                 - td_i(LineNumber)),
+        ("Number of call sites:"        - td_i(NumCallSites)),
+        ("Number of coverage points:"   - td_i(NumCoveragePoints))],
 
     Rows = list.map(make_labelled_table_row, Values),
     Table = table(table_class_do_not_box, 2, no, Rows),
Index: deep_profiler/html_format.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/html_format.m,v
retrieving revision 1.30
diff -u -p -r1.30 html_format.m
--- deep_profiler/html_format.m	25 Aug 2008 07:19:39 -0000	1.30
+++ deep_profiler/html_format.m	27 Aug 2008 12:39:17 -0000
@@ -340,6 +340,10 @@ item_to_html(StartTag, EndTag, FormatInf
         ItemsHTML = wrap_tags(OutsideStartTag, OutsideEndTag, InnerItemsHTML),
         HTML = wrap_tags(StartTag, EndTag,
             TitleHTML ++ PostTitleHTML ++ ItemsHTML)
+    ;
+        Item = display_verbatim(Text),
+        HTML = wrap_tags(StartTag, EndTag, 
+            wrap_tags("<pre>", "</pre>", str_to_html(Text))) 
     ).
 
 %-----------------------------------------------------------------------------%
@@ -905,19 +909,10 @@ init_format_info(Deep, Prefs) = FormatIn
 deep_cmd_to_url(FormatInfo, Cmd, MaybePrefs, URL) :-
     HostAndPort = FormatInfo ^ fi_server_name_port,
     Script = FormatInfo ^ fi_script_name,
-    DataFile = FormatInfo ^ fi_deep_file,
-    CmdStr = cmd_to_string(Cmd),
-    (
-        MaybePrefs = no,
-        string.format("http://%s%s?%s&%s",
-            [s(HostAndPort), s(Script), s(CmdStr), s(DataFile)], URL)
-    ;
-        MaybePrefs = yes(Prefs),
-        PrefStr = preferences_to_string(Prefs),
-        string.format("http://%s%s?%s&%s&%s",
-            [s(HostAndPort), s(Script), s(CmdStr), s(PrefStr), s(DataFile)],
-            URL)
-    ).
+    DeepFileName = FormatInfo ^ fi_deep_file,
+    DeepQuery = deep_query(yes(Cmd), DeepFileName, MaybePrefs),
+    string.format("http://%s%s?%s",
+        [s(HostAndPort), s(Script), s(query_to_string(DeepQuery))], URL).
 
 %-----------------------------------------------------------------------------%
 %
@@ -1290,6 +1285,8 @@ command_relevant_toggles(deep_cmd_module
     toggle_time_format, toggle_inactive_procs].
 command_relevant_toggles(deep_cmd_top_procs(_, _, _, _)) =
     [toggle_fields, toggle_box, toggle_colour, toggle_time_format].
+command_relevant_toggles(deep_cmd_procrep_coverage(_)) = 
+    [].
 command_relevant_toggles(deep_cmd_dump_proc_static(_)) = [].
 command_relevant_toggles(deep_cmd_dump_proc_dynamic(_)) = [].
 command_relevant_toggles(deep_cmd_dump_call_site_static(_)) = [].
@@ -3181,21 +3178,15 @@ special_html_char_or_break(':', ":" ++ z
 % zero_width_space = "​".
 zero_width_space = "<wbr />".
 
-%-----------------------------------------------------------------------------%
-
 :- func machine_datafile_cmd_pref_to_url(string, string, string, cmd,
     preferences) = string.
 
-machine_datafile_cmd_pref_to_url(Machine, ScriptName, DataFileName, Cmd,
+machine_datafile_cmd_pref_to_url(Machine, ScriptName, DeepFileName, Cmd,
         Preferences) =
     "http://" ++
     Machine ++
     ScriptName ++ "?" ++
-    cmd_to_string(Cmd) ++
-    string.char_to_string(query_separator_char) ++
-    preferences_to_string(Preferences) ++
-    string.char_to_string(query_separator_char) ++
-    DataFileName.
+    query_to_string(deep_query(yes(Cmd), DeepFileName, yes(Preferences))). 
 
 %-----------------------------------------------------------------------------%
 :- end_module html_format.
Index: deep_profiler/mdprof_cgi.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/mdprof_cgi.m,v
retrieving revision 1.25
diff -u -p -r1.25 mdprof_cgi.m
--- deep_profiler/mdprof_cgi.m	25 Aug 2008 07:19:39 -0000	1.25
+++ deep_profiler/mdprof_cgi.m	27 Aug 2008 12:39:17 -0000
@@ -29,11 +29,13 @@
 
 :- implementation.
 
-:- import_module profile.
+:- import_module conf.
 :- import_module interface.
-:- import_module startup.
+:- import_module mdbcomp.
+:- import_module mdbcomp.program_representation.
+:- import_module profile.
 :- import_module query.
-:- import_module conf.
+:- import_module startup.
 :- import_module timeout.
 :- import_module util.
 
@@ -69,19 +71,22 @@ main(!IO) :-
             MaybeOptions = error(_Msg),
             error("mdprof_cgi: error parsing empty command line")
         ),
-        split(QueryString0, query_separator_char, Pieces),
-        ( Pieces = [CmdStr, PrefStr, FileName] ->
-            Cmd = string_to_cmd(CmdStr, deep_cmd_menu),
-            process_query(Cmd, yes(PrefStr), FileName, Options, !IO)
-        ; Pieces = [CmdStr, FileName] ->
-            Cmd = string_to_cmd(CmdStr, deep_cmd_menu),
-            process_query(Cmd, no, FileName, Options, !IO)
-        ; Pieces = [FileName] ->
-            process_query(deep_cmd_menu, no, FileName, Options, !IO)
+        string_to_maybe_query(QueryString0) = MaybeDeepQuery,
+        (
+            MaybeDeepQuery = yes(DeepQuery),
+            DeepQuery = deep_query(MaybeCmd, DeepFileName, MaybePrefs),
+            (
+                MaybeCmd = yes(Cmd)
+            ;
+                MaybeCmd = no,
+                Cmd = default_command
+            ),
+            process_query(Cmd, DeepFileName, MaybePrefs, Options, !IO)
         ;
+            MaybeDeepQuery = no,
             io.set_exit_status(1, !IO),
             % Give the simplest URL in the error message.
-            io.write_string("Bad URL; expected filename\n", !IO)
+            io.write_string("Bad URL; expected filename \n", !IO)
         )
     ;
         MaybeQueryString = no,
@@ -156,18 +161,22 @@ decode_input_lines(Decode, DecodeCmd, De
         ;
             Decode = yes,
             io.write_string("considering as query string:\n", !IO),
-            split(LineStr, query_separator_char, Pieces),
-            ( Pieces = [CmdStr, PrefStr, FileName] ->
-                decode_cmd_str(CmdStr, !IO),
-                decode_pref_str(PrefStr, !IO),
-                decode_filename(FileName, !IO)
-            ; Pieces = [CmdStr, FileName] ->
-                decode_cmd_str(CmdStr, !IO),
-                decode_filename(FileName, !IO)
-            ; Pieces = [FileName] ->
-                decode_filename(FileName, !IO)
+            string_to_maybe_query(LineStr) = MaybeQuery,
+            (
+                MaybeQuery = yes(deep_query(MaybeCmd, DeepFileName,
+                    MaybePrefs)),
+                io.write_string("Maybe Command:\n", !IO),
+                io.write(MaybeCmd, !IO),
+                io.nl(!IO),
+                io.format("Deep File Name: %s\n", [s(DeepFileName)], !IO),
+                % The preferences may fail to parse, in this case no
+                % preferences are assumed.
+                io.write_string("Maybe Preferences:\n", !IO),
+                io.write(MaybePrefs, !IO),
+                io.nl(!IO)
             ;
-                io.write_string("invalid query string: " ++
+                MaybeQuery = no,
+                io.write_string("invalid query string: " ++ 
                     "cannot split into components\n", !IO)
             )
         ),
@@ -176,14 +185,30 @@ decode_input_lines(Decode, DecodeCmd, De
         ;
             DecodeCmd = yes,
             io.write_string("considering as cmd string:\n", !IO),
-            decode_cmd_str(LineStr, !IO)
+            MaybeCmd1 = string_to_maybe_cmd(LineStr),
+            (
+                MaybeCmd1 = no,
+                io.format("invalid command string %s\n", [s(LineStr)], !IO)
+            ;
+                MaybeCmd1 = yes(Cmd),
+                io.write(Cmd, !IO),
+                io.nl(!IO)
+            )
         ),
         (
             DecodePrefs = no
         ;
             DecodePrefs = yes,
             io.write_string("considering as preference string:\n", !IO),
-            decode_cmd_str(LineStr, !IO)
+            MaybePref = string_to_maybe_pref(LineStr),
+            (
+                MaybePref = no,
+                io.format("invalid preferences string %s\n", [s(LineStr)], !IO)
+            ;
+                MaybePref = yes(Pref),
+                io.write(Pref, !IO),
+                io.nl(!IO)
+            )
         ),
         decode_input_lines(Decode, DecodeCmd, DecodePrefs, !IO)
     ;
@@ -194,37 +219,6 @@ decode_input_lines(Decode, DecodeCmd, De
         LineResult = eof
     ).
 
-:- pred decode_cmd_str(string::in, io::di, io::uo) is det.
-
-decode_cmd_str(CmdStr, !IO) :-
-    MaybeCmd = string_to_maybe_cmd(CmdStr),
-    (
-        MaybeCmd = no,
-        io.format("invalid command string %s\n", [s(CmdStr)], !IO)
-    ;
-        MaybeCmd = yes(Cmd),
-        io.write(Cmd, !IO),
-        io.nl(!IO)
-    ).
-
-:- pred decode_pref_str(string::in, io::di, io::uo) is det.
-
-decode_pref_str(PrefStr, !IO) :-
-    MaybePref = string_to_maybe_pref(PrefStr),
-    (
-        MaybePref = no,
-        io.format("invalid preferences string %s\n", [s(PrefStr)], !IO)
-    ;
-        MaybePref = yes(Pref),
-        io.write(Pref, !IO),
-        io.nl(!IO)
-    ).
-
-:- pred decode_filename(string::in, io::di, io::uo) is det.
-
-decode_filename(FileName, !IO) :-
-    io.format("data file name: %s\n", [s(FileName)], !IO).
-
 :- func mdprof_cgi_progname = string.
 
 mdprof_cgi_progname = "mdprof_cgi".
@@ -256,11 +250,11 @@ write_help_message(ProgName, !IO) :-
     io::di, io::uo) is cc_multi.
 
 process_args(ProgName, Args, Options, !IO) :-
-    ( Args = [FileName] ->
+    ( Args = [DeepFileName] ->
         % Although this mode of usage is not intended for production use,
         % allowing the filename and a limited range of commands to be supplied
         % on the command line makes debugging very much easier.
-        process_query(default_cmd(Options), no, FileName, Options, !IO)
+        process_query(default_cmd(Options), DeepFileName, no, Options, !IO)
     ;
         io.set_exit_status(1, !IO),
         write_help_message(ProgName, !IO)
@@ -290,17 +284,10 @@ html_header_text = "Content-type: text/h
 
 %-----------------------------------------------------------------------------%
 
-:- pred process_query(cmd::in, maybe(string)::in, string::in,
+:- pred process_query(cmd::in, string::in, maybe(preferences)::in,
     option_table::in, io::di, io::uo) is cc_multi.
 
-process_query(Cmd, MaybePrefStr, DataFileName0, Options0, !IO) :-
-    (
-        MaybePrefStr = yes(PrefStr),
-        MaybePref = string_to_maybe_pref(PrefStr)
-    ;
-        MaybePrefStr = no,
-        MaybePref = no
-    ),
+process_query(Cmd, DeepFileName0, MaybePref, Options0, !IO) :-
     (
         MaybePref = yes(Pref),
         PrefInd = given_pref(Pref)
@@ -308,17 +295,17 @@ process_query(Cmd, MaybePrefStr, DataFil
         MaybePref = no,
         PrefInd = default_pref
     ),
-    ( string.remove_suffix(DataFileName0, ".localhost", DataFileNamePrime) ->
-        DataFileName = DataFileNamePrime,
+    ( string.remove_suffix(DeepFileName0, ".localhost", DeepFileNamePrime) ->
+        DeepFileName = DeepFileNamePrime,
         map.det_update(Options0, localhost, bool(yes), Options)
     ;
-        DataFileName = DataFileName0,
+        DeepFileName = DeepFileName0,
         Options = Options0
     ),
-    ToServerPipe = to_server_pipe_name(DataFileName),
-    FromServerPipe = from_server_pipe_name(DataFileName),
-    StartupFile = server_startup_name(DataFileName),
-    MutexFile = mutex_file_name(DataFileName),
+    ToServerPipe = to_server_pipe_name(DeepFileName),
+    FromServerPipe = from_server_pipe_name(DeepFileName),
+    StartupFile = server_startup_name(DeepFileName),
+    MutexFile = mutex_file_name(DeepFileName),
     lookup_bool_option(Options, debug, Debug),
     WantFile = want_file_name,
     make_want_file(WantFile, !IO),
@@ -333,9 +320,8 @@ process_query(Cmd, MaybePrefStr, DataFil
     ),
     check_for_existing_fifos(ToServerPipe, FromServerPipe, FifoCount, !IO),
     ( FifoCount = 0 ->
-        handle_query_from_new_server(Cmd, PrefInd, DataFileName,
-            ToServerPipe, FromServerPipe, StartupFile, MutexFile, WantFile,
-            Options, !IO)
+        handle_query_from_new_server(Cmd, PrefInd, DeepFileName, ToServerPipe,
+            FromServerPipe, StartupFile, MutexFile, WantFile, Options, !IO)
     ; FifoCount = 2 ->
         handle_query_from_existing_server(Cmd, PrefInd,
             ToServerPipe, FromServerPipe, MutexFile, WantFile, Options, !IO)
@@ -346,6 +332,11 @@ process_query(Cmd, MaybePrefStr, DataFil
         io.write_string("mdprof internal error: bad fifo count", !IO)
     ).
 
+    % This type is used to pass queries between the two servers.
+    %
+:- type cmd_pref
+    --->    cmd_pref(cmd, preferences_indication).
+
     % Handle the given query using the existing server. Delete the mutex and
     % want files when we get out of the critical region.
     %
@@ -403,9 +394,8 @@ handle_query_from_existing_server(Cmd, P
     string::in, string::in, string::in, string::in, string::in, string::in,
     option_table::in, io::di, io::uo) is cc_multi.
 
-handle_query_from_new_server(Cmd, PrefInd, FileName,
-        ToServerPipe, FromServerPipe, StartupFile, MutexFile, WantFile,
-        Options, !IO) :-
+handle_query_from_new_server(Cmd, PrefInd, FileName, ToServerPipe,
+        FromServerPipe, StartupFile, MutexFile, WantFile, Options, !IO) :-
     lookup_bool_option(Options, localhost, LocalHost),
     (
         LocalHost = no,
@@ -434,12 +424,18 @@ handle_query_from_new_server(Cmd, PrefIn
         RecordStartup = no,
         MaybeStartupStream = no
     ),
-    read_and_startup(Machine, ScriptName, [FileName], Canonical,
+    read_and_startup(Machine, ScriptName, FileName, Canonical,
         MaybeStartupStream, [], Res, !IO),
     (
-        Res = ok(Deep),
+        (
+            Res = deep_and_progrep(Deep, Progrep),
+            MaybeProgrep = ok(Progrep)
+        ;
+            Res = deep_and_error(Deep, Error),
+            MaybeProgrep = error(Error)
+        ),
         Pref = solidify_preference(Deep, PrefInd),
-        try_exec(Cmd, Pref, Deep, HTML, !IO),
+        try_exec(Cmd, Pref, Deep, MaybeProgrep, HTML, !IO),
         (
             MaybeStartupStream = yes(StartupStream1),
             io.format(StartupStream1, "query 0 output:\n%s\n", [s(HTML)], !IO),
@@ -463,7 +459,8 @@ handle_query_from_new_server(Cmd, PrefIn
                 io.write_string(HTML, !IO),
                 io.flush_output(!IO),
                 start_server(Options, ToServerPipe, FromServerPipe,
-                    MaybeStartupStream, MutexFile, WantFile, Deep, !IO)
+                    MaybeStartupStream, MutexFile, WantFile, Deep, MaybeProgrep,
+                    !IO)
             ;
                 Success = no,
                 release_lock(Debug, MutexFile, !IO),
@@ -477,18 +474,19 @@ handle_query_from_new_server(Cmd, PrefIn
         release_lock(Debug, MutexFile, !IO),
         remove_want_file(WantFile, !IO),
         io.set_exit_status(1, !IO),
-        io.format("error reading %s: %s\n", [s(FileName), s(Error)], !IO)
+        io.format("%s\n", [s(Error)], !IO)
     ).
 
     % Become the new server. Delete the mutex and want files when we get out
     % of the critical region.
     %
 :- pred start_server(option_table::in, string::in, string::in,
-    maybe(io.output_stream)::in, string::in, string::in, deep::in,
+    maybe(io.output_stream)::in, string::in, string::in, 
+    deep::in, maybe_error(prog_rep)::in,
     io::di, io::uo) is cc_multi.
 
 start_server(Options, ToServerPipe, FromServerPipe, MaybeStartupStream,
-        MutexFile, WantFile, Deep, !IO) :-
+        MutexFile, WantFile, Deep, MaybeProgrep, !IO) :-
     lookup_bool_option(Options, detach_process, DetachProcess),
     lookup_bool_option(Options, record_loop, RecordLoop),
     lookup_bool_option(Options, debug, Debug),
@@ -545,7 +543,7 @@ start_server(Options, ToServerPipe, From
         lookup_int_option(Options, timeout, TimeOut),
         lookup_bool_option(Options, canonical_clique, Canonical),
         server_loop(ToServerPipe, FromServerPipe, TimeOut,
-            MaybeDebugStream, Debug, Canonical, 0, Deep, !IO)
+            MaybeDebugStream, Debug, Canonical, 0, Deep, MaybeProgrep, !IO)
     ;
         DetachRes = in_parent,
         % We are in the parent after we spawned the child. We cause the process
@@ -570,11 +568,12 @@ start_server(Options, ToServerPipe, From
     ).
 
 :- pred server_loop(string::in, string::in, int::in,
-    maybe(io.output_stream)::in, bool::in, bool::in, int::in, deep::in,
+    maybe(io.output_stream)::in, bool::in, bool::in, int::in, 
+    deep::in, maybe_error(prog_rep)::in,
     io::di, io::uo) is cc_multi.
 
 server_loop(ToServerPipe, FromServerPipe, TimeOut0, MaybeStartupStream,
-        Debug, Canonical, QueryNum0, Deep0, !IO) :-
+        Debug, Canonical, QueryNum0, Deep0, MaybeProgrep0, !IO) :-
     setup_timeout(TimeOut0, !IO),
     QueryNum = QueryNum0 + 1,
     recv_term(ToServerPipe, Debug, CmdPref0, !IO),
@@ -592,20 +591,28 @@ server_loop(ToServerPipe, FromServerPipe
 
     ( Cmd0 = deep_cmd_restart ->
         read_and_startup(Deep0 ^ server_name_port, Deep0 ^ script_name,
-            [Deep0 ^ data_file_name], Canonical, MaybeStartupStream, [],
-            MaybeDeep, !IO),
+            Deep0 ^ data_file_name, Canonical, MaybeStartupStream, [],
+            MaybeDeepAndProgrep, !IO),
         (
-            MaybeDeep = ok(Deep),
+            (
+                MaybeDeepAndProgrep = deep_and_progrep(Deep, Progrep),
+                MaybeProgrep = ok(Progrep)
+            ;
+                MaybeDeepAndProgrep = deep_and_error(Deep, Error),
+                MaybeProgrep = error(Error) 
+            ),
             MaybeMsg = no,
             Cmd = deep_cmd_menu
         ;
-            MaybeDeep = error(ErrorMsg),
+            MaybeDeepAndProgrep = error(ErrorMsg),
             MaybeMsg = yes(ErrorMsg),
             Deep = Deep0,
+            MaybeProgrep = MaybeProgrep0,
             Cmd = deep_cmd_quit
         )
     ;
         Deep = Deep0,
+        MaybeProgrep = MaybeProgrep0,
         MaybeMsg = no,
         Cmd = Cmd0
     ),
@@ -614,7 +621,7 @@ server_loop(ToServerPipe, FromServerPipe
         MaybeMsg = yes(HTML)
     ;
         MaybeMsg = no,
-        try_exec(Cmd, Pref0, Deep, HTML, !IO)
+        try_exec(Cmd, Pref0, Deep, MaybeProgrep, HTML, !IO)
     ),
 
     ResponseFileName = response_file_name(Deep0 ^ data_file_name, QueryNum),
@@ -647,10 +654,10 @@ server_loop(ToServerPipe, FromServerPipe
         delete_cleanup_files(!IO)
     ; Cmd = deep_cmd_timeout(TimeOut) ->
         server_loop(ToServerPipe, FromServerPipe, TimeOut, MaybeStartupStream,
-            Debug, Canonical, QueryNum, Deep, !IO)
+            Debug, Canonical, QueryNum, Deep, MaybeProgrep, !IO)
     ;
         server_loop(ToServerPipe, FromServerPipe, TimeOut0, MaybeStartupStream,
-            Debug, Canonical, QueryNum, Deep, !IO)
+            Debug, Canonical, QueryNum, Deep, MaybeProgrep, !IO)
     ).
 
 %-----------------------------------------------------------------------------%
Index: deep_profiler/mdprof_feedback.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/mdprof_feedback.m,v
retrieving revision 1.8
diff -u -p -r1.8 mdprof_feedback.m
--- deep_profiler/mdprof_feedback.m	18 Aug 2008 02:14:51 -0000	1.8
+++ deep_profiler/mdprof_feedback.m	27 Aug 2008 12:39:17 -0000
@@ -83,9 +83,14 @@ main(!IO) :-
             check_options(Options, RequestedFeedbackInfo)
         ->
             lookup_bool_option(Options, verbose, Verbose),
-            read_deep_file(InputFileName, Verbose, MaybeDeep, !IO),
+            read_deep_file(InputFileName, Verbose, MaybeDeepAndProgrep, !IO),
             (
-                MaybeDeep = ok(Deep),
+                ( 
+                    MaybeDeepAndProgrep = deep_and_error(Deep, _ProgrepError)
+                ; 
+                    % _Progrep will be used bo a later version of this program.
+                    MaybeDeepAndProgrep = deep_and_progrep(Deep, _Progrep)
+                ),
                 feedback.read_or_create(OutputFileName, Feedback0, !IO),
                 process_deep_to_feedback(RequestedFeedbackInfo,
                     Deep, Feedback0, Feedback),
@@ -103,7 +108,7 @@ main(!IO) :-
                     io.set_exit_status(1, !IO)
                 )
             ;
-                MaybeDeep = error(Error),
+                MaybeDeepAndProgrep = error(Error),
                 io.stderr_stream(Stderr, !IO),
                 io.set_exit_status(1, !IO),
                 io.format(Stderr, "%s: error reading %s: %s\n",
@@ -178,10 +183,10 @@ write_version_message(ProgName, !IO) :-
 
     % Read a deep profiling data file.
     %
-:- pred read_deep_file(string::in, bool::in, maybe_error(deep)::out,
+:- pred read_deep_file(string::in, bool::in, maybe_deep_and_progrep::out,
     io::di, io::uo) is det.
 
-read_deep_file(Input, Verbose, MaybeProfile, !IO) :-
+read_deep_file(Input, Verbose, MaybeDeepAndProgrep, !IO) :-
     server_name_port(Machine, !IO),
     script_name(ScriptName, !IO),
     (
@@ -192,8 +197,8 @@ read_deep_file(Input, Verbose, MaybeProf
         Verbose = no,
         MaybeOutput = no
     ),
-    read_and_startup(Machine, ScriptName, [Input], no, MaybeOutput,
-        [], MaybeProfile, !IO).
+    read_and_startup(Machine, ScriptName, Input, no, MaybeOutput,
+        [], MaybeDeepAndProgrep, !IO).
 
 %----------------------------------------------------------------------------%
 %
Index: deep_profiler/mdprof_procrep.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/mdprof_procrep.m,v
retrieving revision 1.4
diff -u -p -r1.4 mdprof_procrep.m
--- deep_profiler/mdprof_procrep.m	13 Aug 2008 07:38:08 -0000	1.4
+++ deep_profiler/mdprof_procrep.m	27 Aug 2008 12:39:17 -0000
@@ -31,9 +31,11 @@
 :- import_module mdbcomp.prim_data.
 :- import_module mdbcomp.program_representation.
 :- import_module mdbcomp.rtti_access.
+:- import_module program_representation_utils.
 
 :- import_module bool.
 :- import_module char.
+:- import_module cord.
 :- import_module int.
 :- import_module list.
 :- import_module maybe.
@@ -86,351 +88,8 @@ print_selected_modules([ModuleRep | Modu
 :- pred print_module(module_rep::in, io::di, io::uo) is det.
 
 print_module(ModuleRep, !IO) :-
-    ModuleRep = module_rep(ModuleName, _StringTable, ProcReps),
-    io.format("Module %s\n", [s(ModuleName)], !IO),
-    list.foldl(print_proc, ProcReps, !IO).
-
-:- pred print_proc(proc_rep::in, io::di, io::uo) is det.
-
-print_proc(ProcRep, !IO) :-
-    ProcRep = proc_rep(ProcLabel, ProcDefnRep),
-    ProcDefnRep = proc_defn_rep(ArgVarReps, GoalRep, VarTable, Detism),
-    print_proc_label(Detism, ProcLabel, !IO),
-    print_args(VarTable, ArgVarReps, !IO),
-    io.write_string(" :-\n", !IO),
-    print_goal(VarTable, 1, GoalRep, !IO),
-    io.nl(!IO).
-
-:- pred print_proc_label(detism_rep::in, string_proc_label::in, io::di, io::uo)
-    is det.
-
-print_proc_label(Detism, ProcLabel, !IO) :-
-    print_detism(Detism, !IO),
-    (
-        ProcLabel = str_ordinary_proc_label(PredFunc, DeclModule, _DefModule,
-            Name, Arity, Mode),
-        (
-            PredFunc = pf_predicate,
-            PF = "pred"
-        ;
-            PredFunc = pf_function,
-            PF = "func"
-        ),
-        io.format(" %s %s.%s/%d-%d",
-            [s(PF), s(DeclModule), s(Name), i(Arity), i(Mode)], !IO)
-    ;
-        ProcLabel = str_special_proc_label(TypeName, TypeModule, _DefModule,
-            Name, Arity, Mode),
-        io.format(" %s for %s.%s/%d-%d",
-            [s(Name), s(TypeModule), s(TypeName), i(Arity), i(Mode)], !IO)
-    ).
-
-%-----------------------------------------------------------------------------%
-
-:- pred print_goal(var_table::in, int::in, goal_rep::in, io::di, io::uo) 
-    is det.
-
-print_goal(VarTable, Indent, GoalRep, !IO) :-
-    GoalRep = goal_rep(GoalExprRep, DetismRep),
-    (
-        GoalExprRep = conj_rep(ConjGoalReps),
-        print_conj(VarTable, Indent, ConjGoalReps, !IO)
-    ;
-        GoalExprRep = disj_rep(DisjGoalReps),
-        indent(Indent, !IO),
-        print_detism(DetismRep, !IO),
-        io.write_string(" (\n", !IO),
-        print_disj(VarTable, Indent, DisjGoalReps, no, !IO),
-        indent(Indent, !IO),
-        io.write_string(")\n", !IO)
-    ;
-        GoalExprRep = switch_rep(SwitchVarRep, CasesRep),
-        indent(Indent, !IO),
-        print_detism(DetismRep, !IO),
-        lookup_var_name(VarTable, SwitchVarRep, SwitchVarName),
-        io.format(" ( switch on %s\n", [s(SwitchVarName)], !IO),
-        print_switch(VarTable, Indent, CasesRep, no, !IO),
-        indent(Indent, !IO),
-        io.write_string(")\n", !IO)
-    ;
-        GoalExprRep = ite_rep(CondRep, ThenRep, ElseRep),
-        indent(Indent, !IO),
-        print_detism(DetismRep, !IO),
-        io.write_string(" (\n", !IO),
-        print_goal(VarTable, Indent + 1, CondRep, !IO),
-        indent(Indent, !IO),
-        io.write_string("->\n", !IO),
-        print_goal(VarTable, Indent + 1, ThenRep, !IO),
-        indent(Indent, !IO),
-        io.write_string(";\n", !IO),
-        print_goal(VarTable, Indent + 1, ElseRep, !IO),
-        indent(Indent, !IO),
-        io.write_string(")\n", !IO)
-    ;
-        GoalExprRep = negation_rep(SubGoalRep),
-        indent(Indent, !IO),
-        io.write_string("not (\n", !IO),
-        print_goal(VarTable, Indent + 1, SubGoalRep, !IO),
-        indent(Indent, !IO),
-        io.write_string(")\n", !IO)
-    ;
-        GoalExprRep = scope_rep(SubGoalRep, MaybeCut),
-        indent(Indent, !IO),
-        print_detism(DetismRep, !IO),
-        io.write_string(" scope", !IO),
-        (
-            MaybeCut = scope_is_cut
-        ;
-            MaybeCut = scope_is_no_cut,
-            io.write_string(" cut", !IO)
-        ),
-        io.write_string(" (\n", !IO),
-        print_goal(VarTable, Indent + 1, SubGoalRep, !IO),
-        indent(Indent, !IO),
-        io.write_string(")\n", !IO)
-    ;
-        GoalExprRep = atomic_goal_rep(_FileName, _LineNumber,
-            _BoundVars, AtomicGoalRep),
-        print_atomic_goal(VarTable, Indent, DetismRep, AtomicGoalRep, !IO)
-    ).
-
-:- pred print_conj(var_table::in, int::in, list(goal_rep)::in, io::di, io::uo)
-    is det.
-
-print_conj(VarTable, Indent, GoalReps, !IO) :-
-    (
-        GoalReps = [],
-        indent(Indent, !IO),
-        io.write_string("true\n", !IO)
-    ;
-        GoalReps = [_ | _],
-        print_conj_2(VarTable, Indent, GoalReps, !IO)
-    ).
-
-:- pred print_conj_2(var_table::in, int::in, list(goal_rep)::in, 
-    io::di, io::uo) is det.
-
-print_conj_2(_, _Indent, [], !IO).
-print_conj_2(VarTable, Indent, [GoalRep | GoalReps], !IO) :-
-    % We use the absence of a separator to denote conjunction.
-    %
-    % We could try to append the comma at the end of each goal that is
-    % not last in a conjunction, but that would be significant work,
-    % and (at least for now) there is no real need for it.
-    print_goal(VarTable, Indent, GoalRep, !IO),
-    print_conj_2(VarTable, Indent, GoalReps, !IO).
-
-:- pred print_disj(var_table::in, int::in, list(goal_rep)::in, bool::in, 
-    io::di, io::uo) is det.
-
-print_disj(_, _Indent, [], _PrintSemi, !IO).
-print_disj(VarTable, Indent, [GoalRep | GoalReps], PrintSemi, !IO) :-
-    (
-        PrintSemi = no
-    ;
-        PrintSemi = yes,
-        indent(Indent, !IO),
-        io.write_string(";\n", !IO)
-    ),
-    print_goal(VarTable, Indent + 1, GoalRep, !IO),
-    print_disj(VarTable, Indent, GoalReps, yes, !IO).
-
-:- pred print_switch(var_table::in, int::in, list(case_rep)::in, bool::in, 
-    io::di, io::uo) is det.
-
-print_switch(_, _Indent, [], _PrintSemi, !IO).
-print_switch(VarTable, Indent, [CaseRep | CaseReps], PrintSemi, !IO) :-
-    (
-        PrintSemi = no
-    ;
-        PrintSemi = yes,
-        indent(Indent, !IO),
-        io.write_string(";\n", !IO)
-    ),
-    CaseRep = case_rep(MainConsIdArityRep, OtherConsIdArityRep, GoalRep),
-    print_cons_id_and_arity(Indent + 1, MainConsIdArityRep, !IO),
-    list.foldl(print_cons_id_and_arity(Indent + 1), OtherConsIdArityRep, !IO),
-    print_goal(VarTable, Indent + 1, GoalRep, !IO),
-        print_switch(VarTable, Indent, CaseReps, yes, !IO).
-
-:- pred print_cons_id_and_arity(int::in, cons_id_arity_rep::in,
-    io::di, io::uo) is det.
-
-print_cons_id_and_arity(Indent, ConsIdArityRep, !IO) :-
-    ConsIdArityRep = cons_id_arity_rep(ConsIdRep, Arity),
-    indent(Indent + 1, !IO),
-    io.format("%% case %s/%d\n", [s(ConsIdRep), i(Arity)], !IO).
-
-%-----------------------------------------------------------------------------%
-
-:- pred print_atomic_goal(var_table::in, int::in, detism_rep::in, 
-    atomic_goal_rep::in, io::di, io::uo) is det.
-
-print_atomic_goal(VarTable, Indent, DetismRep, AtomicGoalRep, !IO) :-
-    indent(Indent, !IO),
-    print_detism(DetismRep, !IO),
-    (
-        (
-            AtomicGoalRep = unify_construct_rep(VarRep, ConsIdRep, ArgReps),
-            UnifyOp = "<="
-        ;
-            AtomicGoalRep = unify_deconstruct_rep(VarRep, ConsIdRep, ArgReps),
-            UnifyOp = "=>"
-        ),
-        lookup_var_name(VarTable, VarRep, VarName),
-        io.format(" %s %s %s", [s(VarName), s(UnifyOp), s(ConsIdRep)], !IO),
-        print_args(VarTable, ArgReps, !IO)
-    ;
-        (
-            AtomicGoalRep = partial_construct_rep(VarRep, ConsIdRep,
-                MaybeArgReps),
-            UnifyOp = "<="
-        ;
-            AtomicGoalRep = partial_deconstruct_rep(VarRep, ConsIdRep,
-                MaybeArgReps),
-            UnifyOp = "=>"
-        ),
-        lookup_var_name(VarTable, VarRep, VarName),
-        io.format(" %s %s %s", [s(VarName), s(UnifyOp), s(ConsIdRep)], !IO),
-        print_maybe_args(VarTable, MaybeArgReps, !IO)
-    ;
-        AtomicGoalRep = unify_assign_rep(TargetRep, SourceRep),
-        lookup_var_name(VarTable, TargetRep, TargetName),
-        lookup_var_name(VarTable, SourceRep, SourceName),
-        io.format(" %s := %s", [s(TargetName), s(SourceName)], !IO)
-    ;
-        AtomicGoalRep = cast_rep(TargetRep, SourceRep),
-        lookup_var_name(VarTable, TargetRep, TargetName),
-        lookup_var_name(VarTable, SourceRep, SourceName),
-        io.format(" cast %s to %s", [s(SourceName), s(TargetName)], !IO)
-    ;
-        AtomicGoalRep = unify_simple_test_rep(TargetRep, SourceRep),
-        lookup_var_name(VarTable, TargetRep, TargetName),
-        lookup_var_name(VarTable, SourceRep, SourceName),
-        io.format(" %s == %s", [s(SourceName), s(TargetName)], !IO)
-    ;
-        AtomicGoalRep = pragma_foreign_code_rep(Args),
-        io.write_string(" foreign_proc(", !IO),
-        print_args(VarTable, Args, !IO),
-        io.write_string(")", !IO)
-    ;
-        AtomicGoalRep = higher_order_call_rep(HOVarRep, Args),
-        lookup_var_name(VarTable, HOVarRep, HOVarName),
-        io.format(" %s(", [s(HOVarName)], !IO),
-        print_args(VarTable, Args, !IO),
-        io.write_string(")", !IO)
-    ;
-        AtomicGoalRep = method_call_rep(TCIVarRep, MethodNumber, Args),
-        lookup_var_name(VarTable, TCIVarRep, TCIVarName),
-        io.format(" method %d of %s(", [i(MethodNumber), s(TCIVarName)], !IO),
-        print_args(VarTable, Args, !IO),
-        io.write_string(")", !IO)
-    ;
-        AtomicGoalRep = plain_call_rep(Module, Pred, Args),
-        io.format(" %s.%s", [s(Module), s(Pred)], !IO),
-        print_args(VarTable, Args, !IO)
-    ;
-        AtomicGoalRep = builtin_call_rep(Module, Pred, Args),
-        io.format(" builtin %s.%s", [s(Module), s(Pred)], !IO),
-        print_args(VarTable, Args, !IO)
-    ;
-        AtomicGoalRep = event_call_rep(Event, Args),
-        io.format(" event %s", [s(Event)], !IO),
-        print_args(VarTable, Args, !IO)
-    ),
-    io.nl(!IO).
-
-%-----------------------------------------------------------------------------%
-
-:- pred print_args(var_table::in, list(var_rep)::in, io::di, io::uo) is det.
-
-print_args(VarTable, Args, !IO) :-
-    (
-        Args = []
-    ;
-        Args = [_ | _],
-        io.write_string("(", !IO),
-        print_args_2(VarTable, Args, "", !IO),
-        io.write_string(")", !IO)
-    ).
-
-:- pred print_args_2(var_table::in, list(var_rep)::in, string::in, 
-    io::di, io::uo) is det.
-
-print_args_2(_,        [],                 _,      !IO).
-print_args_2(VarTable, [VarRep | VarReps], Prefix, !IO) :-
-    lookup_var_name(VarTable, VarRep, VarName),
-    io.write_string(Prefix ++ VarName, !IO),
-    print_args_2(VarTable, VarReps, ", ", !IO).
-
-:- pred print_maybe_args(var_table::in, list(maybe(var_rep))::in, 
-    io::di, io::uo) is det.
-
-print_maybe_args(VarTable, MaybeArgs, !IO) :-
-    (
-        MaybeArgs = []
-    ;
-        MaybeArgs = [_ | _],
-        io.write_string("(", !IO),
-        print_maybe_args_2(VarTable, MaybeArgs, "", !IO),
-        io.write_string(")", !IO)
-    ).
-
-:- pred print_maybe_args_2(var_table::in, list(maybe(var_rep))::in, string::in,
-    io::di, io::uo) is det.
-
-print_maybe_args_2(_, [], _, !IO).
-print_maybe_args_2(VarTable, [MaybeVarRep | MaybeVarReps], Prefix, !IO) :-
-    io.write_string(Prefix, !IO),
-    (
-        MaybeVarRep = no,
-        io.write_string("_", !IO)
-    ;
-        MaybeVarRep = yes(VarRep),
-        lookup_var_name(VarTable, VarRep, VarName),
-        io.write_string(VarName, !IO)
-    ),
-    print_maybe_args_2(VarTable, MaybeVarReps, ", ", !IO).
-
-:- pred indent(int::in, io::di, io::uo) is det.
-
-indent(N, !IO) :-
-    ( N =< 0 ->
-        true
-    ;
-        io.write_string("  ", !IO),
-        indent(N - 1, !IO)
-    ).
-
-:- pred print_detism(detism_rep::in, io::di, io::uo) is det.
-
-print_detism(Detism, !IO) :-
-    (
-        Detism = det_rep,
-        DetismStr = "det"
-    ;
-        Detism = semidet_rep,
-        DetismStr = "semidet"
-    ;
-        Detism = nondet_rep,
-        DetismStr = "nondet"
-    ;
-        Detism = multidet_rep,
-        DetismStr = "multi"
-    ;
-        Detism = cc_nondet_rep,
-        DetismStr = "cc_nondet"
-    ;
-        Detism = cc_multidet_rep,
-        DetismStr = "cc_multi"
-    ;
-        Detism = erroneous_rep,
-        DetismStr = "erroneous"
-    ;
-        Detism = failure_rep,
-        DetismStr = "failure"
-    ),
-    io.write_string(DetismStr, !IO).
+    print_module_to_strings(ModuleRep, Strings),
+    io.write_string(string.append_list(list(Strings)), !IO).
 
 %-----------------------------------------------------------------------------%
 :- end_module mdprof_procrep.
Index: deep_profiler/mdprof_test.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/mdprof_test.m,v
retrieving revision 1.18
diff -u -p -r1.18 mdprof_test.m
--- deep_profiler/mdprof_test.m	25 Aug 2008 07:19:39 -0000	1.18
+++ deep_profiler/mdprof_test.m	27 Aug 2008 12:39:17 -0000
@@ -29,6 +29,8 @@
 :- import_module conf.
 :- import_module dump.
 :- import_module interface.
+:- import_module mdbcomp.
+:- import_module mdbcomp.program_representation.
 :- import_module profile.
 :- import_module query.
 :- import_module startup.
@@ -115,10 +117,12 @@ main2(ProgName, Args, Options, !IO) :-
             io.stdout_stream(Stdout, !IO),
             MaybeOutput = yes(Stdout)
         ),
-        read_and_startup(Machine, ScriptName, [FileName], Canonical,
+        read_and_startup(Machine, ScriptName, FileName, Canonical,
             MaybeOutput, DumpStages, DumpOptions, Res, !IO),
         (
-            Res = ok(Deep),
+            ( Res = deep_and_error(Deep, _)
+            ; Res = deep_and_progrep(Deep, _)
+            ),
             lookup_bool_option(Options, test, Test),
             (
                 Test = no
@@ -169,10 +173,12 @@ verify_profile_2(ProgName, Options, File
     lookup_bool_option(Options, canonical_clique, Canonical),
     Machine = "dummy_server",      % For verification this doesn't matter.
     script_name(ScriptName, !IO),
-    read_and_startup(Machine, ScriptName, [FileName], Canonical, no,
+    read_and_startup(Machine, ScriptName, FileName, Canonical, no,
         [], default_dump_options, Res, !IO),
     (
-        Res = ok(_Deep)
+        Res = deep_and_error(_Deep, _ProgrepError)
+    ;
+        Res = deep_and_progrep(_Deep, _Progrep)
     ;
         Res = error(Error),
         io.set_exit_status(1, !IO),
@@ -232,7 +238,8 @@ test_server(DirName, Pref, Deep, !IO) :-
 
 test_cliques(Cur, Max, DirName, Pref, Deep, !IO) :-
     ( Cur =< Max ->
-        try_exec(deep_cmd_clique(clique_ptr(Cur)), Pref, Deep, HTML, !IO),
+        try_exec(deep_cmd_clique(clique_ptr(Cur)), Pref, Deep, progrep_error,
+            HTML, !IO),
         write_test_html(DirName, "clique", Cur, HTML, !IO),
         test_cliques(Cur + 1, Max, DirName, Pref, Deep, !IO)
     ;
@@ -244,13 +251,19 @@ test_cliques(Cur, Max, DirName, Pref, De
 
 test_procs(Cur, Max, DirName, Pref, Deep, !IO) :-
     ( Cur =< Max ->
-        try_exec(deep_cmd_proc(proc_static_ptr(Cur)), Pref, Deep, HTML, !IO),
+        try_exec(deep_cmd_proc(proc_static_ptr(Cur)), Pref, Deep,
+            progrep_error, HTML, !IO),
         write_test_html(DirName, "proc", Cur, HTML, !IO),
         test_procs(Cur + 1, Max, DirName, Pref, Deep, !IO)
     ;
         true
     ).
 
+:- func progrep_error = maybe_error(prog_rep).
+
+progrep_error = 
+    error("No Program Representation available when using mdprof_test").
+
 :- pred write_test_html(string::in, string::in, int::in, string::in,
     io::di, io::uo) is det.
 
Index: deep_profiler/program_representation_utils.m
===================================================================
RCS file: deep_profiler/program_representation_utils.m
diff -N deep_profiler/program_representation_utils.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ deep_profiler/program_representation_utils.m	27 Aug 2008 12:39:17 -0000
@@ -0,0 +1,487 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2008 The University of Melbourne.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+%
+% File: program_representation_utils.m.
+% Author: pbone.
+%
+% Utilities for working with the program representation structures in the
+% mdbcomp library.  This file is not part of the mdbcomp library, since it
+% contains routines only used by the deep profiling tools.  Code here should be
+% moved into the mdbcomp.program_representation.m module if it's to be used by
+% other tools.
+%
+%-----------------------------------------------------------------------------%
+
+:- module program_representation_utils.
+:- interface.
+
+:- import_module mdbcomp.
+:- import_module mdbcomp.program_representation.
+
+:- import_module cord.
+:- import_module string.
+
+%----------------------------------------------------------------------------%
+
+    % Ugly-print a module to a string representation.  A cord of strings is
+    % returned rather than a string, since this reduces the cost of string
+    % concatenations.
+    %
+:- pred print_module_to_strings(module_rep::in, cord(string)::out) is det.
+
+    % Ugly-print a procedure to a string representation.
+    %
+:- pred print_proc_to_strings(proc_rep::in, cord(string)::out) is det.
+
+%----------------------------------------------------------------------------%
+
+    % Search a program representation for the given procedure and return it's
+    % procedure representation if found, otherwise fail.
+    %
+:- pred progrep_search_proc(prog_rep::in, string_proc_label::in, proc_rep::out)
+    is semidet.
+
+%----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module mdbcomp.prim_data.
+
+:- import_module bool.
+:- import_module int.
+:- import_module list.
+:- import_module maybe.
+
+%----------------------------------------------------------------------------%
+
+print_module_to_strings(ModuleRep, Strings) :-
+    ModuleRep = module_rep(ModuleName, _StringTable, ProcReps),
+    list.map(print_proc_to_strings, ProcReps, ProcStrings),
+    Strings = cord.cons(string.format("Module %s\n", [s(ModuleName)]), 
+        cord_list_to_cord(ProcStrings)).
+
+print_proc_to_strings(ProcRep, Strings) :-
+    ProcRep = proc_rep(ProcLabel, ProcDefnRep),
+    ProcDefnRep = proc_defn_rep(ArgVarReps, GoalRep, VarTable, Detism),
+    print_proc_label_to_strings(Detism, ProcLabel, ProcLabelString),
+    print_args_to_strings(VarTable, ArgVarReps, ArgsString),
+    print_goal_to_strings(VarTable, 1, GoalRep, GoalString),
+    Strings = ProcLabelString ++ ArgsString ++ cord.singleton(" :-\n") ++
+        GoalString ++ nl.
+
+:- pred print_proc_label_to_strings(detism_rep::in, string_proc_label::in, 
+    cord(string)::out) is det.
+
+print_proc_label_to_strings(Detism, ProcLabel, Strings) :-
+    (
+        ProcLabel = str_ordinary_proc_label(PredFunc, DeclModule, _DefModule,
+            Name, Arity, Mode),
+        (
+            PredFunc = pf_predicate,
+            PF = "pred"
+        ;
+            PredFunc = pf_function,
+            PF = "func"
+        ),
+        string.format(" %s %s.%s/%d-%d",
+            [s(PF), s(DeclModule), s(Name), i(Arity), i(Mode)], String)
+    ;
+        ProcLabel = str_special_proc_label(TypeName, TypeModule, _DefModule,
+            Name, Arity, Mode),
+        string.format(" %s for %s.%s/%d-%d",
+            [s(Name), s(TypeModule), s(TypeName), i(Arity), i(Mode)], String)
+    ),
+    detism_to_string(Detism, DetismString),
+    Strings = DetismString ++ cord.singleton(String).
+
+%-----------------------------------------------------------------------------%
+
+:- pred print_goal_to_strings(var_table::in, int::in, goal_rep::in,
+    cord(string)::out) is det.
+
+print_goal_to_strings(VarTable, Indent, GoalRep, Strings) :-
+    GoalRep = goal_rep(GoalExprRep, DetismRep, _),
+    (
+        GoalExprRep = conj_rep(ConjGoalReps),
+        print_conj_to_strings(VarTable, Indent, ConjGoalReps, Strings)
+    ;
+        GoalExprRep = disj_rep(DisjGoalReps),
+        detism_to_string(DetismRep, DetismString),
+        print_disj_to_strings(VarTable, Indent, DisjGoalReps, no, DisjString),
+        Strings = indent(Indent) ++ DetismString ++ cord.singleton(" (\n") ++
+            DisjString ++ indent(Indent) ++ cord.singleton(")\n") 
+    ;
+        GoalExprRep = switch_rep(SwitchVarRep, CasesRep),
+        detism_to_string(DetismRep, DetismString),
+        lookup_var_name(VarTable, SwitchVarRep, SwitchVarName),
+        string.format(" ( switch on %s\n", [s(SwitchVarName)],
+            SwitchOpenString),
+        print_switch_to_strings(VarTable, Indent, CasesRep, no, SwitchString),
+        Strings = indent(Indent) ++ DetismString ++
+            cord.singleton(SwitchOpenString) ++ SwitchString ++ 
+            indent(Indent) ++ cord.singleton(")\n")
+    ;
+        GoalExprRep = ite_rep(CondRep, ThenRep, ElseRep),
+        detism_to_string(DetismRep, DetismString),
+        print_goal_to_strings(VarTable, Indent + 1, CondRep, CondString),
+        print_goal_to_strings(VarTable, Indent + 1, ThenRep, ThenString),
+        print_goal_to_strings(VarTable, Indent + 1, ElseRep, ElseString),
+        IndentString = indent(Indent),
+        Strings = IndentString ++ DetismString ++
+            cord.singleton(" (\n") ++ CondString ++ IndentString ++
+            cord.singleton("->\n") ++ ThenString ++ IndentString ++
+            cord.singleton(";\n") ++ ElseString ++ IndentString ++
+            cord.singleton(")\n")
+    ;
+        GoalExprRep = negation_rep(SubGoalRep),
+        print_goal_to_strings(VarTable, Indent + 1, SubGoalRep, SubGoalString),
+        Strings = indent(Indent) ++ cord.singleton("not (\n") ++ SubGoalString
+            ++ indent(Indent) ++ cord.singleton(")\n")
+    ;
+        GoalExprRep = scope_rep(SubGoalRep, MaybeCut),
+        detism_to_string(DetismRep, DetismString),
+        (
+            MaybeCut = scope_is_cut,
+            CutString = cord.empty 
+        ;
+            MaybeCut = scope_is_no_cut,
+            CutString = cord.singleton(" cut")
+        ),
+        print_goal_to_strings(VarTable, Indent + 1, SubGoalRep, SubGoalString),
+        Strings = indent(Indent) ++ DetismString ++ cord.singleton(" scope") ++
+            CutString ++ cord.singleton(" (\n") ++ SubGoalString ++
+            indent(Indent) ++ cord.singleton(")\n") 
+    ;
+        GoalExprRep = atomic_goal_rep(_FileName, _LineNumber,
+            _BoundVars, AtomicGoalRep),
+        print_atomic_goal_to_strings(VarTable, Indent, DetismRep,
+            AtomicGoalRep, Strings)
+    ).
+
+:- pred print_conj_to_strings(var_table::in, int::in, list(goal_rep)::in,
+    cord(string)::out) is det.
+
+print_conj_to_strings(VarTable, Indent, GoalReps, Strings) :-
+    (
+        GoalReps = [],
+        Strings = cord.snoc(indent(Indent), "true\n")
+    ;
+        GoalReps = [_ | _],
+        print_conj_2_to_strings(VarTable, Indent, GoalReps, Strings)
+    ).
+
+:- pred print_conj_2_to_strings(var_table::in, int::in, list(goal_rep)::in, 
+    cord(string)::out) is det.
+
+print_conj_2_to_strings(_, _Indent, [], cord.empty).
+print_conj_2_to_strings(VarTable, Indent, [GoalRep | GoalReps], Strings) :-
+    % We use the absence of a separator to denote conjunction.
+    %
+    % We could try to append the comma at the end of each goal that is
+    % not last in a conjunction, but that would be significant work,
+    % and (at least for now) there is no real need for it.
+    print_goal_to_strings(VarTable, Indent, GoalRep, GoalString),
+    print_conj_2_to_strings(VarTable, Indent, GoalReps, ConjString),
+    Strings = GoalString ++ ConjString.
+
+:- pred print_disj_to_strings(var_table::in, int::in, list(goal_rep)::in,
+    bool::in, cord(string)::out) is det.
+
+print_disj_to_strings(_, _Indent, [], _PrintSemi, cord.empty).
+print_disj_to_strings(VarTable, Indent, [GoalRep | GoalReps], PrintSemi, Strings) :-
+    (
+        PrintSemi = no,
+        DelimString = cord.empty
+    ;
+        PrintSemi = yes,
+        DelimString = indent(Indent) ++ cord.singleton(";\n")
+    ),
+    print_goal_to_strings(VarTable, Indent + 1, GoalRep, GoalString),
+    print_disj_to_strings(VarTable, Indent, GoalReps, yes, DisjString),
+    Strings = DelimString ++ GoalString ++ DisjString.
+
+:- pred print_switch_to_strings(var_table::in, int::in, list(case_rep)::in,
+    bool::in, cord(string)::out) is det.
+
+print_switch_to_strings(_, _Indent, [], _PrintSemi, cord.empty).
+print_switch_to_strings(VarTable, Indent, [CaseRep | CaseReps], PrintSemi, Strings) :-
+    (
+        PrintSemi = no,
+        DelimString = cord.empty
+    ;
+        PrintSemi = yes,
+        DelimString = indent(Indent) ++ cord.singleton(";\n")
+    ),
+    CaseRep = case_rep(MainConsIdArityRep, OtherConsIdArityRep, GoalRep),
+    print_cons_id_and_arity_to_strings(Indent + 1, MainConsIdArityRep,
+        ConsIdArityString),
+    list.map(print_cons_id_and_arity_to_strings(Indent + 1),
+        OtherConsIdArityRep, OtherConsIdArityStrings),
+    print_goal_to_strings(VarTable, Indent + 1, GoalRep, GoalString),
+    print_switch_to_strings(VarTable, Indent, CaseReps, yes, CaseStrings),
+    Strings = DelimString ++ ConsIdArityString ++
+        cord_list_to_cord(OtherConsIdArityStrings) ++ GoalString ++
+        CaseStrings.
+
+:- pred print_cons_id_and_arity_to_strings(int::in, cons_id_arity_rep::in,
+    cord(string)::out) is det.
+
+print_cons_id_and_arity_to_strings(Indent, ConsIdArityRep, Strings) :-
+    ConsIdArityRep = cons_id_arity_rep(ConsIdRep, Arity),
+    string.format("%% case %s/%d\n", [s(ConsIdRep), i(Arity)], String),
+    Strings = cord.snoc(indent(Indent + 1), String).
+
+%-----------------------------------------------------------------------------%
+
+:- pred print_atomic_goal_to_strings(var_table::in, int::in, detism_rep::in, 
+    atomic_goal_rep::in, cord(string)::out) is det.
+
+print_atomic_goal_to_strings(VarTable, Indent, DetismRep, AtomicGoalRep,
+        Strings) :-
+    (
+        (
+            AtomicGoalRep = unify_construct_rep(VarRep, ConsIdRep, ArgReps),
+            UnifyOp = "<="
+        ;
+            AtomicGoalRep = unify_deconstruct_rep(VarRep, ConsIdRep, ArgReps),
+            UnifyOp = "=>"
+        ),
+        lookup_var_name(VarTable, VarRep, VarName),
+        string.format(" %s %s %s", [s(VarName), s(UnifyOp), s(ConsIdRep)],
+            UnifyString),
+        print_args_to_strings(VarTable, ArgReps, ArgsString),
+        Strings0 = cord.cons(UnifyString, ArgsString) 
+    ;
+        (
+            AtomicGoalRep = partial_construct_rep(VarRep, ConsIdRep,
+                MaybeArgReps),
+            UnifyOp = "<="
+        ;
+            AtomicGoalRep = partial_deconstruct_rep(VarRep, ConsIdRep,
+                MaybeArgReps),
+            UnifyOp = "=>"
+        ),
+        lookup_var_name(VarTable, VarRep, VarName),
+        string.format(" %s %s %s", [s(VarName), s(UnifyOp), s(ConsIdRep)],
+            UnifyString),
+        print_maybe_args_to_strings(VarTable, MaybeArgReps, ArgsString),
+        Strings0 = cord.cons(UnifyString, ArgsString)
+    ;
+        AtomicGoalRep = unify_assign_rep(TargetRep, SourceRep),
+        lookup_var_name(VarTable, TargetRep, TargetName),
+        lookup_var_name(VarTable, SourceRep, SourceName),
+        string.format(" %s := %s", [s(TargetName), s(SourceName)], String),
+        Strings0 = cord.singleton(String)
+    ;
+        AtomicGoalRep = cast_rep(TargetRep, SourceRep),
+        lookup_var_name(VarTable, TargetRep, TargetName),
+        lookup_var_name(VarTable, SourceRep, SourceName),
+        string.format(" cast %s to %s", [s(SourceName), s(TargetName)], String),
+        Strings0 = cord.singleton(String)
+    ;
+        AtomicGoalRep = unify_simple_test_rep(TargetRep, SourceRep),
+        lookup_var_name(VarTable, TargetRep, TargetName),
+        lookup_var_name(VarTable, SourceRep, SourceName),
+        string.format(" %s == %s", [s(SourceName), s(TargetName)], String),
+        Strings0 = cord.singleton(String)
+    ;
+        AtomicGoalRep = pragma_foreign_code_rep(Args),
+        print_args_to_strings(VarTable, Args, ArgsString),
+        Strings0 = cord.singleton(" foreign_proc(") ++ ArgsString ++
+            cord.singleton(")") 
+    ;
+        AtomicGoalRep = higher_order_call_rep(HOVarRep, Args),
+        lookup_var_name(VarTable, HOVarRep, HOVarName),
+        string.format(" %s(", [s(HOVarName)], HeadString),
+        print_args_to_strings(VarTable, Args, ArgsString),
+        Strings0 = cord.singleton(HeadString) ++ ArgsString ++
+            cord.singleton(")")
+    ;
+        AtomicGoalRep = method_call_rep(TCIVarRep, MethodNumber, Args),
+        lookup_var_name(VarTable, TCIVarRep, TCIVarName),
+        string.format(" method %d of %s(", [i(MethodNumber), s(TCIVarName)],
+            HeadString),
+        print_args_to_strings(VarTable, Args, ArgsString),
+        Strings0 = cord.singleton(HeadString) ++ ArgsString ++
+            cord.singleton(")")
+    ;
+        AtomicGoalRep = plain_call_rep(Module, Pred, Args),
+        string.format(" %s.%s", [s(Module), s(Pred)], HeadString),
+        print_args_to_strings(VarTable, Args, ArgsString),
+        Strings0 = cord.cons(HeadString, ArgsString)
+    ;
+        AtomicGoalRep = builtin_call_rep(Module, Pred, Args),
+        string.format(" builtin %s.%s", [s(Module), s(Pred)], HeadString),
+        print_args_to_strings(VarTable, Args, ArgsString),
+        Strings0 = cord.cons(HeadString, ArgsString)
+    ;
+        AtomicGoalRep = event_call_rep(Event, Args),
+        string.format(" event %s", [s(Event)], HeadString),
+        print_args_to_strings(VarTable, Args, ArgsString),
+        Strings0 = cord.cons(HeadString, ArgsString)
+    ),
+    detism_to_string(DetismRep, DetismString),
+    Strings = indent(Indent) ++ DetismString ++ Strings0 ++ nl.
+
+%-----------------------------------------------------------------------------%
+
+:- pred print_args_to_strings(var_table::in, list(var_rep)::in,
+    cord(string)::out) is det.
+
+print_args_to_strings(VarTable, Args, Strings) :-
+    (
+        Args = [],
+        Strings = cord.empty
+    ;
+        Args = [_ | _],
+        print_args_2_to_strings(VarTable, Args, cord.empty, ArgsStr),
+        Strings = cord.cons("(", cord.snoc(ArgsStr, ")"))
+    ).
+
+:- pred print_args_2_to_strings(var_table::in, list(var_rep)::in, 
+    cord(string)::in, cord(string)::out) is det.
+
+print_args_2_to_strings(_,        [],                 _,      cord.empty).
+print_args_2_to_strings(VarTable, [VarRep | VarReps], Prefix, Strings) :-
+    lookup_var_name(VarTable, VarRep, VarName),
+    print_args_2_to_strings(VarTable, VarReps, cord.singleton(", "), ArgsString),
+    Strings = Prefix ++ cord.cons(VarName, ArgsString).
+
+:- pred print_maybe_args_to_strings(var_table::in, list(maybe(var_rep))::in, 
+    cord(string)::out) is det.
+
+print_maybe_args_to_strings(VarTable, MaybeArgs, Strings) :-
+    (
+        MaybeArgs = [],
+        Strings = cord.empty
+    ;
+        MaybeArgs = [_ | _],
+        print_maybe_args_2_to_strings(VarTable, MaybeArgs, cord.empty, ArgsStr),
+        Strings = cord.cons("(", cord.snoc(ArgsStr, ")"))
+    ).
+
+:- pred print_maybe_args_2_to_strings(var_table::in, list(maybe(var_rep))::in,
+    cord(string)::in, cord(string)::out) is det.
+
+print_maybe_args_2_to_strings(_, [], _, cord.empty).
+print_maybe_args_2_to_strings(VarTable, [MaybeVarRep | MaybeVarReps], Prefix, Strings) :-
+    (
+        MaybeVarRep = no,
+        VarName = "_"
+    ;
+        MaybeVarRep = yes(VarRep),
+        lookup_var_name(VarTable, VarRep, VarName)
+    ),
+    print_maybe_args_2_to_strings(VarTable, MaybeVarReps, cord.singleton(", "),
+        ArgsString),
+    Strings = Prefix ++ cord.cons(VarName, ArgsString).
+
+:- func indent(int) = cord(string).
+
+indent(N) =
+    ( N =< 0 ->
+        cord.empty
+    ;
+        cord.singleton("  ") ++ indent(N - 1)
+    ).
+
+:- pred detism_to_string(detism_rep::in, cord(string)::out) is det.
+
+detism_to_string(Detism, DetismStrCord) :-
+    (
+        Detism = det_rep,
+        DetismStr = "det"
+    ;
+        Detism = semidet_rep,
+        DetismStr = "semidet"
+    ;
+        Detism = nondet_rep,
+        DetismStr = "nondet"
+    ;
+        Detism = multidet_rep,
+        DetismStr = "multi"
+    ;
+        Detism = cc_nondet_rep,
+        DetismStr = "cc_nondet"
+    ;
+        Detism = cc_multidet_rep,
+        DetismStr = "cc_multi"
+    ;
+        Detism = erroneous_rep,
+        DetismStr = "erroneous"
+    ;
+        Detism = failure_rep,
+        DetismStr = "failure"
+    ),
+    DetismStrCord = cord.singleton(DetismStr).
+
+%----------------------------------------------------------------------------%
+
+:- func nl = cord(string).
+
+nl = cord.singleton("\n").
+
+%----------------------------------------------------------------------------%
+
+% TODO: It'd be nice if this predicate had some sort of indexes or binary tree
+% to use to speed up it's search.
+progrep_search_proc(ProgRep, ProcLabel, ProcRep) :-
+    % XXX: what's the difference between these two module fields? which should
+    % I be using.
+    ( ProcLabel = str_ordinary_proc_label(_, Module, _Module2, _, _, _)
+    ; ProcLabel = str_special_proc_label(_, Module, _Module2, _, _, _)
+    ),
+    progrep_search_module(ProgRep, Module, ModuleRep),
+    modulerep_search_proc(ModuleRep, ProcLabel, ProcRep).
+
+    % Search for a module within a program representation.
+    %
+:- pred progrep_search_module(prog_rep::in, string::in, module_rep::out) 
+    is semidet.
+
+progrep_search_module(ProgRep, ModuleName, ModuleRep) :-
+   ProgRep = prog_rep(ModuleReps),
+   modulerep_list_search_module(ModuleReps, ModuleName, ModuleRep).
+
+    % Search for a module within a list of module representations.
+    %
+:- pred modulerep_list_search_module(list(module_rep)::in, string::in,
+    module_rep::out) is semidet.
+
+modulerep_list_search_module([], _, _) :- fail.
+modulerep_list_search_module([ModuleRep0 | ModuleReps], ModuleName, ModuleRep)
+        :-
+    ( ModuleRep0 ^ mr_name = ModuleName ->
+        ModuleRep = ModuleRep0
+    ;
+        modulerep_list_search_module(ModuleReps, ModuleName, ModuleRep)
+    ).
+
+    % Search for a procedure within a module representation.
+    %
+:- pred modulerep_search_proc(module_rep::in, string_proc_label::in,
+    proc_rep::out) is semidet.
+
+modulerep_search_proc(ModuleRep, ProcLabel, ProcRep) :-
+    procrep_list_search_proc(ModuleRep ^ mr_procs, ProcLabel, ProcRep).
+
+    % Search for a procedure within a list of procedure representations.
+    %
+:- pred procrep_list_search_proc(list(proc_rep)::in, string_proc_label::in,
+    proc_rep::out) is semidet.
+
+procrep_list_search_proc([], _, _) :- fail.
+procrep_list_search_proc([ProcRep0 | ProcReps], ProcLabel, ProcRep) :-
+    ( ProcRep0 ^ pr_id = ProcLabel ->
+        ProcRep = ProcRep0
+    ;
+        procrep_list_search_proc(ProcReps, ProcLabel, ProcRep)
+    ).
+
+%----------------------------------------------------------------------------%
+
Index: deep_profiler/query.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/query.m,v
retrieving revision 1.27
diff -u -p -r1.27 query.m
--- deep_profiler/query.m	25 Aug 2008 07:19:39 -0000	1.27
+++ deep_profiler/query.m	27 Aug 2008 12:39:18 -0000
@@ -27,79 +27,108 @@
 :- module query.
 :- interface.
 
+:- import_module mdbcomp.
+:- import_module mdbcomp.program_representation.
 :- import_module measurement_units.
 :- import_module profile.
 
 :- import_module bool.
-:- import_module char.
 :- import_module io.
 :- import_module maybe.
 
 %-----------------------------------------------------------------------------%
 
-:- pred try_exec(cmd::in, preferences::in, deep::in, string::out,
-    io::di, io::uo) is cc_multi.
+:- pred try_exec(cmd::in, preferences::in, deep::in, maybe_error(prog_rep)::in,
+    string::out, io::di, io::uo) is cc_multi.
+
+%-----------------------------------------------------------------------------%
+%
+% Declarations for reading and writing querys.
+%
+
+    % A deep profiler query.
+    %
+:- type deep_query
+    --->    deep_query(
+                maybe_cmd                   :: maybe(cmd),
+                deep_file_name              :: string,
+                maybe_prefs                 :: maybe(preferences)
+            ).
+
+    % A subtype of the above, with a mandatory command field.
+    %
+:- inst deep_query_with_cmd
+    --->    deep_query(bound(yes(ground)), ground, ground).
+
+:- func query_to_string(deep_query) = string.
+:- mode query_to_string(in(deep_query_with_cmd)) = out is det.
+
+:- func string_to_maybe_query(string) = maybe(deep_query).
+
+:- func string_to_maybe_cmd(string) = maybe(cmd).
+
+:- func string_to_maybe_pref(string) = maybe(preferences).
 
 %-----------------------------------------------------------------------------%
 
 :- type resp
     --->    html(string).
 
-:- type cmd_pref
-    --->    cmd_pref(cmd, preferences_indication).
-
 :- type cmd
     --->    deep_cmd_quit
     ;       deep_cmd_restart
     ;       deep_cmd_timeout(
-                cmd_timeout_minutes         :: int
+                cmd_timeout_minutes             :: int
             )
     ;       deep_cmd_menu
     ;       deep_cmd_root(
                 % If set to yes(Action), chase the dominant call sites
                 % until we get to a clique that is responsible for less than
                 % or equal to Action percent of the program's total callseqs.
-                cmd_root_maybe_action       :: maybe(int)
+                cmd_root_maybe_action           :: maybe(int)
             )
     ;       deep_cmd_clique(
-                cmd_clique_clique_id        :: clique_ptr
+                cmd_clique_clique_id            :: clique_ptr
             )
     ;       deep_cmd_proc(
-                cmd_proc_proc_id            :: proc_static_ptr
+                cmd_proc_proc_id                :: proc_static_ptr
             )
     ;       deep_cmd_proc_callers(
-                cmd_pc_proc_id              :: proc_static_ptr,
-                cmd_pc_called_groups        :: caller_groups,
-                cmd_pc_bunch_number         :: int,
-                cmd_pc_contour_exclusion    :: contour_exclusion
+                cmd_pc_proc_id                  :: proc_static_ptr,
+                cmd_pc_called_groups            :: caller_groups,
+                cmd_pc_bunch_number             :: int,
+                cmd_pc_contour_exclusion        :: contour_exclusion
             )
     ;       deep_cmd_program_modules
     ;       deep_cmd_module(
-                cmd_module_module_name      :: string
+                cmd_module_module_name          :: string
             )
     ;       deep_cmd_top_procs(
-                cmd_tp_display_limit        :: display_limit,
-                cmd_tp_sort_cost_kind       :: cost_kind,
-                cmd_tp_incl_desc            :: include_descendants,
-                cmd_tp_scope                :: measurement_scope
+                cmd_tp_display_limit            :: display_limit,
+                cmd_tp_sort_cost_kind           :: cost_kind,
+                cmd_tp_incl_desc                :: include_descendants,
+                cmd_tp_scope                    :: measurement_scope
+            )
+    ;       deep_cmd_procrep_coverage(
+                cmd_procrep_coverage_proc_id    :: proc_static_ptr
             )
 
     % The following commands are for debugging.
 
     ;       deep_cmd_dump_proc_static(
-                cmd_dps_id                  :: proc_static_ptr
+                cmd_dps_id                      :: proc_static_ptr
             )
     ;       deep_cmd_dump_proc_dynamic(
-                cmd_dpd_id                  :: proc_dynamic_ptr
+                cmd_dpd_id                      :: proc_dynamic_ptr
             )
     ;       deep_cmd_dump_call_site_static(
-                cmd_dcss_id                 :: call_site_static_ptr
+                cmd_dcss_id                     :: call_site_static_ptr
             )
     ;       deep_cmd_dump_call_site_dynamic(
-                cmd_dcsd_id                 :: call_site_dynamic_ptr
+                cmd_dcsd_id                     :: call_site_dynamic_ptr
             )
     ;       deep_cmd_dump_clique(
-                cmd_dcl_id                  :: clique_ptr
+                cmd_dcl_id                      :: clique_ptr
             ).
 
 :- type caller_groups
@@ -137,11 +166,6 @@
             % threshold_value(Value): display procedures whose cost is at least
             % this value.
 
-:- type preferences_indication
-    --->    given_pref(preferences)
-    ;       default_pref
-    ;       all_pref.
-
 :- type preferences
     --->    preferences(
                 % The set of fields to display.
@@ -180,6 +204,11 @@
                 pref_inactive       :: inactive_items
             ).
 
+:- type preferences_indication
+    --->    given_pref(preferences)
+    ;       default_pref
+    ;       all_pref.
+
 :- type port_fields
     --->    no_port
     ;       port.
@@ -266,6 +295,8 @@
     %
 :- func should_display_times(deep) = bool.
 
+:- func default_command = cmd.
+
 :- func solidify_preference(deep, preferences_indication) = preferences.
 
 :- func default_preferences(deep) = preferences.
@@ -284,14 +315,6 @@
 :- func default_time_format = time_format.
 :- func default_inactive_items = inactive_items.
 
-:- func query_separator_char = char.
-
-:- func preferences_to_string(preferences) = string.
-:- func cmd_to_string(cmd) = string.
-:- func string_to_cmd(string, cmd) = cmd.
-:- func string_to_maybe_cmd(string) = maybe(cmd).
-:- func string_to_maybe_pref(string) = maybe(preferences).
-
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
@@ -310,6 +333,7 @@
 :- import_module array.
 :- import_module assoc_list.
 :- import_module bool.
+:- import_module char.
 :- import_module exception.
 :- import_module float.
 :- import_module int.
@@ -325,8 +349,8 @@
 
 %-----------------------------------------------------------------------------%
 
-try_exec(Cmd, Pref, Deep, HTML, !IO) :-
-    try_io(exec(Cmd, Pref, Deep), Result, !IO),
+try_exec(Cmd, Pref, Deep, MaybeProgrep, HTML, !IO) :-
+    try_io(exec(Cmd, Pref, Deep, MaybeProgrep), Result, !IO),
     (
         Result = succeeded(HTML)
     ;
@@ -355,10 +379,10 @@ try_exec(Cmd, Pref, Deep, HTML, !IO) :-
             [s(Msg)])
     ).
 
-:- pred exec(cmd::in, preferences::in, deep::in, string::out,
-    io::di, io::uo) is det.
+:- pred exec(cmd::in, preferences::in, deep::in, maybe_error(prog_rep)::in,
+    string::out, io::di, io::uo) is det.
 
-exec(Cmd, Prefs, Deep, HTMLStr, !IO) :-
+exec(Cmd, Prefs, Deep, MaybeProgRep, HTMLStr, !IO) :-
     % XXX While we are working on converting the deep profiler to use
     % the new report structures, we can use the presence or absence
     % of this file to tell mdprof_cgi which method we want to use at the
@@ -393,10 +417,7 @@ exec(Cmd, Prefs, Deep, HTMLStr, !IO) :-
             old_exec(Cmd, Prefs, Deep, HTMLStr, !IO)
         ;
             FileExists = no,
-            create_report(Cmd, Deep, Report),
-            Display = report_to_display(Deep, Prefs, Report),
-            HTML = htmlize_display(Deep, Prefs, Display),
-            HTMLStr = html_to_string(HTML)
+            new_exec(Cmd, Prefs, Deep, MaybeProgRep, HTMLStr, !IO)
         )
     ;
         ( Cmd = deep_cmd_root(_)
@@ -404,12 +425,26 @@ exec(Cmd, Prefs, Deep, HTMLStr, !IO) :-
         ; Cmd = deep_cmd_dump_clique(_)
         ),
         old_exec(Cmd, Prefs, Deep, HTMLStr, !IO)
+    ;
+        Cmd = deep_cmd_procrep_coverage(_),
+        new_exec(Cmd, Prefs, Deep, MaybeProgRep, HTMLStr, !IO)
     ).
 
+    % Run the command through the new report generation code.
+    %
+:- pred new_exec(cmd::in, preferences::in, deep::in, maybe_error(prog_rep)::in,
+    string::out, io::di, io::uo) is det.
+
+new_exec(Cmd, Prefs, Deep, MaybeProgRep, HTMLStr, !IO) :-
+    create_report(Cmd, Deep, MaybeProgRep, Report),
+    Display = report_to_display(Deep, Prefs, Report),
+    HTML = htmlize_display(Deep, Prefs, Display),
+    HTMLStr = html_to_string(HTML).
+
     % Old deep profiler cgi code.  This should remain supported until all cmds
     % have been updated to use the data structures in report.m.
     %
-:- pred old_exec(cmd::in, preferences::in, deep::in, string::out,
+:- pred old_exec(cmd::in, preferences::in, deep::in, string::out, 
     io::di, io::uo) is det.
 
 old_exec(deep_cmd_restart, _Pref, _Deep, _HTML, !IO) :-
@@ -493,6 +528,8 @@ old_exec(Cmd, Pref, Deep, HTML, !IO) :-
     ).
 old_exec(deep_cmd_dump_clique(CliquePtr), _Pref, Deep, HTML, !IO) :-
     HTML = generate_clique_debug_page(CliquePtr, Deep).
+old_exec(deep_cmd_procrep_coverage(_), _, _, HTML, !IO) :-
+    HTML = "query.m: deep_cmd_procrep_coverage is unsupported by old_exec\n". 
 
 %-----------------------------------------------------------------------------%
 
@@ -2247,6 +2284,8 @@ should_display_times(Deep) =
         no
     ).
 
+default_command = deep_cmd_menu.
+
 solidify_preference(Deep, PrefInd) = Pref :-
     (
         PrefInd = given_pref(Pref)
@@ -2299,6 +2338,7 @@ default_inactive_items = inactive_items(
 
 %-----------------------------------------------------------------------------%
 
+:- func query_separator_char = char.
 :- func cmd_separator_char = char.
 :- func pref_separator_char = char.
 :- func criteria_separator_char = char.
@@ -2314,96 +2354,107 @@ limit_separator_char = ('-').
 
 %-----------------------------------------------------------------------------%
 
+:- func cmd_to_string(cmd) = string.
+
 cmd_to_string(Cmd) = CmdStr :-
     (
         Cmd = deep_cmd_quit,
-        CmdStr = "quit"
+        CmdStr = cmd_str_quit 
     ;
         Cmd = deep_cmd_restart,
-        CmdStr = "restart"
+        CmdStr = cmd_str_restart
     ;
         Cmd = deep_cmd_timeout(Minutes),
-        CmdStr = string.format("timeout%c%d",
-            [c(cmd_separator_char), i(Minutes)])
+        CmdStr = string.format("%s%c%d",
+            [s(cmd_str_timeout), c(cmd_separator_char), i(Minutes)])
     ;
         Cmd = deep_cmd_menu,
-        CmdStr = "menu"
+        CmdStr = cmd_str_menu
     ;
         Cmd = deep_cmd_root(MaybePercent),
         (
             MaybePercent = yes(Percent),
-            CmdStr = string.format("root%c%d",
-                [c(cmd_separator_char), i(Percent)])
+            CmdStr = string.format("%s%c%d",
+                [s(cmd_str_root), c(cmd_separator_char), i(Percent)])
         ;
             MaybePercent = no,
-            CmdStr = string.format("root%c%s",
-                [c(cmd_separator_char), s("no")])
+            CmdStr = string.format("%s%c%s",
+                [s(cmd_str_root), c(cmd_separator_char), s("no")])
         )
     ;
         Cmd = deep_cmd_clique(CliquePtr),
         CliquePtr = clique_ptr(CliqueNum),
-        CmdStr = string.format("clique%c%d",
-            [c(cmd_separator_char), i(CliqueNum)])
+        CmdStr = string.format("%s%c%d",
+            [s(cmd_str_clique), c(cmd_separator_char), i(CliqueNum)])
     ;
         Cmd = deep_cmd_proc(PSPtr),
         PSPtr = proc_static_ptr(PSI),
-        CmdStr = string.format("proc%c%d",
-            [c(cmd_separator_char), i(PSI)])
+        CmdStr = string.format("%s%c%d",
+            [s(cmd_str_proc), c(cmd_separator_char), i(PSI)])
     ;
         Cmd = deep_cmd_proc_callers(PSPtr, GroupCallers, BunchNum, Contour),
         PSPtr = proc_static_ptr(PSI),
         GroupCallersStr = caller_groups_to_string(GroupCallers),
         ContourStr = contour_exclusion_to_string(Contour),
-        CmdStr = string.format("proc_callers%c%d%c%s%c%d%c%s",
-            [c(cmd_separator_char), i(PSI),
+        CmdStr = string.format("%s%c%d%c%s%c%d%c%s",
+            [s(cmd_str_proc_callers),
+            c(cmd_separator_char), i(PSI),
             c(cmd_separator_char), s(GroupCallersStr),
             c(cmd_separator_char), i(BunchNum),
             c(cmd_separator_char), s(ContourStr)])
     ;
         Cmd = deep_cmd_program_modules,
-        CmdStr = "program_modules"
+        CmdStr = cmd_str_program_modules
     ;
         Cmd = deep_cmd_module(ModuleName),
-        CmdStr = string.format("module%c%s",
-            [c(cmd_separator_char), s(ModuleName)])
+        CmdStr = string.format("%s%c%s",
+            [s(cmd_str_module), c(cmd_separator_char), s(ModuleName)])
     ;
         Cmd = deep_cmd_top_procs(Limit, CostKind, InclDesc, Scope),
         LimitStr = limit_to_string(Limit),
         CostKindStr = cost_kind_to_string(CostKind),
         InclDescStr = incl_desc_to_string(InclDesc),
         ScopeStr = scope_to_string(Scope),
-        CmdStr = string.format("top_procs%c%s%c%s%c%s%c%s",
-            [c(cmd_separator_char), s(LimitStr),
+        CmdStr = string.format("%s%c%s%c%s%c%s%c%s",
+            [s(cmd_str_top_procs),
+            c(cmd_separator_char), s(LimitStr),
             c(cmd_separator_char), s(CostKindStr),
             c(cmd_separator_char), s(InclDescStr),
             c(cmd_separator_char), s(ScopeStr)])
     ;
+        Cmd = deep_cmd_procrep_coverage(PSPtr),
+        PSPtr = proc_static_ptr(PSI),
+        CmdStr = string.format("%s%c%d",
+            [s(cmd_str_procrep_coverage), c(cmd_separator_char), i(PSI)])
+    ;
         Cmd = deep_cmd_dump_proc_static(PSPtr),
         PSPtr = proc_static_ptr(PSI),
-        CmdStr = string.format("dump_proc_static%c%d",
-            [c(cmd_separator_char), i(PSI)])
+        CmdStr = string.format("%s%c%d",
+            [s(cmd_str_dump_proc_static), c(cmd_separator_char), i(PSI)])
     ;
         Cmd = deep_cmd_dump_proc_dynamic(PDPtr),
         PDPtr = proc_dynamic_ptr(PDI),
-        CmdStr = string.format("dump_proc_dynamic%c%d",
-            [c(cmd_separator_char), i(PDI)])
+        CmdStr = string.format("%s%c%d",
+            [s(cmd_str_dump_proc_dynamic), c(cmd_separator_char), i(PDI)])
     ;
         Cmd = deep_cmd_dump_call_site_static(CSSPtr),
         CSSPtr = call_site_static_ptr(CSSI),
-        CmdStr = string.format("dump_call_site_static%c%d",
-            [c(cmd_separator_char), i(CSSI)])
+        CmdStr = string.format("%s%c%d",
+            [s(cmd_str_dump_call_site_static), c(cmd_separator_char), i(CSSI)])
     ;
         Cmd = deep_cmd_dump_call_site_dynamic(CSDPtr),
         CSDPtr = call_site_dynamic_ptr(CSDI),
-        CmdStr = string.format("dump_call_site_dynamic%c%d",
-            [c(cmd_separator_char), i(CSDI)])
+        CmdStr = string.format("%s%c%d",
+            [s(cmd_str_dump_call_site_dynamic), c(cmd_separator_char), i(CSDI)])
     ;
         Cmd = deep_cmd_dump_clique(CliquePtr),
         CliquePtr = clique_ptr(CliqueNum),
-        CmdStr = string.format("dump_clique%c%d",
-            [c(cmd_separator_char), i(CliqueNum)])
+        CmdStr = string.format("%s%c%d",
+            [s(cmd_str_dump_raw_clique), c(cmd_separator_char), i(CliqueNum)])
     ).
 
+:- func preferences_to_string(preferences) = string.
+
 preferences_to_string(Pref) = PrefStr :-
     Pref = preferences(Fields, Box, Colour, MaybeAncestorLimit,
         Summarize, Order, Contour, Time, InactiveItems),
@@ -2427,6 +2478,8 @@ preferences_to_string(Pref) = PrefStr :-
         c(pref_separator_char), s(inactive_items_to_string(InactiveItems))
     ]).
 
+:- func string_to_cmd(string, cmd) = cmd.
+
 string_to_cmd(QueryString, DefaultCmd) = Cmd :-
     MaybeCmd = string_to_maybe_cmd(QueryString),
     (
@@ -2439,7 +2492,7 @@ string_to_cmd(QueryString, DefaultCmd) =
 string_to_maybe_cmd(QueryString) = MaybeCmd :-
     split(QueryString, pref_separator_char, Pieces),
     (
-        Pieces = ["root", MaybePercentStr],
+        Pieces = [cmd_str_root, MaybePercentStr],
         ( MaybePercentStr = "no" ->
             MaybePercent = no
         ; string.to_int(MaybePercentStr, Percent) ->
@@ -2451,21 +2504,21 @@ string_to_maybe_cmd(QueryString) = Maybe
         Cmd = deep_cmd_root(MaybePercent),
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["clique", CliqueNumStr],
+        Pieces = [cmd_str_clique, CliqueNumStr],
         string.to_int(CliqueNumStr, CliqueNum)
     ->
         CliquePtr = clique_ptr(CliqueNum),
         Cmd = deep_cmd_clique(CliquePtr),
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["proc", PSIStr],
+        Pieces = [cmd_str_proc, PSIStr],
         string.to_int(PSIStr, PSI)
     ->
         PSPtr = proc_static_ptr(PSI),
         Cmd = deep_cmd_proc(PSPtr),
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["proc_callers", PSIStr, GroupCallersStr, BunchNumStr,
+        Pieces = [cmd_str_proc_callers, PSIStr, GroupCallersStr, BunchNumStr, 
             ContourStr],
         string.to_int(PSIStr, PSI),
         string_to_caller_groups(GroupCallersStr, GroupCallers),
@@ -2476,17 +2529,18 @@ string_to_maybe_cmd(QueryString) = Maybe
         Cmd = deep_cmd_proc_callers(PSPtr, GroupCallers, BunchNum, Contour),
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["program_modules"]
+        Pieces = [cmd_str_program_modules]
     ->
         Cmd = deep_cmd_program_modules,
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["module", ModuleName]
+        Pieces = [cmd_str_module, ModuleName]
     ->
         Cmd = deep_cmd_module(ModuleName),
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["top_procs", LimitStr, CostKindStr, InclDescStr, ScopeStr],
+        Pieces = [cmd_str_top_procs, LimitStr, CostKindStr, InclDescStr, 
+            ScopeStr],
         string_to_limit(LimitStr, Limit),
         string_to_cost_kind(CostKindStr, CostKind),
         string_to_incl_desc(InclDescStr, InclDesc),
@@ -2495,58 +2549,64 @@ string_to_maybe_cmd(QueryString) = Maybe
         Cmd = deep_cmd_top_procs(Limit, CostKind, InclDesc, Scope),
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["menu"]
+        Pieces = [cmd_str_procrep_coverage, PSIStr],
+        string.to_int(PSIStr, PSI)
+    ->
+        PSPtr = proc_static_ptr(PSI),
+        MaybeCmd = yes(deep_cmd_procrep_coverage(PSPtr))
+    ;
+        Pieces = [cmd_str_menu]
     ->
         Cmd = deep_cmd_menu,
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["dump_proc_static", PSIStr],
+        Pieces = [cmd_str_dump_proc_static, PSIStr],
         string.to_int(PSIStr, PSI)
     ->
         PSPtr = proc_static_ptr(PSI),
         Cmd = deep_cmd_dump_proc_static(PSPtr),
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["dump_proc_dynamic", PDIStr],
+        Pieces = [cmd_str_dump_proc_dynamic, PDIStr],
         string.to_int(PDIStr, PDI)
     ->
         PDPtr = proc_dynamic_ptr(PDI),
         Cmd = deep_cmd_dump_proc_dynamic(PDPtr),
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["dump_call_site_static", CSSIStr],
+        Pieces = [cmd_str_dump_call_site_static, CSSIStr],
         string.to_int(CSSIStr, CSSI)
     ->
         CSSPtr = call_site_static_ptr(CSSI),
         Cmd = deep_cmd_dump_call_site_static(CSSPtr),
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["dump_call_site_dynamic", CSDIStr],
+        Pieces = [cmd_str_dump_call_site_dynamic, CSDIStr],
         string.to_int(CSDIStr, CSDI)
     ->
         CSDPtr = call_site_dynamic_ptr(CSDI),
         Cmd = deep_cmd_dump_call_site_dynamic(CSDPtr),
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["dump_clique", CliqueNumStr],
+        Pieces = [cmd_str_dump_raw_clique, CliqueNumStr],
         string.to_int(CliqueNumStr, CliqueNum)
     ->
         CliquePtr = clique_ptr(CliqueNum),
         Cmd = deep_cmd_dump_clique(CliquePtr),
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["timeout", TimeOutStr],
+        Pieces = [cmd_str_timeout, TimeOutStr],
         string.to_int(TimeOutStr, TimeOut)
     ->
         Cmd = deep_cmd_timeout(TimeOut),
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["restart"]
+        Pieces = [cmd_str_restart]
     ->
         Cmd = deep_cmd_restart,
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = ["quit"]
+        Pieces = [cmd_str_quit]
     ->
         Cmd = deep_cmd_quit,
         MaybeCmd = yes(Cmd)
@@ -2582,7 +2642,66 @@ string_to_maybe_pref(QueryString) = Mayb
         MaybePreferences = no
     ).
 
-%-----------------------------------------------------------------------------%
+query_to_string(DeepQuery) = String :-
+    DeepQuery = deep_query(yes(Cmd), DeepFileName, MaybePreferences), 
+    (
+        MaybePreferences = yes(Preferences),
+        PreferencesString = preferences_to_string(Preferences)
+    ;
+        MaybePreferences = no,
+        PreferencesString = ""
+    ),
+    String = cmd_to_string(Cmd) ++
+        string.char_to_string(query_separator_char) ++
+        PreferencesString ++
+        string.char_to_string(query_separator_char) ++
+        DeepFileName.
+
+string_to_maybe_query(String) = MaybeDeepQuery :-
+    % Breakup the string into seperate peices, there may be one to four peices.
+    (
+        split_query_string(String, MaybeCmdStr, MaybePrefStr, DeepFileName)
+    ->
+        (
+            MaybeCmdStr = no,
+            MaybeCmd = no
+        ;
+            MaybeCmdStr = yes(CmdStr),
+            MaybeCmd = yes(string_to_cmd(CmdStr, deep_cmd_menu))
+        ),
+        (
+            MaybePrefStr = yes(PrefStr),
+            MaybePreferences = string_to_maybe_pref(PrefStr)
+        ;
+            MaybePrefStr = no,
+            MaybePreferences = no
+        ),
+        MaybeDeepQuery = 
+            yes(deep_query(MaybeCmd, DeepFileName, MaybePreferences)) 
+    ;
+        MaybeDeepQuery = no
+    ).
+
+:- pred split_query_string(string::in, maybe(string)::out, maybe(string)::out,
+    string::out) is semidet.
+
+split_query_string(QueryString, MaybeCmdStr, MaybePrefStr, DeepFileName) :-
+    split(QueryString, query_separator_char, Pieces),
+    ( Pieces = [DeepFileName0] ->
+        MaybeCmdStr = no,
+        MaybePrefStr = no,
+        DeepFileName = DeepFileName0
+    ; Pieces = [CmdStr, DeepFileName0] ->
+        MaybeCmdStr = yes(CmdStr),
+        MaybePrefStr = no,
+        DeepFileName = DeepFileName0
+    ; Pieces = [CmdStr, PrefsStr, DeepFileName0] ->
+        MaybeCmdStr = yes(CmdStr),
+        MaybePrefStr = yes(PrefsStr),
+        DeepFileName = DeepFileName0
+    ;
+        fail
+    ).
 
 :- func port_fields_to_string(port_fields) = string.
 
@@ -2880,6 +2999,59 @@ box_to_string(Box) = String :-
 string_to_box("box",   box_tables).
 string_to_box("nobox", do_not_box_tables).
 
+    % Constant strings used in command links and parsing.
+    %
+:- func cmd_str_quit = string.
+cmd_str_quit = "quit".
+
+:- func cmd_str_restart = string.
+cmd_str_restart = "restart".
+
+:- func cmd_str_timeout = string.
+cmd_str_timeout = "timeout".
+
+:- func cmd_str_menu = string.
+cmd_str_menu = "menu".
+
+:- func cmd_str_root = string.
+cmd_str_root = "root".
+
+:- func cmd_str_clique = string.
+cmd_str_clique = "clique".
+
+:- func cmd_str_proc = string.
+cmd_str_proc = "proc".
+
+:- func cmd_str_proc_callers = string.
+cmd_str_proc_callers = "proc_callers".
+
+:- func cmd_str_program_modules = string.
+cmd_str_program_modules = "program_modules".
+
+:- func cmd_str_module = string.
+cmd_str_module = "module".
+
+:- func cmd_str_top_procs = string.
+cmd_str_top_procs = "top_procs".
+
+:- func cmd_str_procrep_coverage = string.
+cmd_str_procrep_coverage = "procrep_coverage".
+
+:- func cmd_str_dump_proc_static = string.
+cmd_str_dump_proc_static = "dump_proc_static".
+
+:- func cmd_str_dump_proc_dynamic = string.
+cmd_str_dump_proc_dynamic = "dump_proc_dynamic".
+
+:- func cmd_str_dump_call_site_static = string.
+cmd_str_dump_call_site_static = "dump_call_site_static".
+
+:- func cmd_str_dump_call_site_dynamic = string.
+cmd_str_dump_call_site_dynamic = "dump_call_site_dynamic".
+
+:- func cmd_str_dump_raw_clique = string.
+cmd_str_dump_raw_clique = "dump_raw_clique".
+
 %----------------------------------------------------------------------------%
 :- end_module query.
 %----------------------------------------------------------------------------%
Index: deep_profiler/report.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/report.m,v
retrieving revision 1.7
diff -u -p -r1.7 report.m
--- deep_profiler/report.m	25 Aug 2008 07:19:39 -0000	1.7
+++ deep_profiler/report.m	27 Aug 2008 12:39:18 -0000
@@ -20,6 +20,8 @@
 :- module report.
 :- interface.
 
+:- import_module mdbcomp.
+:- import_module mdbcomp.program_representation.
 :- import_module measurement_units.
 :- import_module profile.
 % TODO: The data structures in query should be moved into a different module,
@@ -40,6 +42,7 @@
     ;       report_module(maybe_error(module_report))
     ;       report_top_procs(maybe_error(top_procs_report))
     ;       report_proc(maybe_error(proc_report))
+    ;       report_procrep_coverage_dump(maybe_error(procrep_coverage_info))
     ;       report_proc_callers(maybe_error(proc_callers_report))
     ;       report_proc_static_dump(maybe_error(proc_static_dump_info))
     ;       report_proc_dynamic_dump(maybe_error(proc_dynamic_dump_info))
@@ -139,6 +142,8 @@
                 nci_type_subst              :: string
             ).
 
+:- type procrep_coverage_info == proc_rep.
+
 :- type proc_callers_report
     --->    proc_callers_report(
                 % The id of the procedure.
@@ -185,8 +190,10 @@
                 psdi_refined_name           :: string,
                 psdi_filename               :: string,
                 psdi_linenumber             :: int,
-                % Should we list the call_site_statics themselves?
-                psdi_num_call_sites         :: int
+                % Should we list the call_site_statics and coverage points
+                % themselves?
+                psdi_num_call_sites         :: int,
+                psdi_num_coverage_points    :: int
             ).
 
 :- type proc_dynamic_dump_info
Index: deep_profiler/startup.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/startup.m,v
retrieving revision 1.21
diff -u -p -r1.21 startup.m
--- deep_profiler/startup.m	25 Aug 2008 07:19:39 -0000	1.21
+++ deep_profiler/startup.m	27 Aug 2008 12:39:18 -0000
@@ -20,6 +20,8 @@
 :- interface.
 
 :- import_module dump.
+:- import_module mdbcomp.
+:- import_module mdbcomp.program_representation.
 :- import_module profile.
 
 :- import_module bool.
@@ -29,13 +31,27 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred read_and_startup(string::in, string::in, list(string)::in, bool::in,
-    maybe(io.output_stream)::in, list(string)::in, maybe_error(deep)::out,
+    % The result of read_and_startup below.
+    %
+:- type maybe_deep_and_progrep
+    --->    error(string)
+                % This error was raised while reading the Deep data.
+
+    ;       deep_and_error(deep, string)
+                % The Deep data was read succesfully, but the reading the
+                % Progrep data raised an error.
+                
+    ;       deep_and_progrep(deep, prog_rep).
+                % Both Deep and Progrep files where read successfully.
+
+
+:- pred read_and_startup(string::in, string::in, string::in, bool::in,
+    maybe(io.output_stream)::in, list(string)::in, maybe_deep_and_progrep::out,
     io::di, io::uo) is det.
 
-:- pred read_and_startup(string::in, string::in, list(string)::in, bool::in,
+:- pred read_and_startup(string::in, string::in, string::in, bool::in,
     maybe(io.output_stream)::in, list(string)::in, dump_options::in,
-    maybe_error(deep)::out, io::di, io::uo) is det.
+    maybe_deep_and_progrep::out, io::di, io::uo) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -60,41 +76,57 @@
 
 %-----------------------------------------------------------------------------%
 
-read_and_startup(Machine, ScriptName, DataFileNames, Canonical,
+read_and_startup(Machine, ScriptName, DataFileName, Canonical,
         MaybeOutputStream, DumpStages, Res, !IO) :-
-    read_and_startup(Machine, ScriptName, DataFileNames, Canonical,
+    read_and_startup(Machine, ScriptName, DataFileName, Canonical,
         MaybeOutputStream, DumpStages, default_dump_options, Res, !IO).
 
-read_and_startup(Machine, ScriptName, DataFileNames, Canonical,
+read_and_startup(Machine, ScriptName, DataFileName, Canonical,
         MaybeOutputStream, DumpStages, DumpOptions, Res, !IO) :-
+    maybe_report_stats(MaybeOutputStream, !IO),
+    maybe_report_msg(MaybeOutputStream,
+        "% Reading graph data...\n", !IO),
+    read_call_graph(DataFileName, Res0, !IO),
+    maybe_report_msg(MaybeOutputStream,
+        "% Done.\n", !IO),
+    maybe_report_stats(MaybeOutputStream, !IO),
     (
-        DataFileNames = [],
-        % This should have been caught and reported by main.
-        error("read_and_startup: no data files")
-    ;
-        DataFileNames = [DataFileName],
-        maybe_report_stats(MaybeOutputStream, !IO),
-        maybe_report_msg(MaybeOutputStream,
-            "% Reading graph data...\n", !IO),
-        read_call_graph(DataFileName, Res0, !IO),
+        Res0 = ok(InitDeep),
+        startup(Machine, ScriptName, DataFileName, 
+            Canonical, MaybeOutputStream, DumpStages, DumpOptions,
+            InitDeep, Deep, !IO),
+        ProgrepFileName = make_progrep_filename(DataFileName),
         maybe_report_msg(MaybeOutputStream,
-            "% Done.\n", !IO),
-        maybe_report_stats(MaybeOutputStream, !IO),
+            "% Reading progrep data...\n", !IO),
+        read_prog_rep_file(ProgrepFileName, Res1, !IO),
         (
-            Res0 = ok(InitDeep),
-            startup(Machine, ScriptName, DataFileName, Canonical,
-                MaybeOutputStream, DumpStages, DumpOptions, InitDeep, Deep,
-                !IO),
-            Res = ok(Deep)
+            Res1 = ok(Progrep),
+            maybe_report_msg(MaybeOutputStream,
+                "% Done.\n", !IO),
+            Res = deep_and_progrep(Deep, Progrep)
         ;
-            Res0 = error(Error),
-            Res = error(Error)
+            Res1 = error(Error),
+            ErrorMessage = io.error_message(Error),
+            maybe_report_msg(MaybeOutputStream,
+                "% Error: " ++ ErrorMessage ++ "\n", !IO),
+            % This error isn't displayed until a query needs the progrep
+            % data.
+            Res = deep_and_error(Deep, ErrorMessage)
         )
     ;
-        DataFileNames = [_, _ | _],
-        error("mdprof_server: merging of data files is not yet implemented")
+        Res0 = error(Error),
+        Res = error(Error)
     ).
 
+:- func make_progrep_filename(string) = string.
+
+make_progrep_filename(DataFileName) = ProgrepFileName :-
+    ( remove_suffix(DataFileName, ".data", BaseFileName) ->
+        ProgrepFileName = BaseFileName ++ ".procrep"
+    ;
+        error("Couldn't remove suffix from deep file name: " ++
+            DataFileName)
+    ).
 
 :- pred startup(string::in, string::in, string::in, bool::in,
     maybe(io.output_stream)::in, list(string)::in, dump_options::in,
Index: mdbcomp/program_representation.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/program_representation.m,v
retrieving revision 1.34
diff -u -p -r1.34 program_representation.m
--- mdbcomp/program_representation.m	13 Aug 2008 07:38:08 -0000	1.34
+++ mdbcomp/program_representation.m	27 Aug 2008 12:39:19 -0000
@@ -44,6 +44,7 @@
 :- import_module io.
 :- import_module list.
 :- import_module maybe.
+:- import_module unit.
 :- import_module type_desc.
 
     % read_prog_rep_file(FileName, Result, !IO)
@@ -51,24 +52,30 @@
 :- pred read_prog_rep_file(string::in, io.res(prog_rep)::out, io::di, io::uo)
     is det.
 
-:- type prog_rep
+:- type prog_rep(GoalAnnotation)
     --->    prog_rep(
-                list(module_rep)
+                list(module_rep(GoalAnnotation))
             ).
 
-:- type module_rep
+:- type prog_rep == prog_rep(unit).
+
+:- type module_rep(GoalAnnotation)
     --->    module_rep(
                 mr_name         :: string,          % The module name.
                 mr_string_table :: string_table,
-                mr_procs        :: list(proc_rep)
+                mr_procs        :: list(proc_rep(GoalAnnotation))
             ).
 
-:- type proc_rep
+:- type module_rep == module_rep(unit).
+
+:- type proc_rep(GoalAnnotation)
     --->    proc_rep(
                 pr_id           :: string_proc_label,
-                pr_defn         :: proc_defn_rep
+                pr_defn         :: proc_defn_rep(GoalAnnotation)
             ).
 
+:- type proc_rep == proc_rep(unit).
+
     % A string_proc_label is a data structure that uniquely identifies a
     % procedure. It is a version of the proc_label type from prim_data.m
     % that can be used outside the compiler, e.g. in RTTI data structures
@@ -107,14 +114,14 @@
     % Each element of this structure will correspond one-to-one
     % to an element of the original HLDS at the code generation stage.
 
-:- type proc_defn_rep
+:- type proc_defn_rep(GoalAnnotation)
     --->    proc_defn_rep(
                 % The head variables, in order, including the ones introduced
                 % by the compiler.
                 pdr_head_vars           :: list(var_rep),
 
                 % The procedure body.
-                pdr_goal                :: goal_rep,
+                pdr_goal                :: goal_rep(GoalAnnotation),
 
                 % The variable table.
                 pdr_var_table           :: var_table,
@@ -124,33 +131,58 @@
                 pdr_detism              :: detism_rep
             ).
 
-:- type goal_rep
+:- type proc_defn_rep == proc_defn_rep(unit).
+
+:- type goal_rep(GoalAnnotation)
     --->    goal_rep(
-                goal_expr_rep       :: goal_expr_rep,
-                goal_detism_rep     :: detism_rep
+                goal_expr_rep       :: goal_expr_rep(GoalAnnotation),
+                    % The expression this goal represents.
+                
+                goal_detism_rep     :: detism_rep,
+                    % The determinism of this goal.
+
+                goal_annotation     :: GoalAnnotation
+                    % This slot may be used to annotate the goal with some
+                    % extra information.  The deep profiling tools make use of
+                    % this to associate coverage profiling data with goals.
             ).
 
-:- type goal_expr_rep
+:- type goal_rep == goal_rep(unit).
+
+:- type goal_expr_rep(GoalAnnotation)
     --->    conj_rep(
-                list(goal_rep)      % The conjuncts in the original order.
+                list(goal_rep(GoalAnnotation))
+                    % The conjuncts in the original order.
             )
     ;       disj_rep(
-                list(goal_rep)      % The disjuncts in the original order.
+                list(goal_rep(GoalAnnotation))
+                    % The disjuncts in the original order.
             )
     ;       switch_rep(
-                var_rep,            % The variable being switched on.
-                list(case_rep)      % The switch arms in the original order.
+                var_rep,            
+                    % The variable being switched on.
+                
+                list(case_rep(GoalAnnotation))
+                    % The switch arms in the original order.
             )
     ;       ite_rep(
-                goal_rep,           % Condition.
-                goal_rep,           % Then branch.
-                goal_rep            % Else branch.
+                goal_rep(GoalAnnotation),
+                    % Condition.
+                
+                goal_rep(GoalAnnotation),
+                    % Then branch.
+                
+                goal_rep(GoalAnnotation)
+                    % Else branch.
             )
     ;       negation_rep(
-                goal_rep            % The negated goal.
+                goal_rep(GoalAnnotation)
+                    % The negated goal.
             )
     ;       scope_rep(
-                goal_rep,           % The quantified goal.
+                goal_rep(GoalAnnotation),
+                    % The quantified goal.
+                
                 maybe_cut
             )
     ;       atomic_goal_rep(
@@ -161,17 +193,22 @@
                 atomic_goal_rep
             ).
 
-:- type case_rep
+:- type case_rep(GoalAnnotation)
     --->    case_rep(
-                cons_id_arity_rep,  % The name and arity of the first
-                                    % function symbol for which this switch arm
-                                    % is applicable.
+                cons_id_arity_rep,  
+                    % The name and arity of the first function symbol for which
+                    % this switch arm is applicable.
+                
                 list(cons_id_arity_rep),
-                                    % The names and arities of any other
-                                    % function symbols for this switch arm.
-                goal_rep            % The code of the switch arm.
+                    % The names and arities of any other function symbols for
+                    % this switch arm.
+                
+                goal_rep(GoalAnnotation)
+                    % The code of the switch arm.
             ).
 
+:- type case_rep == case_rep(unit).
+
 :- type atomic_goal_rep
     --->    unify_construct_rep(
                 var_rep,
@@ -289,7 +326,7 @@
     % If the given goal generates internal events directly then this
     % function will return yes and no otherwise.
     %
-:- func goal_generates_internal_event(goal_rep) = bool.
+:- func goal_generates_internal_event(goal_rep(unit)) = bool.
 
     % call_does_not_generate_events(ModuleName, PredName, Arity): succeeds iff
     % a call to the named predicate will not generate events in a debugging
@@ -545,7 +582,6 @@
     %
 :- pred coverage_point_type_c_value(cp_type::in, string::out) is det.
 
-
 %-----------------------------------------------------------------------------%
 
 :- implementation.
@@ -610,10 +646,10 @@ call_does_not_generate_events(ModuleName
         )
     ).
 
-goal_generates_internal_event(goal_rep(GoalExpr, _)) =
+goal_generates_internal_event(goal_rep(GoalExpr, _, _)) =
     goal_expr_generates_internal_event(GoalExpr).
 
-:- func goal_expr_generates_internal_event(goal_expr_rep) = bool.
+:- func goal_expr_generates_internal_event(goal_expr_rep(unit)) = bool.
 
 goal_expr_generates_internal_event(conj_rep(_)) = no.
 goal_expr_generates_internal_event(disj_rep(_)) = yes.
@@ -801,7 +837,7 @@ lookup_var_name(VarTable, VarRep, String
 read_file_as_bytecode(FileName, Result, !IO) :-
     read_file_as_bytecode_2(FileName, ByteCode, Size, Error, !IO),
     ( Size < 0 ->
-        io.make_err_msg(Error, "opening " ++ FileName, Msg, !IO),
+        io.make_err_msg(Error, "opening " ++ FileName ++ ": ", Msg, !IO),
         Result = error(io.make_io_error(Msg))
     ;
         Result = ok(bytecode(ByteCode, Size))
@@ -898,7 +934,7 @@ read_prog_rep_file(FileName, Result, !IO
 procrep_id_string = "Mercury deep profiler procrep version 3\n".
 
 :- pred read_module_reps(bytecode::in,
-    list(module_rep)::in, list(module_rep)::out,
+    list(module_rep(unit))::in, list(module_rep(unit))::out,
     int::in, int::out) is semidet.
 
 read_module_reps(ByteCode, !RevModuleReps, !Pos) :-
@@ -913,7 +949,7 @@ read_module_reps(ByteCode, !RevModuleRep
         read_module_reps(ByteCode, !RevModuleReps, !Pos)
     ).
 
-:- pred read_module_rep(bytecode::in, module_rep::out, int::in, int::out)
+:- pred read_module_rep(bytecode::in, module_rep(unit)::out, int::in, int::out)
     is semidet.
 
 read_module_rep(ByteCode, ModuleRep, !Pos) :-
@@ -924,7 +960,8 @@ read_module_rep(ByteCode, ModuleRep, !Po
     ModuleRep = module_rep(ModuleName, StringTable, ProcReps).
 
 :- pred read_proc_reps(bytecode::in, string_table::in,
-    list(proc_rep)::in, list(proc_rep)::out, int::in, int::out) is semidet.
+    list(proc_rep(unit))::in, list(proc_rep(unit))::out, int::in, int::out) 
+    is semidet.
 
 read_proc_reps(ByteCode, StringTable, !RevProcReps, !Pos) :-
     read_byte(ByteCode, MoreByte, !Pos),
@@ -938,7 +975,7 @@ read_proc_reps(ByteCode, StringTable, !R
         read_proc_reps(ByteCode, StringTable, !RevProcReps, !Pos)
     ).
 
-:- pred read_proc_rep(bytecode::in, string_table::in, proc_rep::out,
+:- pred read_proc_rep(bytecode::in, string_table::in, proc_rep(unit)::out,
     int::in, int::out) is semidet.
 
 read_proc_rep(ByteCode, StringTable, ProcRep, !Pos) :-
@@ -1201,13 +1238,13 @@ read_goal(VarNumRep, ByteCode, StringTab
                 AtomicGoal, GoalExpr, !Pos)
         ),
         read_determinism(ByteCode, Detism, !Pos),
-        Goal = goal_rep(GoalExpr, Detism)
+        Goal = goal_rep(GoalExpr, Detism, unit)
     ;
         error("read_goal: invalid goal type")
     ).
 
 :- pred read_atomic_info(var_num_rep::in, bytecode::in, string_table::in,
-    read_proc_rep_info::in, atomic_goal_rep::in, goal_expr_rep::out,
+    read_proc_rep_info::in, atomic_goal_rep::in, goal_expr_rep(unit)::out,
     int::in, int::out) is semidet.
 
 read_atomic_info(VarNumRep, ByteCode, StringTable, Info, AtomicGoal, GoalExpr,
@@ -1244,15 +1281,15 @@ read_goals_2(VarNumRep, ByteCode, String
     ).
 
 :- pred read_cases(var_num_rep::in, bytecode::in, string_table::in,
-    read_proc_rep_info::in, list(case_rep)::out, int::in, int::out) is semidet.
+    read_proc_rep_info::in, list(case_rep(unit))::out, int::in, int::out) is semidet.
 
 read_cases(VarNumRep, ByteCode, StringTable, Info, Cases, !Pos) :-
     read_length(ByteCode, Len, !Pos),
     read_cases_2(VarNumRep, ByteCode, StringTable, Info, Len, Cases, !Pos).
 
 :- pred read_cases_2(var_num_rep::in, bytecode::in, string_table::in,
-    read_proc_rep_info::in, int::in, list(case_rep)::out, int::in, int::out)
-    is semidet.
+    read_proc_rep_info::in, int::in, list(case_rep(unit))::out, 
+    int::in, int::out) is semidet.
 
 read_cases_2(VarNumRep, ByteCode, StringTable, Info, N, Cases, !Pos) :-
     ( N > 0 ->
@@ -1566,5 +1603,4 @@ coverage_point_type_c_value(cp_type_bran
         cp_type_branch_arm     - "MR_cp_type_branch_arm"
     ]).
 
-
 %-----------------------------------------------------------------------------%

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mercurylang.org/archives/reviews/attachments/20080827/c423eb4b/attachment.sig>


More information about the reviews mailing list