Files
mercury/doc/mercury_user_guide.texi
Zoltan Somogyi ec0d8ca957 Fill in a large part of "compilation detail".
Minor improvements to the preceding chapters.
2025-08-16 00:30:10 +02:00

9980 lines
387 KiB
Plaintext

\input texinfo
@setfilename mercury_user_guide.info
@settitle The Mercury User's Guide
@c vim: ts=4 sw=4 expandtab ft=texinfo
@dircategory The Mercury Programming Language
@direntry
* Mercury User's Guide: (mercury_user_guide). The Mercury User's Guide.
@end direntry
@c @smallbook
@c @cropmarks
@finalout
@setchapternewpage off
@c ----------------------------------------------------------------------------
@c We use the following indices in this document:
@c
@c The "@cindex" / "cp" (concept) index:
@c for general concepts (e.g. "Determinism", "Debugging", etc.)
@c The "@pindex" / "pg" (program) index:
@c for programs or shell scripts (mmc, mgnuc, etc.).
@c The "@findex" / "fn" (function) index:
@c for command-line options.
@c The "@kindex" / "ky" (keystroke) index:
@c for mdb commands.
@c The "@vindex" / "vr" (variable) index:
@c for environment variables and Mmake variables.
@c
@c That is in case we ever want to produce separate indices for the
@c different categories. Currently, however, we merge them all into
@c a single index, via the commands below.
@syncodeindex fn cp
@syncodeindex ky cp
@syncodeindex vr cp
@syncodeindex pg cp
@c ----------------------------------------------------------------------------
@ifnottex
This file documents the Mercury implementation, version <VERSION>.
Copyright @copyright{} 1995--2012 The University of Melbourne.@*
Copyright @copyright{} 2013--2025 The Mercury team.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
@ignore
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ifnottex
@titlepage
@title The Mercury User's Guide
@subtitle Version <VERSION>
@author Fergus Henderson
@author Thomas Conway
@author Zoltan Somogyi
@author Peter Ross
@author Tyson Dowd
@author Mark Brown
@author Ian MacLarty
@author Paul Bone
@page
@vskip 0pt plus 1filll
Copyright @copyright{} 1995--2012 The University of Melbourne.@*
Copyright @copyright{} 2013--2025 The Mercury team.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end titlepage
@c ----------------------------------------------------------------------------
@contents
@page
@c ----------------------------------------------------------------------------
@ifnottex
@node Top,,, (mercury)
@top The Mercury User's Guide, version <VERSION>
This guide describes the compilation environment of Mercury ---
how to build and debug Mercury programs.
This guide is currently undergoing extensive modifications,
which means that some parts, particularly the ones that contain ZZZ markers,
are not in state that is ready to be consumed.
These modifications started on 2025 July 27,
and will probably continue for around two weeks.
During that time, we advise you to look at
@emph{earlier} versions of this guide.
@menu
* Introduction:: General overview.
* Introduction to mmc:: Introduction to compiling Mercury program
* Mercury grades:: Mercury grades
* Running:: Running Mercury programs
* Compilation details:: The Mercury compilation process in detail
* Filenames:: File naming conventions.
* Using Mmake:: ``Mercury Make'', a tool for building Mercury programs.
* Libraries:: Creating and using libraries of Mercury modules.
* Debugging:: The Mercury debugger @samp{mdb}.
* Profiling:: Analyzing the performance of Mercury programs.
* Invocation:: List of options for the Mercury compiler.
* Environment:: Environment variables used by the compiler and utilities.
* Diagnostic output:: Controlling some aspects of compiler diagnostics.
* C compilers:: How to use a C compiler other than GNU C.
* Foreign language interface:: Interfacing to other programming
languages from Mercury.
* Stand-alone interfaces:: Calling procedures in Mercury libraries from
programs written in other languages.
* Index::
@end menu
@end ifnottex
@c ----------------------------------------------------------------------------
@node Introduction
@chapter Introduction
This document describes the compilation environment of Mercury.
It describes
@itemize
@item
how to use @samp{mmc}, the Mercury compiler;
@item
how to use @samp{mmc --make}, a build tool integrated into @samp{mmc};
@item
how to use an older build tool, @samp{mmake}, built on top of GNU make;
@item
how to use @samp{mdb}, the Mercury debugger;
@item
how to use @samp{mprof}, a @samp{gprof}-style profiler for Mercury; and
@item
how to use @samp{mdprof}, a more detailed profiler for Mercury
that uses a web interface.
@end itemize
Mercury programs can be compiled to executables
via any one of three target languages: C, Java and C#.
The most frequently used target language is C, for two main reasons.
The first is that several important parts of the Mercury system,
such as @samp{mdb}, @samp{mprof} and @samp{mdprof},
are implemented only when targeting C.
The second is that targeting C yields the fastest executables.
@c ----------------------------------------------------------------------------
@node Introduction to mmc
@chapter Introduction to compiling Mercury programs
@pindex mmc
The Mercury compiler is called @command{mmc},
which stands for ``Melbourne Mercury Compiler''.
@cindex Microsoft Management Console
Note that on Microsoft Windows systems,
the name @command{mmc} is also used by the executable
for the Microsoft Management Console.
To avoid the name clash on these systems,
you can either invoke the Mercury compiler
by its alternative name @samp{mercury},
or adjust your @env{PATH} to ensure that
the Mercury @file{bin} directory precedes the Windows system directory.
@node Mmc arguments
@section Mmc arguments
Any useful invocation of @command{mmc}
will specify one or more command line arguments.
How the compiler treats each argument depends on its form.
@itemize
@item
Any command line argument that starts with @samp{-}
specifies one or more @emph{options}.
@item
Any command line argument that starts with @samp{@@}
is a shorthand for a list of other arguments.
@item
Any command line argument
that does not start with either @samp{=} or @samp{@@}
will be treated either as the argument of an option
(if it immediately follows an option that takes an argument),
or as a @dfn{non-option argument}
(if it does not immediately follow an option that takes an argument).
@end itemize
In the absence of the @code{--make} option,
whose description we will defer until @ref{Introduction to mmc --make},
all non-option arguments should be either
the name of a file, or the name of a module.
@c XXX what about e.g. "mmc --make prog.clean"?
The compiler assumes that
non-option arguments ending in @samp{.m} are file names,
while all other non-option arguments are module names.
Both file names and module names tell the compiler
what code it should operate on.
@node Option arguments
@subsection Option arguments
The Mercury compiler follows the usual Unix conventions around options.
(Some of its options (e.g.@: @samp{-c}, @samp{-o}, and @samp{-I})
have a similar meaning to that in compilers for other languages,
though of course most are specific to Mercury.)
Like most other Unix programs, it supports both
short (single-character) and long (multi-character) option names.
On command lines, an option argument that starts with @samp{--}
specifies a single long option.
while an option argument that starts with only a single @samp{-}
specifies one or more short options.
For example, @samp{-v} asks the compiler to be verbose,
printing a message each time it starts a new phase of the compilation process,
while @samp{-w} asks it not to print any warnings.
Some options do not take arguments (we call such @dfn{flags}), while some do.
Single-letter flags may be grouped with a single @samp{-},
so that e.g.@: users can ask for both verbose output and no warnings
either by giving each short option in separate arguments, as in @samp{-v -w},
or by giving them together in one argument, as in @samp{-vw}.
Such grouping cannot be done with long option names:
a single argument can specify just one long option name.
All options that have a short name have a long name as well,
and it does not matter which one is used.
For example, @samp{-v} is interchangeable with @samp{--verbose},
and @samp{-w} is interchangeable with @samp{--inhibit-warnings"}.
In addition, many options have two or more long names.
There are two common reasons for these synonyms.
The reason why the option @samp{intermodule-optimization}
can also be specified as @samp{intermodule-optimisation}
is to allow users to choose either American or British spelling as they wish.
And the reason why that same option
can also be specified as @samp{intermod-opt}
is to reduce the amount of typing required.
Flag options specify a boolean value:
they either ask for something specific to be done,
or they ask for that specific something not to be done.
If you want to negate a single-letter flag,
you can do so by appending a trailing @samp{-} after the short option name,
as in e.g.@: @samp{-v-}.
(You cannot both group @emph{and} negate single-letter flags at the same time.)
Long flags may be negated by preceding them with @samp{no-},
as in e.g.@: @samp{--no-verbose}.
Other options specify integer or string values.
For these options, the value can be specified
in the same argument as the option name,
following it immediately (if the option name is a short name),
or separated from it by an equal sign (if the option name is a long name).
Or it can be in the next argument.
For example, the requested optimization level, which is an integer,
can be specified as either as @samp{-O3} or as @samp{-O 3},
using the short name of that option,
or as @samp{--optimization-level=3} or as @samp{--optimization-level 3}
using the long name of that option.
The name of the color scheme to be used for diagnostics, which a string,
can be specified
either as @samp{--color-scheme=light16}
or as @samp{--color-scheme light16}.
Some options specify an @emph{optional} integer or string value.
For example, you can specify the maximum line width for error messages
as @samp{--max-error-line-width=71},
or you can ask for error messages to have @emph{no} maximum line width
with a @samp{no-} prefix instead of a value,
as in @samp{--no-max-error-line-width}.
Some options let users specify a @emph{list} of strings, one string at a time,
with each occurrence of the option adding one string to the end of the list.
For example, the options @samp{--search-directory=foo --search-directory=bar}
tell the compiler to add the named directories
to the list of directories to be searched
when looking for e.g.@: interface files @ref{Interface files}.
(The default value of that lists consists of just the current directory.)
Negating the option name, e.g.@: with @samp{--no-search-directory},
clears the list, i.e.@: sets it to the empty list.
All option names, both short and long, are case-sensitive.
For example, the meanings of @samp{-e} and @samp{-E} are totally unrelated.
@node @@filename arguments
@subsection @@filename arguments
Any command line argument that has the form @samp{@@filename}
will be replaced with the contents of the named file.
That contents should be a list of arguments,
with one argument per line.
This argument processing is done recursively,
so that some of these arguments may also have the form @file{@@file}.
Fairly obviously, a file named in an @samp{@@file} argument
should never include itself, either directly or indirectly.
The compiler will generate an error message
for any file that violates this rule.
Since @samp{@@filename} arguments are just shorthand
for a list of other arguments,
in the rest of this user guide
we will usually classify all command line arguments
as either option or non-option arguments,
with the latter including only file names and module names
(in the absence of the @code{--make} option).
@node File name and module name arguments
@subsection File name and module name arguments
In the absence of the @code{--make} option,
non-option arguments can be either
file names (if they end in @samp{.m})
or module names (if they don't).
The compiler converts module names to file names in one of two ways.
In the absence of a file named @file{Mercury.modules} in the current directory,
it relies on each module being stored in a file
whose name is just the module name followed by @samp{.m}.
For example, given a module named e.g.@: @code{foo.bar.baz},
the compiler expects to find it in @file{foo.bar.baz.m}.
@c Until commit a618ab31e16de507b66c4c0978a9b9f0c0fa2818 on 2020 jan 12,
@c mmc also searched for module foo.bar.baz in bar.baz.m and baz.m as well.
If any module of the program does not meet this expectation,
then the user must create a @file{Mercury.modules} file,
which contains a map from module names to file names.
@c XXX ... though only for the modules that deviate from the expectation.
This can be created using a command such as @code{mmc -f *.m}
if all the modules of the program are in the current directory
(@pxref{Options that give the compiler its overall task}).
In the presence of the @file{Mercury.modules} file,
the compiler will of course get the file name corresponding to a module name
by looking up the module name in this file.
@c XXX ... falling back to the default module name if the lookup fails.
@c Arguments to @samp{mmc} may be either
@c file names (all non-option arguments ending in @samp{.m}),
@c or module names (all other non-option arguments).
@c For a module name such as @samp{foo.bar.baz},
@c the compiler will look for the source
@c in the file named @file{foo.bar.baz.m}.
@c To make the compiler look for a module in another file,
@c use @samp{mmc -f @var{sources-files}},
@c where @var{sources-files} is the list of source files in the directory,
@c to generate a mapping from module name to file name
@c That command will put the mapping into a file named @file{Mercury.modules},
@c where all later invocations of use @samp{mmc} will look for it.
@node Compiling single-module programs
@section Compiling single-module programs
Given a Mercury program that consists of single module,
which is stored in a file named e.g.@: @file{prog.m},
you can compile it using the command
@example
mmc @code{prog.m}
@end example
or, more generally,
@c ZZZ @var{list of options} looks strange in the generated HTML.
@example
mmc @var{list of options} @code{prog.m}
@end example
If the single module inside @file{prog.m} is also named @file{prog},
then you can also compile it using
@c XXX @var{list of options} looks strange in the generated HTML here as well.
@example
mmc @var{list of options} @code{prog}
@end example
which specifies the module name, not the (matching) file name.
@node Compiling multi-module programs
@section Compiling multi-module programs
Compiling a program that consists of more than one module
is a more complex task than
compiling a program that consists of just one module,
because it requires managing the connections between modules,
and it requires minimizing the number of files needing to be recompiled
after the user changes some but not all of the modules in the program.
@c Specifically, it requires managing how one module, say module @samp{A},
@c accesses the entities exported by another module, say module @samp{B}.
@node Managing connections between modules
@subsection Managing connections between modules
A Mercury module's source file contains
both the interface and the implementation sections of that module.
Given a module @var{A} which imports module @var{B},
when compiling module @var{A},
the compiler needs to know what entities (types, predicates, functions etc)
module @var{B} exports.
It could do that by reading module @var{B}'s source file
and extracting its interface part.
However, given that the interface of a module
tends to be much more stable than its implementation,
that would be incredibly wasteful:
it would compute @var{B}'s interface, many, many times,
getting the same result between each pair of changes to @var{B}'s interface.
It is far more efficient to store @var{B}'s interface in a file,
which only ever needs to be updated when @var{B}'s source module changes,
and does so in a way that @emph{affects its interface}.
@c In programming languages which do not have an explicit module system,
@c the role of module interfaces is taken by hand writen files,
@c with the most frequently-seen example being @emph{header files} in C.
In C and in some programming languages based on it,
hand-written header files (@file{.h} files)
usually store the interface of the source file (@file{.c} file)
with the same base name.
Mercury programming uses a similar file, the @file{.int} file,
with the difference being that
a module's @file{.int} file is @emph{not} hand-written,
but is derived from the module's source file by the Mercury compiler.
In fact, due to Mercury's module system
being substantially more expressive than C's
(not hard when C does not actually @emph{have} an explicit module system),
each Mercury module has three or four @emph{interface} files, not just one.
@itemize
@item
@file{.int} files play the same role as C's @file{.h} files:
they list the entities (types, insts, modes, typeclasses, instances,
predicates, functions, and some others) that this module makes available
to the other modules that import it.
@item
@file{.int2} files contain a subset of the information in @file{.int} files,
the subset which the compiler needs from indirectly imported modules.
(If module @var{A} imports module @var{B}
and module @var{B} imports module @var{C},
but module @var{A} contains
no @code{:- import_module} or @code{:- use_module} declaration
for module @var{C}, then
module @var{A} imports module @var{C} @emph{indirectly}.)
@item
@file{.int3} files contain just the names of the types, insts, modes,
typeclasses and instances exported by the module.
The compiler needs these files to construct @file{A.int} and @file{A.int2}
in the frequent case that
module @var{A}'s interface uses a type named @var{foo}
(maybe as the type of a predicate argument)
that it does not define.
If module @var{A}'s interface imports two modules, @var{B} and @var{C},
the compiler needs to know for each of those modules
whether they define a type named @var{foo},
so it can put either @var{B.foo} @var{C.foo} as the type of that argument
into e.g.@: @file{A.int} if just one of them defines it,
and so that it can generate an error if either neither or both define it.
@item
@file{.int0} files contain the declarations of the entities
that a module that includes submodules
exports @emph{just} to those submodules, and to nowhere else.
This includes entities (such as predicates and functions)
that are declared in the implementation section of the parent module.
Only parent modules, i.e.@: modules that include submodules,
have @file{.int0} files;
non-parent modules no dot.
@end itemize
As you may guess from that description,
managing Mercury interface files is not trivial.
It is not hard either, as shown by @ref{Compilation details},
but it is even simpler to leave their management to automatic build tools.
These build tools also take care of another issue:
separate compilation.
When C programmers update a header file,
they must also recompile all the C source files
that depend on that header file.
Manually keeping track of @emph{which} source files these are
is possible in theory, but very tedious, and extremely error-prone.
This is even more true for Mercury.
Yet the one simple but guaranteed-to-work method, recompiling everything,
can slow down the think-edit-compile-test cycle to an unreasonable degree.
Unlike humans, automatic build tools can be trusted
to recompile only the modules that need recompilation,
reusing the results of previous compilations wherever possible.
The Mercury implementation supports two automatic build tools:
@command{mmake}, and @command{mmc --make}.
As their names imply, both are intended to work
like the traditional Unix build tool @command{make}.
The next two subsections describe them in turn.
They each have strengths and weaknesses
(for example, @command{mmake} supports only compilation to C,
not to Java or C#),
and they support different subsets of the available functionality,
though the overlap (the set of features they both support) is large.
We recommend that projects using Mercury pick one, and use it consistently.
If you can, you should pick @command{mmc --make},
because this is the build tool
that is likely to receive more development in the future.
You can also use both tools, each for different parts of the same project,
such as using @command{mmc --make} for the Mercury parts
and @command{mmake} for tying those parts to the non-Mercury parts,
but in general, you should do this only if you have to.
@c We strongly recommend that programmers use @samp{mmc --make}
@c rather than invoking @samp{mmc} directly,
@c because @samp{mmc --make} is generally easier to use
@c and avoids unnecessary recompilation.
@node Introduction to mmake
@subsection Introduction to mmake
The Mercury build tool that was implemented first is @command{mmake},
whose name is short for ``Mercury make''.
If you have Mercury program containing three modules,
maybe called @file{main_module.m}, @file{module_a.m} and @file{module_b.m},
with the @code{main} predicate being in @file{main_module.m},
you can use these commands to compile a program:
@example
mmc -f *.m
mmake @var{main_module}.depend
mmake @var{main_module}
@end example
The first step creates the @file{Mercury.modules} file
that maps the name of each module inside each Mercury source file
in the current directory to the name of the file containing it.
It is not needed if all the modules are stored in files
whose name is the module name plus the @file{.m} suffix.
The second step creates some small files containing makefile fragments.
These small files will include
@file{main_module.dep} and @file{main_module.dv},
which record whole-program-level information,
such as the list of modules in the program,
and the intended executable name.
In this case, that name will be @file{main_module},
either without an extension,
if the platform does not require one for executables,
or with the required extension (such as @file{.exe} on Windows).
The second step will also create one file with the suffix @file{.d}
for each module in the program,
with e.g.@: @file{module_a.d} recording which other modules
@file{module_a.m} imports.
One important aspect of @file{.d} files is that
every compilation of a Mercury module
will implicitly update that module's @file{.d} file
if its old contents are not up-to-date.
This is not true for @file{.dep} and @file{.dep} files;
those are updated only if you explicitly ask for it,
e.g.@: via the second step command above.
The third step then uses those small files
to create all the necessary interface files in the proper order,
to compile each Mercury module,
and to then link the resulting object files together
to yield the desired executable.
In outline, @command{mmake} works by concatenating
the set of makefile rules for Mercury compilation built into it,
all the makefile fragments in
@file{.dep}, @file{.dv} and @file{.d} files in the current directory,
and the file named @file{Mmakefile} if it exists,
@c I (zs) don't think we should mention here
@c the fact that you can name this file "Mmake" instead,
@c since this would introduce an ambiguity.
and invoking @command{gmake} on it,
passing it the targets or targets that it itself was given.
(@command{gmake} is the GNU version
of the standard Unix @command{make} program,
though on many platforms it is installed as just plain @command{make}.)
This close relationship to @command{gmake}
allows @command{mmake} to be used to control
not just the compilation of Mercury code,
but also the building of any other file,
provided only that one can write makefile rules for their construction.
Many small Mercury projects don't really need an @file{Mmakefile},
but they have one anyway, usually looking something like this:
@example
PROGRAM_NAME = prog
.PHONY: default_target
default_target: $(PROGRAM_NAME)
.PHONY: depend
depend: Mercury.modules $(PROGRAM_NAME).depend
Mercury.modules: $(wildcard *.m)
mmc -f $(wildcard *.m)
.PHONY: install
install:
test -d $(INSTALL_DIR) || mkdir -p $(INSTALL_DIR)
cp $(PROGRAM_NAME) $(INSTALL_DIR)
.PHONY: clean
clean: $(PROGRAM_NAME).clean
@end example
If you have an @file{Mmakefile} like this, you can then type just
@example
mmake depend
@end example
instead of
@example
mmc -f *.m
mmake @var{main_module}.depend
@end example
and you can type just
@example
mmake
@end example
instead of
@example
mmake @var{main_module}
@end example
And obviously, the @file{Mmakefile}
also shortens the command you need to give to install the program, or
to clean up the directory by deleting the automatically regenerable files.
For more information on how to use this tool,
please see @ref{Using Mmake}.
@c ZZZ
@c tags: $(wildcard *.m)
@c mtags $(wildcard *.m)
@node Introduction to mmc --make
@subsection Introduction to mmc --make
The second Mercury build tool is @command{mmc --make},
which, as the name says,
integrates the functionality of a make-like build tool
into the Mercury compiler.
Like @command{mmake},
@command{mmc --make} needs access
to the module-name-to-file-name map in @file{Mercury.modules}
if some module in the program is stored in a file
whose name does not match the module name.
This means that the first step in building an executable
is still usually @command{mmc -f *.m}.
Unlike @command{mmake},
when @command{mmc --make} is asked to build an executable for a program
given the name of its main module,
it can itself find out the dependencies (importer-imported relationships)
between the modules of the program;
it does not need previously-built files
containing makefile fragments to give it this information.
It therefore has no need for any equivalent of the
@command{mmake @var{main_module}.depend} command.
This allows an executable to be built with just these two commands:
@example
mmc -f *.m
mmc --make @var{main_module}
@end example
In this case, the @var{main_module} part of the second command is a file name:
specifically, the name of the executable to be built.
However, this non-option argument to @code{mmc --make}
is not the name of a file to be @emph{compiled};
it is the name of a file to be @emph{built}.
In general, non-option arguments to @code{mmc --make}
should be the names of @emph{targets},
in the same sense of @command{make} targets.
Most targets are files to be built, but some are not,
the same way as @code{PHONY} targets in @command{make} do not represent files.
For example, @command{mmc --make @var{main_module}.realclean}
asks the compiler to delete all the automatically-regenerable files
that are part of the @var{main_module} program.
Note that @command{mmc --make} has a subtle advantage over @command{mmake}.
While @command{mmake} uses (because it has to)
module-to-module dependency information that was current
when the relevant modules' were last (re)compiled
(because that is when their @file{.d} files were last updated),
@command{mmc --make} always uses @emph{current} dependency information,
because it gets that information
from the current versions of the modules' source files.
Most of the time, the difference does not matter,
for one of several reasons:
@itemize
@item
because most changes to Mercury modules do not affect
their @code{:- import_module} and @code{:- use_module} declarations;
@item
because deleting an @code{:- import_module} or @code{:- use_module}
declaration cannot lead to obsolete versions of interface files being read
(since they lead to @emph{fewer} interface files being read);
@item
because when an @code{:- import_module} and @code{:- use_module}
declaration is added,
which @emph{can} lead to obsolete versions of the interface files
of the newly-imported modules being read,
those interface files have a reasonably probability
of being brought up to date
before being needed by the module that added the new import,
due to some @emph{other} module already depending on them; and
@item
because a nontrivial fraction of the time,
the part of the interface file that bringing it up-to-date would change
is of no relevance to the newly-importing module.
@end itemize
Most of the time, one or more of these mitigating circumstances will apply.
However, sometimes none of them do.
In such cases, using @command{mmake} to build the selected target will fail,
with the failure being caused by @command{mmake}'s reliance
on out-of-date dependency information.
(This could mean e.g. @command{mmake} not knowing that
it must update the @file{.int} file of a newly-imported module
before generating target language code for the importing module.)
In pretty much all of the usual scenarios, the attempt to build the target
will cause the out-of-date dependency information to be updated,
so the @emph{next} attempt to build that same target will succeed.
Nevertheless, the failure of the first attempt is annoying.
Such transient failures won't happen with @command{mmc --make},
because it @emph{always} works with up-to-date dependency information.
@c Another difference between @command{mmake} and @command{mmc --make}
@c is that by default, the former puts all the intermediate files it generates
@c (interface files, optimization files, target language files, and so on)
@c into the current directory, which usually leads to a lot of clutter.
@c By contrast, @command{mmc --make} avoids this clutter
@c by putting all intermediate files
@c into a separate directory named @file{Mercury}.
@c In fact, it minimizes clutter even inside the @file{Mercury} directory,
@c by putting e.g.@:
@c @itemize
@c @item all @file{.int3} files into the @file{Mercury/int3s} subdirectory,
@c @item all @file{.int} files into the @file{Mercury/ints} subdirectory,
@c @item all @file{.c} files into the @file{Mercury/cs} subdirectory,
@c @end itemize
@c and so on.
@c You can also choose to use this file organization with @command{mmake}
@c by setting the makefile variable @code{MMAKE_USE_SUBDIRS} to @code{yes}.
For more information on @command{mmc --make},
please see ZZZ @c @ref
@c ----------------------------------------------------------------------------
@node Mercury grades
@chapter Mercury grades
@menu
* The Mercury backends::
* The importance of consistency::
* Base grades::
* Grade modifiers::
@end menu
@node The Mercury backends
@section The Mercury backends
The Mercury compiler has two backends.
The first backend implemented by the Mercury team
translates Mercury programs to
what is effectively assembly-level code in C syntax.
Most compilers generate either assembly level code
(either assembly code itself or binary machine code),
so the first part is quite conventional.
The second part, generating this assembly level code in C syntax,
was rare at the time, though it has become more common since.
We chose that approach because it allowed us to take advantage
of the huge amount of work put into C compilers,
both in terms of making C available on pretty much all commonly used platforms,
and generating for them not just code that works, but @emph{fast} code.
Like most compilers, the Mercury compiler has representations
for both the source code and the target code.
In compilers for imperative languages,
these are usually called the abstract syntax tree (AST)
and the intermediate representation (IR) respectively.
The Mercury compiler's versions of these are substantially different,
so we use different names for them:
the high-level data structure (HLDS)
and the low-level data structure (LLDS).
@c (Revealing a complete lack of originality.)
The low-level code generated by the original backend
is about as far from the code that a human C programmer would write
as it is possible to get.
Later on, as part of a research project,
we investigated translating Mercury code
into @emph{idiomatic} C code,
with a view towards making the approach general enough
to be able to produce idiomatic code
in other imperative programming languages as well.
We call the compiler's internal representation of this kind of the code
the medium-level data structure (MLDS),
since it is clearly lower level than Mercury code,
but higher level than assembly code.
From the names of these internal representations,
Mercury calls the first backend the LLDS backend,
and the second backend the MLDS backend.
The first generates low (assembly) level C code,
while the second generates either high level C code, Java code, or C# code.
@node The importance of consistency
@section The importance of consistency
In general, a Mercury program consists of many modules.
These modules must be compiled in a manner
that allows the resulting files codes to be linked together.
For example if you compile e.g.@:
module @var{module_a} to @file{@var{module_a}.java}
and module @var{module_b} to @file{@var{module_b}.c},
which the Java and C implementations compile further
to @file{@var{module_a}.class} and @file{@var{module_b}.o}.
This is not just because JAR files and object files have different formats;
the more fundamental reason is that the codes in them
make fundamentally different assumptions
about how the different modules of a program
are supposed to communicate and cooperate with each other.
This is why if you compile
both module @var{module_a} and module @var{module_b} to C,
but compile module @var{module_a} using the LLDS backend
and @var{module_b} using the MLDS backend,
any attempt to link @file{@var{module_a}.o} and @file{@var{module_b}.o}
will still fail.
It will fail because the two backends
use different naming schemes for the C code they generate,
so that the name of the C function
that implements e.g.@: the predicate @var{module_b.q}
will be different from the name by which
a call from @var{module_a.p} will try to refer to @var{module_b.q}.
This difference is deliberate.
This is because any attempt to ``cure'' such link failures
by having the two backends use the same C naming scheme
would address only @emph{incidental} incompatibilities;
the @emph{fundamental} incompatibilities,
such as the LLDS backend managing its own stacks (two of them)
while the MLDS backend relies on the standard C call stack,
would still remain.
The @command{mmc} option @option{--target} controls
which of its target languages the Mercury compiler will generate code for.
With @option{--target c}, Mercury will generate C code;
with @option{--target java}, Mercury will generate Java code; and
with @option{--target c#}, Mercury will generate C# code.
When generating C, the option @option{--high-level-code} controls
whether code generation will use the LLDS or the MLDS backend,
generating assembly code in C syntax or idiomatic C code respectively.
(Since you cannot write assembly-level code in either Java or C#,
the compiler will always use the MLDS backend
when generating Java or C# target code.)
What the previous paragraph is saying is that
if you compile all the modules of a program,
an attempt to link the resulting files together can succeed
@emph{only if} all the modules were compiled
using the exact same values of
@option{--target} and @option{--high-level-code} options.
These are not the only options that have this property.
There are other options as well,
and in fact Mercury has more such options than most other languages.
This is why unlike most other languages,
Mercury has an explicit name for this concept:
it calls each set of compatible values of those options a @dfn{grade}.
A Mercury grade succinctly specifies the value of roughly twenty options
(depending on how exactly you count them,
and when, since we add new ones from time to time).
Each grade consists of a @emph{base grade} (which must be present)
followed by zero or more other @emph{grade modifiers}
(which are therefore optional).
@c XXX This says we require the base grade to come first,
@c but we do NOT enforce this.
@c However, there is no point in telling people this,
@c especially because it would give the lie to the next sentence,
@c which *does* help us with explanations.
The names of the grade modifiers all start with period;
the names of the base grades do not.
The name of a grade is a concatenation of the selected base grade
and the selected grade modifiers
(the grade modifiers may be given in any order).
For example, @command{hlc.tr.gc} specifies
the base grade @command{hlc} (meaning high level C code)
and the grade modifiers @command{.tr} and @command{.gc}
(which respectively call for the use of trailing
and of the Boehm-Demers-Weiser garbage collector).
@node Base grades
@section Base grades
The base grade specifies
what target language to compile the Mercury program to,
and if the compiler can do this in several different ways,
selects one of those ways.
There are three MLDS and three LLDS base grades.
The available MLDS base grades, and the option values they correspond to, are
@table @code
@item hlc
@option{--target c} and @option{--high-level-code}
@item java
@option{--target java} and @option{--high-level-code}
@item csharp
@option{--target c} and @option{--high-level-code}
@end table
These base grades each call for the generation of
relatively natural-looking code in the selected target language.
@c and do not require much description beyond that.
The available LLDS base grades, and the option values they correspond to, are
@table @code
@item none
@option{--target c}, @option{--no-high-level-code},
@option{--no-gcc-global-registers}, and @option{--no-gcc-non-local-gotos}
@item reg
@option{--target c}, @option{--no-no-high-level-code},
@option{--gcc-global-registers}, and @option{--no-gcc-non-local-gotos}
@item asm_fast
@option{--target c}, @option{--no-high-level-code},
@option{--gcc-global-registers}, @option{--gcc-non-local-gotos} and
@option{--asm--labels}
@end table
These base grades each call for the generation of
assembly-like code in C syntax,
but they differ in what GNU extensions to C, if any,
the generated code will use.
There are three extensions that they can potentially use:
@table @code
@item @option{--gcc-global-registers}
specifies the use of a GNU extension
that allows the generated code to tell @command{gcc}
that a given global variable should be stored in a machine register.
The Mercury implementation can use this mechanism
to speed up access to the most frequently used virtual registers
of the Mercury abstract machine,
such as the return address register
(which is used on every call)
and the pointer to the top of the det stack
(which is used at the start and end of the code
of all predicates that cannot succeed more than once).
@item @option{--gcc-non-local-gotos}
specifies the use of a GNU extension
that allows the generated code to simply take the address of a C label,
store that address somewhere,
and to later retrieve that address and jump to it.
This speeds up transfers of control
(conditional branches and unconditional jumps)
within a single C function.
@item @option{--asm--labels}
specifies the use of a GNU extension
that the address of a label to be made global,
i.e. accessible from even outside the C function in which it occurs.
With the appropriate precautions,
which the Mercury system of course takes,
this speeds up transfers of control
from anywhere to anywhere else in the Mercury program.
@end table
The base grade @code{none} calls for no GNU extensions to be used.
It is therefore the slowest of the LLDS base grades,
but it is also the most portable.
The base grade @code{reg} is faster and less portable,
and the base grade @code{asm_fast} is faster and less portable still.
In general, using more GNU C extensions will make the program faster,
but some platforms, compilers or compiler versions
do not support specific extensions.
While it is in theory possible to combine
@option{--gcc-non-local-gotos} with @option{--no-asm--labels},
in practice there is no advantage in doing so.
And while it is also possible to combine
@option{--gcc-non-local-gotos} @option{--asm--labels} with
@option{--no-gcc-global-registers},
we do not know of any platforms
on which @option{--gcc-non-local-gotos} and @option{--asm--labels} work
but @option{--gcc-global-registers} does not.
This is why we use only three out of the eight possible combinations
of the values of these three options.
The default base grade is system dependent,
but will be either @samp{hlc} or @samp{asm_fast},
as these are the two fastest.
@node Grade modifiers
@section Grade modifiers
Every grade modifier belongs to a @dfn{grade modifier group}.
Each grade modifier group governs a single aspect of compilation.
Because each modifier calls for handling that aspect
differently from what the other modifiers in its group call for,
a grade may contain at most one modifier from each group.
Note also that
@itemize
@item
some grade modifiers are compatible
only with some base grades (usually the ones that target C) and not others; and
@item
some grade modifiers in one group
are incompatible not just with all other grade modifiers in the same group,
but also with some grade modifiers from other groups.
@end itemize
Note also that the Mercury standard library
will have been installed on your system
in only a subset of the set of all possible grades.
Each of the following subsections except the last
documents one group of grade modifiers.
The last subsection documents which grade modifiers
are compatible with grade modifiers from other groups.
@menu
* Grade modifiers for debugging Mercury programs::
* Grade modifiers for profiling Mercury programs::
* Grade modifiers for trailing::
* Grade modifiers for minimal model tabling::
* Grade modifiers for parallelism::
* Grade modifiers for flexible stack sizes::
* Grade modifiers for garbage collection::
* Grade modifiers for single precision floats::
* Grade modifiers for target language debugging::
* Grade modifiers for pregenerated source distributions::
* Compatibility of grade modifiers::
@end menu
@c NODOC We do not document .pregen
@c NODOC We do not document .rbmm*
@c ----------------------------------------------------------------------------
@node Grade modifiers for debugging Mercury programs
@subsection Grade modifiers for debugging Mercury programs
In the absence of both of the grade modifiers in this group,
the Mercury compiler generates executables that cannot be debugged,
because they do not include the information needed
for the operation of the Mercury debugger,
whose name is @command{mdb} @ref{Debugging}.
@table @code
@item .debug
@item .decldebug
Compiling programs in a grade that includes
either the @code{.debug} or the @code{.decldebug} grade modifier
generates executables that can be debugged using @command{mdb}.
Invoking @command{mdb} on such executables lets users do
the kinds of things that people do with C debuggers such as @command{gdb}
(set breakpoints, step forward e.g. one call at a time,
and print the values of variables, amongst others),
as well as the kinds of things that people do with debug mode in Prolog:
(such as jump back from the end of a call to its beginning).
The difference between them is that
the declarative debugging aspects of @samp{mdb}
will work only with @samp{.decldebug}.
While both @code{.debug} and @code{.decldebug}
increase the size of the executable and reduce its speed,
both the size increase and the speed reduction
is larger with @code{.decldebug} than with @code{.debug}.
@sp 1
Both of these grade modifiers are compatible only with LLDS base grades.
@end table
@c NODOC We do not document ssdebug.
@c ----------------------------------------------------------------------------
@node Grade modifiers for profiling Mercury programs
@subsection Grade modifiers for profiling Mercury programs
In the absence of all of the grade modifiers in this group,
the Mercury compiler generates executables that cannot be profiled.
Mercury actually supports two completely separate profilers:
@command{mprof} and @command{mdprof}.
@command{mprof} is effectively a Mercury clone
of one of the standard profilers for C, namely @command{gprof}.
Like many (if not most) profilers,
it operates by recording what part of the program was executing
when its process is sent a periodic profiling signal by the OS.
Like @command{gprof}, at each profiling signal,
it records what predicate it was executing at the time
and where it was called from, but no more than that.
This works well for C, where each function typically has one job,
but not for Mercury, which has many polymorphic predicates
that can be used in the implementation of many different jobs,
with many different performance behaviors.
This is why Mercury also has @command{mdprof},
the Mercury @emph{deep} profiler,
which at each profiling signal records the identity
of not just the immediate parent of the currently executing predicate,
but effectively the identities of @emph{all} its other ancestors as well.
(This is the ``deep context'' after which the profiler is named.)
The two profilers operate differently
and have different strengths and weaknesses.
You can read more about both of them in @ref{Profiling}.
@table @code
@item .prof
Compiling programs in a grade that includes the @code{.prof} grade modifier
generates executables that, when executed,
generate files containing information that @command{mprof},
the @command{gprof}-style profiler,
can use to tell you where the program is spending its time.
@sp 1
This grade modifier is compatible only with base grades that target C.
@item .memprof
Compiling programs in a grade that includes the @code{.memprof} grade modifier
generates executables that, when executed,
generate files containing information that @command{mprof},
the @command{gprof}-style profiler,
can use to tell you where the program is allocating memory.
@sp 1
This grade modifier is compatible only with base grades that target C.
@item .profdeep
Compiling programs in a grade that includes the @code{.profdeep} grade modifier
generates executables that, when executed,
generate files containing information that @command{mdprof},
the Mercury deep profiler, can use to tell you
both where the program is spending its time and where it is allocating memory.
@sp 1
This grade modifier is compatible only with LLDS base grades
(which all target C).
@end table
@c NODOC We do not document .proftime, .profcalls, and .profall
@c NODOC We do not document Threadscope (here, but we do elsewhere?).
@c NODOC We do not document term size profiling.
@c ----------------------------------------------------------------------------
@node Grade modifiers for trailing
@subsection Grade modifiers for trailing
In the absence of the @code{.tr} grade modifier,
the Mercury compiler generates executables that do not support trailing.
Trailing is a technique that
the implementations of logic programming languages use
to support constraint solving.
All Prolog implementations use it,
because unification in standard Prolog is effectively a solver
for constraints of the form ``are these two terms unifiable?''.
(Such constraints are usually called @dfn{Herbrand} constraints.)
In Mercury, the mode system imposes a requirement that
when two terms are unified, one of them must be ground,
which means that such questions are always trivially answerable.
In fact, the design of Mercury was driven in large part by the intention
to @emph{avoid} any requirement for constraint solving,
because it makes programs harder to understand
both by humans, and by the compiler.
Unlike Prolog, Mercury thus has no constraint solver built into it.
However, Mercury @emph{can} be used to @emph{implement} constraint solvers.
While the act of posting a constraint in such a program is a declarative action,
its implementation requires updating a constraint store.
This in turn requires that when execution backtracks
past the goal that posted the constraint,
the update to the constraint store must be undone.
This is why in the right grades, Mercury can support a trail.
@c XXX CHECKME
(@pxref{Trailing, , ,
mercury_reference_manual,The Mercury language Reference Manual}).
The trail is a stack-like data structure
that consists of a sequence of entries,
each of which effectively describes how to undo an update to a data structure.
This can be used to implement constraint solvers like this:
@itemize @bullet
@item
When execution is about to enter a disjunction or an if-then-else,
the implementation records the address of the top of the trail,
effectively as a snapshot.
@item
When the program adds a new constraint to the constraint store,
it must also push a new entry on top of the trail that describes
how to undo the addition of this new constraint.
(That entry will consist of the address of the undo function,
and an argument for it that identifies the specific addition to undo.)
@item
Whenever execution backtracks,
either to a later disjunct in a disjunction
or to the else part of an if-then-else,
the implementation walks the trail
from the current top of the trail down to the snapshot address
that was recorded on entry to the current disjunction or if-then-else,
and executes the undo actions that they encode.
(For example, a trail entry can contain
the address of a C function to call,
and an argument to invoke that function with.)
This is usually called @emph{unwinding} the trail.
@end itemize
@table @code
@item .tr
Compiling programs in a grade that includes the @code{.tr} grade modifier
generates executables that support trailing.
This means that the compiler-generated code
will create the snapshots and unwind the trail as needed.
@c The part in between,
The addition of new constraints to the constraint store,
and the addition of new entries to the trail to undo those additions,
will be done by C code in @code{foreign_proc} pragmas written by the user.
(Each trail entry consists of the address of a C function to call,
and an argument to invoke that function with.)
This grade modifier is compatible only with base grades that target C.
@end table
@c ----------------------------------------------------------------------------
@node Grade modifiers for parallelism
@subsection Grade modifiers for parallelism
In the absence of the @code{.par} grade modifier,
the Mercury compiler generates executables
that do not support parallel execution in any form.
@table @code
@item .par
Compiling programs in a grade that includes the @code{.par} grade modifier
generates executables that support parallel execution.
What form of parallel execution is supported depends on the backend.
@itemize
@item
With the MLDS backend, @code{.par} grades support user-managed parallelism,
using whatever thread support is provided by the target language.
Programmers can use the operations
of the @code{thread} module of the Mercury standard library
to spawn new threads, and to collect their results once they are done.
@item
With the LLDS backend, @code{.par} grades support compiler-managed parallelism.
Programmers can ask the compiler to execute two goals in parallel
simply by replacing the comma (the sequential conjunction operator)
between them with an ampersand @samp{&}, the parallel conjunction operator.
The compiler will take care of the rest.
(Note that @samp{&} has this effect @emph{only} in LLDS @code{.par} grades;
in all other grades, the compiler silently converts all @samp{&}s into commas.)
Note: due to a code generation bug,
at the moment LLDS parallelism does not work.
@end itemize
@end table
@c ----------------------------------------------------------------------------
@node Grade modifiers for minimal model tabling
@subsection Grade modifiers for minimal model tabling
Mercury supports several forms of tabling,
most of which must be explicit enabled
for each procedure that are intended to apply to
@c XXX CHECKME
(@pxref{Tabled evaluation, , ,
mercury_reference_manual,The Mercury language Reference Manual}).
(Recall that a @dfn{procedure} is one mode of a predicate or function.)
Tabling operates by recording (in a table, hence the name),
for each vector of input values to a procedure,
the set of vectors of output values the procedure returns as results.
(For @code{det} code, the set will contain exactly one vector;
for @code{semidet} code, the set will contain at most one vector.)
For later calls to a tabled procedure,
the Mercury implementation will automatically check whether
the current vector of values of the input arguments has occurred before.
If it has, it will return the recorded set of answers.
If it has not, it will compute the result or results, and record it or them.
This system has a problem if the tabled procedure calls itself recursively,
either directly or indirectly,
with the exact same vector of input values,
@emph{before} its initial invocation has completed,
because in that case,
there will be an entry recording the input vector,
but the corresponding set of output value vectors will not yet be available.
With the most frequently used form of tabling, i.e. @emph{memoization},
this is a fatal error,
and the Mercury implementation will automatically abort the program.
However, for @code{nondet} predicates, there is a way to avoid this abort,
at the cost of a much more complicated execution model.
This solution gets its name, @dfn{minimal model tabling},
from the fact that it is intended to return,
for each query, all the answers that match that query
in a specific @dfn{minimal model} of the program,
named the @dfn{perfect model}.
(We call it ``minimal model tabling'' instead of ``perfect model tabling''
because the former is the standard terminology for this kind of tabling
in the logic programming literature.)
@c ZZZ Wikipedia has no reference for perfect model semantics.
@c We could point to Przymusinski's paper titled
@c "On the declarative and procedural semantics of logic programs".
Minimal model tabling consists of
@itemize
@item
recording that state of the computation at the point of the recursive call;
@item
continuing execution as if the call failed;
@item
when the top-level call to the procedure
with the given vector of input argument values
finds a new solution,
@emph{restoring} the recorded state of the computation,
and restarting its execution, but this time behaving
as if the recursive call just returned the new solution.
@item
This restarted execution may obviously return even more solutions,
which have to be fed back to the recursive call
(or in the general, the recursive calls, plural).
The process ends when all restarted calls lead
either to no solution, or to solutions that have all previously been
not just recorded, but also fed back to all recursive call sites.
@end itemize
The execution mechanisms required for this are quite complicated,
and impose significant overheads in both time and space,
even on the parts of the program that do not benefit from it.
This is why in the absence of the following grade modifiers,
the Mercury compiler generates executables
that do not support minimal model tabling.
@table @code
@item .mm
Compiling programs in a grade that includes the @code{.mm} grade modifier
generates executables that support minimal model tabling.
This grade modifier is compatible only with LLDS base grades.
@item .mmsc
The grade modifier @samp{.mmsc} is a synonym for @samp{.mm},
standing for ``minimal model via stack copying'',
since the standard implementation works by copying parts of the stack.
The synonym exists because Mercury also has
another implementation of minimal model tabling.
This other implementation, which is incomplete
and was only ever useful for experiments,
is based on a completely different implementation technique.
@end table
@c ----------------------------------------------------------------------------
@node Grade modifiers for flexible stack sizes
@subsection Grade modifiers for flexible stack sizes
In MLDS grades, the code generated by the Mercury compiler
uses the native call stack of the target language.
In LLDS grades, on the other hand,
the generated code manages its own two stacks:
the @dfn{det stack}, which stores the data
of procedures that @emph{cannot} succeed more than once,
and the @dfn{nondet stack}, which stores the data
of procedures that @emph{can} succeed more than once.
(The two stacks are separate because
for predicates that can succeed more than once, we cannot throw away
the values of their input arguments and local variables when they succeed,
while for predicates that cannot succeed more than once,
we can throw them away, and for good performance, we @emph{must} do so.)
By default, Mercury reserves a fixed size block of memory for each stack,
and never increases their size during execution.
To make this work even for programs that use relatively deep recursion,
the default size of the det stack is
16 megabytes on 32-bit machines, and 32 megabytes on 64-bit machines.
These default sizes can be overridden using runtime options
(@pxref{Environment variables affecting the Mercury runtime system}),
but whatever pair of sizes one picks,
for some programs, they will be wasteful overkill,
while for some other programs, hopefully rarely,
they nevertheless will not be enough.
If the platform allows it, we make the top page of each stack inaccessible,
so that a stack overflow,
instead of accessing and overwriting memory effectively randomly,
causes the operating system to send a signal to the program.
If not caught and handled,
this signal will abort the program, minimizing the damage.
@c Each frame on the det stack contains
@c a pointer to the stack frame just below it,
@c the values of the input arguments and local variables of a call,
@c and the return address to which the call will jump when done.
@c Each frame on the nondet stack is similar,
@c but it contains more information to manage the distinct actions
@c that such procedures should take on success and on failure.
We therefore have a grade modifier
that makes the sizes of the two stacks dynamic,
and able to respond to the actual requirements of the program being executed.
@table @code
@item .stseg
Compiling programs in a grade that includes the @code{.stseg} grade modifier
generates executables that use @dfn{stack segments},
small memory areas whose size is 16 or 32 kilobytes
on 32- and 64-bit systems respectively.
In @code{.stseg} grades, the det and nondet stacks
both consist of a linked list of one or more stack segments.
Each stack grows by adding a new segment at a time on demand,
and shrinks by putting segments back on a free list
once they are no longer needed.
Using stack segments does have a small performance penalty,
because it requires code for checking
@itemize @bullet
@item
whether the creation of a new stack frame
requires the allocation of a new stack segment
and adding it to the linked list, and
@item
whether a stack frame being popped off the stack
was the last frame in its segment,
allowing the segment to be removed from the stack's linked list,
and made available for future allocations.
@end itemize
However, for many applications,
this is a more than acceptable price to pay
for not imposing any limit on stack sizes
other than the amount of available memory.
This grade modifier is relevant only for LLDS base grades,
and is compatible only with them.
@end table
@c NODOC We do not document .exts
@c When generating low-level C,
@c Mercury implements its own stacks (two of them).
@c The default is to make each stack a fixed size
@c (usually a relatively large size,
@c though the size of each stack can be controlled using runtime options).
@c We make the page(s) at the tops of the stacks inaccessible,
@c so that a stack overflow,
@c instead of accessing and overwriting memory effectively randomly,
@c causes the operating system to send a signal to the program.
@c If not caught and handled, this signal will abort the program,
@c minimizing the damage.
@c However, for programs for which this is not acceptable,
@c users can specify the @samp{.stseg} grade component.
@c This calls for each stack to be composed of
@c small memory segments chained together in a list.
@c When there is no room in the current segment for a new stack frame,
@c we simply allocate a new segment and add it to the list.
@c This approach has higher overhead,
@c since calls to, and returns from, procedures must execute more code,
@c but it avoids imposing any limit on stack size
@c other than the size of available memory.
@c When targeting anything other than low-level C,
@c the stack is always managed by the implementation of the target language,
@c so for them, the @samp{.stseg} modifier is neither relevant nor supported.
@c ----------------------------------------------------------------------------
@node Grade modifiers for garbage collection
@subsection Grade modifiers for garbage collection
By default, the Mercury system provides no garbage collection
beyond what the target language provides.
C# and Java have their own builtin garbage collectors, but C does not.
Since garbage collection is essential for all programs
other than those with @emph{very} short runtimes,
base grades that target C usually include a grade modifier
that specifies which garbage collector to use.
@table @code
@item .gc
Compiling programs in a grade that includes the @code{.gc} grade modifier
generates executables that use the standard Mercury garbage collector,
which is the Boehm-Demers-Weiser conservative collector for C.
This grade modifier is relevant only for base grades that target C,
and is compatible only with them.
@end table
The reason why this is an explicit grade modifier is that
over the years, we have tried out several collectors for C.
These had their own grade modifiers, to allow users to specify their use.
However, only the Boehm-Demers-Weiser collector has stood the test of time.
@c NODOC We do not document .agc, .hgc, or other experimental gc systems.
@c ----------------------------------------------------------------------------
@node Grade modifiers for single precision floats
@subsection Grade modifiers for single precision floats
Many imperative languages have at least two floating point types,
one single precision and one double precision,
which usually means they are 32 bits and 64 bits in size respectively.
Mercury has only one floating point type, @code{float},
which by default is implemented
as an IEEE 754 double-precision 64-bit floating point number.
When targeting Java or C#,
this default cannot be overridden:
values of the Mercury type @code{float}
are always represented by values of type @code{double}
(which exists in both those languages).
When targeting C, the default @emph{can} be overridden
by using the following grade modifier.
@table @code
@item .spf
Compiling programs in a grade that includes the @code{.spf} grade modifier
(which stands for ``single-precision float'')
generates executables that represent values of the Mercury @code{float} type
as 32-bit values of C's @samp{float} type.
This grade modifier was intended to be used on 32-bit platforms.
On those platforms, 64-bit floats are twice the size of a machine word,
which means that they cannot be stored the same way as all other values,
and must instead be stored on the heap.
This means that every operation
that generates a new 64-bit floating point value
must allocate a heap cell for it, and write those 64 bits to that cell.
(This is usually called @dfn{boxing} the 64-bit value.)
Representing Mercury @code{float}s as 32-bit single-precision values
avoids this overhead, improving both memory consumption and speed.
This made this grade modifier useful for programs
that did not require the extra precision (or range) offered using 64-bits.
@code{.spf} grades provide no performance advantage at all 64-bit platforms,
because on those platforms, 64-bit values do not require boxing.
On the other hand, they may simplify the use of C APIs
that exclusively use single precision floats.
This grade modifier is relevant only for base grades that target C,
and is compatible only with them.
@end table
@c ----------------------------------------------------------------------------
@node Grade modifiers for target language debugging
@subsection Grade modifiers for target language debugging
Mercury programs are intended to be debugged
using @command{mdb}, the Mercury debugger.
However, @command{mdb} treats non-Mercury code as a black box,
and cannot give any insights into its behavior.
@table @code
@item .target_debug
Compiling programs in a grade that
includes the @code{.target_debug} grade modifier
generates executables that are intended to be debuggable
with usual debuggers for the target language selected by the base grade.
This grade modifier is intended mainly
to help the implementors of Mercury itself debug interactions
between compiler-generated target code and the Mercury runtime system.
However, in certain rare cases, it may also be useful to other users
in debugging interactions between compiler-generated target code
and the contents of @code{foreign_proc} and/or @code{foreign_code} pragmas.
This grade modifier could be applicable to all base grades,
but is intentionally restricted to MLDS grades.
This is because in LLDS grades,
the assembler-like C code generated by @command{mmc}
will probably confuse debuggers such as @command{gdb},
and it will definitely confuse
any Mercury programmer who is not a Mercury implementor.
The more idiomatic target language code
that @command{mmc} generates in MLDS grades
is still far from trivial for non-implementors to understand,
but at least they have a fighting chance.
@end table
@c ----------------------------------------------------------------------------
@node Grade modifiers for pregenerated source distributions
@subsection Grade modifiers for pregenerated source distributions
There is one grade modifier that users will probably encounter
that they will propably never need to use themselves.
This the grade modifier that the Mercury team itself
uses only for a single purpose: making source distributions.
Such distributions include not just the code of the Mercury system,
which is mostly written in Mercury itself.
but also the C code generated for each Mercury module.
This allows people
who do not have a working Mercury installation on their machine to create one.
@table @code
@item .pregen
Compiling programs in a grade that
includes the @code{.pregen} grade modifier
switches off all optional features,
and tells the compiler to make the fewest possible assumptions
about the platform on which the generated code will run.
(For example, the generated code will work
on both 32-bit and 64-bit platforms.)
Source distributions use grades that include this modifier
(the grade usually being @code{hlc.gc.pregen})
because it makes the C code in them portable to as many platforms as possible.
However, it has no advantages beyond this,
and, on 64-bit machines,
the requirement to use a data representation scheme
that also works on 32-bit platforms
imposes a nontrivial cost in performance.
This is why for pretty much any purpose other than source distributions,
other grades are a better choice.
This grade modifier is applicable
only to the base grades @code{hlc} and @code{none}.
@c Actually, grade_lib/grade_structure.m also allows it
@c for the reg and asm_fast base grades as well, but that conflicts with
@c the whole "make as few assumptions about the platform as possible" thing.
@end table
@c ----------------------------------------------------------------------------
@node Compatibility of grade modifiers
@subsection Compatibility of grade modifiers
ZZZ TODO
@c ----------------------------------------------------------------------------
@ignore
This is the original documentation of the --grade option.
It is saved here to serve as a mine of ideas and text
for a new chapter on grades.
@table @asis
@c @cindex .agc (grade modifier)
@c @cindex .ssdebug (grade modifier)
@cindex .debug (grade modifier)
@cindex .decldebug (grade modifier)
@cindex .gc (grade modifier)
@cindex .memprof (grade modifier)
@cindex .mm (grade modifier)
@cindex .par (grade modifier)
@cindex .prof (grade modifier)
@cindex .profdeep (grade modifier)
@cindex .spf (grade modifier)
@cindex .stseg (grade modifier)
@cindex .threadscope (grade modifier)
@cindex .tr (grade modifier)
@item threads
The default is whatever thread support is provided by the target language.
When targeting C,
thread support can be enabled by specifying the grade modifier @samp{.par}.
When targeting low-level C,
this also enables the use of the parallel conjunction operator @samp{&}.
Since Mercury implements parallel conjunctions
only in low-level C grades with the @samp{.par} grade modifier,
in every other situation, the compiler silently converts
every occurrence of @samp{&} to a comma,
the usual @emph{sequential} conjunctions operator.
@item thread profiling
In low-level C grades with the grade modifier @samp{.par},
users can enable support for ThreadScope-style thread profiling
by also specifying the grade module @samp{.threadscope}.
The default is no support for thread profiling.
Note that form of profiling is experimental,
and it is not currently supported.
@end table
The default grade is system-dependent;
it is chosen at installation time by @samp{configure},
the auto-configuration script,
but can be overridden if desired
with the environment variable @env{MERCURY_DEFAULT_GRADE}.
@vindex MERCURY_DEFAULT_GRADE
On any given particular installation,
the Mercury runtime system and Mercury standard library
will be installed in only a subset of the possible grades;
you can find out which grades these are
by invoking the Mercury compiler
with the @samp{--output-stdlib-grades} option.
Attempting to use a grade which has not been installed
will result in an error at link time.
(The error message will typically be something like
@samp{ld: can't find library for -lmercury}.)
The tables below show the options
that are selected by each base grade and grade modifier;
they are followed by descriptions of those options.
@table @asis
@item @var{Grade}
@var{Options implied}.
@findex --gcc-global-registers
@findex --no-gcc-global-registers
@findex --gcc-nonlocal-gotos
@findex --no-gcc-nonlocal-gotos
@findex --asm-labels
@findex --no-asm-labels
@findex --high-level-code
@findex --no-high-level-code
@findex --target
@findex --csharp
@findex --java
@findex --gc
@findex --profiling
@findex --memory-profiling
@findex --deep-profiling
@findex --use-trail
@findex --record-term-sizes-as-words
@findex --record-term-sizes-as-cells
@findex --single-prec-float
@findex --stack-segments
@item @samp{hlc}
@code{--target c --high-level-code}.
@item @samp{none}
@code{--target c --no-gcc-global-registers --no-gcc-nonlocal-gotos --no-asm-labels}.
@item @samp{reg}
@code{--target c --gcc-global-registers --no-gcc-nonlocal-gotos --no-asm-labels}.
@c @item @samp{jump}
@c @code{--target c --no-gcc-global-registers --gcc-nonlocal-gotos --no-asm-labels}.
@c @item @samp{fast}
@c @code{--target c --gcc-global-registers --gcc-nonlocal-gotos --no-asm-labels}.
@c @item @samp{asm_jump}
@c @code{--target c --no-gcc-global-registers --gcc-nonlocal-gotos --asm-labels}.
@item @samp{asm_fast}
@code{--target c --gcc-global-registers --gcc-nonlocal-gotos --asm-labels}.
@item @samp{csharp}
@code{--target csharp --high-level-code}.
@item @samp{java}
@code{--target java --high-level-code}.
@item @samp{.gc}
@code{--gc boehm}.
@c @item @samp{.agc}
@c @code{--gc accurate}.
@item @samp{.prof}
@code{--profiling}.
@item @samp{.memprof}
@code{--memory-profiling}.
@item @samp{.profdeep}
@code{--deep-profiling}.
@c The following are undocumented because
@c they are basically useless... documenting
@c them would just confuse people.
@c
@c @item @samp{.profall}
@c @code{--profile-calls --profile-time --profile-memory}.
@c (not recommended because --profile-memory interferes with
@c --profile-time)
@c
@c @item @samp{.proftime}
@c @code{--profile-time}.
@c
@c @item @samp{.profcalls}
@c @code{--profile-calls}.
@c
@item @samp{.tr}
@code{--use-trail}.
@c @item @samp{.tsw}
@c @code{--record-term-sizes-as-words}.
@c @item @samp{.tsc}
@c @code{--record-term-sizes-as-cells}.
@item @samp{.spf}
@code{--single-prec-float}
@item @samp{.stseg}
@code{--stack-segments}
@item @samp{.debug}
@code{--debug}.
@item @samp{.decldebug}
@code{--decl-debug}.
@c @item @samp{.ssdebug}
@c @code{--ss-debug}.
@item @samp{.par}
@code{--parallel}.
@item @samp{.threadscope}
@code{--threadscope}.
@end table
@end table
@end ignore
@c ----------------------------------------------------------------------------
@node Running
@chapter Running Mercury programs
ZZZ TODO
When targeting C on systems that do not require an executable file extension,
@samp{mmc} will put the executable into a file called @file{@var{filename}};
on systems (such as Windows)
that use @file{.exe} as the file extension for executables,
@samp{mmc} will put the executable
into a file called @file{@var{filename}.exe}.
When targeting C#,
@samp{mmc} will generate a process assembly called @file{@var{filename}.exe}.
On Windows, this process assembly can be run directly.
On non-Windows systems,
@samp{mmc} will also generate a shell script called @file{@var{filename}}
that invokes the CLI execution environment on the process assembly.
(See the file @file{README.CSharp.md} included in the Mercury distribution
for further details.)
When targeting Java,
@samp{mmc} will package up all of the class files for the executable
into a Java archive (JAR) named @file{@var{filename}.jar}.
It will also generate a launcher that invokes the program using the Java
interpreter.
If you are using the Windows command line interpreter @samp{cmd.exe}, this
launcher will be a batch file called @file{@var{filename}.bat}.
Otherwise, the launcher will be a shell script called @file{@var{filename}}.
Java runtime flags can be set using @samp{mmc}'s @samp{--java-runtime-flags} or
@samp{--java-runtime-flag} options.
Such Java runtime flags will be included in the generated launcher shell script
or batch file.
You may override any runtime flags set at (Mercury) compile time by setting the
variable @var{MERCURY_JAVA_OPTIONS} in the environment.
Classpath settings made using @samp{mmc}'s @samp{--java-classpath} option will
also be included in the generated launcher shell script or batch file.
@c ----------------------------------------------------------------------------
@node Compilation details
@chapter The Mercury compilation process in detail
ZZZ move target and object code to just before executables
@menu
* Creating target and object code files::
* Creating interface files::
* Creating optimization files::
* Creating executables::
@end menu
@c ----------------------------------------------------------------------------
@node Creating target and object code files
@section Creating target and object code files
If you use Mmake or @samp{mmc --make},
then you do not need to understand the details
of how the Mercury implementation goes about building programs.
Thus you may wish to skip this chapter.
To compile a Mercury source file to C code,
use a command such as
@example
mmc --grade asm_fast.gc -C @var{module_name}.m
@end example
@findex -C
@findex --target-code-only
On that command line,
the @code{--grade asm_fast.gc} part obviously specifies the grade,
while the @code{-C} option,
whose long name is @code{--target-code-only},
tells the compiler to stop after generating the target language file
(in this case, @file{@var{module_name}.c}).
You can then compile @file{@var{module_name}.c} to @file{@var{module_name}.o},
or you can tell the Mercury compiler to do this for you.
To compile a source file not just to C code but to object code,
use the command
@example
mmc --grade asm_fast.gc -c @var{module_name}.m
@end example
@findex -c
@findex --compile-only
The @code{-c} option, whose long name is @code{--compile-only},
tells the compiler to stop after compiling the Mercury code into object code.
(In grades that target Java,
it tells the compiler to stop after generating @file{@var{module_name}.class},
and In grades that target C#,
it tells the compiler to stop after generating @file{@var{module_name}.dll},
since these file types are the equivalents of object files
for these target languages.)
@c Since targeting C is the default,
@c this tells @samp{mmc} to generate C code,
@c and then invoke the configured C compiler to translate that to object code.
@c @samp{mmc} puts the generated C code into a file called @file{@var{module}.c}
@c and the generated object code into a file called @file{@var{module}.o},
@c where @var{module} is the name of the Mercury module
@c defined in @file{@var{filename}.m}.
@c If the source file contains nested modules,
@c then each submodule will get compiled to separate C and object files.
If the source file contains nested modules,
then both the main module in the file,
and all the submodules nested inside it, directly or indirect,
will all get compiled
first to separate @file{.c} (or @file{.java}, or @file{.cs} files,
and then to separate @file{.o} (or @file{.class}, or @file{.dll} files.
However, before you can compile a module,
you must first make the interface files
for the modules that it imports, either directly or indirectly.
And if you want to compile the program with intermodule optimization,
then you must first also create the files that enable that.
The next two sections cover these in turn.
@c ----------------------------------------------------------------------------
@node Creating interface files
@section Creating interface files
You can create the interface files for one or more source files
using the following commands:
@example
mmc --make-short-interface @var{module_1}.m @var{module_2}.m @dots{}
or, equivalently,
mmc --make-short-int @var{module_1}.m @var{module_2}.m @dots{}
mmc --make-private-interface @var{module_1}.m @var{module_2}.m @dots{}
or, equivalently,
mmc --make-priv-int @var{module_1}.m @var{module_2}.m @dots{}
mmc --make-interface @var{module_1}.m @var{module_2}.m @dots{}
or, equivalently,
mmc --make-int @var{module_1}.m @var{module_2}.m @dots{}
@end example
@findex --make-short-interface
@findex --make-short-int
@findex --make-private-interface
@findex --make-priv-int
@findex --make-interface
@findex --make-int
@itemize @bullet
@item
The commands in the first pair build (or rebuild)
the @samp{.int3} file of each module contained in the named source files.
(@emph{Not} just the top module of each source file.)
@item
The commands in the second pair build (or rebuild)
the @samp{.int0} file of each module contained in the named source files.
(Note that only modules that have submodules need @samp{.int0} files.)
@item
The commands in the third pair build (or rebuild)
both the @samp{.int} and @samp{.int2} file
of each module contained in the named source files.
@end itemize
There are constraints on the order in which these interface files can be built.
@itemize
@item
Each @file{.int3} file depends only on the source code of the module it is for.
Since
@file{.int0}, @file{.int} and @file{.int2} files
all depend on @file{.int3} files,
the building process must start off by building @file{.int3} files.
The order in which they are built does not matter.
@item
Each @file{.int0} file depends only
on the @file{.int3} files that the module it is for imports,
directly or indirectly,
@emph{and}
on the @file{.int0} files of its ancestor modules (if any).
Therefore the @file{.int0} files of the program must be built next,
with the @file{.int0} files of ancestor modules being built
before the @file{.int0} files of descendant modules.
@item
Each @file{.int} file, and its specialized @file{.int2} version,
depends on the @file{.int3} files that the module it is for imports,
directly or indirectly,
and on the @file{.int0} files of its ancestor modules (if any).
Therefore these files will in general be the last interface files built.
The order in which they are built does not matter.
@end itemize
As the description above shows,
interface files will in general be built in an order
with the @file{.int3} files first, then the @file{.int0} files,
and then the @file{.int}/@file{.int2} files.
However, there is no hard-and-fast separation between these phases.
For example, if neither @var{module_a} nor any of its ancestors
import @var{module_z} either directly or indirectly,
then it is ok
@itemize
@item
to build @file{@var{module_a}.int0}
before @file{@var{module_z}.int3}, and
@item
to build @file{@var{module_a}.int}
before @file{@var{module_z}.int0} or @file{@var{module_z}.int3}.
@end itemize
@c ----------------------------------------------------------------------------
@node Creating optimization files
@section Creating optimization files
By default, when @command{mmc} compiles a module, say @var{module_a},
the only code it has access to is the code of @var{module_a} itself.
The only source of information that @command{mmc} has
about the modules imported by @var{module_a} are their @file{.int} files.
Beyond the definitions of types, insts and modes,
these contain the @emph{declarations} of predicates and functions,
but their @emph{definitions}.
However, the compiler usual optimizations could do a better job
if they @emph{did} have access
to the definitions of those predicates and functions.
This is why the Mercury compiler has a mechanism for providing that access.
This mechanism, intermodule optimization, has two faces:
recording extra information about the nominally-private parts of each module
in a file,
and making use of that information while compiling other modules.
Commands that do the first part look like this:
@example
mmc --make-optimization-interface @var{module_1}.m @var{module_2}.m @dots{}
or, equivalently,
mmc --make-opt-int @var{module_1}.m @var{module_2}.m @dots{}
@end example
@findex --make-optimization-interface
@findex --make-opt-int
Each of these commands
will build @file{@var{module_1}.opt}, @file{@var{module_2}.opt},
and in general a @file{.opt} file for each named module.
These files contain information that is normally private to the module
that the @file{.opt} file is for,
but which may be useful for optimization.
Mostly, this includes the definitions (i.e. the code)
of both public and private predicates and functions of the module,
if those definitions match one or more from a list of criteria,
which include (but are not limited to) the following.
@itemize
@item
Predicates and function definitions that are so simple
that inlining calls to them
(meaning replacing the call
with an appropriately-renamed copy of the callee's definition)
is likely to result in a speedup.
@item
Predicates and function definitions
that contain switches on the values of arguments,
meaning that after inlining calls to them
at call sites that know the values of those arguments,
the switch can be eliminated.
@item
Predicates and function definitions that have higher-order arguments,
meaning that after inlining calls to them
at call sites that know the values of those higher order arguments,
the higher-order calls in the inlined version
can be replaced by first order calls.
@end itemize
Beside such code, @file{.opt} files also contain
definitions and declarations needed to make sense of that code,
such as the definitions of the types, insts and modes they involve,
and the declarations of both
the predicates and functions they define.
and the predicates and functions they call.
After @file{.opt} files have been created,
any invocation of @command{mmc} to compile say @var{module_1}
with the @code{--intermodule-optimization} option
(or @code{--intermod-opt} for short),
will read in, and use,
the @file{.opt} files of the modules that @var{module_1} imports.
In some cases, when compiling e.g. @var{module_1},
an optimization would like access to information that is derived
not just from a module that @var{module_1} imports, call it @var{module_2},
but also from modules that @var{module_2} imports,
and they import, and so on.
The information that these optimizations need
is not so much the code of e.g. predicates
defined in modules that @var{module_2} imports,
but their effect on the properties
of the predicates and functions of @var{module_2} itself.
Consider a conjunction such as
@example
... p(...), q(...), r(...), ...
@end example
where the definition of @code{r}
traverses a data structure created by @code{p}.
The Mercury compiler contains an optimization
that can fuse two traversals into one.
The optimization is called @emph{deforestation},
because it can eliminate the intermediate data structure
created by @code{p} and consumed by @file{r},
and in logic programming languages,
data structures are terms, which can be viewed as trees.
Deforestation can fuse two traversals only if they are next to each other,
and in this case, the two calls to be fused are @emph{not} next to each other.
The first step is therefor to replace
@example
... p(...), q(...), r(...), ...
@end example
with
@example
... p(...), r(...), q(...), ...
@end example
However, this is safe only in certain circumstances.
One situation in which it is unsafe
occurs when @code{q} is semidet, meaning it can fail. and
@code{r} can throw an exception.
This is because in this case, the reordering above
can replace code that simply fails with code that throws an exception.
This is an @emph{no observable effect} on the execution of the program,
which optimizations are not allowed to make.
To perform the above reordering,
the compiler needs to know that @code{r} can never throw an exception.
(It would also need to be able to rule out other situations
that could cause the reordering to have an observable effect,
but in this example, we are focusing on just this one.)
For this, it needs to know not just
that the code of @code{r} (which must be available
if we are considering fusing it with the code of @code{p})
contains no code to throw an exception,
but also that the same is true for the predicates and functions it calls,
and the predicates and functions they call, directly or indirectly.
In effect, we need to know that no predicate or function
in the call tree of @code{r} can throw an exception.
ZZZ
To make this possible in at least some cases,
Mercury has a mechanism to make such information available:
@code{.trans_opt} files.
These files contain analysis results,
with compiler options specifying the set of analyses
whose results they contain.
One of these analyses is exception analysis,
which computes safe approximations to the set of exceptions
that each predicate or function can possibly throw.
If this approximations is the empty set,
then we know for sure that
the predicate or function cannot throw any exception.
(An approximation can overestimate
the set of actions that the predicate or function may perform,
but it is safe only if will never underestimate that set.)
Consider a call chain between functions where
@code{f} calls @code{g},
@code{g} calls @code{h}, and
@code{h} calls @code{i}.
with @code{f}, @code{g}, @code{h}, @code{i} being defined in
@code{module_f}, @code{module_g}, @code{module_h} and @code{module_i}
respectively.
Suppose none of these functions contain
any calls other than the ones listed here,
and none of these modules contain anything else.
In that case,
@itemize
@item
to know whether @code{i} can throw exceptions,
we need only the code of @code{i};
@item
to know whether @code{h} can throw exceptions,
we need the code of @code{h} and the results of the analysis for @code{i};
@item
to know whether @code{g} can throw exceptions,
we need the code of @code{g} and the results of the analysis for @code{h};
@item
to know whether @code{f} can throw exceptions,
we need the code of @code{f} and the results of the analysis for @code{g}.
@end itemize
These dependencies transfor to the files involved:
@itemize
@item
We record the result of exception analysis for @code{i}
in @file{module_i.trans_opt}.
Creating @file{module_i.trans_opt}
does not require reading any other @file{.trans_opt} files.
@item
We record the result of exception analysis for @code{h}
in @file{module_h.trans_opt}.
Creating @file{module_h.trans_opt}
requires reading @file{module_i.trans_opt}.
@item
We record the result of exception analysis for @code{g}
in @file{module_g.trans_opt}.
Creating @file{module_g.trans_opt}
requires reading @file{module_h.trans_opt},
which makes @file{module_g.trans_opt} depends on
@file{module_h.trans_opt} directly, and on
@file{module_i.trans_opt} indirectly.
@item
We record the result of exception analysis for @code{f}
in @file{module_f.trans_opt}.
Creating @file{module_f.trans_opt}
requires reading @file{module_g.trans_opt},
which makes @file{module_f.trans_opt} depends on
@file{module_g.trans_opt} directly, and on
@file{module_h.trans_opt} and @file{module_i.trans_opt} indirectly.
@end itemize
While we can build each @file{.opt} file
independently of any other @file{.opt} file,
this is not true for @file{.trans_opt} files.
Not only is it the case that @file{.trans_opt} files
@emph{can} depend on other @file{.trans_opt} files,
that in fact is their @emph{job}.
In this case, if e.g.@: @file{module_f.trans_opt} records
that @code{f} cannot throw any exception,
it can do so only because @file{module_i.trans_opt}, @file{module_h.trans_opt},
and @file{module_g.trans_opt} all record that
@code{g}, @code{h} and @code{i} respectively also have this property.
And if code to possibly throw exceptions is ever added
to any one of @file{module_i.m}, @file{module_h.m}, and @file{module_g.m},
then both the @file{.trans_opt} file of the updated module,
and all the @file{.trans_opt} files that depend on it,
must all be rebuilt.
ZZZ TODO
no circular dependencies
@example
mmc --make-transitive-optimization-interface @var{module_1}.m @var{module_2}.m @dots{}
or, equivalently,
mmc --make-trans-opt @var{module_1}.m @var{module_2}.m @dots{}
@end example
@findex --make-transitive-optimization-interface
@findex --make-trans-opt
@c ----------------------------------------------------------------------------
@node Creating executables
@section Creating executables
ZZZ TODO
After you have made all the interface files,
one way to create an executable for a multi-module program
is to compile all the modules at the same time
using the command
@example
mmc @var{filename1}.m @var{filename2}.m @dots{}
@end example
This will by default put the resulting executable in @file{@var{filename1}},
though you can use the @samp{-o @var{filename}} option
to specify a different name for the output file, if you so desire.
@findex -o
The other way to create an executable for a multi-module program
is to compile each module separately using @samp{mmc -c},
@findex -c
and then link the resulting object files together.
The linking is a two stage process.
First, you must create and compile an @emph{initialization file},
which is a C source file
containing calls to automatically generated initialization functions
contained in the C code of the modules of the program:
@example
c2init @var{module1}.c @var{module2}.c @dots{} > @var{main-module}_init.c,
mgnuc -c @var{main-module}_init.c
@end example
@pindex c2init
@pindex mgnuc
The @samp{c2init} command line must contain
the name of the C file of every module in the program.
The order of the arguments is not important.
The @samp{mgnuc} command is the Mercury GNU C compiler;
it is a shell script that invokes the configured C compiler with the options
appropriate for compiling the C programs generated by Mercury.
(In the early days of the Mercury project, the configured C compiler
was almost always GCC, which is why the name of the script is what it is,
but the script itself will work with clang or MSVC as well.)
You then link the object code of each module
with the object code of the initialization file to yield the executable:
@example
ml -o @var{main-module} @var{module1}.o @var{module2}.o @dots{} @var{main_module}_init.o
@end example
@pindex ml
@samp{ml}, the Mercury linker,
is another shell script that invokes a C compiler
with options appropriate for Mercury, this time for linking.
@samp{ml} also pipes any error messages from the linker
through @samp{mdemangle}, the Mercury symbol demangler,
so that any error messages refer to
predicate and function names from the Mercury source code
rather than to the names used in the intermediate C code.
The above command puts the executable in the file @file{@var{main-module}}.
The same command line without the @samp{-o} option
would put the executable into the file @file{a.out}.
@samp{mmc} and @samp{ml} both accept a @samp{-v} (verbose) option.
You can use that option to see what is actually going on.
For the full set of options of @samp{mmc}, see @ref{Invocation}.
@c ----------------------------------------------------------------------------
@c ZZZ
@c @node Running
@c @chapter Running programs
Once you have created an executable for a Mercury program,
you can go ahead and execute it.
You may however wish to specify certain options to the Mercury runtime system.
The Mercury runtime accepts
options via the @env{MERCURY_OPTIONS} environment variable.
@vindex MERCURY_OPTIONS
The most useful of these are the options that set the size of the stacks.
(For the full list of available options, see @ref{Environment}.)
In MLDS grades,
stack management is the responsibility of the target language's compiler.
In LLDS grades,
stack management is the responsibility of @samp{mmc}
and of the Mercury runtime system for C.
This backend uses two stacks, the det stack and the nondet stack.
With @samp{mmc --stack-segments},
both of these stacks will grow and shrink automatically as needed.
Without @samp{--stack-segments},
their size is fixed at program start-up.
@c Note: The definitions for these defaults are in runtime/mercury_wrapper.c.
The default size is 4096k times the word size (in bytes) for the det stack
and 64k times the word size (in bytes) for the nondet stack,
but these can be overridden with the
@samp{--detstack-size} and @samp{--nondetstack-size} options,
@findex --detstack-size
@findex --nondetstack-size
whose arguments are the desired sizes of the det and nondet stacks
respectively, in units of kilobytes.
On operating systems that provide the appropriate support,
the Mercury runtime will ensure that stack overflow
is trapped by the virtual memory system.
@cindex Stack size
@cindex Stack overflow
With conservative garbage collection (the default),
the heap will start out with a zero size,
and will be dynamically expanded as needed,
When not using conservative garbage collection,
the heap has a fixed size like the stacks.
The default size is 8Mb times the word size (in bytes),
but this can be overridden with the @samp{--heap-size} option.
@cindex Heap size
@cindex Heap overflow
@c ----------------------------------------------------------------------------
@node Filenames
@chapter File naming conventions
@cindex File extensions
@cindex File names
Mercury source files must have a name that ends with the @file{.m} extension.
Each other kind of files (documented below) is identified by its own extension.
For source files,
the part of the filename before the @file{.m} extension can be anything,
It is simplest if it is the full name of the module contained in the file,
because if it isn't, for any module in a program,
then you will need to tell the compiler
to construct a module-name-to-filename map.
You can do this using a command such as @code{mmc -f *.m}
(if all the source files in the program are in the current directory).
For all the other kinds files mentioned in this chapter,
which are always constructed automatically by the Mercury compiler,
the part of the filename before the suffix
will be the fully qualified name of the module that the file belongs to.
@findex --use-subdirs
For historical reasons, the default behaviour
is for these files to be created in the current directory.
However,
if you use the @samp{--use-subdirs} option to @samp{mmc} or @samp{mmake},
all these intermediate files will be created in a @file{Mercury} subdirectory,
where you can happily ignore them.
(With @samp{mmc --make}, @samp{--use-subdirs} is the default.)
The rest of this chapter lists the extensions
@c *most* of the kinds of files; there are many more now.
@c XXX We should consider
@c - moving the rest of this chapter to a spot close to the end; and/or
@c - adding to it all the other extensions in compiler/file_names.m.
used by the files automatically generated by the Mercury compiler.
It also briefly introduces their roles.
This is just in case you are interested.
You don't actually need to know anything about them;
if you want, you can skip now to the next chapter.
@node Interface files
@section Interface files
Files whose names end in
@file{.int}, @file{.int2}, @file{.int0} and @file{.int3} are interface files.
In the order of their usual creation,
@itemize
@item
@findex --make-short-interface
@findex --make-short-int
@file{.int3} files are created by invoking @samp{mmc} with the
@samp{--make-short-interface} (or @samp{--make-short-int}) option.
Roughly, they contain basic information about the entities
defined in the interface section of the module,
and exported from the module to all other modules importing this one.
Their purpose is to provide the information needed
for the generation of the other kinds of interface files below.
@item
@findex --make-private-interface
@findex --make-priv-interface
@file{.int0} files are created by invoking @samp{mmc} with the
@samp{--make-private-interface} (or @samp{--make-priv-int}) option.
They contain a list of the entities
defined in the implementation section of the module
that are available only to its own submodules.
Modules that do not have any submodules won't have @file{.int0} files.
@item
@findex --make-interface
@findex --make-int
@file{.int} and @file{.int2} are both created,
at the same time, by invoking @samp{mmc} with the
@samp{--make-interface} (or @samp{--make--int}) option.
The difference between them is that e.g.@:
@file{module_a.int} is intended to contain
everything that is needed by another module, such as @samp{module_b},
that imports @samp{module_a} @emph{directly},
while @file{module_a.int2} is intended to contain what is needed
by another module, such as @samp{module_c},
that imports @samp{module_a} @emph{indirectly}.
@end itemize
@node Optimization files
@section Optimization files
Files whose names end in
@file{.opt} and @file{.trans_opt}
are files used for optimization;
these are generated automatically by the compiler.
@itemize
@item
@findex --make-transitive-optimization-interface
@findex --make-optimization-interface
@file{.opt} files are used for inter-module optimization,
and are created using the @samp{--make-optimization-interface}
(or @samp{--make-opt-int}) option.
@item
@findex --make-transitive-optimization-interface
@findex --make-trans-opt
@file{.trans_opt} files
are used for transitive inter-module optimization,
and are created using the @samp{--make-transitive-optimization-interface}
(or @samp{--make-trans-opt}) option.
@end itemize
@node Timestamp files
@section Timestamp files
Since the interface of a module changes less often than its implementation,
the @file{.int}, @file{.int0}, @file{.int2}, @file{.int3}, @file{.opt},
and @file{.trans_opt} files will often remain unchanged when they are rebuilt.
To avoid unnecessary recompilations of the clients of the module,
the timestamps on these files are updated only if their contents change.
Files with the suffixes @file{.date}, @file{.date0}, @file{.date3},
@file{.optdate}, and @file{.trans_opt_date} serve as timestamp files:
they each record the last time when the file or files it represents
has last been checked for being up to date.
(@file{.date} files serve as the last-time-this-was-checked timestamp
for both @file{.int} and @file{.int2} files.)
The Mercury implementation uses these timestamp files
when deciding whether the files they represent need to be rebuilt.
@node Mmakefile fragment files
@section Mmakefile fragment files
The @samp{mmake} build tool
gets the information it needs about the program being built
from Makefile fragments automatically generated by the Mercury compiler.
These fragments come from files with the following extensions.
@itemize
@item
@file{.dep} files are automatically generated Makefile fragments
which contain the rules for an entire program.
@item
@file{.dv} files are automatically generated Makefile fragments
which contain variable definitions for an entire program.
@item
@file{.d} files are automatically generated Makefile fragments
which contain the dependencies for a module.
@end itemize
@file{.dep} and @file{.dv} files are built
as part of the initial setup of the program,
when @samp{mmc} is invoked with @samp{--generate-dependencies}
(or some related options).
@file{.d} files contain information about a single module,
and they are updated (if needed) by every recompilation of that module.
@node Files generated when targeting C
@section Files generated when targeting C
@itemize
@item
@file{.c} files are C source code.
@item
@file{.o} files are object code (generated by C compilers other than MSVC).
@item
@file{.obj} files are object code (generated by MSVC).
@item
@file{.pic_o} files are object code files
that contain position-independent (PIC) code.
@c XXX "egrep lpic_o *.m" in the compiler directory yields no hits.
@c c8d718ec57a7517bf8427ca375ee27dc6864b700 in 2016 deleted lpic_o support.
@c @item
@c @file{.lpic_o} files are object code files
@c that can be linked with shared libraries,
@c but don't necessarily contain position-independent code themselves.
@end itemize
@file{.mh} and @file{.mih} files are C header files
generated by the Mercury compiler.
Their non-standard extensions are necessary
to avoid conflicts with system header files.
@itemize
@item
@file{.mh} files contain the declarations of C function versions
of Mercury predicates and/or functions that are exported to C code
by @samp{foreign_export} pragmas written by programmers.
They are intended to be @code{#included} by the user-written C code
that the @samp{foreign_export} pragmas were intended for.
@item
@file{.mih} files are C header files
that are part of the Mercury implementation.
They are intended to be @code{#included} only by C source files
that are generated automatically by the Mercury compiler.
@end itemize
@node Files generated when targeting Java
@section Files generated when targeting Java
@itemize
@item @file{.java} files are Java source code,
@item @file{.class} files are Java bytecode, and
@item @file{.jar} files are Java archives.
@end itemize
@node Files generated when targeting c#
@section Files generated when targeting c#
@c when we support shared libraries on Windows .dll will also be used for them.
@itemize
@item @file{.cs} files are C# source code,
@item @file{.dll} files are library assemblies, and
@item @file{.exe} files are process assemblies.
@end itemize
@c When smart recompilation (@pxref{Auxiliary output options}) is enabled,
@c @file{.c_date}, @file{.cs_date} and @file{.java_date} files
@c perform the same function for
@c @file{.c}, @file{.cs} and @file{.java} files respectively
@c as e.g. @file{.date3} files do for @file{.int3} files:
@c when smart recompilation works out
@c that a module does not need to be recompiled,
@c it updates the timestamp of the @emph{timestamp file} for the target file,
@c but leaves the timestamp of the target file itself unchanged.
@c @findex --smart-recompilation
@c @file{.used} files contain dependency information for smart recompilation
@c (@pxref{Auxiliary output options}).
@c @findex --smart-recompilation
@c ----------------------------------------------------------------------------
@node Using Mmake
@chapter Using Mmake
@pindex mmake
@pindex make --- see Mmake
@cindex Building programs
@cindex Recompiling
Mmake, short for ``Mercury Make'',
is a tool for building Mercury programs.
The same functionality is now provided in @samp{mmc} directly by using the
@samp{--make} option:
@example
mmc --make @var{main-module}
@end example
@noindent
The usage of Mmake is discouraged,
not least because it works only when targeting C.
Mmake is built on top of GNU Make.
With Mmake, building even a complicated Mercury program
consisting of a number of modules is as simple as
@example
mmc -f @var{source-files}
mmake @var{main-module}.depend
mmake @var{main-module}
@end example
Mmake only recompiles those files that need to be recompiled,
based on automatically generated dependency information.
Most of the dependencies are stored in @file{.d} files that are
automatically recomputed every time you recompile,
so they are never out-of-date.
A little bit of the dependency information
is stored in @file{.dep} and @file{.dv} files
which are more expensive to recompute.
The @samp{mmake @var{main-module}.depend} command which recreates
the @file{@var{main-module}.dep} and @file{@var{main-module}.dv} files
needs to be repeated only when you either
add a module to your program or remove a module from it.
There is no danger of getting an inconsistent executable
if you forget this step ---
instead you will get a compile or link error.
The @samp{mmc -f} step above is only required if there are any source files
for which the file name does not match the module name.
@samp{mmc -f} generates a file named @file{Mercury.modules}
containing a mapping from module name to source file.
The @file{Mercury.modules} file must be updated
when a source file for which the file name does not match the module name
is added to or removed from the directory.
@samp{mmake} allows you to build more than one program in the same directory.
Each program must have its own @file{.dep} and @file{.dv} files,
and therefore you must run @samp{mmake @var{program}.depend} for each program.
The @samp{Mercury.modules} file is used for all programs in the directory.
If there is a file called @file{Mmake} or @file{Mmakefile}
in the current directory,
Mmake will include that file in its automatically generated Makefile.
The @samp{Mmake} file can override
the default values of various variables used by Mmake's builtin rules,
or it can add additional rules, dependencies, and actions.
Mmake's builtin rules are defined by the file
@file{@var{prefix}/lib/mercury/mmake/Mmake.rules}
(where @var{prefix} is @file{/usr/local/mercury-@var{version}} by default,
and @var{version} is the version number, e.g.@: @samp{0.6}),
as well as the rules and variables in the automatically generated
@file{.dep} and @file{.dv} files.
These rules define the following targets:
@table @file
@item @var{main-module}.depend
Creates the files @file{@var{main-module}.dep} and
@file{@var{main-module}.dv} from @file{@var{main-module}.m}
and the modules it imports.
This step must be performed first.
It is also required whenever you wish to change
the level of inter-module optimization performed
(@pxref{Overall control of optimizations}).
@item @var{main-module}.all_ints
Ensure that the interface files for @var{main-module}
and its imported modules are up-to-date.
(If the underlying @samp{make} program does not handle transitive dependencies,
this step may be necessary before
attempting to make @file{@var{main-module}} or @file{@var{main-module}.check};
if the underlying @samp{make} is GNU Make, this step should not be necessary.)
@item @var{main-module}.check
Perform semantic checking on @var{main-module} and its imported modules.
Error messages are placed in @file{.err} files.
@item @var{main-module}
Compiles and links @var{main-module} using the Mercury compiler.
Error messages are placed in @file{.err} files.
@c XXX mention .dlls and .exe targets?
@item lib@var{main-module}
Builds a library whose top-level module is @var{main-module}.
This will build a static object library, a shared object library
(for platforms that support it), and the necessary interface files.
For more information, see @ref{Libraries}.
@item lib@var{main-module}.install
Builds and installs a library whose top-level module is @var{main-module}.
This target will build and install a static object library and
(for platforms that support it) a shared object library,
for the default grade and also for the additional grades specified
in the @code{LIBGRADES} variable. It will also build and install the
necessary interface files. The variable @code{INSTALL} specifies
the name of the command to use to install each file, by default
@samp{cp}. The variable @code{INSTALL_MKDIR} specifies the command to use
to create directories, by default @samp{mkdir -p}.
@vindex LIBGRADES
@vindex LIB_LINKAGES
@vindex INSTALL
@vindex INSTALL_MKDIR
@item @var{main-module}.clean
Removes the automatically generated files
that contain the compiled code of the program
and the error messages produced by the compiler.
Specifically, this will remove all the @samp{.c}, @samp{.o},
@samp{.pic_o}, @samp{.prof}, @samp{.used}, @samp{.mih},
and @samp{.err} files
belonging to the named @var{main-module} or its imported modules.
Use this target whenever you wish to change compilation model
(@pxref{Grade options}).
This target is also recommended whenever you wish to change
the level of inter-module optimization performed
(@pxref{Overall control of optimizations})
in addition to the mandatory @var{main-module}.depend.
@item @var{main-module}.realclean
Removes all the automatically generated files.
In addition to the files removed by @var{main-module}.clean, this
removes the @samp{.int}, @samp{.int0}, @samp{.int2},
@samp{.int3}, @samp{.opt}, @samp{.trans_opt},
@samp{.date}, @samp{.date0}, @samp{.date3}, @samp{.optdate},
@samp{.trans_opt_date},
@samp{.mh} and @samp{.d} files
belonging to one of the modules of the program,
and also the various possible executables, libraries and dependency files
for the program as a whole ---
@samp{@var{main-module}},
@samp{lib@var{main-module}.a},
@samp{lib@var{main-module}.so},
@samp{lib@var{main-module}.dylib},
@samp{@var{main-module}.init},
@samp{@var{main-module}.dep}
and
@samp{@var{main-module}.dv}.
@item clean
This makes @samp{@var{main-module}.clean} for every @var{main-module}
for which there is a @file{@var{main-module}.dep} file in the current
directory, as well as deleting the profiling files
@samp{Prof.CallPair},
@samp{Prof.Counts},
@samp{Prof.Decl},
@samp{Prof.MemWords}
and
@samp{Prof.MemCells}.
@item realclean
This makes @samp{@var{main-module}.realclean} for every @var{main-module}
for which there is a @file{@var{main-module}.dep} file in the current
directory, as well as deleting the profiling files as per the @samp{clean}
target.
@end table
@cindex Variables, Mmake
@cindex Mmake variables
The variables used by the builtin rules (and their default values) are
defined in the file @file{@var{prefix}/lib/mercury/mmake/Mmake.vars}, however
these may be overridden by user @samp{Mmake} files. Some of the more
useful variables are:
@table @code
@item MAIN_TARGET
@vindex MAIN_TARGET
The name of the default target to create if @samp{mmake} is invoked with
any target explicitly named on the command line.
@item MC
@vindex MC
The executable that invokes the Mercury compiler.
@item GRADEFLAGS and EXTRA_GRADEFLAGS
@vindex GRADEFLAGS
@vindex EXTRA_GRADEFLAGS
Compilation model options (@pxref{Grade options})
to pass to the Mercury compiler, linker, and other tools
(in particular @code{mmc}, @code{mgnuc}, @code{ml}, and @code{c2init}).
@item MCFLAGS and EXTRA_MCFLAGS
@vindex MCFLAGS
@vindex EXTRA_MCFLAGS
Options to pass to the Mercury compiler.
(Note that compilation model options should be
specified in @code{GRADEFLAGS}, not in @code{MCFLAGS}.)
@item MGNUC
@vindex MGNUC
The executable that invokes the C compiler.
@item MGNUCFLAGS and EXTRA_MGNUCFLAGS
@vindex MGNUCFLAGS
@vindex EXTRA_MGNUCFLAGS
Options to pass to the mgnuc script.
@item CFLAGS and EXTRA_CFLAGS
@vindex CFLAGS
@vindex EXTRA_CFLAGS
Options to pass to the C compiler.
@item JAVACFLAGS and EXTRA_JAVACFLAGS
@vindex JAVACFLAGS
@vindex EXTRA_JAVACFLAGS
Options to pass to the Java compiler (if you are using it).
@item ML
@vindex ML
The executable that invokes the linker.
@item LINKAGE
@vindex LINKAGE
Can be set to either @samp{shared} to link with shared libraries,
or @samp{static} to always link statically. The default is @samp{shared}.
This variable only has an effect with @samp{mmc --make}.
@item MERCURY_LINKAGE
@vindex MERCURY_LINKAGE
Can be set to either @samp{shared} to link with shared Mercury libraries,
or @samp{static} to always link with the static versions of Mercury libraries.
The default is system dependent.
This variable only has an effect with @samp{mmc --make}.
@xref{Using installed libraries with mmc --make}.
@item MLFLAGS and EXTRA_MLFLAGS
@vindex MLFLAGS
@vindex EXTRA_MLFLAGS
Options to pass to the ml and c2init scripts.
(Note that compilation model options should be
specified in @code{GRADEFLAGS}, not in @code{MLFLAGS}.)
These variables have no effect with @samp{mmc --make}.
@item LDFLAGS and EXTRA_LDFLAGS
@vindex LDFLAGS
@vindex EXTRA_LDFLAGS
Options to pass to the command used by the ml script to link
executables (use @code{ml --print-link-command} to find out
what command is used, usually the C compiler).
@item LD_LIBFLAGS and EXTRA_LD_LIBFLAGS
@vindex LD_LIBFLAGS
@vindex EXTRA_LD_LIBFLAGS
Options to pass to the command used to by the ml script to link
shared libraries (use @code{ml --print-shared-lib-link-command}
to find out what command is used, usually the C compiler
or the system linker, depending on the platform).
@item MLLIBS and EXTRA_MLLIBS
@vindex MLLIBS
@vindex EXTRA_MLLIBS
A list of @samp{-l} options specifying libraries used by the program
(or library) that you are building. @xref{Using libraries with Mmake}.
@xref{Using installed libraries with mmc --make}.
@item MLOBJS and EXTRA_MLOBJS
@vindex MLOBJS
@vindex EXTRA_MLOBJS
A list of extra object files or archives to link into the program or library
that you are building.
@item C2INITFLAGS and EXTRA_C2INITFLAGS
@vindex C2INITFLAGS
@vindex EXTRA_C2INITFLAGS
Options to pass to the linker and the c2init program.
@code{C2INITFLAGS} and @code{EXTRA_C2INITFLAGS} are obsolete synonyms
for @code{MLFLAGS} and @code{EXTRA_MLFLAGS} (@code{ml} and @code{c2init}
take the same set of options).
(Note that compilation model options and extra files to be processed by
c2init should not be specified in @code{C2INITFLAGS} --- they should be
specified in @code{GRADEFLAGS} and @code{C2INITARGS}, respectively.)
@item C2INITARGS and EXTRA_C2INITARGS
@vindex C2INITARGS
@vindex EXTRA_C2INITARGS
Extra files to be processed by c2init. These variables should not be
used for specifying flags to c2init (those should be specified in
@code{MLFLAGS}) since they are also used to derive extra dependency
information.
@item EXTRA_LIBRARIES
@vindex EXTRA_LIBRARIES
A list of extra Mercury libraries to link into any programs or libraries
that you are building.
Libraries should be specified using their base name; that is, without any
@samp{lib} prefix or extension.
For example, the library including the files @file{libfoo.a} and
@file{foo.init} would be referred to as just @samp{foo}.
@xref{Using libraries with Mmake}.
@xref{Using installed libraries with mmc --make}.
@item EXTRA_LIB_DIRS
@vindex EXTRA_LIB_DIRS
A list of extra Mercury library directory hierarchies to search when
looking for extra libraries. @xref{Using libraries with Mmake}.
@xref{Using installed libraries with mmc --make}.
@item INSTALL_PREFIX
@vindex INSTALL_PREFIX
The path to the root of the directory hierarchy where the libraries,
etc.@: you are building should be installed. The default is to install in
the same location as the Mercury compiler being used to do the install.
@item INSTALL
@vindex INSTALL
The command used to install each file in a library. The command should
take a list of files to install and the location to install them.
The default command is @samp{cp}.
@item INSTALL_MKDIR
@vindex INSTALL_MKDIR
The command used to create each directory in the directory hierarchy
where the libraries are to be installed. The default command is
@samp{mkdir -p}.
@item LIBGRADES
@vindex LIBGRADES
A list of additional grades which should be built when installing libraries.
The default is to install the Mercury compiler's default set of grades.
Note that this may not be the set of grades in which the standard libraries
were actually installed.
@vindex GRADEFLAGS
Note also that any @code{GRADEFLAGS} settings will also be applied when
the library is built in each of the listed grades, so you may not get what
you expect if those options are not subsumed by each of the grades listed.
@item LIB_LINKAGES
@vindex LIB_LINKAGES
A list of linkage styles (@samp{shared} or @samp{static}) for which libraries
should be built and installed. The default is to install libraries for both
static and shared linking. This variable only has an effect with
@samp{mmc --make}.
@end table
Other variables also exist --- see
@file{@var{prefix}/lib/mercury/mmake/Mmake.vars} for a complete list.
If you wish to temporarily change the flags passed to an executable,
rather than setting the various @samp{FLAGS} variables directly, you can
set an @samp{EXTRA_} variable. This is particularly intended for
use where a shell script needs to call mmake and add an extra parameter,
without interfering with the flag settings in the @samp{Mmakefile}.
For each of the variables for which there is version with an @samp{EXTRA_}
prefix, there is also a version with an @samp{ALL_} prefix that
is defined to include both the ordinary and the @samp{EXTRA_} version.
If you wish to @emph{use} the values any of these variables
in your Mmakefile (as opposed to @emph{setting} the values),
then you should use the @samp{ALL_} version.
It is also possible to override these variables on a per-file basis.
For example, if you have a module called say @file{bad_style.m}
which triggers lots of compiler warnings, and you want to disable
the warnings just for that file, but keep them for all the other modules,
then you can override @code{MCFLAGS} just for that file. This is done by
setting the variable @samp{MCFLAGS-bad_style}, as shown here:
@example
MCFLAGS-bad_style = --inhibit-warnings
@end example
Mmake has a few options, including @samp{--use-subdirs}, @samp{--use-mmc-make},
@samp{--save-makefile}, @samp{--verbose}, and @samp{--no-warn-undefined-vars}.
For details about these options, see the man page or type @samp{mmake --help}.
Finally, since Mmake is built on top of GNU Make, you can also
make use of the features and options supported by the underlying Make.
In particular, GNU Make has support for running jobs in parallel, which
is very useful if you have a machine with more than one CPU.
As an alternative to Mmake, the Mercury compiler now contains a
significant part of the functionality of Mmake, using @samp{mmc}'s
@samp{--make} option.
@findex --make
The advantages of the @samp{mmc --make} over Mmake are that there
is no @samp{mmake depend} step and the dependencies are more accurate.
Note that @samp{--use-subdirs} is automatically enabled if you specify
@samp{mmc --make}.
@cindex Options files
@cindex Mercury.options
The Mmake variables above can be used by @samp{mmc --make} if they
are set in a file called @file{Mercury.options}. The @file{Mercury.options}
file has the same syntax as an Mmakefile, but only variable assignments and
@samp{include} directives are allowed.
All variables in @file{Mercury.options} are treated as if they are
assigned using @samp{:=}.
Variables may also be set in the environment, overriding settings in
options files.
@samp{mmc --make} can be used in conjunction with Mmake. This is useful
for projects which include source code written in languages other than
Mercury. The @samp{--use-mmc-make} Mmake option disables Mmake's
Mercury-specific rules. Mmake will then process source files written in
other languages, but all Mercury compilation will be done by
@samp{mmc --make}. The following variables can be set in the Mmakefile
to control the use of @samp{mmc --make}.
@table @code
@item MERCURY_MAIN_MODULES
@vindex MERCURY_MAIN_MODULES
The top-level modules of the programs or libraries being built in
the directory. This must be set to tell Mmake to use @samp{mmc --make}
to rebuild the targets for the main modules even if those files already
exist.
@item MC_BUILD_FILES
@vindex MC_BUILD_FILES
Other files which should be built with @samp{mmc --make}.
This should only be necessary for header files generated by the
Mercury compiler which are included by the user's C source files.
@item MC_MAKE_FLAGS and EXTRA_MC_MAKE_FLAGS
@vindex MC_MAKE_FLAGS
@vindex EXTRA_MC_MAKE_FLAGS
Options to pass to the Mercury compiler only when using @samp{mmc --make}.
@end table
The following variables can also appear in options files but are
@emph{only} supported by @w{@samp{mmc --make}}.
@table @code
@item GCC_FLAGS
@vindex GCC_FLAGS
Options to pass to the C compiler, but only if the C compiler is GCC.
If the C compiler is not GCC then this variable is ignored.
These options will be passed @emph{after} any options given by the
@samp{CFLAGS} variable.
@item CLANG_FLAGS
@vindex CLANG_FLAGS
Options to pass to the C compiler, but only if the C compiler is clang.
If the C compiler is not clang then this variable is ignored.
These options will be passed @emph{after} any options given by the
@samp{CFLAGS} variable.
@item MSVC_FLAGS
@vindex MSVC_FLAGS
Options to pass to the C compiler,
but only if the C compiler is Microsoft Visual C.
If the C compiler is not Visual C then this variable is ignored.
These options will be passed @emph{after} any options given by the
@samp{CFLAGS} variable.
@end table
@c ----------------------------------------------------------------------------
@node Libraries
@chapter Libraries
@cindex Libraries
Often you will want to use a particular set of Mercury modules
in more than one program. The Mercury implementation
includes support for developing libraries, i.e.@: sets of Mercury modules
intended for reuse. It allows separate compilation of libraries
and, on many platforms, it supports shared object libraries.
@menu
* Writing libraries::
* Building with mmc --make::
* Building with Mmake::
* Libraries and the Java grade::
* Libraries and the C# grade::
@end menu
@node Writing libraries
@section Writing libraries
A Mercury library is identified by a top-level module,
which should contain all of the modules in that library as submodules.
It may be as simple as this @file{mypackage.m} file:
@example
:- module mypackage.
:- interface.
:- include_module foo.
:- include_module bar.
:- include_module baz.
@end example
@noindent
This defines a module @samp{mypackage} containing submodules
@samp{mypackage.foo}, @samp{mypackage.bar}, and @samp{mypackage.baz}.
It is also possible to build libraries of unrelated modules,
so long as the top-level module imports all the necessary modules.
For example:
@example
:- module blah.
:- implementation.
:- import_module fee.
:- import_module fie.
:- import_module foe.
:- import_module fum.
@end example
@noindent
This example defines a module @samp{blah},
which has no functionality of its own,
and which is just used for grouping the unrelated modules
@samp{fee}, @samp{fie}, @samp{foe}, and @samp{fum}.
To avoid a warning about the interface of this module being empty,
this module would have to be compiled with @samp{--no-warn-nothing-exported}.
Alternatively, the library could of course just export something,
such as a predicate that returns its version number.
Generally it is better style for each library
to consist of a single module which encapsulates its submodules,
as in the first example,
rather than just a group of unrelated modules,
as in the second example.
@node Building with mmc --make
@section Building with mmc --make
@menu
* Building and installing libraries with mmc --make::
* Using installed libraries with mmc --make::
* Using non-installed libraries with mmc --make::
@end menu
@node Building and installing libraries with mmc --make
@subsection Building and installing libraries with mmc --make
To build a library from the source @samp{mypackage.m}
(and other included modules),
run @samp{mmc} with the following arguments:
@example
mmc --make libmypackage
@end example
@noindent
@samp{mmc} will create static (non-shared) object libraries
and, on most platforms, shared object libraries;
however, we do not yet support the creation of dynamic link
libraries (DLLs) on Windows.
Use the @samp{mmc} option @samp{--lib-linkage} to specify which versions of the
library should be created: @samp{shared} or @samp{static}. The
@samp{--lib-linkage} option can be specified multiple times.
In our example, the files @samp{libmypackage.a} and @samp{libmypackage.so}
should appear in the current directory.
(On macOS @samp{libmypackage.dylib} will appear instead of
@samp{libmypackage.so}.)
Other programs can more easily use a library that is installed.
To install the library, issue the following command:
@example
mmc --make --install-prefix <dir> libmypackage.install
@end example
@noindent
@samp{mmc} will create the directory @samp{<dir>/lib/mercury} and install the
library there.
The library will be compiled in all valid grades and with all interface files.
Because several grades are usually compiled,
installing the library can be a lengthy process.
You can specify the set of installed grades using the option
@samp{--no-libgrade} followed by @samp{--libgrade <grade>} for all grades you
wish to install.
If no @samp{--install-prefix <dir>} is specified, the library will be installed
in the standard location, next to the Mercury standard library.
@node Using installed libraries with mmc --make
@subsection Using installed libraries with mmc --make
@cindex Libraries, linking with
@findex --mld
@findex --mercury-library-directory
@findex --ml
@findex --mercury-library
Once a library is installed, it can be used by running @samp{mmc} with the
following options:
@example
mmc @dots{} --ml mypackage @dots{} --ml myotherlib @dots{} --ml my_yet_another_lib @dots{}
@end example
@noindent
If a library was installed in a different place (using @samp{--install-prefix
<dir>}), you will also need to add this option:
@example
mmc @dots{} --mld <dir>/lib/mercury @dots{}
@end example
@noindent
Note that @samp{/lib/mercury} has to be added to the searched path. The
@samp{--mld} option can be used several times to add more directories to the
library search path.
You can also specify whether to link executables with the shared or static
versions of Mercury libraries using @samp{--mercury-linkage shared} or
@samp{--mercury-linkage static}.
@node Using non-installed libraries with mmc --make
@subsection Using non-installed libraries with mmc --make
@cindex Libraries, linking with
@findex --search-lib-files-dir
@findex --init-file
@findex --link-object
Suppose the user wants to link against library @samp{mypackage} without
installing the library. The source of the library is stored in the directory
@samp{<dir>} and that the library has been properly built using @samp{mmc
--make libmypackage}. To link against the library, the following options have
to be added to @samp{mmc}:
@example
mmc @dots{} --search-lib-files-dir <dir> \
--init-file <dir>/mypackage.init \
--link-object <dir>/libmypackage.a \
@dots{}
@end example
@noindent
Note that the option @samp{--ml} is not used.
You need to make sure the library @samp{libmypackage.a} and the main program
were compiled in the same grade.
If you need to experiment with more grades, be sure to build the library in all
the grades (building several times using @samp{mmc --grade <grade> --make
libmypackage}) and use the @samp{libmypackage.a} that is compatible with your
main program's grade:
@example
mmc @dots{} --use-grade-subdirs \
--grade <grade> \
--search-lib-files-dir <dir> \
--init-file <dir>/mypackage.init \
--link-object <dir>/Mercury/<grade>/*/Mercury/lib/libmypackage.a \
@dots{}
@end example
@node Building with Mmake
@section Building with Mmake
@menu
* Building libraries with Mmake::
* Installing libraries with Mmake::
* Using libraries with Mmake::
@end menu
@node Building libraries with Mmake
@subsection Building libraries with Mmake
@cindex Shared objects
@cindex Shared libraries
@cindex Static libraries
@cindex Position independent code
@cindex PIC (position independent code)
Generally Mmake will do most of the work of building
libraries automatically.
Here is a sample @code{Mmakefile} for creating a library.
@example
MAIN_TARGET = libmypackage
depend: mypackage.depend
@end example
The Mmake target @samp{lib@var{foo}} is a builtin target for
creating a library whose top-level module is @samp{@var{foo}.m}.
The automatically generated Mmake rules for the target @samp{lib@var{foo}}
will create all the files needed to use the library.
(You will need to run @samp{mmake @var{foo}.depend} first
to generate the module dependency information.)
Mmake will create static (non-shared) object libraries
and, on most platforms, shared object libraries;
however, we do not yet support the creation of dynamic link
libraries (DLLs) on Windows.
Static libraries are created using the standard tools @command{ar} and
@command{ranlib}.
Shared libraries are created using the @samp{--make-shared-lib}
option to @samp{ml}.
The automatically generated Make rules for @samp{libmypackage}
will look something like this:
@example
libmypackage: libmypackage.a libmypackage.so \
$(mypackage.ints) $(mypackage.int3s) \
$(mypackage.opts) $(mypackage.trans_opts) mypackage.init
libmypackage.a: $(mypackage.os)
rm -f libmypackage.a
$(AR) $(ARFLAGS) libmypackage.a $(mypackage.os) $(MLOBJS)
$(RANLIB) $(RANLIBFLAGS) mypackage.a
libmypackage.so: $(mypackage.pic_os)
$(ML) $(MLFLAGS) --make-shared-lib -o libmypackage.so \
$(mypackage.pic_os) $(MLPICOBJS) $(MLLIBS)
libmypackage.init:
@dots{}
clean:
rm -f libmypackage.a libmypackage.so
@end example
@vindex AR
@vindex ARFLAGS
@vindex MLOBJS
@vindex RANLIB
@vindex RANLIBFLAGS
@vindex ML
@vindex MLFLAGS
@vindex MLPICOBJS
@vindex MLLIBS
If necessary, you can override the default definitions of the variables
such as @samp{ML}, @samp{MLFLAGS}, @samp{MLPICOBJS}, and @samp{MLLIBS}
to customize the way shared libraries are built. Similarly @samp{AR},
@samp{ARFLAGS}, @samp{MLOBJS}, @samp{RANLIB}, and @samp{RANLIBFLAGS}
control the way static libraries are built. (The @samp{MLOBJS} variable
is supposed to contain a list of additional object files to link into
the library, while the @samp{MLLIBS} variable should contain a list of
@samp{-l} options naming other libraries used by this library.
@samp{MLPICOBJS} is described below.)
Note that to use a library, as well as the shared or static object library,
you also need the interface files. That is why the
@samp{libmypackage} target builds @samp{$(mypackage.ints)} and
@samp{$(mypackage.int3s)}.
If the people using the library are going to use intermodule
optimization, you will also need the intermodule optimization interfaces.
The @samp{libmypackage} target will build @samp{$(mypackage.opts)} if
@samp{--intermodule-optimization} is specified in your @samp{MCFLAGS}
variable (this is recommended).
@findex --intermodule-optimization
Similarly, if the people using the library are going to use transitive
intermodule optimization, you will also need the transitive intermodule
optimization interfaces (@samp{$(mypackage.trans_opt)}).
These will be built if @samp{--trans-intermod-opt} is specified in your
@samp{MCFLAGS} variable.
@findex --trans-intermod-opt
In addition, with certain compilation grades, programs will need to
execute some startup code to initialize the library; the
@samp{mypackage.init} file contains information about initialization
code for the library. The @samp{libmypackage} target will build this file.
On some platforms, shared objects must be created using position independent
code (PIC), which requires passing some special options to the C compiler.
On these platforms, @code{Mmake} will create @file{.pic_o} files,
and @samp{$(mypackage.pic_os)} will contain a list of the @file{.pic_o} files
for the library whose top-level module is @samp{mypackage}.
In addition, @samp{$(MLPICOBJS)} will be set to @samp{$MLOBJS} with
all occurrences of @samp{.o} replaced with @samp{.pic_o}.
On other platforms, position independent code is the default,
so @samp{$(mypackage.pic_os)} will just be the same as @samp{$(mypackage.os)},
which contains a list of the @file{.o} files for that module,
and @samp{$(MLPICOBJS)} will be the same as @samp{$(MLOBJS)}.
@node Installing libraries with Mmake
@subsection Installing libraries with Mmake
@samp{mmake} has support for alternative library directory hierarchies.
These have the same structure as the @file{@var{prefix}/lib/mercury} tree,
including the different subdirectories for different grades and different
machine architectures.
In order to support the installation of a library into such a tree, you
simply need to specify (e.g.@: in your @file{Mmakefile}) the path prefix
and the list of grades to install:
@example
INSTALL_PREFIX = /my/install/dir
LIBGRADES = asm_fast asm_fast.gc.tr.debug
@end example
@vindex INSTALL_PREFIX
@vindex LIBGRADES
This specifies that libraries should be installed in
@file{/my/install/dir/lib/mercury}, in the default grade plus
@samp{asm_fast} and @samp{asm_fast.gc.tr.debug}.
If @samp{INSTALL_PREFIX} is not specified, @samp{mmake} will attempt to
install the library in the same place as the standard Mercury libraries.
If @samp{LIBGRADES} is not specified, @samp{mmake} will use the Mercury
compiler's default set of grades, which may or may not correspond to the
actual set of grades in which the standard Mercury libraries were installed.
To actually install a library @samp{lib@var{foo}}, use the @samp{mmake}
target @samp{lib@var{foo}.install}.
This also installs all the needed interface files, and (if intermodule
optimisation is enabled) the relevant intermodule optimisation files.
One can override the list of grades to install for a given library
@samp{lib@var{foo}} by setting the @samp{LIBGRADES-@var{foo}} variable,
or add to it by setting @samp{EXTRA_LIBGRADES-@var{foo}}.
The command used to install each file is specified by @samp{INSTALL}.
If @samp{INSTALL} is not specified, @samp{cp} will be used.
@vindex INSTALL
The command used to create directories is specified by @samp{INSTALL_MKDIR}.
If @samp{INSTALL_MKDIR} is not specified, @samp{mkdir -p} will be used.
@vindex INSTALL_MKDIR
Note that currently it is not possible to set the installation prefix
on a library-by-library basis.
@node Using libraries with Mmake
@subsection Using libraries with Mmake
@cindex Libraries, linking with
Once a library is installed, using it is easy.
Suppose the user wishes to use the library @samp{mypackage} (installed
in the tree rooted at @samp{/some/directory/mypackage}) and the library
@samp{myotherlib} (installed in the tree rooted at
@samp{/some/directory/myotherlib}).
The user need only set the following Mmake variables:
@example
EXTRA_LIB_DIRS = /some/directory/mypackage/lib/mercury \
/some/directory/myotherlib/lib/mercury
EXTRA_LIBRARIES = mypackage myotherlib
@end example
@vindex EXTRA_LIBRARIES
@vindex EXTRA_LIB_DIRS
@findex --intermodule-optimization
When using @samp{--intermodule-optimization} with a library which
uses the C interface, it may be necessary to add @samp{-I} options to
@samp{MGNUCFLAGS} so that the C compiler can find any header files
used by the library's C code.
Mmake will ensure that the appropriate directories are searched for
the relevant interface files, module initialisation files, compiled
libraries, etc.
Beware that the directory name that you must use in @samp{EXTRA_LIB_DIRS}
or as the argument of the @samp{--mld} option is not quite the same as
the name that was specified in the @samp{INSTALL_PREFIX} when the library
was installed --- the name needs to have @samp{/lib/mercury} appended.
One can specify extra libraries to be used on a program-by-program
basis. For instance, if the program @samp{foo} also uses the library
@samp{mylib4foo}, but the other programs governed by the Mmakefile don't,
then one can declare:
@example
EXTRA_LIBRARIES-foo = mylib4foo
@end example
@node Libraries and the Java grade
@section Libraries and the Java grade
@cindex jar files
@cindex Java libraries
To create or install a library in the Java grade, specify that you want to
use the Java grade and use @samp{mmc --make}.
Mmake does @emph{not} support Java targets.
Libraries are compiled to class files that are added to a Java archive (JAR)
file whose name has the form @file{@var{library-name}.jar}.
@node Libraries and the C# grade
@section Libraries and the C# grade
@cindex C# libraries
To create or install a library in the C# grade,
specify that you want to use the C# grade and use @samp{mmc --make}.
Mmake does @emph{not} support C# targets.
Libraries are complied to a dynamic link library assembly
whose name has the form @file{@var{library-name}.dll}.
@c ----------------------------------------------------------------------------
@node Debugging
@chapter Debugging
@cindex Debugging
@cindex Tracing
@pindex mdb
@menu
* Quick overview::
* GNU Emacs interface::
* Tracing of Mercury programs::
* Preparing a program for debugging::
* Tracing optimized code::
* Mercury debugger invocation::
* Mercury debugger concepts::
* User defined events::
* I/O tabling::
* Debugger commands::
* Declarative debugging::
* Trace counts::
@end menu
@node Quick overview
@section Quick overview
This section gives a quick and simple guide to getting
started with the debugger. The remainder of this chapter
contains more detailed documentation.
To use the debugger, you must
first compile your program with debugging enabled.
You can do this by using
one of the @samp{--debug} or @samp{--decl-debug} options
when invoking @samp{mmc},
or by including @samp{GRADEFLAGS = --debug}
or @samp{GRADEFLAGS = --decl-debug}
in your @file{Mmakefile}.
@findex --debug
@example
bash$ mmc --debug hello.m
@end example
Once you have compiled with debugging enabled, you can use the @samp{mdb}
command to invoke your program under the debugger:
@pindex mdb
@example
bash$ mdb ./hello arg1 arg2 @dots{}
@end example
Any arguments (such as @samp{arg1 arg2 @dots{}} in this example)
that you pass after the program name will be given as arguments
to the program.
The debugger will print a start-up message
and will then show you the first trace event,
namely the call to @code{main/2}:
@example
1: 1 1 CALL pred hello:main/2-0 (det)
hello.m:13
mdb>
@end example
By hitting enter at the @samp{mdb>} prompt, you can step through
the execution of your program to the next trace event:
@example
2: 2 2 CALL pred io:write_string/3-0 (det)
io.m:2837 (hello.m:14)
mdb>
Hello, world
3: 2 2 EXIT pred io:write_string/3-0 (det)
io.m:2837 (hello.m:14)
mdb>
@end example
For each trace event, the debugger prints out several pieces of information.
The three numbers at the start of the display are
the event number, the call sequence number, and the call depth.
(You don't really need to pay too much attention to those.)
They are followed by the event type (e.g.@: @samp{CALL} or @samp{EXIT}).
After that comes the identification of the procedure
in which the event occurred, consisting of the module-qualified name
of the predicate or function to which the procedure belongs,
followed by its arity, mode number and determinism.
This may sometimes be followed by a ``path''
(@pxref{Tracing of Mercury programs}).
At the end is the file name and line number of the
called procedure and (if available) also the file name
and line number of the call.
The most useful @code{mdb} commands have single-letter abbreviations.
The @samp{alias} command will show these abbreviations:
@example
mdb> alias
? => help
EMPTY => step
NUMBER => step
P => print *
b => break
c => continue
d => stack
f => finish
g => goto
h => help
p => print
r => retry
s => step
v => vars
@end example
The @samp{P} or @samp{print *} command will display the values
of any live variables in scope.
The @samp{f} or @samp{finish} command can be used if you want
to skip over a call.
The @samp{b} or @samp{break} command can be used to set breakpoints.
The @samp{d} or @samp{stack} command will display the call stack.
The @samp{quit} command will exit the debugger.
That should be enough to get you started.
But if you are a GNU Emacs user,
you should strongly consider using the Emacs interface to @samp{mdb} ---
see the following section.
For more information about the available commands,
use the @samp{?} or @samp{help} command, or see @ref{Debugger commands}.
@node GNU Emacs interface
@section GNU Emacs interface
@cindex GNU Emacs
@cindex Emacs
As well as the command-line debugger, mdb,
there is also an Emacs interface to this debugger.
Note that the Emacs interface only works with GNU Emacs, not with XEmacs.
With the Emacs interface,
the debugger will display your source code as you trace through it,
marking the line that is currently being executed,
and allowing you to easily set breakpoints
on particular lines in your source code.
You can have separate windows for the debugger prompt,
the source code being executed,
and for the output of the program being executed.
In addition, most of the mdb commands are accessible via menus.
To start the Emacs interface,
you first need to put the following text
in the @file{.emacs} file in your home directory,
replacing ``/usr/local/mercury-1.0''
with the directory that your Mercury implementation was installed in:
@example
(setq load-path (cons (expand-file-name
"/usr/local/mercury-1.0/lib/mercury/elisp")
load-path))
(autoload 'mdb "gud" "Invoke the Mercury debugger" t)
@end example
Build your program with debugging enabled, as described
in @ref{Quick overview} or @ref{Preparing a program for debugging}.
Then start up Emacs, e.g.@: using the command @samp{emacs},
and type @kbd{M-x mdb @key{RET}}.
Emacs will then prompt you for the mdb command to invoke
@example
Run mdb (like this): mdb
@end example
@noindent
and you should type in the name of the program that you want to debug
and any arguments that you want to pass to it:
@example
Run mdb (like this): mdb ./hello arg1 arg2 @dots{}
@end example
Emacs will then create several ``buffers'': one for the debugger prompt,
one for the input and output of the program being executed,
and one or more for the source files.
By default, Emacs will split the display into two parts, called ``windows'',
so that two of these buffers will be visible.
You can use the command @kbd{C-x o} to switch between windows,
and you can use the command @kbd{C-x 2} to split a window into two windows.
You can use the ``Buffers'' menu
to select which buffer is displayed in each window.
If you are using X-Windows, then it is a good idea
to set the Emacs variable @samp{pop-up-frames} to @samp{t} before starting mdb,
since this will cause each buffer
to be displayed in a new ``frame'' (i.e.@: a new X window).
You can set this variable interactively
using the @samp{set-variable} command,
i.e.@: @kbd{M-x set-variable @key{RET} pop-up-frames @key{RET} t @key{RET}}.
Or you can put @samp{(setq pop-up-frames t)}
in the @file{.emacs} file in your home directory.
For more information on buffers, windows, and frames,
see the Emacs documentation.
Another useful Emacs variable is @samp{gud-mdb-directories}.
This specifies the list of directories to search for source files.
You can use a command such as
@example
M-x set-variable @key{RET}
gud-mdb-directories @key{RET}
(list "/foo/bar" "../other" "/home/guest") @key{RET}
@end example
@noindent
to set it interactively, or you can put a command like
@example
(setq gud-mdb-directories
(list "/foo/bar" "../other" "/home/guest"))
@end example
@noindent
in your @file{.emacs} file.
At each trace event,
the debugger will search for the source file corresponding to that event,
first in the same directory as the program,
and then in the directories specified
by the @samp{gud-mdb-directories} variable.
It will display the source file,
with the line number corresponding to that trace event
marked by an arrow (@samp{=>}) at the start of the line.
Several of the debugger features can be accessed
by moving the cursor to the relevant part of the source code
and then selecting a command from the menu.
You can set a break point on a line
by moving the cursor to the appropriate line in your source code
(e.g.@: with the arrow keys,
or by clicking the mouse there), and then
selecting the ``Set breakpoint on line'' command
from the ``Breakpoints'' sub-menu of the ``MDB'' menu.
You can set a breakpoint on a procedure
by moving the cursor over the procedure name and then
selecting the ``Set breakpoint on procedure'' command from the same menu.
And you can display the value of a variable
by moving the cursor over the variable name and then
selecting the ``Print variable'' command
from the ``Data browsing'' sub-menu of the ``MDB'' menu.
Most of the menu commands also have keyboard short-cuts,
which are displayed on the menu.
Note that @samp{mdb}'s @samp{context} and @samp{user_event_context} commands
should not be used if you are using the Emacs interface,
otherwise the Emacs interface
won't be able to parse the file names and line numbers that @samp{mdb} outputs,
and so it won't be able to highlight the correct location in the source code.
@node Tracing of Mercury programs
@section Tracing of Mercury programs
@cindex Tracing
The Mercury debugger is based on a modified version of the box model
on which the four-port debuggers of most Prolog systems are based.
Such debuggers abstract the execution of a program into a sequence,
also called a @dfn{trace}, of execution events of various kinds.
The four kinds of events supported by most Prolog systems (their @emph{ports})
are
@cindex debugger trace events
@cindex trace events
@cindex call (trace event)
@cindex exit (trace event)
@cindex redo (trace event)
@cindex fail (trace event)
@table @emph
@item call
A call event occurs just after a procedure has been called,
and control has just reached the start of the body of the procedure.
@item exit
An exit event occurs when a procedure call has succeeded,
and control is about to return to its caller.
@item redo
A redo event occurs when all computations
to the right of a procedure call have failed,
and control is about to return to this call
to try to find alternative solutions.
@item fail
A fail event occurs when a procedure call has run out of alternatives,
and control is about to return to the rightmost computation to its left
that still has possibly successful alternatives left.
@end table
Mercury also supports these four kinds of events,
but not all events can occur for every procedure call.
Which events can occur for a procedure call, and in what order,
depend on the determinism of the procedure.
The possible event sequences for procedures of the various determinisms
are as follows.
@table @emph
@item nondet procedures
a call event, zero or more repeats of (exit event, redo event), and a fail event
@item multi procedures
a call event, one or more repeats of (exit event, redo event), and a fail event
@item semidet and cc_nondet procedures
a call event, and either an exit event or a fail event
@item det and cc_multi procedures
a call event and an exit event
@item failure procedures
a call event and a fail event
@item erroneous procedures
a call event
@end table
In addition to these four event types,
Mercury supports @emph{exception} events.
An exception event occurs
when an exception has been thrown inside a procedure,
and control is about to propagate this exception to the caller.
An exception event can replace the final exit or fail event
in the event sequences above
or, in the case of erroneous procedures,
can come after the call event.
Besides the event types call, exit, redo, fail and exception,
which describe the @emph{interface} of a call,
Mercury also supports several types of events
that report on what is happening @emph{internal} to a call.
Each of these internal event types has an associated parameter called a path.
The internal event types are:
@cindex cond (trace event)
@cindex then (trace event)
@cindex else (trace event)
@cindex disj (trace event)
@cindex switch (trace event)
@cindex neg_enter (trace event)
@cindex neg_fail (trace event)
@cindex neg_success (trace event)
@table @emph
@item cond
A cond event occurs when execution reaches
the start of the condition of an if-then-else.
The path associated with the event specifies which if-then-else this is.
@item then
A then event occurs when execution reaches
the start of the then part of an if-then-else.
The path associated with the event specifies which if-then-else this is.
@item else
An else event occurs when execution reaches
the start of the else part of an if-then-else.
The path associated with the event specifies which if-then-else this is.
@item disj
A disj event occurs when execution reaches
the start of a disjunct in a disjunction.
The path associated with the event specifies
which disjunct of which disjunction this is.
@item switch
A switch event occurs when execution reaches
the start of one arm of a switch
(a disjunction in which each disjunct unifies a bound variable
with different function symbol).
The path associated with the event specifies
which arm of which switch this is.
@item neg_enter
A neg_enter event occurs when execution reaches
the start of a negated goal.
The path associated with the event specifies which negation goal this is.
@item neg_fail
A neg_fail event occurs when
a goal inside a negation succeeds,
which means that its negation fails.
The path associated with the event specifies which negation goal this is.
@item neg_success
A neg_success event occurs when
a goal inside a negation fails,
which means that its negation succeeds.
The path associated with the event specifies which negation goal this is.
@end table
@cindex path
@cindex goal path
A goal path is a sequence of path components,
each of which is followed by a semicolon.
Each path component is one of the following:
@table @code
@item c@var{num}
The @var{num}'th conjunct of a conjunction.
@item d@var{num}
The @var{num}'th disjunct of a disjunction.
@item s@var{num}
The @var{num}'th arm of a switch.
@item ?
The condition of an if-then-else.
@item t
The then part of an if-then-else.
@item e
The else part of an if-then-else.
@item ~
The goal inside a negation.
@item q!
The goal inside an existential quantification or other scope
that changes the determinism of the goal.
@item q
The goal inside an existential quantification or other scope
that does not change the determinism of the goal.
@end table
A goal path describes the position of a goal
inside the body of a procedure definition.
For example, if the procedure body is a disjunction
in which each disjunct is a conjunction,
then the goal path @samp{d2;c3;} denotes
the third conjunct within the second disjunct.
If the third conjunct within the second disjunct is an atomic goal
such as a call or a unification,
then this will be the only goal with whose path has @samp{d2;c3;} as a prefix.
If it is a compound goal,
then its components will all have paths that have @samp{d2;c3;} as a prefix,
e.g.@: if it is an if-then-else,
then its three components will have the paths
@samp{d2;c3;?;}, @samp{d2;c3;t;} and @samp{d2;c3;e;}.
Goal paths refer to the internal form of the procedure definition.
When debugging is enabled
(and the option @samp{--trace-optimized} is not given),
the compiler will try to keep this form
as close as possible to the source form of the procedure,
in order to make event paths as useful as possible to the programmer.
Due to the compiler's flattening of terms,
and its introduction of extra unifications to implement calls in implied modes,
the number of conjuncts in a conjunction will frequently differ
between the source and internal form of a procedure.
This is rarely a problem, however, as long as you know about it.
Mode reordering can be a bit more of a problem,
but it can be avoided by writing single-mode predicates and functions
so that producers come before consumers.
The compiler transformation that
potentially causes the most trouble in the interpretation of goal paths
is the conversion of disjunctions into switches.
In most cases, a disjunction is transformed into a single switch,
and it is usually easy to guess, just from the events within a switch arm,
just which disjunct the switch arm corresponds to.
Some cases are more complex;
for example, it is possible for a single disjunction
to be transformed into several switches,
possibly with other, smaller disjunctions inside them.
In such cases, making sense of goal paths
may require a look at the internal form of the procedure.
You can ask the compiler to generate a file
with the internal forms of the procedures in a given module
by including the options @samp{-dfinal -Dpaths} on the command line
when compiling that module.
@node Preparing a program for debugging
@section Preparing a program for debugging
When you compile a Mercury program, you can specify
whether you want to be able to run the Mercury debugger on the program or not.
If you do, the compiler embeds calls to the Mercury debugging system
into the executable code of the program,
at the execution points that represent trace events.
At each event, the debugging system decides
whether to give control back to the executable immediately,
or whether to first give control to you,
allowing you to examine the state of the computation and issue commands.
Mercury supports two broad ways of preparing a program for debugging.
The simpler way is to compile a program in a debugging grade,
which you can do directly by specifying a grade
that includes the word ``debug'' or ``decldebug''
(e.g.@: @samp{asm_fast.gc.debug}, or @samp{asm_fast.gc.decldebug}),
or indirectly by specifying one of the @samp{--debug} or @samp{--decl-debug}
grade options to the compiler, linker, and other tools
(in particular @code{mmc}, @code{mgnuc}, @code{ml}, and @code{c2init}).
If you follow this way,
and accept the default settings of the various compiler options
that control the selection of trace events (which are described below),
you will be assured of being able to get control
at every execution point that represents a potential trace event,
which is very convenient.
The ``decldebug'' grades improve declarative debugging by allowing the user
to track the source of subterms (see @ref{Improving the search}).
Doing this increases the size of executables,
so these grades should only be used when you need
the subterm dependency tracking feature of the declarative debugger.
Note that declarative debugging,
with the exception of the subterm dependency tracking features,
also works in the .debug grades.
@c XXX mention ssdebug grades when ready
The two drawbacks of using a debugging grade
are the large size of the resulting executables,
and the fact that often you discover that you need to debug a big program
only after having built it in a non-debugging grade.
This is why Mercury also supports another way
to prepare a program for debugging,
one that does not require the use of a debugging grade.
With this way, you can decide, individually for each module,
which of four trace levels,
@samp{none}, @samp{shallow}, @samp{deep}, and @samp{rep}
you want to compile them with:
@cindex debugger trace level
@cindex trace level
@cindex shallow tracing
@cindex deep tracing
@table @samp
@item none
A procedure compiled with trace level @samp{none}
will never generate any events.
@item deep
A procedure compiled with trace level @samp{deep}
will always generate all the events requested by the user.
By default, this is all possible events,
but you can tell the compiler that
you are not interested in some kinds of events
via compiler options (see below).
However, declarative debugging requires all events to be generated
if it is to operate properly,
so do not disable the generation of any event types
if you want to use declarative debugging.
For more details see @ref{Declarative debugging}.
@item rep
This trace level is the same as trace level @samp{deep},
except that a representation of the module is stored in the executable
along with the usual debugging information.
The declarative debugger can use this extra information
to help it avoid asking unnecessary questions,
so this trace level has the effect of better declarative debugging
at the cost of increased executable size.
For more details see @ref{Declarative debugging}.
@item shallow
A procedure compiled with trace level @samp{shallow}
will generate interface events
if it is called from a procedure compiled with trace level @samp{deep},
but it will never generate any internal events,
and it will not generate any interface events either
if it is called from a procedure compiled with trace level @samp{shallow}.
If it is called from a procedure compiled with trace level @samp{none},
the way it will behave is dictated by whether
its nearest ancestor whose trace level is not @samp{none}
has trace level @samp{deep} or @samp{shallow}.
@end table
The intended uses of these trace levels are as follows.
@table @samp
@item deep
You should compile a module with trace level @samp{deep}
if you suspect there may be a bug in the module,
or if you think that being able to examine what happens inside that module
can help you locate a bug.
@item rep
You should compile a module with trace level @samp{rep}
if you suspect there may be a bug in the module,
you wish to use the full power of the declarative debugger,
and you are not concerned about the size of the executable.
@item shallow
You should compile a module with trace level @samp{shallow}
if you believe the code of the module is reliable and unlikely to have bugs,
but you still want to be able to get control at calls to and returns from
any predicates and functions defined in the module,
and if you want to be able to see the arguments of those calls.
@item none
You should compile a module with trace level @samp{none}
only if you are reasonably confident that the module is reliable,
and if you believe that knowing what calls other modules make to this module
would not significantly benefit you in your debugging.
@end table
In general, it is a good idea for most or all modules
that can be called from modules compiled with trace level
@samp{deep} or @samp{rep}
to be compiled with at least trace level @samp{shallow}.
You can control what trace level a module is compiled with
by giving one of the following compiler options:
@table @samp
@item --trace shallow
This always sets the trace level to @samp{shallow}.
@item --trace deep
This always sets the trace level to @samp{deep}.
@item --trace rep
This always sets the trace level to @samp{rep}.
@item --trace minimum
In debugging grades, this sets the trace level to @samp{shallow};
in non-debugging grades, it sets the trace level to @samp{none}.
@item --trace default
In debugging grades, this sets the trace level to @samp{deep};
in non-debugging grades, it sets the trace level to @samp{none}.
@end table
As the name implies, the last alternative is the default,
which is why by default you get
no debugging capability in non-debugging grades
and full debugging capability in debugging grades.
The table also shows that in a debugging grade,
no module can be compiled with trace level @samp{none}.
@strong{Important note}:
If you are not using a debugging grade, but you compile some modules with
a trace level other than none,
then you must also pass the @samp{--trace} (or @samp{-t}) option
to c2init and to the Mercury linker.
If you are using Mmake, then you can do this by including @samp{--trace}
in the @samp{MLFLAGS} variable.
If you are using Mmake, then you can also set the compilation options
for a single module named @var{Module} by setting the Mmake variable
@samp{MCFLAGS-@var{Module}}. For example, to compile the file
@file{foo.m} with deep tracing, @file{bar.m} with shallow tracing,
and everything else with no tracing, you could use the following:
@example
MLFLAGS = --trace
MCFLAGS-foo = --trace deep
MCFLAGS-bar = --trace shallow
@end example
@node Tracing optimized code
@section Tracing optimized code
@c XXX we should consider where to document --suppress-trace
@c and --stack-trace-higher-order
By default, all trace levels other than @samp{none}
turn off all compiler optimizations
that can affect the sequence of trace events generated by the program,
such as inlining.
If you are specifically interested in
how the compiler's optimizations affect the trace event sequence,
you can specify the option @samp{--trace-optimized},
which tells the compiler that it does not have to disable those optimizations.
(A small number of low-level optimizations
have not yet been enhanced to work properly in the presence of tracing,
so the compiler disables these even if @samp{--trace-optimized} is given.)
@node Mercury debugger invocation
@section Mercury debugger invocation
The executables of Mercury programs
by default do not invoke the Mercury debugger
even if some or all of their modules were compiled with some form of tracing,
and even if the grade of the executable is a debugging grade.
This is similar to the behaviour of executables
created by the implementations of other languages;
for example the executable of a C program compiled with @samp{-g}
does not automatically invoke gdb or dbx etc when it is executed.
Unlike those other language implementations,
when you invoke the Mercury debugger @samp{mdb},
you invoke it not just with the name of an executable
but with the command line you want to debug.
If something goes wrong when you execute the command
@example
@var{prog} @var{arg1} @var{arg2} @dots{}
@end example
and you want to find the cause of the problem,
you must execute the command
@example
mdb [@var{mdb-options}] @var{prog} @var{arg1} @var{arg2} @dots{}
@end example
because you do not get a chance
to specify the command line of the program later.
When the debugger starts up, as part of its initialization
it executes commands from the following three sources, in order:
@enumerate
@item
@vindex MERCURY_DEBUGGER_INIT
The file named by the @env{MERCURY_DEBUGGER_INIT} environment variable.
Usually, @samp{mdb} sets this variable to point to a file
that provides documentation for all the debugger commands
and defines a small set of aliases.
However, if @env{MERCURY_DEBUGGER_INIT} is already defined
when @samp{mdb} is invoked, it will leave its value unchanged.
You can use this override ability to provide alternate documentation.
If the file named by @env{MERCURY_DEBUGGER_INIT} cannot be read,
@samp{mdb} will print a warning,
since in that case, that usual online documentation will not be available.
@item
@cindex mdbrc
@cindex .mdbrc
The file named @file{.mdbrc} in your home directory.
You can put your usual aliases and settings here.
@item
The file named @file{.mdbrc} in the current working directory.
You can put program-specific aliases and settings here.
@end enumerate
mdb will ignore any lines starting with the character @samp{#}
in any of the above mentioned files.
mdb accepts the following options from the command line. The options
should be given to mdb before the name of the executable to be debugged.
@table @code
@item -t @var{file-name}, --tty @var{file-name}
@findex --tty (mdb option)
Redirect all of the I/O for the debugger to the device
specified by @var{file-name}.
The I/O for the program being debugged will not be redirected.
This option allows the contents of a file to be piped to the program being
debugged and not to mdb.
For example, on Linux the command
@example
mdb -t /dev/tty ./myprog < myinput
@end example
will cause the contents of @file{myinput} to be piped to the program
@samp{myprog}, but mdb will read its input from the terminal.
@sp 1
@item -w, --window, --mdb-in-window
@findex --mdb-in-window (mdb option)
@findex --window (mdb option)
Run mdb in a new window, with mdb's I/O going to that
window, but with the program's I/O going to the current
terminal. Note that this will not work on all systems.
@sp 1
@item --program-in-window
@findex --program-in-window (mdb option)
Run the program in a new window, with the program's I/O
going to that window, but with mdb's I/O going to the
current terminal. Note that input and output redirection
will not work with the @samp{--program-in-window} option.
@samp{--program-in-window} will work on most Unix systems
running the X Window System, even those for which
@samp{--mdb-in-window} is not supported.
@sp 1
@item -c @var{window-command}, --window-command @var{window-command}
@findex --window-command (mdb option)
Specify the command used by the @samp{--program-in-window}
option for executing a command in a new window.
The default such command is @samp{xterm -e}.
@end table
@node Mercury debugger concepts
@section Mercury debugger concepts
The operation of the Mercury debugger @samp{mdb}
is based on the following concepts.
@table @emph
@item break points
@cindex debugger break points
@cindex break points
@cindex spy points
The user may associate a break point
with some events that occur inside a procedure;
the invocation condition of the break point says which events these are.
The four possible invocation conditions (also called scopes) are:
@sp 1
@itemize @bullet
@item
the call event,
@item
all interface events,
@item
all events, and
@item
the event at a specific point in the procedure.
@end itemize
@sp 1
The effect of a break point depends on the state of the break point.
@sp 1
@itemize @bullet
@item
If the state of the break point is @samp{stop},
execution will stop and user interaction will start
at any event within the procedure that matches the invocation conditions,
unless the current debugger command has specifically disabled this behaviour
(see the concept @samp{strict commands} below).
@sp 1
@item
If the state of the break point is @samp{print},
the debugger will print any event within the procedure
that matches the invocation conditions,
unless the current debugger command has specifically disabled this behaviour
(see the concept @samp{print level} below).
@end itemize
@sp 1
Neither of these will happen if the break point is disabled.
@sp 1
Every break point has a print list.
Every time execution stops at an event that matches the breakpoint,
mdb implicitly executes a print command for each element
in the breakpoint's print list.
A print list element can be the word @samp{goal},
which causes the goal to the printed as if by @samp{print goal};
it can be the word @samp{*},
which causes all the variables to the printed as if by @samp{print *};
or it can be the name or number of a variable,
possibly followed (without white space) by a term path,
which causes the specified variable or part thereof to the printed
as if the element were given as an argument to the @samp{print} command.
@sp 1
@item strict commands
@cindex strict debugger commands
When a debugger command steps over some events
without user interaction at those events,
the @emph{strictness} of the command controls whether
the debugger will stop execution and resume user interaction
at events to which a break point with state @samp{stop} applies.
By default, the debugger will stop at such events.
However, if the debugger is executing a strict command,
it will not stop at an event
just because a break point in the stop state applies to it.
@cindex debugger interrupt
@cindex interrupt, in debugger
@cindex control-C
If the debugger receives an interrupt (e.g.@: if the user presses control-C),
it will stop at the next event regardless of what command it is executing
at the time.
@sp 1
@item print level
@cindex print level
@cindex debugger print level
When a debugger command steps over some events
without user interaction at those events,
the @emph{print level} controls under what circumstances
the stepped over events will be printed.
@sp 1
@itemize @bullet
@item
When the print level is @samp{none},
none of the stepped over events will be printed.
@sp 1
@item
When the print level is @samp{all},
all the stepped over events will be printed.
@sp 1
@item
When the print level is @samp{some},
the debugger will print the event only if a break point applies to the event.
@end itemize
@sp 1
Regardless of the print level, the debugger will print
any event that causes execution to stop and user interaction to start.
@sp 1
@item default print level
The debugger maintains a default print level.
The initial value of this variable is @samp{some},
but this value can be overridden by the user.
@sp 1
@item current environment
Whenever execution stops at an event, the current environment
is reset to refer to the stack frame of the call specified by the event.
However, the @samp{up}, @samp{down} and @samp{level} commands
can set the current environment
to refer to one of the ancestors of the current call.
This will then be the current environment until another of these commands
changes the environment yet again or execution continues to another event.
@sp 1
@item paths in terms
@cindex paths in terms
@cindex term navigation
When browsing or printing a term,
you can use "^@samp{n}" to refer to the @var{n}th subterm of that term.
If the term's type has named fields,
you can use "^@samp{fname}" to refer to
the subterm of the field named @samp{fname}.
You can use several of these subterm specifications in a row
to refer to subterms deep within the original term.
For example, when applied to a list,
"^2" refers to the tail of the list
(the second argument of the list constructor),
"^2^2" refers to the tail of the tail of the list,
and "^2^2^1" refers to the head of the tail of the tail,
i.e. to the third element of the list.
You can think of terms as Unix directories,
with constants (function symbols of arity zero) being plain files
and function symbols of arity greater than zero being directories themselves.
Each subterm specification such as "^2" goes one level down in the hierarchy.
The exception is the subterm specification "^..",
which goes one level up, to the parent of the current directory.
@sp 1
@item held variables
@cindex held variables (in mdb)
Normally, the only variables from the program accessible in the debugger
are the variables in the current environment at the current program point.
However, the user can @emph{hold} variables,
causing their values -or selected parts of their values-
to stay available for the rest of the debugger session.
@c XXX Document the relationship of this command
@c to partially instantiated data structures and solver types
@c when the debugger is extended to handle these constructs.
All the commands that accept variable names
also accept the names of held variables;
users can ask for a held variable
by prefixing the name of the held variable with a dollar sign.
@sp 1
@item user defined events
@cindex user defined events (in mdb)
Besides the builtin set of events,
the Mercury debugger also supports events defined by the user.
Each event appears in the source code of the Mercury program
as a call prefixed by the keyword @samp{event},
with each argument of the call giving the value of an event @emph{attribute}.
Users can specify the set of user defined events that can appear in a program,
and the names, types and order of the attributes
of each kind of user defined event,
by giving the name of an event set specification file to the compiler
when compiling that program.
For more details, see @ref{User defined events}.
@sp 1
@item user defined event attributes
@cindex user defined event attributes (in mdb)
Normally, the only variables from the program accessible in the debugger
are the variables in the current environment at the current program point.
However, if the current event is a user defined event,
then the attributes of that event are also available.
All the commands that accept variable names
also accept the names of attributes;
users can ask for an attribute
by prefixing the name of the attribute with an exclamation point.
@sp 1
@item procedure specification
@cindex procedure specification (in mdb)
@cindex debugger procedure specification
Some debugger commands, e.g.@: @samp{break},
require a parameter that specifies a procedure.
The procedure may or may not be a compiler-generated
unify, compare or index procedure of a type constructor.
If it is, the procedure specification has
the following components in the following order:
@itemize @bullet
@item
An optional prefix of the form
@samp{unif*}, @samp{comp*}, @samp{indx*} or @samp{init*},
that specifies whether the procedure belongs
to a unify, compare, index or init predicate.
@item
An optional prefix of the form @samp{@var{module}.} or @samp{@var{module}__}
that specifies the name of the module that defines the predicate or function
to which the procedure belongs.
@item
The name of the type constructor.
@item
An optional suffix of the form @samp{/@var{arity}}
that specifies the arity of the type constructor.
@item
An optional suffix of the form @samp{-@var{modenum}}
that specifies the mode number of the procedure
within the predicate or function to which the procedure belongs.
@end itemize
For other procedures, the procedure specification has
the following components in the following order:
@itemize @bullet
@item
An optional prefix of the form @samp{pred*} or @samp{func*}
that specifies whether the procedure belongs to a predicate or a function.
@item
An optional prefix of the form @samp{@var{module}:}, @samp{@var{module}.}
or @samp{@var{module}__} that specifies the name of the module that defines
the predicate or function to which the procedure belongs.
@item
The name of the predicate or function to which the procedure belongs.
@item
An optional suffix of the form @samp{/@var{arity}}
that specifies the arity of the predicate or function
to which the procedure belongs.
@item
An optional suffix of the form @samp{-@var{modenum}}
that specifies the mode number of the procedure
within the predicate or function to which the procedure belongs.
@end itemize
@end table
@node User defined events
@section User defined events
Besides the builtin set of events,
the Mercury debugger also supports events defined by the user.
The intention is that users can define one kind of event
for each semantically important event in the program
that is not captured by the standard builtin events,
and can then generate those events at the appropriate point in the source code.
Each event appears in the source code
as a call prefixed by the keyword @samp{event},
with each argument of the call giving the value of an event @emph{attribute}.
Users can specify the set of user defined events that can appear in a program,
and the names, types and order of the attributes
of each kind of user defined event,
by giving the name of an event set specification file to the compiler
when compiling that program
as the argument of the @samp{event-set-file-name} option.
This file should contain a header giving the event set's name,
followed by a sequence of one or more event specifications,
like this:
@c XXX replace with more realistic example
@example
event set queens
event nodiag_fail(
test_failed: string,
arg_b: int,
arg_d: int,
arg_list_len: int synthesized by list_len_func(sorted_list),
sorted_list: list(int) synthesized by list_sort_func(arg_list),
list_len_func: function,
list_sort_func: function,
arg_list: list(int)
)
event safe_test(
test_list: listint
)
event noargs
@end example
The header consists of the keywords @samp{event set}
and an identifier giving the event set name.
Each event specification consists of the keyword @samp{event},
the name of the event, and,
if the event has any attributes, a parenthesized list of those attributes.
Each attribute's specification consists of
a name, a colon and information about the attribute.
There are three kinds of attributes.
@itemize
@item
For ordinary attributes, like @samp{arg_b},
the information about the attribute is the Mercury type of that attribute.
@item
For function attributes, like @samp{list_sort_func},
the information about the attribute is just the keyword @samp{function}.
@item
For synthesized attributes, like @samp{sorted_list},
the information about the attribute is the type of the attribute,
the keywords @samp{synthesized by},
and a description of the Mercury function call
required to synthesize the value of the attribute.
The synthesis call consists of the name of a function attribute
and a list of the names of one or more argument attributes.
Argument attributes cannot be function attributes;
they may be either ordinary attributes, or previously synthesized attributes.
A synthesized attribute is not allowed
to depend on itself directly or indirectly,
but there are no restrictions on the positions of synthesized attributes
compared to the positions of the function attributes computing them
or of the argument attributes of the synthesis functions.
@end itemize
The result types of function attributes
are given by the types of the synthesized attributes they compute.
The argument types of function attributes (and the number of those arguments)
are given by the types of the arguments they are applied to.
Each function attribute must be used
to compute at least one synthesized attribute,
otherwise there would be no way to compute its type.
If it is used to compute more than one synthesized attribute,
the result and argument types must be consistent.
Each event goal in the program must use
the name of one of the events defined here as the predicate name of the call,
and the call's arguments must match
the types of that event's non-synthesized attributes.
Given that B and N are integers and L is a list of integers,
these event goals are fine,
@example
event nodiag_fail("N - B", B, N, list.length, list.sort, [N | L]),
event safe_test([1, 2, 3])
@end example
but these goals
@example
event nodiag_fail("N - B", B, N, list.sort, list.length, [N | L]),
event nodiag_fail("N - B", B, list.length, N, list.sort, [N | L]),
event safe_test([1], [2])
event safe_test(42)
event nonexistent_event(42)
@end example
will all generate errors.
The attributes of event calls are always input,
and the event goal is always @samp{det}.
@node I/O tabling
@section I/O tabling
In Mercury, predicates that want to do I/O
must take a di/uo pair of I/O state arguments.
Some of these predicates call other predicates to do I/O for them,
but some are @emph{I/O primitives}, i.e. they perform the I/O themselves.
The Mercury standard library provides a large set of these primitives,
and programmers can write their own through the foreign language interface.
An I/O action is the execution of one call to an I/O primitive.
In debugging grades, the Mercury implementation has the ability
to automatically record, for every I/O action,
the identity of the I/O primitive involved in the action
and the values of all its arguments.
The size of the table storing this information
is proportional to the number of @emph{tabled} I/O actions,
which are the I/O actions whose details are entered into the table.
Therefore the tabling of I/O actions is never turned on automatically;
instead, users must ask for I/O tabling to start
with the @samp{table_io start} command in mdb.
The purpose of I/O tabling is to enable transparent retries across I/O actions.
(The mdb @samp{retry} command
restores the computation to a state it had earlier,
allowing the programmer to explore code that the program has already executed;
see its documentation in the @ref{Debugger commands} section below.)
In the absence of I/O tabling,
retries across I/O actions can have bad consequences.
Retry of a goal that reads some input requires that input to be provided twice;
retry of a goal that writes some output generates duplicate output.
Retry of a goal that opens a file leads to a file descriptor leak;
retry of a goal that closes a file can lead to errors
(duplicate closes, reads from and writes to closed files).
I/O tabling avoids these problems by making I/O primitives @emph{idempotent}.
This means that they will generate their desired effect
when they are first executed,
but reexecuting them after a retry won't have any further effect.
The Mercury implementation achieves this
by looking up the action (which is identified by a I/O action number)
in the table and returning the output arguments stored in the table
for the given action @emph{without} executing the code of the primitive.
Starting I/O tabling when the program starts execution
and leaving it enabled for the entire program run
will work well for program runs that don't do lots of I/O.
For program runs that @emph{do} lots of I/O,
the table can fill up all available memory.
In such cases, the programmer may enable I/O tabling with @samp{table_io start}
just before the program enters the part they wish to debug
and in which they wish to be able to perform
transparent retries across I/O actions,
and turn it off with @samp{table_io stop} after execution leaves that part.
The commands @samp{table_io start} and @samp{table_io stop}
can each be given only once during an mdb session.
They divide the execution of the program into three phases:
before @samp{table_io start},
between @samp{table_io start} and @samp{table_io stop},
and after @samp{table_io stop}.
Retries across I/O will be transparent only in the middle phase.
@node Debugger commands
@section Debugger commands
When the debugger (as opposed to the program being debugged) is interacting
with the user, the debugger prints a prompt and reads in a line of text,
which it will interpret as its next command line.
A command line consists of a single command,
or several commands separated by semicolons.
Each command consists of several words separated by white space.
The first word is the name of the command,
while any other words give options and/or parameters to the command.
A word may itself contain semicolons or whitespace if it is
enclosed in single quotes (@samp{'}).
This is useful for commands that have other commands as parameters,
for example @w{@samp{view -w 'xterm -e'}}.
Characters that have special meaning to @samp{mdb} will be treated like
ordinary characters if they are escaped with a backslash (@samp{\}).
It is possible to escape single quotes, whitespace, semicolons, newlines
and the escape character itself.
Some commands take a number as their first parameter.
For such commands, users can type `@var{number} @var{command}'
as well as `@var{command} @var{number}'.
The debugger will treat the former as the latter,
even if the number and the command are not separated by white space.
@menu
* Interactive query commands::
* Forward movement commands::
* Backward movement commands::
* Browsing commands::
* Breakpoint commands::
* I/O tabling commands::
* Parameter commands::
* Help commands::
* Declarative debugging mdb commands::
* Miscellaneous commands::
* Experimental commands::
* Developer commands::
@end menu
@node Interactive query commands
@subsection Interactive query commands
@table @code
@item query @var{module1} @var{module2} @dots{}
@itemx cc_query @var{module1} @var{module2} @dots{}
@itemx io_query @var{module1} @var{module2} @dots{}
@kindex query (mdb command)
@kindex cc_query (mdb command)
@kindex io_query (mdb command)
@c This documentation has been duplicated in
@c Opium-M/source/interactive_queries.op so please tell me (jahier@irisa.fr)
@c to update my documentation on interactive queries if you update this
@c subsection.
These commands allow you to type in queries (goals) interactively
in the debugger. When you use one of these commands, the debugger
will respond with a query prompt (@samp{?-} or @samp{run <--}),
at which you can type in a goal; the debugger will then compile
and execute the goal and display the answer(s).
You can return from the query prompt to the @samp{mdb>} prompt
by typing the end-of-file indicator (typically control-D or control-Z),
or by typing @samp{quit.}.
@sp 1
The module names @var{module1}, @var{module2}, @dots{} specify
which modules will be imported. Note that you can also
add new modules to the list of imports directly at the query prompt,
by using a command of the form @samp{[@var{module}]}, e.g.@: @samp{[int]}.
You need to import all the modules that define symbols used in your query.
Queries can only use symbols that are exported from a module;
entities which are declared in a module's implementation section
only cannot be used.
@sp 1
The three variants differ in what kind of goals they allow.
For goals which perform I/O, you need to use @samp{io_query};
this lets you type in the goal using DCG syntax.
For goals which don't do I/O, but which have determinism
@samp{cc_nondet} or @samp{cc_multi}, you need to use @samp{cc_query};
this finds only one solution to the specified goal.
For all other goals, you can use plain @samp{query}, which
finds all the solutions to the goal.
@sp 1
Goals can refer to variables in the current environment,
which will be treated as inputs to the query.
Any variables in the goal that do not exist in the current environment,
and that do not start with an underscore, will be treated as outputs.
For @samp{query} and @samp{cc_query}, the debugger will print
the bindings of output variables in the goal using @samp{io.write_cc}.
The goal must bind all of its output variables to ground terms,
otherwise you will get a mode error.
@sp 1
The current implementation works by compiling the queries on-the-fly
and then dynamically linking them into the program being debugged.
Thus it may take a little while for your query to be executed.
Each query will be written to a file named @file{mdb_query.m} in the current
directory, so make sure you don't name your source file @file{mdb_query.m}.
Note that dynamic linking may not be supported on some systems;
if you are using a system for which dynamic linking is not supported,
you will get an error message when you try to run these commands.
@sp 1
You may also need to build your program using shared libraries
for interactive queries to work.
See @ref{Libraries} for details of how to build with shared libraries.
@end table
@sp 1
@node Forward movement commands
@subsection Forward movement commands
@sp 1
@table @code
@item step [-NSans] [@var{num}]
@kindex step (mdb command)
Steps forward @var{num} events.
If this command is given at event @var{cur}, continues execution until
event @var{cur} + @var{num}. The default value of @var{num} is 1.
@sp 1
The options @samp{-n} or @samp{--none}, @samp{-s} or @samp{--some},
@samp{-a} or @samp{--all} specify the print level to use
for the duration of the command,
while the options @samp{-S} or @samp{--strict}
and @samp{-N} or @samp{--nostrict} specify
the strictness of the command.
@sp 1
By default, this command is not strict, and it uses the default print level.
@sp 1
A command line containing only a number @var{num} is interpreted as
if it were `step @var{num}'.
@sp 1
An empty command line is interpreted as `step 1'.
@sp 1
@item goto [-NSans] @var{num}
@c The @var{generatorname} option is enabled
@c only in own stack minimal model grades.
@c @item goto [-NSans] @var{num} [@var{generatorname}]
@kindex goto (mdb command)
Continues execution until the program reaches event number @var{num}.
If the current event number is larger than @var{num}, it reports an error.
@sp 1
The options @samp{-n} or @samp{--none}, @samp{-s} or @samp{--some},
@samp{-a} or @samp{--all} specify the print level to use
for the duration of the command,
while the options @samp{-S} or @samp{--strict}
and @samp{-N} or @samp{--nostrict} specify
the strictness of the command.
@c @sp 1
@c If given, @var{generatorname} specifies
@c the generator in which to reach the given event number.
@c In this case, the command does not check
@c whether the event has already passed.
@sp 1
By default, this command is strict, and it uses the default print level.
@sp 1
@item next [-NSans] [@var{num}]
@kindex next (mdb command)
Continues execution until it reaches the next event of
the @var{num}'th ancestor of the call to which the current event refers.
The default value of @var{num} is zero,
which means skipping to the next event of the current call.
Reports an error if execution is already at the end of the specified call.
@sp 1
The options @samp{-n} or @samp{--none}, @samp{-s} or @samp{--some},
@samp{-a} or @samp{--all} specify the print level to use
for the duration of the command,
while the options @samp{-S} or @samp{--strict}
and @samp{-N} or @samp{--nostrict} specify
the strictness of the command.
@sp 1
By default, this command is strict, and it uses the default print level.
@sp 1
@item finish [-NSans]
@item finish [-NSans] @var{num}
@item finish [-NSans] (@samp{clentry}|@samp{clique})
@item finish [-NSans] @samp{clparent}
@kindex finish (mdb command)
If invoked without arguments,
continues execution until it reaches a final (EXIT, FAIL or EXCP) port
of the current call.
If invoked with the number @var{num} as argument,
continues execution until it reaches a final port
of the @var{num}'th ancestor of the call to which the current event refers.
If invoked with the argument @samp{clentry} or @samp{clique},
continues execution until it reaches a final port of the call
that first entered into the clique of recursive calls
of which the current call is a part.
(If the current call is not recursive or mutually recursive
with any other currently active call,
it will skip to the end of the current call.)
If the command is given the argument @samp{clparent},
it skips to the end of the first call outside the current call's clique.
This will be the parent of the call that @samp{finish clentry} would finish.
@sp 1
If invoked as
@samp{finish clentry}, @samp{finish clique} or @samp{finish clparent},
this command will report an error
unless we have stack trace information
about all of the current call's ancestors.
@sp 1
Also reports an error if execution is already at the desired port.
@sp 1
The options @samp{-n} or @samp{--none}, @samp{-s} or @samp{--some},
@samp{-a} or @samp{--all} specify the print level to use
for the duration of the command,
while the options @samp{-S} or @samp{--strict}
and @samp{-N} or @samp{--nostrict} specify
the strictness of the command.
@sp 1
By default, this command is strict, and it uses the default print level.
@c The documentation of fail is commented out, because the implementation does
@c not yet do this right thing when the procedure call we want to get to the
@c FAIL port of is inside a commit.
@c @sp 1
@c @item fail [-NSans] [@var{num}]
@c Continues execution until it reaches a FAIL or EXCP port
@c of the @var{num}'th ancestor of the call to which the current event refers.
@c The default value of @var{num} is zero,
@c which means skipping to the end of the current call.
@c Reports an error if execution is already at the desired port,
@c or if the determinism of the selected call
@c does not guarantee that it will eventually fail.
@c @sp 1
@c The options @samp{-n} or @samp{--none}, @samp{-s} or @samp{--some},
@c @samp{-a} or @samp{--all} specify the print level to use
@c for the duration of the command,
@c while the options @samp{-S} or @samp{--strict}
@c and @samp{-N} or @samp{--nostrict} specify
@c the strictness of the command.
@c @sp 1
@c By default, this command is strict, and it uses the default print level.
@sp 1
@item exception [-NSans]
@kindex exception (mdb command)
Continues the program until execution reaches an exception event.
Reports an error if the current event is already an exception event.
@sp 1
The options @samp{-n} or @samp{--none}, @samp{-s} or @samp{--some},
@samp{-a} or @samp{--all} specify the print level to use
for the duration of the command,
while the options @samp{-S} or @samp{--strict}
and @samp{-N} or @samp{--nostrict} specify
the strictness of the command.
@sp 1
By default, this command is strict, and it uses the default print level.
@sp 1
@item return [-NSans]
@kindex return (mdb command)
Continues the program until the program finished returning,
i.e.@: until it reaches a port other than EXIT.
Reports an error if the current event already refers to such a port.
@sp 1
The options @samp{-n} or @samp{--none}, @samp{-s} or @samp{--some},
@samp{-a} or @samp{--all} specify the print level to use
for the duration of the command,
while the options @samp{-S} or @samp{--strict}
and @samp{-N} or @samp{--nostrict} specify
the strictness of the command.
@sp 1
By default, this command is strict, and it uses the default print level.
@sp 1
@item user [-NSans]
@kindex return (mdb command)
Continues the program until the next user defined event.
@sp 1
The options @samp{-n} or @samp{--none}, @samp{-s} or @samp{--some},
@samp{-a} or @samp{--all} specify the print level to use
for the duration of the command,
while the options @samp{-S} or @samp{--strict}
and @samp{-N} or @samp{--nostrict} specify
the strictness of the command.
@sp 1
By default, this command is strict, and it uses the default print level.
@sp 1
@item forward [-NSans]
@kindex forward (mdb command)
Continues the program until the program resumes forward execution,
i.e.@: until it reaches a port other than REDO or FAIL.
Reports an error if the current event already refers to such a port.
@sp 1
The options @samp{-n} or @samp{--none}, @samp{-s} or @samp{--some},
@samp{-a} or @samp{--all} specify the print level to use
for the duration of the command,
while the options @samp{-S} or @samp{--strict}
and @samp{-N} or @samp{--nostrict} specify
the strictness of the command.
@sp 1
By default, this command is strict, and it uses the default print level.
@sp 1
@item mindepth [-NSans] @var{depth}
@kindex mindepth (mdb command)
Continues the program until the program reaches an event
whose depth is at least @var{depth}.
Reports an error if the current event already refers to such a port.
@sp 1
The options @samp{-n} or @samp{--none}, @samp{-s} or @samp{--some},
@samp{-a} or @samp{--all} specify the print level to use
for the duration of the command,
while the options @samp{-S} or @samp{--strict}
and @samp{-N} or @samp{--nostrict} specify
the strictness of the command.
@sp 1
By default, this command is strict, and it uses the default print level.
@sp 1
@item maxdepth [-NSans] @var{depth}
@kindex maxdepth (mdb command)
Continues the program until the program reaches an event
whose depth is at most @var{depth}.
Reports an error if the current event already refers to such a port.
@sp 1
The options @samp{-n} or @samp{--none}, @samp{-s} or @samp{--some},
@samp{-a} or @samp{--all} specify the print level to use
for the duration of the command,
while the options @samp{-S} or @samp{--strict}
and @samp{-N} or @samp{--nostrict} specify
the strictness of the command.
@sp 1
By default, this command is strict, and it uses the default print level.
@sp 1
@item continue [-NSans]
@kindex continue (mdb command)
Continues execution until it reaches the end of the program.
@sp 1
The options @samp{-n} or @samp{--none}, @samp{-s} or @samp{--some},
@samp{-a} or @samp{--all} specify the print level to use
for the duration of the command,
while the options @samp{-S} or @samp{--strict}
and @samp{-N} or @samp{--nostrict} specify
the strictness of the command.
@sp 1
By default, this command is not strict. The print level used
by the command by default depends on the final strictness level:
if the command is strict, it is @samp{none}, otherwise it is @samp{some}.
@end table
@sp 1
@node Backward movement commands
@subsection Backward movement commands
@sp 1
@table @code
@item retry [-fio]
@item retry [-fio] @var{num}
@item retry [-fio] (@samp{clentry}|@samp{clique})
@item retry [-fio] @samp{clparent}
@c @item retry [-afio] [@var{num}]
@kindex retry (mdb command)
If the command is given no arguments,
restarts execution at the call port
of the call corresponding to the current event.
If the command is given the number @var{num} as argument,
restarts execution at the call port of the call corresponding to
the @var{num}'th ancestor of the call to which the current event belongs.
For example, if @var{num} is 1, it restarts the parent of the current call.
If the command is given the argument @samp{clentry} or @samp{clique},
restarts execution at the call port of the call
that first entered into the clique of recursive calls
of which the current call is a part.
(If the current call is not (mutually) recursive
with any other currently active call,
the restarted call will be the current call.)
If the command is given the argument @samp{clparent},
restarts execution at the call port
of the first call outside the current call's clique.
This will be the parent of the call that @samp{retry clentry} would restart.
@sp 1
If invoked as
@samp{retry clentry}, @samp{retry clique} or @samp{retry clparent},
this command will report an error
unless we have stack trace information
about all of the current call's ancestors.
@sp 1
The command will also report an error unless
the values of all the input arguments of the selected call are available
at the return site at which control would reenter the selected call.
(The compiler will keep the values
of the input arguments of traced predicates as long as possible,
but it cannot keep them beyond the point where they are destructively updated.)
The exception is values of type `io.state';
the debugger can perform a retry if the only missing value is of
type `io.state' (there can be only one io.state at any given time).
@sp 1
Retries over I/O actions are guaranteed to be safe
only if the events at which the retry starts and ends
are both within the I/O tabled region of the program's execution.
If the retry is not guaranteed to be safe,
the debugger will normally ask the user if they really want to do this.
The option @samp{-f} or @samp{--force} suppresses the question,
telling the debugger that retrying over I/O is OK;
the option @samp{-o} or @samp{--only-if-safe} suppresses the question,
telling the debugger that retrying over I/O is not OK;
the option @samp{-i} or @samp{--interactive} restores the question
if a previous option suppressed it.
@c The --assume-all-io-is-tabled option is for developers only. Specifying it
@c makes an assertion, and if the assertion is incorrect, the resulting
@c behaviour would be hard for non-developers to understand. The option is
@c therefore deliberately not documented.
@c
@c @sp 1
@c A retry in which the values of all input arguments are available
@c works fine, provided that the predicates defined in C code that are
@c called inside the repeated computation do not pose any problems.
@c A retry in which a value of type `io.state' is missing has the
@c following effects:
@c @sp 1
@c @itemize @bullet
@c @item
@c Any input and/or output actions in the repeated code will be repeated.
@c @item
@c Any file close actions in the repeated code
@c for which the corresponding file open action is not also in the repeated code
@c may cause later I/O actions referring to the file to fail.
@c @item
@c Any file open actions in the repeated code
@c for which the corresponding file close action
@c is not also in the repeated code
@c may cause later file open actions to fail due to file descriptor leak.
@c @end itemize
@c @sp 1
@c XXX the following limitation applies only in minimal model grades,
@c which are not officially supported:
@c The debugger can perform a retry only from an exit or fail port;
@c only at these ports does the debugger have enough information
@c to figure out how to reset the stacks.
@c If the debugger is not at such a port when a retry command is given,
@c the debugger will continue forward execution
@c until it reaches an exit or fail port of the call to be retried
@c before it performs the retry.
@c This may require a noticeable amount of time,
@c and may result in the execution of I/O and/or other side-effects.
@c If the predicate being retried does I/O, the indirect retry will fail.
@end table
@sp 1
@table @code
@item track @var{num} [@var{termpath}]
@kindex track (mdb command)
Goto the EXIT event of the procedure in which the subterm in argument
@var{num} at term path @var{termpath} was bound,
and display information about where the term was bound.
@sp 1
Note that this command just invokes a script that is equivalent to running
the following sequence of commands:
@example
dd
browse @var{num}
cd @var{termpath}
track
info
pd
@end example
@end table
@sp 1
@node Browsing commands
@subsection Browsing commands
@sp 1
@table @code
@item vars
@kindex vars (mdb command)
Prints the names of all the known variables in the current environment,
together with an ordinal number for each variable.
@item held_vars
@kindex held_vars (mdb command)
Prints the names of all the held variables.
@sp 1
@item print [-fpv] @var{name}[@var{termpath}]
@itemx print [-fpv] @var{num}[@var{termpath}]
@kindex print (mdb command)
Prints the value of the variable in the current environment
with the given name, or with the given ordinal number.
If the name or number is followed by a term path such as "^2",
then only the specified subterm of the given variable is printed.
This is a non-interactive version of the @samp{browse} command (see below).
Various settings which affect the way that terms are printed out
(including e.g.@: the maximum term depth)
can be set using the @samp{format_param} command.
@sp 1
The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose} specify the format to use for printing.
@sp 1
@item print [-fpv] *
Prints the values of all the known variables in the current environment.
@sp 1
The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose} specify the format to use for printing.
@sp 1
@item print [-fpv]
@item print [-fpv] goal
Prints the goal of the current call in its present state of instantiation.
@sp 1
The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose} specify the format to use for printing.
@sp 1
@item print [-fpv] exception
Prints the value of the exception at an EXCP port.
Reports an error if the current event does not refer to such a port.
@sp 1
The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose} specify the format to use for printing.
@sp 1
@item print io limits
@itemx print action limits
Prints the numbers of the lowest and highest numbered
I/O actions executed and recorded by the program, if any.
@sp 1
@item print [-fpv] io @var{num}
@itemx print [-fpv] action @var{num}
Prints a representation
of the @var{num}'th I/O action executed by the program,
if there was such an action and if it was recorded.
@sp 1
The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose} specify the format to use for printing.
@sp 1
@item print [-fpv] io @var{min}-@var{max}
@itemx print [-fpv] action @var{min}-@var{max}
Prints a representation of the I/O actions executed by the program
from the @var{min}'th to the @var{min}'th,
if there were such actions and if they were recorded.
@sp 1
The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose} specify the format to use for printing.
@sp 1
@item print [-fpv] [-m @var{max}] io
@itemx print [-fpv] [-m @var{max}] action
If no I/O actions have been printed yet,
or if the last mdb command to print I/O actions was not successful,
prints a representation of the first @var{max} I/O actions
executed and recorded by the program.
If there was an mdb command to print I/O actions and it was successful,
prints a representation of the next @var{max} I/O actions
executed and recorded by the program.
@sp 1
The value of @var{max} is given by the @samp{-m} option.
If the option is not specified, the default is 20.
@sp 1
The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose} specify the format to use for printing.
@sp 1
@item print [-fpv] [-m @var{max}] io *
@itemx print [-fpv] [-m @var{max}] action *
Prints a representation of the first @var{max} I/O actions
executed and recorded by the program.
@sp 1
The value of @var{max} is given by the @samp{-m} option.
If the option is not specified, the default is 500.
@sp 1
The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose} specify the format to use for printing.
@c @sp 1
@c @item print [-fpv] proc_body
@c Prints a representation of the body of the current procedure,
@c if it is available.
@c @sp 1
@c The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
@c and @samp{-v} or @samp{--verbose} specify the format to use for printing.
@sp 1
@item browse [-fpvw] @var{name}[@var{termpath}]
@itemx browse [-fpvw] @var{num}[@var{termpath}]
@kindex browse (mdb command)
Invokes an interactive term browser to browse
the value of the variable in the current environment
with the given ordinal number or with the given name.
If the name or number is followed by a term path such as "^2",
then only the specified subterm of the given variable is given to the browser.
@sp 1
The interactive term browser allows you
to selectively examine particular subterms.
The depth and size of printed terms may be controlled.
The displayed terms may also be clipped to fit within a single screen.
@sp 1
The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose} specify the format to use for browsing.
The @samp{-w} or @samp{--web} option tells mdb to dump the value of the
variable to an HTML file and then invoke a web browser on that file.
@sp 1
For further documentation on the interactive term browser,
invoke the @samp{browse} command from within @samp{mdb} and then
type @samp{help} at the @samp{browser>} prompt.
@sp 1
@item browse [-fpvw]
@itemx browse [-fpvw] goal
Invokes the interactive term browser to browse
the goal of the current call in its present state of instantiation.
@sp 1
The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose} specify the format to use for browsing.
The @samp{-w} or @samp{--web} option tells mdb
to dump the goal to an HTML file and then invoke a web browser on that file.
@sp 1
@item browse [-fpvw] exception
Invokes the interactive term browser to browse
the value of the exception at an EXCP port.
Reports an error if the current event does not refer to such a port.
@sp 1
The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose} specify the format to use for browsing.
The @samp{-w} or @samp{--web} option tells mdb
to dump the exception to an HTML file
and then invoke a web browser on that file.
@sp 1
@item browse [-fpvw] io @var{num}
@itemx browse [-fpvw] action @var{num}
Invokes an interactive term browser to browse a representation
of the @var{num}'th I/O action executed by the program,
if there was such an action and if it was recorded.
@sp 1
The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose} specify the format to use for browsing.
The @samp{-w} or @samp{--web} option tells mdb
to dump the I/O action representation to an HTML file,
and then invoke a web browser on that file.
@c @sp 1
@c @item browse [-fpv] proc_body
@c Invokes an interactive term browser to browse a representation
@c of the body of the current procedure, if it is available.
@c @sp 1
@c The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
@c and @samp{-v} or @samp{--verbose} specify the format to use for browsing.
@sp 1
@item stack [-a] [-d] [-c@var{cliquelines}] [-f@var{numframes}] [@var{numlines}]
@kindex stack (mdb command)
Prints the names of the ancestors of the call
specified by the current event.
If two or more consecutive ancestor calls are for the same procedure,
the procedure identification will be printed once
with the appropriate multiplicity annotation.
@sp 1
The option @samp{-d} or @samp{--detailed}
specifies that for each ancestor call,
the call's event number, sequence number and depth should also be printed
if the call is to a procedure that is being execution traced.
@sp 1
If the @samp{-f} option, if present, specifies that
only the topmost @var{numframes} stack frames should be printed.
@sp 1
The optional number @var{numlines}, if present,
specifies that only the topmost @var{numlines} lines should be printed.
The default value is 100;
the special value 0 asks for all the lines to be printed.
@sp 1
By default, this command will look for cliques of mutually recursive ancestors.
It will draw boxes next to them to identify them as such in the output,
and it will print at most 10 lines from any clique.
The @samp{-c} option can be used to specify
the maximum number of lines to print for a clique,
with the special value 0 asking for all of them to be printed.
The option @samp{-a} asks for all lines to be printed
@emph{without} cliques being detected or marked.
@sp 1
This command will report an error if there is no stack trace
information available about any ancestor.
@sp 1
@item up [-d] [@var{num}]
@kindex up (mdb command)
Sets the current environment to the stack frame
of the @var{num}'th level ancestor of the current environment
(the immediate caller is the first-level ancestor).
@sp 1
If @var{num} is not specified, the default value is one.
@sp 1
This command will report an error
if the current environment doesn't have the required number of ancestors,
or if there is no execution trace information about the requested ancestor,
or if there is no stack trace information about any of the ancestors
between the current environment and the requested ancestor.
@sp 1
The option @samp{-d} or @samp{--detailed}
specifies that for each ancestor call,
the call's event number, sequence number and depth should also be printed
if the call is to a procedure that is being execution traced.
@sp 1
@item down [-d] [@var{num}]
@kindex down (mdb command)
Sets the current environment to the stack frame
of the @var{num}'th level descendant of the current environment
(the procedure called by the current environment
is the first-level descendant).
@sp 1
If @var{num} is not specified, the default value is one.
@sp 1
This command will report an error
if there is no execution trace information about the requested descendant.
@sp 1
The option @samp{-d} or @samp{--detailed}
specifies that for each ancestor call,
the call's event number, sequence number and depth should also be printed
if the call is to a procedure that is being execution traced.
@sp 1
@item level [-d]
@item level [-d] @var{num}
@item level [-d] (@samp{clentry}|@samp{clique})
@item level [-d] @samp{clparent}
@kindex level (mdb command)
If the command is given no arguments,
it sets the current environment
to the stack frame that belongs to the current event.
If invoked with the number @var{num} as argument,
it sets the current environment
to the stack frame of the @var{num}'th level ancestor
of the call to which the current event belongs.
If invoked with the argument @samp{clentry} or @samp{clique},
it sets the current environment to the stack frame of the call
that first entered into the clique of recursive calls
of which the current call is a part.
(If the current call is not (mutually) recursive
with any other currently active call,
it sets the current environment to the stack frame of the current event.)
If the command is given the argument @samp{clparent},
it sets the current environment to the stack frame of the first call
outside the current call's clique.
This will be the parent of the stack frame
that @samp{level clentry} would set the current environment to.
@sp 1
This command will report an error
if the current environment doesn't have the required number of ancestors,
or if there is no execution trace information about the requested ancestor,
or if there is no stack trace information about any of the ancestors
between the current environment and the requested ancestor.
@sp 1
The option @samp{-d} or @samp{--detailed}
specifies that for each ancestor call,
the call's event number, sequence number and depth should also be printed
if the call is to a procedure that is being execution traced.
@sp 1
@item current
@kindex current (mdb command)
Prints the current event.
This is useful if the details of the event,
which were printed when control arrived at the event,
have since scrolled off the screen.
@sp 1
@item view [-vf2] [-w @var{window-cmd}] [-s @var{server-cmd}] [-n @var{server-name}] [-t @var{timeout}]
@itemx view -c [-v] [-s @var{server-cmd}] [-n @var{server-name}]
@kindex view (mdb command)
Opens a new window displaying the source code,
at the location of the current event.
As mdb stops at new events,
the window is updated to track through the source code.
This requires X11 and a version of @samp{vim}
compiled with the client/server option enabled.
@sp 1
The debugger only updates one window at a time.
If you try to open a new source window when there is already one open,
this command aborts with an error message.
@sp 1
The variant with @samp{-c} (or @samp{--close})
does not open a new window but instead
attempts to close a currently open source window.
The attempt may fail if, for example,
the user has modified the source file without saving.
@sp 1
The option @samp{-v} (or @samp{--verbose})
prints the underlying system calls before running them,
and prints any output the calls produced.
This is useful to find out what is wrong if the server does not start.
@sp 1
The option @samp{-f} (or @samp{--force})
stops the command from aborting if there is already a window open.
Instead it attempts to close that window first.
@sp 1
The option @samp{-2} (or @samp{--split-screen})
starts the vim server with two windows,
which allows both the callee as well as the caller
to be displayed at interface events.
The lower window shows what would normally be seen
if the split-screen option was not used,
which at interface events is the caller.
At these events,
the upper window shows the callee definition.
At internal events,
the lower window shows the associated source,
and the view in the upper window
(which is not interesting at these events)
remains unchanged.
@sp 1
The option @samp{-w} (or @samp{--window-command}) specifies
the command to open a new window.
The default is @samp{xterm -e}.
@sp 1
The option @samp{-s} (or @samp{--server-command}) specifies
the command to start the server.
The default is @samp{vim}.
@sp 1
The option @samp{-n} (or @samp{--server-name}) specifies
the name of an existing server.
Instead of starting up a new server,
mdb will attempt to connect to the existing one.
@sp 1
The option @samp{-t} (or @samp{--timeout}) specifies
the maximum number of seconds to wait for the server to start.
@sp 1
@item hold @var{name}[@var{termpath}] [@var{heldname}]
@kindex hold (mdb command)
Holds on to the variable @var{name} of the current event,
or the part of the specified by @var{termpath},
even after execution leaves the current event.
The held value will stay accessible via the name @var{$heldname}.
If @var{heldname} is not specified, it defaults to @var{name}.
There must not already be a held variable named @var{heldname}.
@sp 1
@item diff [-s @var{start}] [-m @var{max}] @var{name1}[@var{termpath1}] @var{name2}[@var{termpath2}]
@kindex diff (mdb command)
Prints a list of some of the term paths
at which the (specified parts of) the specified terms differ.
Normally this command prints the term paths of the first 20 differences.
@sp 1
The option @samp{-s} (or @samp{--start}), if present,
specifies how many of the initial differences to skip.
@sp 1
The option @samp{-m} (or @samp{--max}), if present,
specifies how many differences to print.
@sp 1
@item dump [-pqx] goal @var{filename}
@kindex dump (mdb command)
Writes the goal of the current call in its present state of instantiation
to the specified file,
and outputs a message announcing this fact
unless the option @samp{-q} (or @samp{--quiet}) was given.
The option @samp{-p} (or @samp{--prettyprint}) causes the goal to be output
in a pretty-printed form.
The option @samp{-x} (or @samp{--xml}) causes the goal to be output
in XML format.
@sp 1
@item dump [-pqx] exception @var{filename}
Writes the value of the exception at an EXCP port to the specified file,
and outputs a message announcing this fact
unless the option @samp{-q} (or @samp{--quiet}) was given.
Reports an error if the current event does not refer to such a port.
The option @samp{-p} (or @samp{--prettyprint}) causes the exception value
to be output in a pretty-printed form.
The option @samp{-x} (or @samp{--xml}) causes the output to be in XML.
@sp 1
@item dump [-pqx] @var{name}[@var{termpath}] @var{filename}
@itemx dump [-pqx] @var{num}[@var{termpath}] @var{filename}
Writes the value of the variable in the current environment
with the given ordinal number or with the given name to the specified file,
and outputs a message announcing this fact
unless the option @samp{-q} (or @samp{--quiet}) was given.
The option @samp{-p} (or @samp{--prettyprint}) causes the variable's value
to be output in a pretty-printed form.
The option @samp{-x} (or @samp{--xml}) causes the output to be in XML.
If the name or number is followed by a term path such as "^2",
then only the specified subterm of the given variable is dumped.
@sp 1
@item open @var{term}
Save @var{term} to a temporary file and open the file in an editor.
The name of the editor to be used is taken from
the environment variable @env{EDITOR} if this is set;
if it is not set, then the editor will be @samp{vi}.
@var{term} may be any term
that can be saved to a file with the @samp{save_to_file} command.
@sp 1
@item grep @var{pattern} @var{term}
Saves the given term to a temporary file
and invokes grep on the file using @var{pattern}.
@var{term} may be any term that can be saved to a file
with the @samp{save_to_file} command.
The Unix @samp{grep} command must be available from the shell
for this command to work.
@c @sp 1
@c @item dump [-qx] proc_body @var{filename}
@c Writes the representation of the body of the current procedure,
@c if it is available, to the specified file,
@c and outputs a message announcing this fact
@c unless the option @samp{-q} (or @samp{--quiet}) was given.
@c The option @samp{-x} (or @samp{--xml}) causes the output to be in XML.
@sp 1
@item list [@var{num}]
@kindex list (mdb command)
Lists the source code text for the current environment, including
@var{num} preceding and following lines. If @var{num} is not provided then
the default of two is used.
@end table
@sp 1
@node Breakpoint commands
@subsection Breakpoint commands
@cindex Breakpoints
@sp 1
@table @code
@item break [-PS] [-E@var{ignore-count}] [-I@var{ignore-count}] [-n] [-p@var{print-spec}]* @var{filename}:@var{linenumber}
@kindex break (mdb command)
Puts a break point on the specified line of the specified source file,
if there is an event or a call at that position.
If the filename is omitted,
it defaults to the filename from the context of the current event.
@sp 1
The options @samp{-P} or @samp{--print}, and @samp{-S} or @samp{--stop}
specify the action to be taken at the break point.
@sp 1
The options @samp{-E@var{ignore-count}}
and @samp{--ignore-entry @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of a call event
that matches the breakpoint.
The options @samp{-I@var{ignore-count}}
and @samp{--ignore-interface @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of interface events
that match the breakpoint.
@sp 1
Each occurrence of the options
@samp{-p@var{printspec}} and @samp{--print-list @var{printspec}}
tells the debugger to include the specified entity
in the breakpoint's print list.
@sp 1
Normally, if a variable with the given name or number doesn't exist
when execution reaches the breakpoint, mdb will issue a warning.
The option @samp{-n} or @samp{--no-warn}, if present, suppresses this warning.
This can be useful if e.g. the name is the name of an output variable,
which of course won't be present at call events.
@sp 1
By default, the action of the break point is @samp{stop},
the ignore count is zero, and the print list is empty.
@item break [-AOPSaei] [-E@var{ignore-count}] [-I@var{ignore-count}] [-n] [-p@var{print-spec}]* @var{proc-spec}
@c <module name> <predicate name> [<arity> [<mode> [<predfunc>]]]
Puts a break point on the specified procedure.
@sp 1
The options @samp{-A} or @samp{--select-all},
and @samp{-O} or @samp{--select-one}
select the action to be taken
if the specification matches more than one procedure.
If you have specified option @samp{-A} or @samp{--select-all},
mdb will put a breakpoint on all matched procedures,
whereas if you have specified option @samp{-O} or @samp{--select-one},
mdb will report an error.
By default, mdb will ask you whether you want to put a breakpoint
on all matched procedures or just one, and if so, which one.
@sp 1
The options @samp{-P} or @samp{--print}, and @samp{-S} or @samp{--stop}
specify the action to be taken at the break point.
@sp 1
The options @samp{-a} or @samp{--all},
@samp{-e} or @samp{--entry}, and @samp{-i} or @samp{--interface}
specify the invocation conditions of the break point.
If none of these options are specified,
the default is the one indicated by the current scope
(see the @samp{scope} command below).
The initial scope is @samp{interface}.
@sp 1
The options @samp{-E@var{ignore-count}}
and @samp{--ignore-entry @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of a call event
that matches the breakpoint.
The options @samp{-I@var{ignore-count}}
and @samp{--ignore-interface @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of interface events
that match the breakpoint.
@sp 1
Each occurrence of the options
@samp{-p@var{printspec}} and @samp{--print-list @var{printspec}}
tells the debugger to include the specified entity
in the breakpoint's print list.
@sp 1
Normally, if a variable with the given name or number doesn't exist
when execution reaches the breakpoint, mdb will issue a warning.
The option @samp{-n} or @samp{--no-warn}, if present, suppresses this warning.
This can be useful if e.g. the name is the name of an output variable,
which of course won't be present at call events.
@sp 1
By default, the action of the break point is @samp{stop},
its invocation condition is @samp{interface},
the ignore count is zero, and the print list is empty.
@sp 1
@item break [-OPS] [-E@var{ignore-count}] [-I@var{ignore-count}] [-n] [-p@var{print-spec}]* @var{proc-spec} @var{portname}
Puts a break point on
one or more events of the specified type in the specified procedure.
Port names should be specified as they are printed at events,
e.g. @samp{CALL}, @samp{EXIT}, @samp{DISJ}, @samp{SWTC}, etc.
@sp 1
The option @samp{-O} or @samp{--select-one}
selects the action to be taken
if the specification matches more than one procedure.
If you have specified option @samp{-O} or @samp{--select-one},
mdb will report an error;
otherwise, mdb will ask you which of the matched procedures you want to select.
@sp 1
If there is only one event of the given type in the specified procedure,
mdb will put the breakpoint on it;
otherwise, it will ask you whether you want to put a breakpoint
on all matched events or just one, and if so, which one.
@sp 1
The options @samp{-P} or @samp{--print}, and @samp{-S} or @samp{--stop}
specify the action to be taken at the break point.
@sp 1
The options @samp{-E@var{ignore-count}}
and @samp{--ignore-entry @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of a call event
that matches the breakpoint.
The options @samp{-I@var{ignore-count}}
and @samp{--ignore-interface @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of interface events
that match the breakpoint.
@sp 1
Each occurrence of the options
@samp{-p@var{printspec}} and @samp{--print-list @var{printspec}}
tells the debugger to include the specified entity
in the breakpoint's print list.
@sp 1
Normally, if a variable with the given name or number doesn't exist
when execution reaches the breakpoint, mdb will issue a warning.
The option @samp{-n} or @samp{--no-warn}, if present, suppresses this warning.
This can be useful if e.g. the name is the name of an output variable,
which of course won't be present at call events.
@sp 1
By default, the action of the break point is @samp{stop},
the ignore count is zero, and the print list is empty.
@sp 1
@item break [-PS] [-E@var{ignore-count}] [-I@var{ignore-count}] [-n] [-p@var{print-spec}]* here
Puts a break point on the procedure referred to by the current event,
with the invocation condition being the event at the current location
in the procedure body.
@sp 1
The options @samp{-P} or @samp{--print}, and @samp{-S} or @samp{--stop}
specify the action to be taken at the break point.
@sp 1
The options @samp{-E@var{ignore-count}}
and @samp{--ignore-entry @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of a call event
that matches the breakpoint.
The options @samp{-I@var{ignore-count}}
and @samp{--ignore-interface @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of interface events
that match the breakpoint.
@sp 1
Each occurrence of the options
@samp{-p@var{printspec}} and @samp{--print-list @var{printspec}}
tells the debugger to include the specified entity
in the breakpoint's print list.
@sp 1
Normally, if a variable with the given name or number doesn't exist
when execution reaches the breakpoint, mdb will issue a warning.
The option @samp{-n} or @samp{--no-warn}, if present, suppresses this warning.
This can be useful if e.g. the name is the name of an output variable,
which of course won't be present at call events.
@sp 1
By default, the action of the break point is @samp{stop},
the ignore count is zero, and the print list is empty.
@sp 1
@item break [-PS] [-X@var{ignore-count}] [-n] [-p@var{print-spec}]* user_event [@var{user-event-set}] @var{user-event-name}
Puts a break point on all user events named @var{user-event-name},
or, if @var{user-event-set} is specified as well,
on the user event named @var{user-event-name} in that event set.
@sp 1
The options @samp{-P} or @samp{--print}, and @samp{-S} or @samp{--stop}
specify the action to be taken at the break point.
@sp 1
The options @samp{-X@var{ignore-count}}
and @samp{--ignore @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of an event
that matches the breakpoint.
@sp 1
Each occurrence of the options
@samp{-p@var{printspec}} and @samp{--print-list @var{printspec}}
tells the debugger to include the specified entity
in the breakpoint's print list.
@sp 1
Normally, if a variable with the given name or number doesn't exist
when execution reaches the breakpoint, mdb will issue a warning.
The option @samp{-n} or @samp{--no-warn}, if present, suppresses this warning.
This can be useful if e.g. the name is the name of an output variable,
which of course won't be present at call events.
@sp 1
By default, the action of the break point is @samp{stop},
the ignore count is zero, and the print list is empty.
@sp 1
@item break [-PS] [-X@var{ignore-count}] [-n] [-p@var{print-spec}]* user_event_set [@var{user-event-set}]
Puts a break point either on all user events in all event sets,
or, if @var{user-event-set} is specified,
on all user events in the event set of the given name.
@sp 1
The options @samp{-P} or @samp{--print}, and @samp{-S} or @samp{--stop}
specify the action to be taken at the break point.
@sp 1
The options @samp{-X@var{ignore-count}}
and @samp{--ignore @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of an event
that matches the breakpoint.
@sp 1
Each occurrence of the options
@samp{-p@var{printspec}} and @samp{--print-list @var{printspec}}
tells the debugger to include the specified entity
in the breakpoint's print list.
@sp 1
Normally, if a variable with the given name or number doesn't exist
when execution reaches the breakpoint, mdb will issue a warning.
The option @samp{-n} or @samp{--no-warn}, if present, suppresses this warning.
This can be useful if e.g. the name is the name of an output variable,
which of course won't be present at call events.
@sp 1
By default, the action of the break point is @samp{stop},
the ignore count is zero, and the print list is empty.
@sp 1
@item break info
Lists the details, status and print lists of all break points.
@sp 1
@item condition [-b@var{break-num}] [-p] [-v] @var{varname}[@var{pathspec}] @var{op} @var{term}
@kindex condition (mdb command)
Attaches a condition to the most recent breakpoint,
or, if the @samp{-b} or @samp{--break-num} is given,
to the breakpoint whose number is given as the argument.
Execution won't stop at the breakpoint if the condition is false.
@sp 1
The condition is a match between a variable live at the breakpoint,
or a part thereof, and @var{term}.
It is ok for @var{term} to contain spaces.
The term from the program to be matched
is specified by @var{varname};
if it is followed by @var{pathspec} (without a space),
it specifies that the match is to be
against the specified part of @var{varname}.
@sp 1
There are two kinds of values allowed for @var{op}.
If @var{op} is @samp{=} or @samp{==}, the condition is true
if the term specified by @var{varname} (and @var{pathspec}, if present)
matches @var{term}.
If @var{op} is @samp{!=} or @samp{\=}, the condition is true
if the term specified by @var{varname} (and @var{pathspec}, if present)
doesn't match @var{term}.
@var{term} may contain integers and strings
(as long as the strings don't contain double quotes),
but floats and characters are not supported (yet),
and neither is any special syntax for operators.
Operators can be specified in prefix form
by quoting them with escaped single quotes,
as in @samp{\'+\'(1, 2)}.
Lists can be specified using the usual syntax.
@var{term} also may not contain variables, with one exception:
any occurrence of @samp{_} in @var{term} matches any term.
@sp 1
If execution reaches a breakpoint and the condition cannot be evaluated,
execution will normally stop at that breakpoint with a message to that effect.
If the @samp{-p} or @samp{--dont-require-path} option is given,
execution won't stop at breakpoints at which
the specified part of the specified variable doesn't exist.
If the @samp{-v} or @samp{--dont-require-var} option is given,
execution won't stop at breakpoints at which
the specified variable itself doesn't exist.
The @samp{-v} or @samp{--dont-require-var} option is implicitly assumed
if the specified breakpoint is on all user events.
@sp 1
@item ignore [-E@var{ignore-count}] [-I@var{ignore-count}] @var{num}
@kindex ignore (mdb command)
The options @samp{-E@var{ignore-count}}
and @samp{--ignore-entry @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of a call event
that matches the breakpoint with the specified number.
The options @samp{-I@var{ignore-count}}
and @samp{--ignore-interface @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of interface events
that match the breakpoint with the specified number.
If neither option is given,
the default is to ignore one call event
that matches the breakpoint with the specified number.
Reports an error if there is no break point with the specified number.
@sp 1
@item ignore [-E@var{ignore-count}] [-I@var{ignore-count}]
The options @samp{-E@var{ignore-count}}
and @samp{--ignore-entry @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of a call event
that matches the most recently added breakpoint.
The options @samp{-I@var{ignore-count}}
and @samp{--ignore-interface @var{ignore-count}}
tell the debugger to ignore the breakpoint
until after @var{ignore-count} occurrences of interface events
that match the most recently added breakpoint.
If neither option is given,
the default is to ignore one call event
that matches the most recently added breakpoint.
Reports an error if the most recently added breakpoint has since been deleted.
@sp 1
@item break_print [-fpv] [-e] [-n] [-b @var{num}] @var{print-spec}*
@kindex break_print (mdb command)
Adds the specified print list elements (there may be more than one)
to the print list of the breakpoint numbered @var{num}
(if the @samp{-b} or @samp{--break-num} option is given),
or to the print list of the most recent breakpoint (if it is not given).
@sp 1
Normally, if a variable with the given name or number doesn't exist
when execution reaches the breakpoint, mdb will issue a warning.
The option @samp{-n} or @samp{--no-warn}, if present, suppresses this warning.
This can be useful if e.g. the name is the name of an output variable,
which of course won't be present at call events.
@sp 1
Normally, the specified elements will be added
at the start of the breakpoint's print list.
The option @samp{-e} or @samp{--end}, if present,
causes them to be added at the end.
@sp 1
By default, the specified elements will be printed with format "flat".
The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose}, if given,
explicitly specify the format to use.
@sp 1
@item break_print [-b @var{num}] none
@kindex break_print (mdb command)
Clears the print list of the breakpoint numbered @var{num}
(if the @samp{-b} or @samp{--break-num} option is given),
or the print list of the most recent breakpoint (if it is not given).
@sp 1
@item disable @var{num}
@kindex disable (mdb command)
Disables the break point with the given number.
Reports an error if there is no break point with that number.
@sp 1
@item disable *
Disables all break points.
@sp 1
@item disable
Disables the most recently added breakpoint.
Reports an error if the most recently added breakpoint has since been deleted.
@sp 1
@item enable @var{num}
Enables the break point with the given number.
Reports an error if there is no break point with that number.
@sp 1
@item enable *
@kindex enable (mdb command)
Enables all break points.
@sp 1
@item enable
Enables the most recently added breakpoint.
Reports an error if the most recently added breakpoint has since been deleted.
@sp 1
@item delete @var{num}
@kindex delete (mdb command)
Deletes the break point with the given number.
Reports an error if there is no break point with that number.
@sp 1
@item delete *
Deletes all break points.
@sp 1
@item delete
Deletes the most recently added breakpoint.
Reports an error if the most recently added breakpoint
has already been deleted.
@sp 1
@item modules
@kindex modules (mdb command)
Lists all the debuggable modules
(i.e.@: modules that have debugging information).
@sp 1
@item procedures @var{module}
@kindex procedures (mdb command)
Lists all the procedures in the debuggable module @var{module}.
@sp 1
@item register [-q]
@kindex register (mdb command)
Registers all debuggable modules with the debugger.
Has no effect if this registration has already been done.
The debugger will perform this registration when creating breakpoints
and when listing debuggable modules and/or procedures.
The command will print a message to this effect
unless the @samp{-q} or @samp{--quiet} option is given.
@end table
@sp 1
@node I/O tabling commands
@subsection I/O tabling commands
@sp 1
@table @code
@item table_io
@kindex table_io (mdb command)
Reports which phase of I/O tabling we are in at the moment.
@sp 1
@item table_io start
Tells the debugger to start tabling I/O actions.
@sp 1
@item table_io stop
Tells the debugger to stop tabling I/O actions.
@sp 1
@item table_io stats
Reports statistics about I/O tabling.
@c "table_io allow" is not documented because its use by a non-expert
@c can yield weird results.
@c @sp 1
@c @item table_io allow
@c Allow I/O tabling to be started, even in grades in which
@c not all I/O primitives are guaranteed to be tabled.
@end table
@sp 1
@node Parameter commands
@subsection Parameter commands
@sp 1
@table @code
@item mmc_options @var{option1} @var{option2} @dots{}
@kindex mmc_options (mdb command)
This command sets the options that will be passed to @samp{mmc}
to compile your query when you use one of the query commands:
@samp{query}, @samp{cc_query}, or @samp{io_query}.
For example, if a query results in a compile error,
it may sometimes be helpful to use @samp{mmc_options --verbose-error-messages}.
@sp 1
@item printlevel none
@kindex printlevel (mdb command)
Sets the default print level to @samp{none}.
@sp 1
@item printlevel some
Sets the default print level to @samp{some}.
@sp 1
@item printlevel all
Sets the default print level to @samp{all}.
@sp 1
@item printlevel
Reports the current default print level.
@sp 1
@item scroll on
@kindex scroll (mdb command)
Turns on user control over the scrolling of sequences of event reports.
This means that every screenful of event reports
will be followed by a @samp{--more--} prompt.
You may type an empty line, which allows the debugger
to continue to print the next screenful of event reports.
By typing a line that starts with @samp{a}, @samp{s} or @samp{n},
you can override the print level of the current command,
setting it to @samp{all}, @samp{some} or @samp{none} respectively.
By typing a line that starts with @samp{q},
you can abort the current debugger command
and get back control at the next event.
@sp 1
@item scroll off
Turns off user control over the scrolling of sequences of event reports.
@sp 1
@item scroll @var{size}
Sets the scroll window size to @var{size},
which tells scroll control to stop and print a @samp{--more--} prompt
after every @var{size} @minus{} 1 events.
The default value of @var{size}
is the value of the @env{LINES} environment variable,
which should correspond to the number of lines available on the terminal.
@sp 1
@item scroll
Reports whether user scroll control is enabled and what the window size is.
@sp 1
@item stack_default_limit @var{size}
@kindex stack_default_limit (mdb command)
Set the default number of lines printed by
the @samp{stack} and @samp{nondet_stack} commands to @var{size}.
If @var{size} is zero, the limit is disabled.
@sp 1
@item goal_paths on
@kindex goal_path (mdb command)
Turns on printing of goal paths at events.
@sp 1
@item goal_paths off
Turns off printing of goal paths at events.
@sp 1
@item goal_paths
Reports whether goal paths are printed at events.
@sp 1
@item scope all
@kindex scope (mdb command)
Sets the default scope of new breakpoints to ``all'',
i.e.@: by default, new breakpoints on procedures
will stop at all events in the procedure.
@sp 1
@item scope interface
Sets the default scope of new breakpoints to ``interface'',
i.e.@: by default, new breakpoints on procedures
will stop at all interface events in the procedure.
@sp 1
@item scope entry
Sets the default scope of new breakpoints to ``entry'',
i.e.@: by default, new breakpoints on procedures
will stop only at events representing calls to the procedure.
@sp 1
@item scope
Reports the current default scope of new breakpoints.
@sp 1
@item echo on
@kindex echo (mdb command)
Turns on the echoing of commands.
@sp 1
@item echo off
Turns off the echoing of commands.
@sp 1
@item echo
Reports whether commands are being echoed or not.
@sp 1
@item context none
@kindex context (mdb command)
@cindex line numbers
@cindex file names
When reporting events or ancestor levels,
does not print contexts (filename/line number pairs).
@sp 1
@item context before
When reporting events or ancestor levels,
prints contexts (filename/line number pairs)
before the identification of the event or call to which they refer,
on the same line.
With long fully qualified predicate and function names,
this may make the line wrap around.
@sp 1
@item context after
When reporting events or ancestor levels,
prints contexts (filename/line number pairs)
after the identification of the event or call to which they refer,
on the same line.
With long fully qualified predicate and function names,
this may make the line wrap around.
@sp 1
@item context prevline
When reporting events or ancestor levels,
prints contexts (filename/line number pairs) on a separate line
before the identification of the event or call to which they refer.
@sp 1
@item context nextline
When reporting events or ancestor levels,
prints contexts (filename/line number pairs) on a separate line
after the identification of the event or call to which they refer.
@sp 1
@item context
Reports where contexts are being printed.
@sp 1
@item user_event_context none
@kindex user_event_context (mdb command)
When reporting user-defined events,
does not print either filename/line number pairs or procedure ids.
@sp 1
@item user_event_context file
When reporting user-defined events,
prints only filename/line number pairs, not procedure ids.
@sp 1
@item user_event_context proc
When reporting user-defined events,
prints only procedure ids, not filename/line number pairs.
@sp 1
@item user_event_context full
When reporting user-defined events,
prints both filename/line number pairs and procedure ids.
@sp 1
@item user_event_context
Reports what parts of the context are being printed at user events.
@sp 1
@item list_context_lines @var{num}
@kindex list_context_lines (mdb command)
Sets the number of lines to be printed by the @samp{list} command
printed before and after the target context.
@sp 1
@item list_context_lines
Prints the number of lines to be printed by the @samp{list} command
printed before and after the target context.
@sp 1
@item list_path @var{dir1} @var{dir2} @dots{}
@kindex list_path (mdb command)
The @samp{list} command searches a list of directories
when looking for a source code file.
The @samp{list_path} command sets the search path
to the given list of directories.
@sp 1
@item list_path
When invoked without arguments, the @samp{list_path} command
prints the search path consulted by the @samp{list} command.
@sp 1
@item push_list_dir @var{dir1} @var{dir2} @dots{}
@kindex push_list_dir (mdb command)
Pushes the given directories
on to the search path consulted by the @samp{list} command.
@sp 1
@item pop_list_dir
@kindex pop_list_dir (mdb command)
Pops the leftmost (most recently pushed) directory
from the search path consulted by the @samp{list} command.
@sp 1
@item list_cmd @var{ExternalCommand}
@kindex list_cmd (mdb command)
Tells mdb that all future @samp{list} commands should be handled by
@var{ExternalCommand}.
The command will be called with four arguments:
the source file name,
the first line number (counting from 1),
the last line number,
the current line number.
The command should print all the lines from the first to the last,
both inclusive, with the current line marked (or highlighted) in some fashion
to standard output, and report any errors to standard error.
@sp 1
If @var{ExternalCommand} is @samp{none} then the @samp{list} command
will revert to printing source listings internally.
@sp 1
@item list_cmd
When invoked without arguments, the @samp{list_cmd} command
prints the last value set by the @samp{list_cmd} command.
@sp 1
@item fail_trace_counts @var{filename}
@kindex fail_trace_counts (mdb command)
The declarative debugger can exploit information
about the failing and passing test cases to ask better questions.
This command tells the @samp{dice} command
that @var{filename} contains execution trace counts from failing test cases.
The @samp{dice} command will use this file
unless this is overridden with its @samp{--fail-trace-counts} option.
@sp 1
@item fail_trace_counts
Prints the name of the file containing
execution trace counts from failing test cases,
if this has already been set.
@sp 1
@item pass_trace_counts @var{filename}
@kindex pass_trace_counts (mdb command)
The declarative debugger can exploit information
about the failing and passing test cases to ask better questions.
This command tells the @samp{dice} command
that @var{filename} contains execution trace counts from passing test cases.
The @samp{dice} command will use this file
unless this is overridden with its @samp{--pass-trace-counts} option.
@sp 1
@item pass_trace_counts
Prints the name of the file containing
execution trace counts from passing test cases,
if this has already been set.
@sp 1
@item max_io_actions @var{num}
@kindex max_io_actions (mdb command)
Set the maximum number of I/O actions to print
in questions from the declarative debugger to @var{num}.
@sp 1
@item max_io_actions
Prints the maximum number of I/O actions to print
in questions from the declarative debugger.
@sp 1
@item web_browser_cmd @var{command}
@kindex web_browser_cmd (mdb command)
Set the shell command used to launch a web browser to @var{command}.
@sp 1
@item web_browser_cmd
Prints the shell command used to launch a web browser,
if this has been set.
@sp 1
@item format [-APB] @var{format}
@kindex format (mdb command)
Sets the default format of the browser to @var{format},
which should be one of @samp{flat}, @samp{pretty} or @samp{verbose}.
@sp 1
The browser maintains separate configuration parameters
for the three commands @samp{print *}, @samp{print @var{var}},
and @samp{browse @var{var}}.
A @samp{format} command applies to all three,
unless it specifies one or more of the options
@samp{-A} or @samp{--print-all},
@samp{-P} or @samp{--print},
and @samp{-B} or @samp{--browse},
in which case it will set only the selected command's default format.
@sp 1
@item format_param [-APBfpv] @var{param} @var{value}
@kindex format_param (mdb command)
@kindex depth (mdb command)
@kindex size (mdb command)
@kindex width (mdb command)
@kindex lines (mdb command)
Sets one of the parameters of the browser to the given value.
The parameter @var{param} must be one of
@samp{depth}, @samp{size}, @samp{width} and @samp{lines}.
@sp 1
@itemize @bullet
@item
@samp{depth} is the maximum depth to which subterms will be displayed.
Subterms at the depth limit may be abbreviated as functor/arity,
or (in lists) may be replaced by an ellipsis (@samp{...}).
The principal functor of any term has depth zero.
For subterms which are not lists,
the depth of any argument of the functor is one greater than the
depth of the functor.
For subterms which are lists,
the depth of each element of the list
is one greater than the depth of the list.
@sp 1
@item
@samp{size} is the suggested maximum number of functors to display.
Beyond this limit, subterms may be abbreviated as functor/arity,
or (in lists) may be replaced by an ellipsis (@samp{...}).
For the purposes of this parameter,
the size of a list is one greater than
the sum of the sizes of the elements in the list.
@sp 1
@item
@samp{width} is the width of the screen in characters.
@sp 1
@item
@samp{lines} is the preferred maximum number of lines of one term to display.
@sp 1
@end itemize
@sp 1
The browser maintains separate configuration parameters
for the three commands @samp{print *}, @samp{print @var{var}},
and @samp{browse @var{var}}.
A @samp{format_param} command applies to all three,
unless it specifies one or more of the options
@samp{-A} or @samp{--print-all},
@samp{-P} or @samp{--print},
and @samp{-B} or @samp{--browse},
in which case it will set only the selected command's parameters.
@sp 1
The browser also maintains separate configuration parameters
for the different output formats: flat, pretty and verbose.
A @samp{format_param} command applies to all of these,
unless it specifies one or more of the options
@samp{-f} or @samp{--flat},
@samp{-p} or @samp{--pretty},
and @samp{-v} or @samp{--verbose},
in which case it will set only the selected format's parameter.
@sp 1
@item alias @var{name} @var{command} [@var{command-parameter} @dots{}]
@kindex alias (mdb command)
Introduces @var{name} as an alias
for the given command with the given parameters.
Whenever a command line has @var{name} as its first word,
the debugger will substitute the given command and parameters for this word
before executing the command line.
@sp 1
If @var{name} is the upper-case word @samp{EMPTY},
the debugger will substitute the given command and parameters
whenever the user types in an empty command line.
@sp 1
If @var{name} is the upper-case word @samp{NUMBER},
the debugger will insert the given command and parameters
before the command line
whenever the user types in a command line that consists of a single number.
@sp 1
@item unalias @var{name}
@kindex unalias (mdb command)
Removes any existing alias for @var{name}.
@end table
@sp 1
@node Help commands
@subsection Help commands
@sp 1
@table @code
@item document_category @var{slot} @var{category}
@kindex document_category (mdb command)
Create a new category of help items, named @var{category}.
The summary text for the category is given by the lines following this command,
up to but not including a line containing only the lower-case word @samp{end}.
The list of category summaries printed in response to the command @samp{help}
is ordered on the integer @var{slot} numbers of the categories involved.
@sp 1
@item document @var{category} @var{slot} @var{item}
@kindex document (mdb command)
Create a new help item named @var{item} in the help category @var{category}.
The text for the help item is given by the lines following this command,
up to but not including a line containing only the lower-case word @samp{end}.
The list of items printed in response to the command @samp{help @var{category}}
is ordered on the integer @var{slot} numbers of the items involved.
@sp 1
@item help @var{category} @var{item}
@kindex help (mdb command)
Prints help text about the item @var{item} in category @var{category}.
@sp 1
@item help @var{word}
Prints help text about @var{word},
which may be the name of a help category or a help item.
@sp 1
@item help
Prints summary information about all the available help categories.
@end table
@sp 1
@node Declarative debugging mdb commands
@subsection Declarative debugging mdb commands
@sp 1
The following commands relate to the declarative debugger. See
@ref{Declarative debugging} for details.
@sp 1
@table @code
@item dd [-r] [-R] [-n@var{nodes}] [-s@var{search-mode}] [-p@var{passfile}] [-f@var{failfile}]
@c @item dd [--assume-all-io-is-tabled] [-d@var{depth}] [-t]
@c [--debug [filename]]
@c The --assume-all-io-is-tabled option is for developers only. Specifying it
@c makes an assertion, and if the assertion is incorrect, the resulting
@c behaviour would be hard for non-developers to understand. The option is
@c therefore deliberately not documented.
@c @sp 1
@c The value of the @samp{-d} or @samp{--depth} option determines
@c how much of the annotated trace to build initially. Subsequent runs
@c will try to add @var{nodes} events to the annotated trace, but initially
@c there is not enough information available to do this. We do not document
@c this option since it requires an understanding of the internal workings of
@c the declarative debugger.
@c @sp 1
@c The @samp{-t} or @samp{--test} option causes the declarative debugger
@c to simulate a user who answers `no' to all questions, except for
@c `Is this a bug?' questions to which the simulated user answers `yes'.
@c This is useful for benchmarking the declarative debugger.
@c @sp 1
@c The @samp{--debug} option causes events generated by the declarative
@c debugger to become visible. This allows the declarative debugger to be
@c debugged.
@c If a filename is provided, the front end of the debugger is not called
@c at all. Instead a representation of the debugging tree is dumped to
@c the file.
@c @sp 1
Starts declarative debugging using the current event as the initial symptom.
@sp 1
When searching for bugs the declarative debugger needs to keep portions of the
execution trace in memory. If it requires a new portion of the trace then it
needs to rerun the program. The @samp{-n@var{nodes}} or
@samp{--nodes @var{nodes}} option tells the declarative debugger how
much of the execution trace to gather when it reruns the program. A higher
value for @var{nodes} requires more memory, but improves the
performance of the declarative debugger for long running programs since it will
not have to rerun the program as often.
@sp 1
The @samp{-s@var{search-mode}} or @samp{--search-mode @var{search-mode}}
option tells the declarative debugger which
search mode to use. Valid search modes are @samp{top_down} (or @samp{td}),
@samp{divide_and_query} (or @samp{dq}) and @samp{suspicion_divide_and_query}
(or @samp{sdq}).
@samp{top_down} is the default when this option is not given.
@sp 1
Use the @samp{-r} or @samp{--resume} option to continue your previous
declarative debugging session. If the @samp{--resume} option is given and
there were no previous declarative debugging sessions then the option will be
ignored. A @samp{dd --resume} command can be issued at any event.
The @samp{--search-mode} option may be used with the @samp{--resume} option
to change the search mode of a previously started declarative debugging
session.
@sp 1
Use the @samp{-R} or @samp{--reset-knowledge-base} option to reset the
declarative debugger's knowledge base.
The declarative debugger will forget any previous answers that
have been supplied.
It will ask previous questions again if it needs to.
This option does not affect what predicates or modules are trusted.
@sp 1
The arguments supplied to the @samp{--pass-trace-counts} (or @samp{-p}) and
@samp{--fail-trace-counts} (or @samp{-f}) options are either trace count
files or files containing a list of trace count files.
The supplied trace counts are used to assign
a suspicion to each event based on which parts of program were executed in
the failing test case(s), but not the passing test case(s).
This is used to guide the declarative debugger when
the suspicion-divide-and-query search mode is used. If the
suspicion-divide-and-query search mode is specified then either both the
@samp{-p} and @samp{-f} options must be given, or the @samp{fail_trace_counts}
and @samp{pass_trace_counts} configuration parameters must be set (using
the @samp{set} command).
@item trust @var{module-name}|@var{proc-spec}
@kindex trust (mdb command)
Tells the declarative debugger to trust the given module, predicate or
function.
@sp 1
Individual predicates or functions can be trusted by just giving the
predicate or function name. If there is more than one predicate or function
with the given name then a list of alternatives will be shown.
@sp 1
The entire Mercury standard library is trusted by default and can be
untrusted in the usual manner using the `untrust' command. To restore trusted
status to the Mercury standard library issue the command
`trust standard library' or just `trust std lib'.
@sp 1
See also `trusted' and `untrust'.
@sp 1
@item trusted
@kindex trusted (mdb command)
Lists all the trusted modules, predicates and functions. See also `trust'
and `untrust'.
@sp 1
@item untrust @var{num}
@kindex untrust (mdb command)
Removes the object from the list of trusted objects. @var{num} should
correspond with the number shown in the list produced by issuing a `trusted'
command. See also `trust' and `trusted'.
@end table
@sp 1
@node Miscellaneous commands
@subsection Miscellaneous commands
@sp 1
@table @code
@item source [-i] @var{filename} [@var{args}]
@kindex source (mdb command)
Executes the commands in the file named @var{filename}.
Optionally a list of at most nine arguments can be given.
Occurrences of the strings "$1" to "$9" in the sourced file
will be replaced by the corresponding arguments given in the source
command before the commands in the sourced file are executed.
@sp 1
Lines that start with a hash (#) character are ignored.
Hash characters can be used to place comments in your mdb scripts.
@sp 1
The option @samp{-i} or @samp{--ignore-errors} tells @samp{mdb}
not to complain if the named file does not exist or is not readable.
@sp 1
@item save @var{filename}
@kindex save (mdb command)
Saves the persistent state of the debugger
(aliases, print level, scroll controls,
set of breakpoints, browser parameters,
set of objects trusted by the declarative debugger, etc)
to the specified file.
The state is saved in the form of mdb commands,
so that sourcing the file will recreate the saved state.
Note that this command does not save transient state,
such as the current event.
There is also a small part of the persistent state
(breakpoints established with a @samp{break here} command)
that cannot be saved.
@sp 1
@item quit [-y]
@kindex quit (mdb command)
Quits the debugger and aborts the execution of the program.
If the option @samp{-y} is not present, asks for confirmation first.
Any answer starting with @samp{y}, or end-of-file, is considered confirmation.
@sp 1
End-of-file on the debugger's input is considered a quit command.
@end table
@sp 1
@node Experimental commands
@subsection Experimental commands
@sp 1
@table @code
@item histogram_all @var{filename}
@kindex histogram_all (mdb command)
Prints (to file @var{filename})
a histogram that counts all events at various depths
since the start of the program.
This histogram is available
only in some experimental versions of the Mercury runtime system.
@sp 1
@item histogram_exp @var{filename}
@kindex histogram_exp (mdb command)
Prints (to file @var{filename})
a histogram that counts all events at various depths
since the start of the program or since the histogram was last cleared.
This histogram is available
only in some experimental versions of the Mercury runtime system.
@sp 1
@item clear_histogram
@kindex clear_histogram (mdb command)
Clears the histogram printed by @samp{histogram_exp},
i.e.@: sets the counts for all depths to zero.
@sp 1
@item dice [-p@var{filename}] [-f@var{filename}] [-n@var{num}] [-s[pPfFsS]+] [-o @var{filename}] [-m @var{module}]
@kindex dice (mdb command)
Display a program dice on the screen.
@sp 1
A dice is a comparison between
some successful test runs of the program and a failing test run.
Before using the @samp{dice} command one or more passing execution summaries
and one failing execution summary need to be generated.
This can be done by compiling the program with deep tracing enabled
(either by compiling in a .debug or .decldebug grade
or with the @samp{--trace deep} or @samp{--trace rep} compiler options)
and then running the program under @samp{mtc}.
This will generate a file with the prefix
@samp{.mercury_trace_counts} and a unique suffix,
that contains a summary of the program's execution
This summary is called a slice.
Copy the generated slice to a new file for each test case,
to end up with a failing slice, say @samp{fail},
and some passing slices, say @samp{pass1}, @samp{pass2}, @samp{pass3}, etc.
Union the passing slices with a command such as
@samp{mtc_union -p passes pass1 pass2 pass3}.
@sp 1
The @samp{dice} command can use these files to display a table of statistics
comparing the passing test runs to the failing run.
Here is an example of a dice displayed in an mdb session:
@sp 1
@example
mdb> dice -f fail -p passes -s S -n 4
Procedure Path/Port File:Line Pass (3) Fail Suspicion
pred s.mrg/3-0 <s2;c2;e;> s.m:74 0 (0) 1 1.00
pred s.mrg/3-0 <s2;c2;t;> s.m:67 10 (3) 4 0.29
pred s.mrg/3-0 CALL s.m:64 18 (3) 7 0.28
pred s.mrg/3-0 EXIT s.m:64 18 (3) 7 0.28
@end example
@sp 1
This example tells us that the @samp{else} in @samp{s.m} on line 74
was executed once in the failing test run,
but never in the passing test runs,
so this would be a good place to start looking for a bug.
@sp 1
Each row in the table contains statistics
about the execution of a separate goal in the program.
Six columns are displayed:
@sp 1
@itemize @bullet
@item @samp{Procedure}:
The procedure in which the goal appears.
@item @samp{Path/Port}:
The goal path and/or port of the goal. For atomic goals, statistics about the
CALL event and the corresponding EXIT, FAIL or EXCP event are displayed on
separate rows. For other types of goals the goal path is displayed, except for
NEGE, NEGS and NEGF events where the goal path and port are displayed.
@item @samp{File:Line}:
The file name and line number of the goal. This can be used to set a
breakpoint on the goal.
@item @samp{Pass (total passing test runs)}:
The total number of times the goal was executed in all the passing test runs.
This is followed by a number in parentheses which indicates the number of test
runs the goal was executed in. The heading of this column also has a number in
parentheses which is the total number of passing test cases. In the example
above we can see that 3 passing tests were run.
@item @samp{Fail}:
The number of times the goal was executed in the failing test run.
@item @samp{Suspicion}:
A number between 0 and 1 which gives an indication of how likely a
particular goal is to be buggy. The is calculated as
Suspicion = F / (P + F) where F is the number of times the goal
was executed in the failing test run and P is the number of times the goal
was executed in passing test runs.
@end itemize
@sp 1
The name of the file containing the failing slice can be specified with the
@samp{-f} or @samp{--fail-trace-counts} option or with a separate
@samp{set fail_trace_count @var{filename}} command.
@sp 1
The name of the file containing the union of the passing slices
can be given with the @samp{-p} or @samp{--pass-trace-counts} option.
Alternatively a separate @samp{set pass_trace_counts @var{filename}} command
can be given. See @ref{Trace counts} for more information about trace counts.
@sp 1
The table can be sorted on the Pass, Fail or Suspicion columns, or a
combination of these. This can be done with the @samp{-s} or @samp{--sort}
option. The argument of this option is a string made up of any combination of
the letters @samp{pPfFsS}. The letters in the string indicate how the table
should be sorted:
@sp 1
@itemize @bullet
@item @samp{p}: Pass ascending
@item @samp{P}: Pass descending
@item @samp{f}: Fail ascending
@item @samp{F}: Fail descending
@item @samp{s}: Suspicion ascending
@item @samp{S}: Suspicion descending
@end itemize
@sp 1
For example, the string "SF" means sort the table by suspicion, descending, and
if any two suspicions are the same, then by number of executions in the failing
test case, descending.
@sp 1
The option @samp{-n} or @samp{--top} can be used to limit the number lines
displayed. Only the top @var{num} lines, with respect to
the ordering specified by the @samp{-s} option, will be displayed.
By default the table is limited to 50 lines.
@sp 1
If the @samp{-o} or @samp{--output-to-file} option is given then the output
will be written to the specified file instead of being displayed on the
screen. Note that the file will be overwritten without warning if it
already exists.
@sp 1
The @samp{-m} or @samp{--module} option limits the output to the given module
and its submodules, if any.
@end table
@sp 1
@node Developer commands
@subsection Developer commands
@sp 1
The following commands are intended for use by the developers
of the Mercury implementation.
@sp 1
@table @code
@item var_details
@kindex var_details (mdb command)
Prints all the information the debugger has
about all the variables at the current program point.
@c @item term_size @var{name}
@c @itemx term_size @var{num}
@c @itemx term_size *
@c @kindex term_size (mdb command)
@c In term size profiling grades, prints the size of the term
@c bound to the specified variable(s).
@c In other grades, reports an error.
@c @sp 1
@item flag
@kindex flag (mdb command)
Prints the values of all the runtime low-level debugging flags.
@sp 1
@item flag @var{flagname}
Prints the value of the specified runtime low-level debugging flag.
@sp 1
@item flag @var{flagname} on
Sets the specified runtime low-level debugging flag to true.
@sp 1
@item flag @var{flagname} off
Sets the specified runtime low-level debugging flag to false.
@sp 1
@item subgoal @var{n}
@kindex subgoal (mdb command)
In minimal model grades,
prints the details of the specified subgoal.
In other grades, it reports an error.
@sp 1
@item consumer @var{n}
@kindex consumer (mdb command)
In minimal model grades,
prints the details of the specified consumer.
In other grades, it reports an error.
@sp 1
@item gen_stack
@kindex gen_stack (mdb command)
In minimal model grades,
prints the contents of the frames on the generator stack.
In other grades, it reports an error.
@sp 1
@item cut_stack
@kindex cut_stack (mdb command)
In minimal model grades,
prints the contents of the frames on the cut stack.
In other grades, it reports an error.
@sp 1
@item pneg_stack
@kindex pneg_stack (mdb command)
In minimal model grades,
prints the contents of the frames on the possible negated context stack.
In other grades, it reports an error.
@sp 1
@item mm_stacks
@kindex mm_stacks (mdb command)
In minimal model grades,
prints the contents of the frames on the generator stack,
the cut stack and the possible negated context stack.
In other grades, it reports an error.
@sp 1
@item nondet_stack [-d] [-f@var{numframes}] [@var{numlines}]
@kindex nondet_stack (mdb command)
Prints the contents of the frames on the nondet stack.
By default, it prints only the fixed slots in each nondet stack frame,
but if the @samp{-d} or @samp{--detailed} option is given,
it will also print the names and values of the live variables in them.
@sp 1
The @samp{-f} option, if present, specifies that
only the topmost @var{numframes} stack frames should be printed.
@sp 1
The optional number @var{numlines}, if present,
specifies that only the topmost @var{numlines} lines should be printed.
@sp 1
@item stack_regs
@kindex stack_regs (mdb command)
Prints the contents of the virtual machine registers
that point to the det and nondet stacks.
@sp 1
@item all_regs
@kindex all_regs (mdb command)
Prints the contents of all the virtual machine registers.
@sp 1
@item debug_vars
@kindex debug_vars (mdb command)
Prints the values of the variables used by the debugger
to record event numbers, call sequence numbers and call depths.
@sp 1
@item stats [-f @var{filename}] @var{subject}
@kindex stats (mdb command)
Prints statistics about the given subject to standard output,
unless the @samp{-f} or @samp{--filename} option is given,
in which case it prints the statistic to @var{filename}.
@sp 1
@var{subject} can be @samp{procs},
which asks for statistics about proc layout structures in the program.
@sp 1
@var{subject} can be @samp{labels},
which asks for statistics about label layout structures in the program.
@sp 1
@var{subject} can be @samp{var_names},
which asks for statistics about the space occupied by variable names
in the layout structures in the program.
@sp 1
@var{subject} can be @samp{io_tabling},
which asks for statistics about the number of times
each predicate appears in the I/O action table.
@sp 1
@item print_optionals
@kindex print_optionals (mdb command)
Reports whether optionally-printed values such as typeinfos
that are usually of interest only to implementors are being printed or not.
@sp 1
@item print_optionals on
Tells the debugger to print optionally-printed values.
@sp 1
@item print_optionals off
Tells the debugger not to print optionally-printed values.
@sp 1
@item unhide_events
@kindex unhide_events (mdb command)
Reports whether events that are normally hidden
(that are usually of interest only to implementors)
are being exposed or not.
@sp 1
@item unhide_events on
Tells the debugger to expose events that are normally hidden.
@sp 1
@item unhide_events off
Tells the debugger to hide events that are normally hidden.
@sp 1
@item table @var{proc} [@var{num1} @dots{}]
@kindex table (mdb command)
Tells the debugger to print the call table of the named procedure,
together with the saved answer (if any) for each call.
Reports an error if the named procedure isn't tabled.
@sp 1
For now, this command is supported only for procedures
whose arguments are all either integers, floats or strings.
@sp 1
If the user specifies one or more integers on the command line,
the output is restricted to the entries in the call table in which
the @var{n}th argument is equal to the @var{n}th number on the command line.
@sp 1
@item type_ctor [-fr] @var{modulename} @var{typectorname} @var{arity}
@kindex type_ctor (mdb command)
Tests whether there is a type constructor defined in the given module,
with the given name, and with the given arity.
If there isn't, it prints a message to that effect.
If there is, it echoes the identity of the type constructor.
@sp 1
If the option @samp{-r} or @samp{--print-rep} option is given,
it also prints the name of the type representation scheme
used by the type constructor
(known as its `type_ctor_rep' in the implementation).
@sp 1
If the option @samp{-f} or @samp{--print-functors} option is given,
it also prints the names and arities
of function symbols defined by type constructor.
@sp 1
@item all_type_ctors [-fr] [@var{modulename}]
@kindex all_type_ctors (mdb command)
If the user specifies a module name,
lists all the type constructors defined in the given module.
If the user doesn't specify a module name,
lists all the type constructors defined in the whole program.
@sp 1
If the option @samp{-r} or @samp{--print-rep} option is given,
it also prints the name of the type representation scheme
of each type constructor
(known as its `type_ctor_rep' in the implementation).
@sp 1
If the option @samp{-f} or @samp{--print-functors} option is given,
it also prints the names and arities
of function symbols defined by each type constructor.
@sp 1
@item class_decl [-im] @var{modulename} @var{typeclassname} @var{arity}
@kindex class_decl (mdb command)
Tests whether there is a type class defined in the given module,
with the given name, and with the given arity.
If there isn't, it prints a message to that effect.
If there is, it echoes the identity of the type class.
@sp 1
If the option @samp{-m} or @samp{--print-methods} option is given,
it also lists all the methods of the type class.
@sp 1
If the option @samp{-i} or @samp{--print-instance} option is given,
it also lists all the instances of the type class.
@sp 1
@item all_class_decls [-im] [@var{modulename}]
@kindex all_class_decls (mdb command)
If the user specifies a module name,
lists all the type classes defined in the given module.
If the user doesn't specify a module name,
lists all the type classes defined in the whole program.
@sp 1
If the option @samp{-m} or @samp{--print-methods} option is given,
it also lists all the methods of each type class.
@sp 1
If the option @samp{-i} or @samp{--print-instance} option is given,
it also lists all the instances of each type class.
@sp 1
@item all_procedures [-su] [-m @var{modulename}] @var{filename}
@kindex all_procedures (mdb command)
In the absence of the @samp{-m} or @samp{--module} option,
puts a list of all the debuggable procedures in the program
into the named file.
In the presence of the @samp{-m} or @samp{--module} option,
puts a list of all the debuggable procedures in the names module
into the named file.
@sp 1
If the @samp{-s} or @samp{--separate} option is given,
the various components of procedure names are separated by spaces.
@sp 1
If the @samp{-u} or @samp{--uci} option is given,
the list will include the procedures of
compiler generated unify, compare, index and initialization predicates.
Normally, the list includes the procedures of only user defined predicates.
@sp 1
@item ambiguity [-o @var{filename}] [-ptfbs] [@var{modulename} @dots{}]
@kindex ambiguity (mdb command)
Print ambiguous procedure, type constructor and/or function symbol names.
A procedure name is ambiguous
if a predicate or function is defined with that name
in more than one module or with more than one arity.
A type constructor name is ambiguous
if a type constructor is defined with that name
in more than one module or with more than one arity.
A function symbol name is ambiguous
if a function symbol is defined with that name
in more than one module or with more than one arity.
@sp 1
If any module names are given, then only those modules are consulted,
(any ambiguities involving predicates, functions and type constructors
in non-listed modules are ignored).
The module names have to be fully qualified,
if a module @var{child} is a submodule of module @var{parent},
the module name list must include @var{parent.child};
listing just @var{child} won't work,
since that is not a fully qualified module name.
@sp 1
If the @samp{-o} or @samp{--outputfile} option is given,
the output goes to the file named as the argument of the option;
otherwise, it goes to standard output.
@sp 1
If given one or more of the @samp{-p}, @samp{-t} and @samp{-f} options,
or their long equivalents
@samp{--procedures}, @samp{--types}, and @samp{--functors},
this command prints ambiguities only for the indicated kinds of constructs.
The default is to print ambiguities for all these three kinds of constructs.
@sp 1
This command does not normally report
two kinds of ambiguities among procedures.
@sp 1
First, this command does not usually report
operations that have both function and predicate forms,
with the predicate version having a (usually output) argument
in place of the function's return value.
An example is @code{list.length} being both a function with arity one
and a predicate with arity two.
The reason for not reporting this by default is that
this is usually an @emph{intended} ambiguity,
and this command is usually used to find @emph{unintended} ambiguities,
so that they can be eliminated by renaming.
However, users can ask for these ambiguities to be printed
by specifying either the option @samp{-b},
or its long form @samp{--both-pred-and-func}.
@sp 1
Second, this command does not usually report
ambiguities involving procedures that were created by the compiler
as a type specialized version of another procedure.
The reason for not reporting this by default is that
ambiguities among the names of type specialized procedures
cannot arise without ambiguities among
the names of the original, not-yet-type-specialized procedures,
and eliminating the ambiguities among the original names
will perforce eliminate the ambiguities among the specialized names as well.
However, users can ask for these ambiguities to be printed
by specifying either the option @samp{-s},
or its long form @samp{--typespec}.
@sp 1
@item trail_details
@kindex trail_details (mdb command)
In grades that specify trailing,
prints out low-level details of the state of the trail.
In other grades, it reports an error.
@end table
@node Declarative debugging
@section Declarative debugging
The debugger incorporates a declarative debugger
which can be accessed from its command line.
Starting from an event that exhibits a bug,
e.g.@: an event giving a wrong answer,
the declarative debugger can find a bug which explains that behaviour
using knowledge of the intended interpretation of the program only.
Note that this is a work in progress,
so there are some limitations in the implementation.
@menu
* Declarative debugging overview::
* Declarative debugging concepts::
* Oracle questions::
* Declarative debugging commands::
* Diagnoses::
* Search modes::
* Improving the search::
@end menu
@node Declarative debugging overview
@subsection Overview
The declarative debugger tries to find a bug in your program by asking
questions about the correctness of calls executed in your program.
Because pure Mercury code does not have any side effects, the declarative
debugger can make inferences such as ``if a call produces incorrect output
from correct input, then there must be a bug in the code executed by one of
the descendants of the call''.
The declarative debugger is therefore able to automate much of the
`detective work' that must be done manually when using the
procedural debugger.
@node Declarative debugging concepts
@subsection Concepts
Every CALL event corresponds to an atomic goal,
the one printed by the "print" command at that event.
This atom has the actual arguments in the input argument positions
and distinct free variables in the output argument positions
(including the return value for functions).
We refer to this as the @emph{call atom} of the event.
The same view can be taken of EXIT events,
although in this case the outputs as well as the inputs will be bound.
We refer to this as the @emph{exit atom} of the event.
The exit atom is always an instance of
the call atom for the corresponding CALL event.
Using these concepts, it is possible to interpret
the events at which control leaves a procedure
as assertions about the semantics of the program.
These assertions may be true or false, depending on whether or not
the program's actual semantics are consistent with its intended semantics.
@sp 1
@table @asis
@item EXIT
The assertion corresponding to an EXIT event is that
the exit atom is valid in the intended interpretation.
In other words, the procedure generates correct outputs
for the given inputs.
@sp 1
@item FAIL
Every FAIL event has a matching CALL event,
and a (possibly empty) set of matching EXIT events
between the call and fail.
The assertion corresponding to a FAIL event is that
every instance of the call atom which is true in the intended interpretation
is an instance of one of the exit atoms.
In other words, the procedure generates the complete set of answers
for the given inputs.
(Note that this does not imply that all exit atoms represent correct answers;
some exit atoms may in fact be wrong,
but the truth of the assertion is not affected by this.)
@sp 1
@item EXCP
Every EXCP event is associated with an exception term,
and has a matching CALL event.
The assertion corresponding to an EXCP event is that
the call atom can abnormally terminate with the given exception.
In other words, the thrown exception was expected for that call.
@end table
If one of these assertions is wrong,
then we consider the event to represent incorrect behaviour of the program.
If the user encounters an event for which the assertion is wrong,
then they can request the declarative debugger to
diagnose the incorrect behaviour by giving the @samp{dd} command
to the procedural debugger at that event.
@node Oracle questions
@subsection Oracle questions
Once the @samp{dd} command has been given,
the declarative debugger asks the user
a series of questions about the truth of various assertions
in the intended interpretation.
The first question in this series will be about
the validity of the event for which the @samp{dd} command was given.
The answer to this question will nearly always be ``no'',
since the user has just implied the assertion is false
by giving the @samp{dd} command.
Later questions will be about other events
in the execution of the program,
not all of them necessarily of the same kind as the first.
The user is expected to act as an ``oracle''
and provide answers to these questions
based on their knowledge of the intended interpretation.
The debugger provides some help here:
previous answers are remembered and used where possible,
so questions are not repeated unnecessarily.
Commands are available to provide answers,
as well as to browse the arguments more closely
or to change the order in which the questions are asked.
See the next section for details of the commands that are available.
When seeking to determine the validity of
the assertion corresponding to an EXIT event,
the declarative debugger prints the exit atom
followed by the question @samp{Valid?} for the user to answer.
The atom is printed using
the same mechanism that the debugger uses to print values,
which means some arguments may be abbreviated if they are too large.
When seeking to determine the validity of
the assertion corresponding to a FAIL event,
the declarative debugger prints the call atom, prefixed by @samp{Call},
followed by each of the exit atoms
(indented, and on multiple lines if need be),
and prints the question @samp{Complete?} (or @samp{Unsatisfiable?} if there
are no solutions) for the user to answer.
Note that the user is not required to provide any missing instance
in the case that the answer is no.
(A limitation of the current implementation is that
it is difficult to browse a specific exit atom.
This will hopefully be addressed in the near future.)
When seeking to determine the validity of
the assertion corresponding to an EXCP event,
the declarative debugger prints the call atom
followed by the exception that was thrown,
and prints the question @samp{Expected?} for the user to answer.
In addition to asserting whether a call behaved correctly or not
the user may also assert that a call should never have occurred in the first
place, because its inputs violated some precondition of the call. For example
if an unsorted list is passed to a predicate that is only designed to work with
sorted lists. Such calls should be deemed @emph{inadmissible} by the user.
This tells the declarative debugger that either the call was given the wrong
input by its caller or whatever generated the input is incorrect.
In some circumstances
the declarative debugger provides a default answer to the question.
If this is the case, the default answer will be shown in square brackets
immediately after the question,
and simply pressing @key{RET} is equivalent to giving that answer.
@node Declarative debugging commands
@subsection Commands
At the above mentioned prompts, the following commands may be given.
Most commands can be abbreviated by their first letter.
It is also legal to press @key{RET} without specifying a command.
If there is a default answer (@pxref{Oracle questions}),
pressing @key{RET} is equivalent to giving that answer.
If there is no default answer,
pressing @key{RET} is equivalent to the skip command.
@table @code
@item yes
Answer `yes' to the current question.
@sp 1
@item no
Answer `no' to the current question.
@sp 1
@item inadmissible
Answer that the call is inadmissible.
@sp 1
@item trust
Answer that the predicate or function the question is about does not contain
any bugs. However predicates or functions called by this predicate/function
may contain bugs. The debugger will not ask you further questions about the
predicate or function in the current question.
@sp 1
@item trust module
Answer that the module the current question relates to does not contain any
bugs. No more questions about any predicates or functions from this module
will be asked.
@item skip
Skip this question and ask a different one if possible.
@sp 1
@item undo
Undo the most recent answer or mode change.
@sp 1
@item mode [ top-down | divide-and-query | binary ]
Change the current search mode. The search modes may be abbreviated to
@samp{td}, @samp{dq} and @samp{b} respectively.
@sp 1
@item browse [--web] [@var{n}]
Start the interactive term browser and browse the @var{n}th argument
before answering. If the argument number
is omitted then browse the whole call as if it were a data term.
While browsing a @samp{track} command may be issued to find the point at
which the current subterm was bound (see @ref{Improving the search}).
To return to the declarative debugger question issue a @samp{quit}
command from within the interactive term browser. For more information
on the use of the interactive term browser see the @samp{browse} command
in @ref{Browsing commands} or type @samp{help} from within the
interactive query browser.
@sp 1
Giving the @samp{--web} or @samp{-w} option causes the term to be displayed
in a web browser.
@sp 1
@item browse io [--web] @var{n}
Browse the @var{n}'th I/O action.
@sp 1
@item print [@var{n}]
Print the @var{n}'th argument of the current question.
If no argument is given, then display the current question.
@sp 1
@item print io @var{n}
Print the @var{n}'th I/O action.
@sp 1
@item print io @var{n}-@var{m}
Print the @var{n}'th to @var{m}'th I/O actions (inclusive).
@sp 1
@item print io limits
Print the values for which @samp{print @var{n}} makes sense.
@sp 1
@item print io
Print some I/O actions,
starting just after the last action printed (if there was one)
or at the first available action (if there was not).
@sp 1
@item format @var{format}
Set the default format to @var{format},
which should be one of @samp{flat}, @samp{verbose} or @samp{pretty}.
@sp 1
@item depth @var{num}
Set the maximum depth to which terms are printed to @var{num}.
@sp 1
@item depth io @var{num}
Set the maximum depth to which I/O actions are printed to @var{num}.
I/O actions are printed using the browser's @samp{print *} command so the
@samp{depth io} command updates the configuration parameters for the
browser's @samp{print *} command.
@sp 1
@item size @var{num}
Set the maximum number of function symbols
to be printed in terms to @var{num}.
@sp 1
@item size io @var{num}
Set the maximum number of function symbols
to be printed in I/O actions to @var{num}.
I/O actions are printed using the browser's @samp{print *} command so the
@samp{size io} command updates the configuration parameters for the
browser's @samp{print *} command.
@sp 1
@item width @var{num}
Set the number of columns in which terms are to be printed to @var{num}.
@sp 1
@item width io @var{num}
Set the number of columns in which I/O actions are to be printed to @var{num}.
I/O actions are printed using the browser's @samp{print *} command so the
@w{@samp{width io}} command updates the configuration parameters for the
browser's @samp{print *} command.
@sp 1
@item lines @var{num}
Set the maximum number of lines in terms to be printed to @var{num}.
@sp 1
@item lines io @var{num}
Set the maximum number of lines in I/O actions to be printed to @var{num}.
I/O actions are printed using the browser's @samp{print *} command so the
@samp{lines io} command updates the configuration parameters for the
browser's @samp{print *} command.
@sp 1
@item actions @var{num}
Set the maximum number of I/O actions to be printed in questions to @var{num}.
@sp 1
@item params
Print the current values of browser parameters.
@sp 1
@item track [-a] [@var{term-path}]
The @samp{track} command can only be given from within the interactive
term browser and tells the declarative debugger to find the point at which
the current subterm was bound.
If no argument is given the current subterm is taken to be incorrect.
If a @var{term-path} is given then the subterm at @var{term-path} relative to
the current subterm will be considered incorrect.
The declarative debugger will ask about the call that bound the given subterm
next.
To find out the location of the unification that bound the subterm,
issue an @samp{info} command when asked about the call that bound the subterm.
The declarative debugger can use one of two algorithms to find the
point at which the subterm was bound.
The first algorithm uses some heuristics
to find the subterm more quickly than the second algorithm.
It is possible, though unlikely,
for the first algorithm to find the wrong call.
The first algorithm is the default.
To tell the declarative debugger to
use the second, more accurate but slower algorithm,
give the @samp{-a} or @samp{--accurate} option to the @samp{track} command.
@item mark [-a] [@var{term-path}]
The @samp{mark} command has the same effect as the @samp{track} command
except that it also asserts that the atom is inadmissible or erroneous,
depending on whether the subterm is input or output respectively.
@sp 1
@item pd
Commence procedural debugging from the current point.
This command is notionally the inverse of the @samp{dd} command
in the procedural debugger.
The session can be resumed with a @samp{dd --resume} command.
@item quit
End the declarative debugging session and return to
the event at which the @samp{dd} command was given.
The session can be resumed with a @samp{dd --resume} command.
@sp 1
@item info
List the filename and line number of the predicate the current question
is about as well as the filename and line number where the predicate
was called (if this information is available). Also print some information
about the state of the bug search, such as the current search mode,
how many events are yet to be eliminated and the reason for asking
the current question.
@sp 1
@item help [@var{command}]
Summarize the list of available commands or give help on a specific
command.
@end table
@node Diagnoses
@subsection Diagnoses
If the oracle keeps providing answers to the asked questions,
then the declarative debugger will eventually locate a bug.
A ``bug'', for our purposes,
is an assertion about some call which is false,
but for which the assertions about every child of that call are not false
(i.e. they are either correct or inadmissible).
There are four different classes of bugs that this debugger can diagnose,
one associated with each kind of assertion.
Assertions about EXIT events
lead to a kind of bug we call an ``incorrect contour''.
This is a contour (an execution path through the body of a clause)
which results in a wrong answer for that clause.
When the debugger diagnoses a bug of this kind, it displays the exit atoms in
the contour. The resulting incorrect exit atom is displayed last. The program
event associated with this bug, which we call the ``bug event'', is the exit
event at the end of the contour.
Assertions about FAIL events lead to a kind of bug we call
a ``partially uncovered atom''.
This is a call atom which has some instance which is valid,
but which is not covered by any of the applicable clauses.
When the debugger diagnoses a bug of this kind,
it displays the call atom;
it does not, however,
provide an actual instance that satisfies the above condition.
The bug event in this case is the fail event
reached after all the solutions were exhausted.
Assertions about EXCP events lead to a kind of bug we call
an ``unhandled exception''.
This is a contour which throws an exception
that needs to be handled but which is not handled.
When the debugger diagnoses a bug of this kind,
it displays the call atom
followed by the exception which was not handled.
The bug event in this case is the exception event
for the call in question.
If the assertion made by an EXIT, FAIL or EXCP event is false and one or
more of the children of the call that resulted in the incorrect EXIT, FAIL or
EXCP event is inadmissible, while all the other calls are correct, then an
``inadmissible call'' bug has been found. This is a call that behaved
incorrectly (by producing the incorrect output, failing or throwing an
exception) because it passed unexpected input to one of its children.
The guilty call is displayed as well as the inadmissible child.
After the diagnosis is displayed, the user is asked to confirm
that the event located by the declarative debugger
does in fact represent a bug.
The user can answer @samp{yes} or @samp{y} to confirm the bug,
@samp{no} or @samp{n} to reject the bug,
or @samp{abort} or @samp{a} to abort the diagnosis.
If the user confirms the diagnosis,
they are returned to the procedural debugger
at the event which was found to be the bug event.
This gives the user an opportunity, if they need it,
to investigate (procedurally) the events in the neighbourhood of the bug.
If the user rejects the diagnosis,
which implies that some of their earlier answers may have been mistakes,
diagnosis is resumed from some earlier point determined by the debugger.
The user may now be asked questions they have already answered,
with the previous answer they gave being the default,
or they may be asked entirely new questions.
If the user aborts the diagnosis,
they are returned to the event at which the @samp{dd} command was given.
@node Search modes
@subsection Search modes
The declarative debugger can operate in one of several modes when
searching for a bug.
Different search modes will result in different sequences of questions
being asked by the declarative debugger.
The user can specify which mode to use by giving the
@samp{--search-mode} option to the @samp{dd} command (see
@ref{Declarative debugging mdb commands}) or with the @samp{mode} declarative
debugger command (see @ref{Declarative debugging commands}).
@subsubsection Top-down mode
Using this mode the declarative debugger will ask about the children of the
last question the user answered @samp{no} to. The child calls will be asked
about in the order they were executed. This makes the search more predictable
from the user's point of view as the questions will more or less follow the
program execution. The drawback of top-down search is that it may require a
lot of questions to be answered before a bug is found, especially with deeply
recursive programs.
This search mode is used by default when no other mode is specified.
@subsubsection Divide and query mode
With this search mode the declarative debugger attempts to halve the size
of the search space with each question. In many cases this will result in the
bug being found after O(log(N)) questions where N is the number of events
between the event where the @samp{dd} command was given and the corresponding
@samp{CALL} event. This makes the search feasible for long running programs
where top-down search would require an unreasonably large number of questions
to be answered. However, the questions may appear to come from unrelated parts
of the program which can make them harder to answer.
@subsubsection Suspicion divide and query mode
In this search mode the declarative debugger assigns a suspicion level to
each event based on which parts of the program were executed in failing
test cases, but not in passing test cases. It then attempts to divide the
search space into two areas of equal suspicion with each question. This tends
to result in questions about parts of the program executed in a failing test
case, but not in passing test cases.
@subsubsection Binary search mode
The user may ask the declarative debugger to do a binary search along the
path in the call tree between the current question and the question that the
user last answered @samp{no} to. This is useful, for example, when a
recursive predicate is producing incorrect output, but the base case is
correct.
@node Improving the search
@subsection Improving the search
The number of questions asked by the declarative debugger before it pinpoints
the location of a bug can be reduced by giving it extra information. The kind
of extra information that can be given and how to convey this information are
explained in this section.
@subsubsection Tracking suspicious subterms
An incorrect subterm can be tracked to the call that bound the subterm
from within the interactive term browser
(see @ref{Declarative debugging commands}).
After issuing a @samp{track} command,
the next question asked by the declarative debugger will
be about the call that bound the incorrect subterm,
unless that call was
eliminated as a possible bug because of an answer to a previous
question or the call that bound the subterm was not traced.
For example consider the following fragment of a program that calculates
payments for a loan:
@example
:- type payment
---> payment(
date :: date,
amount :: float
).
:- type date ---> date(int, int, int). % date(day, month, year).
:- pred get_payment(loan::in, int::in, payment::out) is det.
get_payment(Loan, PaymentNo, Payment) :-
get_payment_amount(Loan, PaymentNo, Amount),
get_payment_date(Loan, PaymentNo, Date),
Payment = payment(Date, Amount).
@end example
Suppose that @code{get_payment} produces an incorrect result and the
declarative debugger asks:
@noindent
@example
get_payment(loan(...), 10, payment(date(9, 10, 1977), 10.000000000000)).
Valid?
@end example
Then if we know that this is the right payment amount for the given loan,
but the date is incorrect, we can track the @code{date(...)} subterm and the
debugger will then ask us about @code{get_payment_date}:
@noindent
@example
get_payment(loan(...), 10, payment(date(9, 10, 1977), 10.000000000000)).
Valid? browse
browser> cd 3/1
browser> ls
date(9, 10, 1977)
browser> track
get_payment_date(loan(...), 10, date(9, 10, 1977)).
Valid?
@end example
Thus irrelevant questions about @code{get_payment_amount} are avoided.
@noindent
If, say, the date was only wrong in the year part, then we could also have
tracked the year subterm in which case the next question would have been about
the call that constructed the year part of the date.
This feature is also useful when using the procedural debugger. For example,
suppose that you come across a @samp{CALL} event and you would like to know the
source of a particular input to the call. To find out you could first go to
the final event by issuing a @samp{finish} command. Invoke the declarative
debugger with a @samp{dd} command and then track the input term you are
interested in. The next question will be about the call that bound the term.
Issue a @samp{pd} command at this point to return to the procedural debugger.
It will now show the final event of the call that bound the term.
Note that this feature is only available if the executable is compiled
in a .decldebug grade or with the @samp{--trace rep} option. If a module
is compiled with the @samp{--trace rep} option but other modules in the
program are not then you will not be able to track subterms through those
other modules.
@subsubsection Trusting predicates, functions and modules
The declarative debugger can also be told to assume that certain predicates,
functions or entire modules do not contain any bugs. The declarative
debugger will never ask questions about trusted predicates or functions. It
is a good idea to trust standard library modules imported by a program being
debugged.
The declarative debugger can be told which predicates/functions it can trust
before the @samp{dd} command is given. This is done using the @samp{trust},
@samp{trusted} and @samp{untrust} commands at the mdb prompt (see
@ref{Declarative debugging mdb commands} for details on how to use these
commands).
Trust commands may be placed in the @samp{.mdbrc} file which contains default
settings for mdb (see @ref{Mercury debugger invocation}). Trusted
predicates will also be exported with a @samp{save} command (see
@ref{Miscellaneous commands}).
During the declarative debugging session the user may tell the declarative
debugger to trust the predicate or function in the current question.
Alternatively the user may tell the declarative debugger to trust all the
predicates and functions in the same module as the predicate or function in the
current question. See the @samp{trust} command in
@ref{Declarative debugging commands}.
@subsubsection When different search modes are used
If a search mode is given when invoking the declarative debugger then that
search mode will be used, unless (a) a subterm is tracked during the session,
or (b) the user has not answered @samp{no} to any questions yet,
in which case top-down search is used until @samp{no} is answered to at least
one question.
If no search mode is specified with the @samp{dd} command then
the search mode depends on if the @samp{--resume} option is
given.
If it is then the previous search mode will be used,
otherwise top-down search will be used.
You can check the search mode used to find a particular question by issuing
an @samp{info} command at the question prompt in the declarative debugger.
You can also change the search mode from within the declarative debugger
with the @samp{mode} command.
@node Trace counts
@section Trace counts
A program with debugging enabled may be run in a special mode
that causes it to write out to a @emph{trace count file}
a record of how many times each @emph{debugger event} in the program
was executed during that run.
Trace counts are useful for determining
what parts of a failing program are being run
and possibly causing the failure;
this is called @emph{slicing}.
Slices from failing and passing runs can be compared
to see which parts of the program are being executed during failing runs,
but not during passing runs; this is called @emph{dicing}.
@menu
* Generating trace counts::
* Combining trace counts::
* Slicing::
* Dicing::
* Coverage testing::
@end menu
@node Generating trace counts
@subsection Generating trace counts
To generate a slice for a program run,
first compile the program with deep tracing enabled
(either by using the @samp{--trace deep} option
or by compiling the program in a debugging grade).
Then invoke the program with the @samp{mtc} script,
passing any required arguments after the program name.
@sp 1
For example:
@sp 1
@example
mtc ./myprog arg1 arg2
@end example
@sp 1
The program will run as usual, except that when it terminates
it will write the number of times each debugger event was executed
to a trace count file.
@sp 1
@samp{mtc} accepts an @samp{-o} or @samp{--output-file} option.
The argument to this option is the filename to use
for the generated trace count file.
If this option is not given,
then the trace count will be written to a file
with the prefix @samp{.mercury_trace_counts} and a unique suffix.
@sp 1
Ordinarily, the generated trace count file will list
only the debugger events that were actually executed during this run.
However, it will list all debugger events, even unexecuted ones,
if @samp{mtc} is given the @samp{-c} or @samp{--coverage-test} option.
@sp 1
@samp{mtc} also supports two more options intended for coverage testing:
@samp{-s} or @samp{--summary-file}, and @samp{--summary-count}.
These each set an option in the @env{MERCURY_OPTIONS} environment variable,
@samp{--trace-count-summary-file} and @samp{--trace-count-summary-max}
respectively.
For the documentation of these @samp{mtc} options,
see the documentation of @env{MERCURY_OPTIONS} environment variable.
@sp 1
Trace count files
can be manipulated with the @samp{mtc_union} and @samp{mtc_diff} tools,
and they can be analysed by the @samp{mslice} and @samp{mdice} tools.
They can also be used to help direct a declarative debugging search
(see @ref{Search modes}).
@sp 1
@node Combining trace counts
@subsection Combining trace counts
The @samp{mtc_union} tool can be used
to combine several trace count files into one trace count file.
You need to use this when you have
many trace count files you wish to analyse with @samp{mslice} or @samp{mdice}.
@samp{mtc_union} is invoked by issuing a command of the form:
@sp 1
@example
mtc_union [-v] -o output_file file1 file2 @dots{}
@end example
@sp 1
@samp{file1}, @samp{file2}, etc.
are the trace count files that should be combined.
The new trace count file will be written to @samp{output_file}.
This file will preserve
the count of the test cases that contributed to its contents,
even if some of @samp{file1}, @samp{file2}, etc themselves
were created by @samp{mtc_union}.
If the @samp{-v} or @samp{--verbose} option is specified
then a progress message will be displayed
as each file is read and its contents merged into the union.
The @samp{mtc_diff} tool can be used
to subtract one trace count file from another.
@samp{mtc_diff} is invoked by issuing a command of the form:
@sp 1
@example
mtc_diff -o output_file file1 file2
@end example
@sp 1
@samp{file1} and @samp{file2} must both be trace counts files.
The output, written to @samp{output_file}, will contain
the difference between the trace counts in @samp{file1} and @samp{file2}
for every event that occurs in @samp{file1}.
Unlike @samp{mtc_union}, @samp{mtc_diff} does not preserve
the count of the test cases that contributed to its contents in any useful way.
@sp 1
@node Slicing
@subsection Slicing
Once a slice has been generated
it can be viewed in various ways using the mslice tool.
The output of the mslice tool will look something like the following:
@sp 1
@example
Procedure Path/Port File:Line Count (1)
pred mrg.merge/3-0 CALL mrg.m:60 14 (1)
pred mrg.merge/3-0 EXIT mrg.m:60 14 (1)
pred mrg.msort_n/4-0 CALL mrg.m:33 12 (1)
pred mrg.msort_n/4-0 EXIT mrg.m:33 12 (1)
pred mrg.msort_n/4-0 <?;> mrg.m:35 12 (1)
@end example
@sp 1
Each row corresponds to a label in the program.
The meanings of the columns are as follows:
@itemize @bullet
@item @samp{Procedure}:
This column displays the procedure that the label relates to.
@item @samp{Path/Port}:
For interface events this column displays the event port,
while for internal events it displays the goal path.
(See @ref{Tracing of Mercury programs}
for an explanation of interface and internal events.)
@item @samp{File:Line}:
This column displays the context of the event.
@item @samp{Count}:
This column displays how many times the event was executed.
The number in parentheses for each event row
says in how many runs the event was executed.
The number in parentheses in the heading row (after the word "Count")
indicates how many runs were represented
in the trace counts file analysed by the mslice tool.
@end itemize
@sp 1
The mslice tool is invoked using a command of the form:
@example
mslice [-s sortspec] [-l N] [-m module] [-n N] [-p N] [-f N] file
@end example
@sp 1
where @samp{file} is a trace count file,
generated either directly by a program run
or indirectly by the @samp{mtc_union} or @samp{mtc_diff} tools.
@sp 1
The @samp{-s} or @samp{--sort} option
specifies how the output should be sorted.
@samp{sortspec} should be a string made up of
any combination of the letters @samp{cCtT}.
Each letter specifies a column and direction to sort on:
@itemize @bullet
@item @samp{c}: Count ascending
@item @samp{C}: Count descending
@item @samp{t}: Number of runs ascending
@item @samp{T}: Number of runs descending
@end itemize
@sp 1
For example, the option @samp{-s cT} will sort the output table
by the Count column in ascending order.
If the counts for two or more events are the same,
then those events will be sorted by number of runs in descending order.
@sp 1
The default is to sort descending on the Count column.
@sp 1
The @samp{-l} or @samp{--limit} option limits the output to @samp{N} lines.
@sp 1
The @samp{-m} or @samp{--module} option limits the output
to events only from the given module.
@sp 1
The @samp{-n} or @samp{--max-name-column-width} option's argument gives the
maximum width of the column containing predicate and function names.
If the argument is zero, there is no maximum width.
@sp 1
The @samp{-p} or @samp{--max-path-column-width} option's argument gives the
maximum width of the column containing ports and goal paths.
If the argument is zero, there is no maximum width.
@sp 1
The @samp{-f} or @samp{--max-file-column-width} option's argument gives the
maximum width of the column containing file names and line numbers.
If the argument is zero, there is no maximum width.
@sp 1
@node Dicing
@subsection Dicing
A dice is a comparison between passing and failing runs of a program.
@sp 1
Dice are created using the @samp{mdice} tool.
To use the @samp{mdice} tool,
one must first generate a set of trace count files for passing runs
and a set of trace count files for failing runs
using the @samp{mtc} tool (@ref{Generating trace counts}).
Once this has been done,
and the union of each set computed using @samp{mtc_union},
@samp{mdice} can be used to display a table of statistics
that compares the passing runs to the failing runs.
@sp 1
Here is an example of the output of the @samp{mdice} tool:
@sp 1
@example
Procedure Path/Port File:Line Pass (3) Fail Suspicion
pred s.mrg/3-0 <s2;c2;e;> s.m:74 0 (0) 1 1.00
pred s.mrg/3-0 <s2;c2;t;> s.m:67 10 (3) 4 0.29
pred s.mrg/3-0 CALL s.m:64 18 (3) 7 0.28
pred s.mrg/3-0 EXIT s.m:64 18 (3) 7 0.28
@end example
@sp 1
This example tells us that the @samp{else} in @samp{s.m} on line 74
was executed once in the failing test run,
but never during the passing test runs,
so this would be a good place to start looking for a bug.
@sp 1
Each row corresponds to an event in the program.
The meanings of the columns are as follows:
@itemize @bullet
@item @samp{Procedure}:
This column displays the procedure the event relates to.
@item @samp{Path/Port}:
For interface events this column displays the event port,
while for internal events it displays the goal path.
(See @ref{Tracing of Mercury programs}
for an explanation of interface and internal events.)
@item @samp{File:Line}:
This column displays the context of the event.
@item @samp{Pass (total passing test runs)}:
This columns displays the total number of times
the event was executed in all the passing test runs.
This is followed by a number in parentheses
which indicates the number of test runs the event was executed in.
The heading of this column also has a number in parentheses
which is the total number of passing test cases.
@item @samp{Fail}:
This column displays the number of times
the goal was executed in the failing test run(s).
@item @samp{Suspicion}:
This columns displays a number between 0 and 1
which gives an indication of how likely a particular goal is to contain a bug.
The suspicion is calculated as Suspicion = F / (P + F)
where F is the number of times the goal was executed in failing runs
and P is the number of times the goal was executed in passing runs.
@end itemize
@sp 1
The @samp{mdice} tool is invoked with a command of the form:
@sp 1
@example
mdice [-s sortspec] [-l N] [-m module] [-n N] [-p N] [-f N] passfile failfile
@end example
@samp{passfile} is a trace count file,
generated either directly by a passing program run
or as the union of the trace count files of passing program runs.
@samp{failfile} is a trace count file,
generated either directly by a failing program run
or as the union of the trace count files of failing program runs.
@sp 1
The table can be sorted on the Pass, Fail or Suspicion columns,
or a combination of these.
This can be done with the @samp{-s} or @samp{--sort} option.
The argument of this option is a string
made up of any combination of the letters @samp{pPfFsS}.
The letters in the string indicate how the table should be sorted:
@sp 1
@itemize @bullet
@item @samp{p}: Pass ascending
@item @samp{P}: Pass descending
@item @samp{f}: Fail ascending
@item @samp{F}: Fail descending
@item @samp{s}: Suspicion ascending
@item @samp{S}: Suspicion descending
@end itemize
@sp 1
For example the string "SF" means
sort the table by suspicion in descending order,
and if any two suspicions are the same,
then by number of executions in the failing run(s), also in descending order.
@sp 1
The default is to sort descending on the Suspicion column.
@sp 1
The option @samp{-l} or @samp{--limit}
can be used to limit the number of lines displayed.
@sp 1
The @samp{-m} or @samp{--module} option
limits the output to the given module and any submodules.
@sp 1
The @samp{-n} or @samp{--max-name-column-width} option's argument gives the
maximum width of the column containing predicate and function names.
If the argument is zero, there is no maximum width.
@sp 1
The @samp{-p} or @samp{--max-path-column-width} option's argument gives the
maximum width of the column containing ports and goal paths.
If the argument is zero, there is no maximum width.
@sp 1
The @samp{-f} or @samp{--max-file-column-width} option's argument gives the
maximum width of the column containing file names and line numbers.
If the argument is zero, there is no maximum width.
@sp 1
@node Coverage testing
@subsection Coverage testing
Coverage testing is the process of finding out
which parts of the code of a program
are not executed during any test case,
so that new test cases can be designed specifically to exercise those parts.
@sp 1
The first step in coverage testing a Mercury program
is compiling that program with execution tracing enabled,
either by using the @samp{--trace deep} option
or by compiling the program in a debugging grade.
The second step is to execute that program on all its test cases
with coverage testing enabled.
This can be done either by running the program with @samp{mtc --coverage-test},
or by including one of the corresponding options
(@samp{--coverage-test} or @samp{--coverage-test-if-exec=@var{programname}})
in the value of the @env{MERCURY_OPTIONS} environment variable.
These runs generate a set of trace counts files
that can be given to the Mercury test coverage tool, the @samp{mcov} program.
As usual, trace count files are named with the prefix
@samp{.mercury_trace_counts} if the @samp{mtc --output-file} option is not
given.
@sp 1
The @samp{mcov} tool is invoked with a command of the form:
@sp 1
@example
mcov [-d] [-v] [-o output_file] tracecountfile1 @dots{}
@end example
The arguments consist of one or more trace count files.
The output will normally be a list of all the procedures in the program
that were not executed in any of the runs
that generated these trace count files.
The output will go to standard output
unless this is overridden by the @samp{-o} or @samp{--output-file} option.
@sp 1
If the @samp{-d} or @samp{--detailed} option is specified,
then the output will list all the @emph{events} in the program
that were not executed in any of these runs.
This option can thus show the unexecuted parts of the executed procedures.
@sp 1
If the @samp{-v} or @samp{--verbose} option is specified,
then a progress message will be displayed as each file is read.
@c ----------------------------------------------------------------------------
@node Profiling
@chapter Profiling
@pindex mprof
@pindex mdprof
@cindex Profiling
@cindex Profiling memory allocation
@cindex Time profiling
@cindex Heap profiling
@cindex Memory profiling
@cindex Allocation profiling
@cindex Deep profiling
@c XXX
@c This chapter should have just three or four sections:
@c introduction, mprof, mdprof and possibly threadscope.
@c Each of the post-introduction sections should have subsections
@c for creating profiles, using profiles for x, using profiles for y etc,
@c followed by any relevant caveats about e.g. dynamic linking.
@menu
* Profiling introduction:: What is profiling useful for?
* Building profiled applications:: How to enable profiling.
* Creating profiles:: How to create profile data.
* Using mprof for time profiling:: How to analyze the time performance of a
program with mprof.
* Using mprof for profiling memory allocation::
How to analyze the memory performance of a
program with mprof.
* Using mprof for profiling memory retention::
How to analyze what memory is on the heap.
* Using mdprof:: How to analyze the time and/or memory
performance of a program with mdprof.
* Using threadscope:: How to analyse the parallel
execution of a program with threadscope.
* Profiling and shared libraries:: Profiling dynamically linked executables.
@end menu
@node Profiling introduction
@section Profiling introduction
@cindex Profiling
@cindex Measuring performance
@cindex Optimization
@cindex Efficiency
@cindex Parallel performance
To obtain the best trade-off between productivity and efficiency,
programmers should not spend too much time optimizing their code
until they know which parts of the code are really taking up most of the time.
Only once the code has been profiled should the programmer consider
making optimizations that would improve efficiency
at the expense of readability or ease of maintenance.
A good profiler is therefore a tool
that should be part of every software engineer's toolkit.
Mercury programs can be analyzed using two distinct profilers.
The Mercury profiler @samp{mprof} is a conventional call-graph profiler
(or graph profiler for short) in the style of @samp{gprof}.
The Mercury deep profiler @samp{mdprof} is a new kind of profiler
that associates a lot more context with each measurement.
@samp{mprof} can be used to profile either time or space,
but not both at the same time;
@samp{mdprof} can profile both time and space at the same time.
@c THREADSCOPE
The parallel execution of Mercury programs can be analyzed with a third
profiler called @samp{threadscope}.
@samp{threadscope} allows programmers to visualise CPU utilisation for work,
garbage collection, and idle time.
This enables programmers to see the effect of parallelization decisions such as
task granularity.
The @samp{threadscope} tool is not included with the Melbourne Mercury
Compiler,
See @url{https://research.microsoft.com/en-us/projects/threadscope/,
Threadscope: Performance Tuning Parallel Haskell Programs}.
@node Building profiled applications
@section Building profiled applications
@cindex Building profiled applications
@pindex mprof
@pindex mdprof
@pindex threadscope
@cindex Time profiling
@cindex Heap profiling
@cindex Memory profiling
@cindex Allocation profiling
@cindex Deep profiling
@cindex Threadscope profiling
@cindex Parallel runtime profiling
@findex --parallel
@findex --threadscope
To enable profiling, your program must be built with profiling enabled.
The three different profilers require different support,
and thus you must choose which one to enable when you build your program.
@itemize @bullet
@item
To build your program with time profiling enabled for @samp{mprof},
pass the @samp{-p} (@samp{--profiling}) option to @samp{mmc}
(and also to @samp{mgnuc} and @samp{ml}, if you invoke them separately).
@item
To build your program with memory profiling enabled for @samp{mprof},
pass the @samp{--memory-profiling} option to @samp{mmc},
@samp{mgnuc} and @samp{ml}.
@item
To build your program with deep profiling enabled (for @samp{mdprof}),
pass the @samp{--deep-profiling} option to @samp{mmc},
@samp{mgnuc} and @samp{ml}.
@c ZZZ THREADSCOPE should we comment threadscope out?
@item
To build your program with threadscope profiling enabled
(for @samp{threadscope}).
pass the @samp{--parallel} and @samp{--threadscope} options to @samp{mmc},
@samp{mgnuc} and @samp{ml}.
@end itemize
If you are using Mmake,
then you pass these options to all the relevant programs
by setting the @samp{GRADEFLAGS} variable in your Mmakefile,
e.g.@: by adding the line @samp{GRADEFLAGS=--profiling}.
(For more information about the different grades,
see @ref{Grade options}.)
Enabling @samp{mprof} or @samp{mdprof} profiling has several effects.
First, it causes the compiler to generate slightly modified code,
which counts the number of times each predicate or function is called,
and for every call, records the caller and callee.
With deep profiling, there are other modifications as well, the most important
impact of which is the loss of tail-recursion.
(By default, the deep profiling versions of the library and runtime are built
with @samp{--stack-segments} in order to minimize this impact.)
Second, your program will be linked with versions of the library and runtime
that were compiled with the same kind of profiling enabled.
Third, if you enable graph profiling,
the compiler will generate for each source file
the static call graph for that file in @samp{@var{module}.prof}.
Enabling @samp{threadscope} profiling causes the compiler to build the program
against a different runtime system.
This runtime system logs events relevant to parallel execution.
@samp{threadscope} support is not compatible with all processors,
see @file{README.ThreadScope} for more information.
@node Creating profiles
@section Creating profiles
@cindex Profiling
@cindex Creating profiles
@pindex mprof
@pindex mdprof
@cindex Time profiling
@cindex Heap profiling
@cindex Memory profiling
@cindex Allocation profiling
@cindex Deep profiling
Once you have created a profiled executable,
you can gather profiling information by running the profiled executable
on some test data that is representative of the intended uses of the program.
The profiling version of your program
will collect profiling information during execution,
and save this information at the end of execution,
provided execution terminates normally and not via an abort.
Executables compiled with @samp{--profiling}
save profiling data in the files
@file{Prof.Counts}, @file{Prof.Decl}, and @file{Prof.CallPair}.
(@file{Prof.Decl} contains the names
of the procedures and their associated addresses,
@file{Prof.CallPair} records the number of times
each procedure was called by each different caller,
and @file{Prof.Counts} records the number of times
that execution was in each procedure when a profiling interrupt occurred.)
Executables compiled with @samp{--memory-profiling}
will use two of those files (@file{Prof.Decl} and @file{Prof.CallPair})
and two others: @file{Prof.MemoryWords} and @file{Prof.MemoryCells}.
Executables compiled with @samp{--deep-profiling}
save profiling data in two files whose names will have form
@file{@var{programname}_on_@var{date}_at_@var{time}.data} and
@file{@var{programname}_on_@var{date}_at_@var{time}.procrep}.
(On Windows, the @code{.exe} suffix will be omitted from @var{programname}.)
@c THREADSCOPE
Executables compiled with the @samp{--threadscope} option write profiling data
to a file whose name is that of the program being profiled with the extension
@samp{.eventlog}.
For example, the profile for the program @samp{my_program} would be written to
the file @file{my_program.eventlog}.
It is also possible to combine @samp{mprof} profiling results
from multiple runs of your program.
You can do by running your program several times,
and typing @samp{mprof_merge_counts} after each run.
It is not (yet) possible to combine @samp{mdprof} profiling results
from multiple runs of your program.
Due to a known timing-related bug in our code,
you may occasionally get segmentation violations
when running your program with @samp{mprof} profiling enabled.
If this happens, just run it again --- the problem occurs only very rarely.
The same vulnerability does not occur with @samp{mdprof} profiling.
With the @samp{mprof} and @samp{mdprof} profilers,
you can control whether time profiling measures
real (elapsed) time, user time plus system time, or user time only,
by including the options @samp{-Tr}, @samp{-Tp}, or @samp{-Tv} respectively
in the environment variable @env{MERCURY_OPTIONS}
when you run the program to be profiled.
@c (See the environment variables section below.)
Currently, only the @samp{-Tr} option works on Cygwin; on that
platform it is the default.
@c the above sentence is duplicated below
The default is user time plus system time,
which counts all time spent executing the process,
including time spent by the operating system working on behalf of the process,
but not including time that the process was suspended
(e.g.@: due to time slicing, or while waiting for input).
When measuring real time,
profiling counts even periods during which the process was suspended.
When measuring user time only,
profiling does not count time inside the operating system at all.
@node Using mprof for time profiling
@section Using mprof for time profiling
@pindex mprof
@cindex Time profiling
To display the graph profile information
gathered from one or more profiling runs,
just type @samp{mprof} or @samp{mprof -c}.
(For programs built with @samp{--high-level-code},
you need to also pass the @samp{--no-demangle} option to @samp{mprof} as well.)
@findex --high-level-code
@findex --demangle
@findex --no-demangle
Note that @samp{mprof} can take quite a while to execute
(especially with @samp{-c}),
and will usually produce quite a lot of output,
so you will usually want to redirect the output into a file
with a command such as @samp{mprof > mprof.out}.
The output of @samp{mprof -c} consists of three major sections.
These are named the call graph profile,
the flat profile and the alphabetic listing.
The output of @samp{mprof} contains
the flat profile and the alphabetic listing only.
@cindex Call graph profile
The call graph profile presents the local call graph of each procedure.
For each procedure it shows
the parents (callers) and children (callees) of that procedure,
and shows the execution time and call counts for each parent and child.
It is sorted on the total amount of time spent
in the procedure and all of its descendants
(i.e.@: all of the procedures that it calls, directly or indirectly.)
@cindex Flat profile
The flat profile presents the just execution time spent in each procedure.
It does not count the time spent in descendants of a procedure.
The alphabetic listing just lists the procedures in alphabetical order,
along with their index number in the call graph profile,
so that you can quickly find the entry for a particular procedure
in the call graph profile.
@cindex Profiling interrupts
The profiler works by interrupting the program at frequent intervals,
and each time recording the currently active procedure and its caller.
It uses these counts to determine
the proportion of the total time spent in each procedure.
This means that the figures calculated for these times
are only a statistical approximation to the real values,
and so they should be treated with some caution.
In particular, if the profiler's assumption
that calls to a procedure from different callers have roughly similar costs
is not true,
the graph profile can be quite misleading.
The time spent in a procedure and its descendants is calculated by
propagating the times up the call graph,
assuming that each call to a procedure from a particular caller
takes the same amount of time.
This assumption is usually reasonable,
but again the results should be treated with caution.
(The deep profiler does not make such an assumption,
and hence its output is significantly more reliable.)
@cindex Garbage collection, profiling
Note that any time spent in a C function
(e.g.@: time spent in @samp{GC_malloc()},
which does memory allocation and garbage collection)
is credited to the Mercury procedure that called that C function.
Here is a small portion of the call graph profile from an example program.
@example
called/total parents
index %time self descendants called+self name index
called/total children
<spontaneous>
[1] 100.0 0.00 0.75 0 call_engine_label [1]
0.00 0.75 1/1 do_interpreter [3]
-----------------------------------------------
0.00 0.75 1/1 do_interpreter [3]
[2] 100.0 0.00 0.75 1 io.run/0(0) [2]
0.00 0.00 1/1 io.init_state/2(0) [11]
0.00 0.74 1/1 main/2(0) [4]
-----------------------------------------------
0.00 0.75 1/1 call_engine_label [1]
[3] 100.0 0.00 0.75 1 do_interpreter [3]
0.00 0.75 1/1 io.run/0(0) [2]
-----------------------------------------------
0.00 0.74 1/1 io.run/0(0) [2]
[4] 99.9 0.00 0.74 1 main/2(0) [4]
0.00 0.74 1/1 sort/2(0) [5]
0.00 0.00 1/1 print_list/3(0) [16]
0.00 0.00 1/10 io.write_string/3(0) [18]
-----------------------------------------------
0.00 0.74 1/1 main/2(0) [4]
[5] 99.9 0.00 0.74 1 sort/2(0) [5]
0.05 0.65 1/1 list.perm/2(0) [6]
0.00 0.09 40320/40320 sorted/1(0) [10]
-----------------------------------------------
8 list.perm/2(0) [6]
0.05 0.65 1/1 sort/2(0) [5]
[6] 86.6 0.05 0.65 1+8 list.perm/2(0) [6]
0.00 0.60 5914/5914 list.insert/3(2) [7]
8 list.perm/2(0) [6]
-----------------------------------------------
0.00 0.60 5914/5914 list.perm/2(0) [6]
[7] 80.0 0.00 0.60 5914 list.insert/3(2) [7]
0.60 0.60 5914/5914 list.delete/3(3) [8]
-----------------------------------------------
40319 list.delete/3(3) [8]
0.60 0.60 5914/5914 list.insert/3(2) [7]
[8] 80.0 0.60 0.60 5914+40319 list.delete/3(3) [8]
40319 list.delete/3(3) [8]
-----------------------------------------------
0.00 0.00 3/69283 tree234.set/4(0) [15]
0.09 0.09 69280/69283 sorted/1(0) [10]
[9] 13.3 0.10 0.10 69283 compare/3(0) [9]
0.00 0.00 3/3 __Compare___io__stream/0(0) [20]
0.00 0.00 69280/69280 builtin_compare_int/3(0) [27]
-----------------------------------------------
0.00 0.09 40320/40320 sort/2(0) [5]
[10] 13.3 0.00 0.09 40320 sorted/1(0) [10]
0.09 0.09 69280/69283 compare/3(0) [9]
-----------------------------------------------
@end example
The first entry is @samp{call_engine_label} and its parent is
@samp{<spontaneous>}, meaning that it is the root of the call graph.
(The first three entries, @samp{call_engine_label}, @samp{do_interpreter},
and @samp{io.run/0} are all part of the Mercury runtime;
@samp{main/2} is the entry point to the user's program.)
Each entry of the call graph profile consists of three sections, the parent
procedures, the current procedure and the children procedures.
Reading across from the left, for the current procedure the fields are:
@itemize @bullet
@item
The unique index number for the current procedure.
(The index numbers are used only to make it easier to find
a particular entry in the call graph.)
@item
The percentage of total execution time spent in the current procedure
and all its descendants.
As noted above, this is only a statistical approximation.
@item
The ``self'' time: the time spent executing code that is
part of current procedure.
As noted above, this is only a statistical approximation.
@item
The descendant time: the time spent in the
current procedure and all its descendants.
As noted above, this is only a statistical approximation.
@item
The number of times a procedure is called.
If a procedure is (directly) recursive, this column
will contain the number of calls from other procedures,
a plus sign, and then the number of recursive calls.
These numbers are exact, not approximate.
@item
The name of the procedure followed by its index number.
@end itemize
The predicate or function names are not just followed by their arity but
also by their mode in brackets. A mode of zero corresponds to the first mode
declaration of that predicate in the source code. For example,
@samp{list.delete/3(3)} corresponds to the @samp{(out, out, in)} mode
of @samp{list.delete/3}.
Now for the parent and child procedures the self and descendant time have
slightly different meanings. For the parent procedures the self and descendant
time represent the proportion of the current procedure's self and descendant
time due to that parent. These times are obtained using the assumption that
each call contributes equally to the total time of the current procedure.
@node Using mprof for profiling memory allocation
@section Using mprof for profiling memory allocation
@pindex mprof
@cindex Memory profiling
@cindex Allocation profiling
@cindex Profiling memory allocation
To create a profile of memory allocations, you can invoke @samp{mprof}
with the @samp{-m} (@samp{--profile memory-words}) option.
This will profile the amount of memory allocated, measured in units of words.
(A word is 4 bytes on a 32-bit architecture,
and 8 bytes on a 64-bit architecture.)
Alternatively, you can use @samp{mprof}'s @samp{-M}
(@samp{--profile memory-cells}) option.
This will profile memory in units of ``cells''.
A cell is a group of words allocated together in a single allocation,
to hold a single object.
Selecting this option this will therefore profile
the number of memory allocations,
while ignoring the size of each memory allocation.
With memory profiling, just as with time profiling,
you can use the @samp{-c} (@samp{--call-graph}) option to display
call graph profiles in addition to flat profiles.
When invoked with the @samp{-m} option, @samp{mprof} only reports
allocations, not deallocations (garbage collection).
It can tell you how much memory was allocated by each procedure,
but it won't tell you how long the memory was live for,
or how much of that memory was garbage-collected.
This is also true for @samp{mdprof}.
The memory retention profiling tool described in the next section can tell
you which memory cells remain on the heap.
@node Using mprof for profiling memory retention
@section Using mprof for profiling memory retention
@pindex mprof
@cindex Memory attribution
@cindex Memory retention
@cindex Heap profiling
When a program is built with memory profiling enabled and uses the Boehm
garbage collector, i.e. a grade with @samp{.memprof.gc} modifiers,
each memory cell is ``attributed'' with information about its origin
and type. This information can be
collated to tell you what kinds of objects are being retained when
the program executes.
To do this, you must instrument the program by adding calls to
@code{benchmarking.report_memory_attribution/1} or
@code{benchmarking.report_memory_attribution/3}
at points of interest.
The first argument of the @code{report_memory_attribution} predicates is a
string that is used to label the memory retention data corresponding to that
call in the profiling output.
You may want to call them from within @samp{trace} goals:
@example
@group
trace [run_time(env("SNAPSHOTS")), io(!IO)] (
benchmarking.report_memory_attribution("Phase 2", !IO)
)
@end group
@end example
If a program operates in distinct phases
you may want to add a call in between the phases.
The @samp{report_memory_attribution} predicates do nothing in other grades,
so are safe to leave in the program.
Next, build the program in a @samp{.memprof.gc} grade.
After the program has finished executing, it will generate a file
called @file{Prof.Snapshots} in the current directory.
Run @samp{mprof -s} to view the profile.
You will see the memory cells which were on the heap at each time
that @samp{report_memory_attribution} was called: the origin of the cells, and
their type constructors.
Passing the option @samp{-T} will group the profile first by
type constructors, then by procedure. The @samp{-b} option produces a brief
profile by hiding the secondary level of information.
Memory cells allocated by the Mercury runtime system
itself are normally excluded from the profile; they can be viewed by passing
the @samp{-r} option.
Note that Mercury values which are dead may in fact be still reachable from the
various execution stacks. This is particularly noticeable on the high-level C
backend, as the C compiler does not take conservative garbage collection into
account and Mercury values may linger on the C stack for longer than necessary.
The low-level C grades should suffer to a lesser extent.
The attribution requires an extra word of memory per cell, which
is then rounded up by the memory allocator.
This is accounted for in @samp{mprof} output, but the memory usage
of the program may be significantly higher than in non-memory profiling grades.
@node Using mdprof
@section Using mdprof
@pindex mdprof
@cindex Deep profiling
The user interface of the deep profiler is a browser.
To display the information contained in a deep profiling data file
(whose name will have the form
@file{@var{programname}_@var{date}_@var{time}.data}
unless you renamed it),
start up your browser and give it a URL of the form
@file{http://server.domain.name/cgi-bin/mdprof_cgi?/full/path/name/Deep.data}.
The @file{server.domain.name} part should be the name of a machine
with the following qualifications:
it should have a web server running on it,
and it should have the @samp{mdprof_cgi} program installed in
the web server's CGI program directory.
(On many Linux systems, this directory is @file{/usr/lib/cgi-bin}.)
The @file{/full/path/name/@var{programname}_@var{date}_@var{time}.data} part
should be the full path name of the deep profiling data file
whose data you wish to explore.
The name of this file must not have percent signs in it,
and it must end in the suffix @file{.data}.
(The deep profiler will replace this suffix with @file{.procrep}
to get access to the other file generated by the profiling run.)
When you start up @samp{mdprof} using the command above,
you will see a list of the usual places
where you may want to start looking at the profile.
Each place is represented by a link.
Clicking on and following that link will give you a web page
that contains both the profile information you asked for
and other links,
some of which present the same information in a different form
and some of which lead to further information.
You explore the profile
by clicking on links and looking at the resulting pages.
The deep profiler can generate several kinds of pages,
including the following.
@table @asis
@item The menu page
The menu page gives summary information about the profile,
and the usual starting points for exploration.
@item Clique pages
Clique pages are the most fundamental pages of the deep profiler.
Each clique page presents performance information about a clique,
which is either a single procedure or a group of mutually recursive procedures,
in a given ancestor context,
which in turn is a list of other cliques
starting with the caller of the entry point of the clique
and ending with the clique of the @samp{main} predicate.
Each clique page lists the closest ancestor cliques,
and then the procedures of the clique.
It gives the cost of each call site in each procedure,
as well as the cost of each procedure in total.
These costs will be just those incurred in the given ancestor context;
the costs incurred by these call sites
and procedures in other ancestor contexts
will be shown on other clique pages.
@item Procedure pages
Procedure pages give the total cost of a procedure and its call sites
in all ancestor contexts.
@item Module pages
Module pages give the total cost of all the procedures of a module.
@item Module getters and setters pages
These pages identifies the getter and setter procedures in a module.
Getters and setters are simply predicates and functions
that contain @samp{_get_} and @samp{_set_} respectively in their names;
they are usually used to access fields of data structures.
@item Program modules page
The program modules page gives the list of the program's modules.
@item Top procedure pages
Top procedure pages identify the procedures that are
most expensive as measured by various criteria.
@item Procedure caller pages
A procedure caller page lists the call sites, procedures, modules or cliques
that call the given procedure.
@end table
When exploring a procedure's callers,
you often want only the ancestors
that are at or above a certain level of abstraction.
Effectively you want to draw a line through the procedures of the program,
such that you are interested in the procedures on or above the line
but those below the line.
Since we want to exclude procedures below the line
from procedure caller pages,
we call this line an @emph{exclusion contour}.
You can tell the deep profiler where you want to draw this line
by giving it a @samp{exclusion contour file}.
The name of this file should be the same
as the name of the deep profiling data file,
but with the suffix @samp{.data} replaced with @samp{.contour}.
This file should consist of a sequence of lines,
and each line should contain two words.
The first word should be either @samp{all} or @samp{internal};
the second should the name of a module.
If the first word is @samp{all}, then
all procedures in the named module are below the exclusion contour;
if the first word is @samp{internal}, then
all internal (non-exported) procedures in the named module
are below the exclusion contour.
Here is an example of an exclusion contour file.
@example
all bag
all list
all map
internal set
@end example
@c THREADSCOPE
@node Using threadscope
@section Using threadscope
@pindex threadscope
@pindex show-ghc-events
@cindex ThreadScope profiling
@cindex Parallel execution profiling
The ThreadScope tools are not distributed with Mercury.
For information about how to install them please see the
@file{README.ThreadScope} file included in the Mercury distribution.
ThreadScope provides two programs that can be used to view profiles in
@file{.eventlog} files.
The first, @samp{show-ghc-events},
lists the ThreadScope events sorted from the earliest to the latest,
while the second, @samp{threadscope} provides
a graphical display for browsing the profile.
Both programs accept the name of a @file{.eventlog} file on the command line.
The @samp{threadscope} program also provides
a menu from which users can choose a file to open.
@node Profiling and shared libraries
@section Profiling and shared libraries
@pindex mprof
@cindex Shared libraries and profiling
@cindex Profiling and shared libraries
@vindex LD_BIND_NOW
On some operating systems,
Mercury's profiling doesn't work properly with shared libraries.
The symptom is errors (@samp{map.lookup failed}) or warnings from @samp{mprof}.
On some systems, the problem occurs because the C implementation
fails to conform to the semantics specified by the ISO C standard
for programs that use shared libraries.
For other systems, we have not been able to analyze the cause of the failure
(but we suspect that the cause may be the same as on those systems
where we have been able to analyze it).
If you get errors or warnings from @samp{mprof},
and your program is dynamically linked,
try rebuilding your application statically linked,
e.g.@: by using @samp{MLFLAGS=--static} in your Mmakefile.
Another work-around that sometimes works is to set the environment variable
@env{LD_BIND_NOW} to a non-null value before running the program.
@c ----------------------------------------------------------------------------
@node Invocation
@chapter Invocation
This section contains a brief description of all the options
available for @samp{mmc}, the Melbourne Mercury compiler.
Sometimes this list is a little out-of-date;
use @samp{mmc --help} to get the most up-to-date list.
@c This should no longer be a concern.
@findex --help
@include ug_invocation.texi
@c ----------------------------------------------------------------------------
@node Environment
@chapter Environment variables
@cindex Environment variables
@cindex Variables, environment
@cindex Directories
@cindex Search path
The various components of the Mercury compilation environment
will use the following environment variables if they are set.
There should be little need to use most of these,
because the default values will generally work fine.
@menu
* Environment variables affecting the Mercury compiler::
* Environment variables affecting the Mercury debugger::
* Environment variables affecting the Mercury runtime system::
@end menu
@node Environment variables affecting the Mercury compiler
@section Environment variables affecting the Mercury compiler
@cindex Environment variables affecting the Mercury compiler
@table @code
@item MERCURY_COMPILER
@vindex MERCURY_COMPILER
Filename of the Mercury compiler.
@sp 1
@item MERCURY_MKINIT
@vindex MERCURY_MKINIT
Filename of the program to create the @file{*_init.c} file.
@sp 1
@item MERCURY_DEFAULT_GRADE
@vindex MERCURY_DEFAULT_GRADE
The default grade to use if no @samp{--grade} option is specified.
@sp 1
@item MERCURY_STDLIB_DIR
@vindex MERCURY_STDLIB_DIR
The directory containing the installed Mercury standard library.
@samp{--mercury-stdlib-dir} options passed to the @samp{mmc}, @samp{ml},
@samp{mgnuc} and @samp{c2init} scripts override the setting of
the @env{MERCURY_STDLIB_DIR} environment variable.
@sp 1
@item MERCURY_COLOR_SCHEME
@vindex MERCURY_COLOR_SCHEME
The specification of the map from color roles to color shades
that the Mercury compiler should use in diagnostics.
For the details of the syntax, semantics, and effects of such specifications,
please see @ref{Color schemes}.
@sp 1
@item MERCURY_ENABLE_COLOR
@vindex MERCURY_ENABLE_COLOR
This environment variable should contain either
@samp{always} or @samp{1}
to enable the use of color in diagnostics by the Mercury compiler,
or either @samp{never} or @samp{0}
to disable it.
Note however that this effect can be overruled by command line options;
for the details, please see @ref{Enabling the use of color}.
@sp 1
@item NO_COLOR
@vindex NO_COLOR
This environment variable being set to any nonempty string
will disable the use of color in diagnostics by the Mercury compiler.
Note however that this effect can be overruled by command line options
and by the @samp{MERCURY_ENABLE_COLOR} environment variable;
for the details, please see @ref{Enabling the use of color}.
@end table
@node Environment variables affecting the Mercury debugger
@section Environment variables affecting the Mercury debugger
@cindex Environment variables affecting the Mercury debugger
@table @code
@item MERCURY_DEBUGGER_INIT
@vindex MERCURY_DEBUGGER_INIT
Name of a file that contains startup commands for the Mercury debugger.
This file should contain documentation for the debugger command set,
and possibly a set of default aliases.
@end table
@node Environment variables affecting the Mercury runtime system
@section Environment variables affecting the Mercury runtime system
@cindex Environment variables affecting the Mercury runtime system
@table @code
@item MERCURY_OPTIONS
@vindex MERCURY_OPTIONS
A list of options for the Mercury runtime system,
which gets linked into every Mercury program.
The options given in this environment variable apply to every program;
the options given in an environment variable
whose name is of the form @env{MERCURY_OPTIONS_@var{progname}}
apply only to programs named @var{progname}.
Note that @var{progname} does @emph{not} include the @file{.exe} extension
on those systems (e.g. Windows) that use it.
Options may also be set for a particular executable at compile time
by passing @samp{--runtime-flags} options
to the invocations of @samp{ml} and @samp{c2init} which create that executable.
These options are processed first,
followed by those in @env{MERCURY_OPTIONS},
with the options in @env{MERCURY_OPTIONS_@var{progname}} being processed last.
The Mercury runtime system accepts the following options.
@sp 1
@table @code
@c @item -a
@c If given force a redo when the entry point procedure succeeds;
@c this is useful for benchmarking when this procedure is model_non.
@c @item -c
@c Check how much of the space reserved for local variables
@c by mercury_engine.c was actually used.
@item -C @var{size}
@findex -C (runtime option)
Tells the runtime system to optimize the locations of the starts of the various
data areas for a primary data cache of @var{size} kilobytes.
The optimization consists of arranging the starts of the areas to differ as
much as possible modulo this size.
@c @item -d @var{debugflag}
@c @findex -d (runtime option)
@c Sets a low-level debugging flag.
@c These flags are consulted only if
@c the runtime was compiled with the appropriate definitions;
@c most of them depend on MR_LOWLEVEL_DEBUG.
@c For the meanings of the debugflag parameters,
@c see process_options() in mercury_wrapper.c
@c and do a grep for the corresponding variable.
@sp 1
@item -D @var{debugger}
@findex -D (runtime option)
Enables execution tracing of the program,
via the internal debugger if @var{debugger} is @samp{i}
and via the external debugger if @var{debugger} is @samp{e}.
(The mdb script works by including @samp{-Di} in MERCURY_OPTIONS.)
The external debugger is not yet available.
@sp 1
@item -p
@findex -p (runtime option)
Disables profiling.
This only has an effect if the executable was built in a profiling grade.
@sp 1
@item -P @var{num}
@findex -P (runtime option)
Tells the runtime system to create @var{num} threads for executing Mercury code
if the program was built in a parallel low-level C grade.
The Mercury runtime attempts to automatically determine this value if support
is available from the operating system.
If it cannot or support is unavailable it defaults to @samp{1}.
@sp 1
@item --max-engines @var{num}
@findex --max-engines (runtime option)
Tells the runtime system to allow a maximum of @var{num} POSIX threads, each
with its own Mercury engine.
This only affects programs in low-level C parallel grades.
@sp 1
@item --max-contexts-per-thread @var{num}
@findex --max-contexts-per-thread (runtime option)
Tells the runtime system to create at most @var{num} contexts per
POSIX thread for parallel execution.
Each context created requires a set of stacks, setting this value too high
can consume excess memory.
This only has an effect if the executable was built in a low-level C parallel
grade.
@c @sp 1
@c @item --num-contexts-per-lc-per-thread @var{num}
@c @findex --num-contexts-per-lc-per-thread (runtime option)
@c Tells the runtime system to use @var{num} contexts per POSIX thread
@c to handle each loop controlled loop.
@c This only has an effect if the executable
@c was built in a low-level C parallel c grade.
@c
@c @sp 1
@c @item --runtime-granularity-wsdeque-length-factor @var{factor}
@c @findex --runtime-granularity-wsdeque-length-factor (runtime option)
@c Configures the runtime granularity control method not to create sparks if a
@c context's local spark wsdeque is longer than
@c @math{ @var{factor} * @var{num_engines}}.
@c @var{num_engines} is configured with the @samp{-P} runtime option.
@c
@c @sp 1
@c @item --profile-parallel-execution
@c @findex --profile-parallel-execution
@c Tells the runtime to collect and write out parallel execution profiling
@c information to a file named @file{parallel_execution_profile.txt}.
@c This only has an effect if the executable was built in a low-level C,
@c parallel, threadscope grade.
@c
@c @sp 1
@c @item --threadscope-use-tsc
@c @findex --threadscope-use-tsc
@c Requests that the runtime's threadscope support use the CPU's time stamp
@c counter (TSC) to measure time rather than gettimeofday(). The TSC may
@c not always be available so the runtime may still use gettimeofday() even
@c with this option.
@sp 1
@item --thread-pinning
@findex --thread-pinning (runtime option)
Request that the runtime system attempts to pin Mercury engines (POSIX threads)
to CPU cores/hardware threads.
This only has an effect if the executable was built in a parallel low-level C
grade.
This is disabled by default but may be enabled by default in the future.
@c In case this is enabled by default the following comment is relevant.
@c This is disabled by default
@c unless @samp{-P @var{num}} is not specified and the
@c runtime system is able to detect the number of processors enabled by the
@c operating system.
@c @item -r @var{num}
@c @findex -r (runtime option)
@c Repeats execution of the entry point procedure @var{num} times,
@c to enable accurate timing.
@c @item -t
@c @findex -t (runtime option)
@c Tells the runtime system to measure the time taken by
@c the (required number of repetitions of) the program,
@c and to print the result of this time measurement.
@sp 1
@item -T @var{time-method}
@findex -T (runtime option)
If the executable was compiled in a grade that includes time profiling,
this option specifies what time is counted in the profile.
@var{time-method} must have one of the following values:
@sp 1
@table @code
@item @samp{r}
Profile real (elapsed) time (using ITIMER_REAL).
@item @samp{p}
Profile user time plus system time (using ITIMER_PROF).
This is the default.
@item @samp{v}
Profile user time (using ITIMER_VIRTUAL).
@end table
@sp 1
Currently, only the @samp{-Tr} option works on Cygwin; on that
platform it is the default.
@c the above sentence is duplicated above
@c @item -x
@c @findex -x (runtime option)
@c Tells the Boehm collector not to perform any garbage collection.
@sp 1
@item --heap-size @var{size}
@findex --heap-size (runtime option)
Sets the size of the heap to @var{size} kilobytes.
@sp 1
@item --heap-size-kwords @var{size}
@findex --heap-size-kwords (runtime option)
Sets the size of the heap to @var{size} kilobytes multiplied by the word size
in bytes.
@sp 1
@item --detstack-size @var{size}
@findex --detstack-size (runtime option)
Sets the size of the det stack to @var{size} kilobytes.
@sp 1
@item --detstack-size-kwords @var{size}
@findex --detstack-size-kwords (runtime option)
Sets the size of the det stack to @var{size} kilobytes
multiplied by the word size in bytes.
@sp 1
@item --nondetstack-size @var{size}
@findex --nondetstack-size (runtime option)
Sets the size of the nondet stack to @var{size} kilobytes.
@sp 1
@item --nondetstack-size-kwords @var{size}
@findex --nondetstack-size-kwords (runtime option)
Sets the size of the nondet stack to @var{size} kilobytes multiplied by the
word size in bytes.
@sp 1
@item --small-detstack-size @var{size}
@findex --small-detstack-size (runtime option)
Sets the size of the det stack used for executing parallel conjunctions
to @var{size} kilobytes.
The regular det stack size must be equal or greater.
@sp 1
@item --small-detstack-size-kwords @var{size}
@findex --small-detstack-size-kwords (runtime option)
Sets the size of the det stack used for executing parallel conjunctions to
@var{size} kilobytes multiplied by the word size in bytes.
The regular det stack size must be equal or greater.
@sp 1
@item --small-nondetstack-size @var{size}
@findex --small-nondetstack-size (runtime option)
Sets the size of the nondet stack for executing parallel computations
to @var{size} kilobytes.
The regular nondet stack size must be equal or greater.
@sp 1
@item --small-nondetstack-size-kwords @var{size}
@findex --small-nondetstack-size-kwords (runtime option)
Sets the size of the nondet stack for executing parallel computations
to @var{size} kilobytes
multiplied by the word size in bytes.
The regular nondet stack size must be equal or greater.
@sp 1
@item --solutions-heap-size @var{size}
@findex --solutions-heap-size (runtime option)
Sets the size of the solutions heap to @var{size} kilobytes.
@sp 1
@item --solutions-heap-size-kwords @var{size}
@findex --solutions-heap-size-kwords (runtime option)
Sets the size of the solutions heap to @var{size} kilobytes
multiplied by the word size in bytes.
@c These two options are commented out as we support a fixed size tail ONLY
@c for developers.
@c
@c @sp 1
@c @item --trail-size @var{size}
@c @findex --trail-size (runtime option)
@c @cindex Trail size
@c Sets the size of the trail to @var{size} kilobytes.
@c This option is ignored in grades that use trail segments.
@c @sp 1
@c @item --trail-size-kwords @var{size}
@c @findex --trail-size-kwords (runtime option)
@c @cindex Trail size
@c Sets the size of the trail to @var{size} kilobytes
@c multiplied by the word size in bytes.
@c This option is ignored in grades that use trail segments.
@sp 1
@item --trail-segment-size @var{size}
@findex --trail-segment-size (runtime option)
@cindex Trail size
Sets the size of each trail segment to be @var{size} kilobytes.
This option is ignored in grades that do not use a trail.
@sp 1
@item --trail-segment-size-kwords @var{size}
@findex --trail-segment-size-kwords (runtime option)
@cindex Trail size
Set the size of each trail segment to be @var{size} kilobytes multiplied by the
words size in bytes.
This option is ignored in grades that do not use trail.
@sp 1
@item --genstack-size @var{size}
@findex --genstack-size (runtime option)
@cindex Generator stack size
Sets the size of the generator stack to @var{size} kilobytes.
@sp 1
@item --genstack-size-kwords @var{size}
@findex --genstack-size-kwords (runtime option)
@cindex Generator stack size
Sets the size of the generator stack to @var{size} kilobytes
multiplied by the word size in bytes.
@sp 1
@item --cutstack-size @var{size}
@findex --cutstack-size (runtime option)
@cindex Cut stack size
Sets the size of the cut stack to @var{size} kilobytes.
@sp 1
@item --cutstack-size-kwords @var{size}
@findex --cutstack-size-kwords (runtime option)
@cindex Cut stack size
Sets the size of the cut stack to @var{size} kilobytes
multiplied by the word size in bytes.
@sp 1
@item --pnegstack-size @var{size}
@findex --pnegstack-size (runtime option)
@cindex Pneg stack size
Sets the size of the pneg stack to @var{size} kilobytes.
@sp 1
@item --pnegstack-size-kwords @var{size}
@findex --pnegstack-size-kwords (runtime option)
@cindex Pneg stack size
Sets the size of the pneg stack to @var{size} kilobytes multiplied by the word
size in bytes.
@c @sp 1
@c @item --heap-redzone-size @var{size}
@c @findex --heap-redzone-size (runtime option)
@c Sets the size of the redzone on the heap to @var{size} kilobytes.
@c @sp 1
@c @item --heap-redzone-size-kwords @var{size}
@c @findex --heap-redzone-size-kwords (runtime option)
@c Sets the size of the redzone on the heap to @var{size} kilobytes
@c multiplied by the word size in bytes.
@c @sp 1
@c @item --detstack-redzone-size @var{size}
@c @findex --detstack-redzone-size (runtime option)
@c Sets the size of the redzone on the det stack to @var{size} kilobytes.
@c @sp 1
@c @item --detstack-redzone-size-kwords @var{size}
@c @findex --detstack-redzone-size-kwords (runtime option)
@c Sets the size of the redzone on the det stack to @var{size} kilobytes
@c multiplied by the word size in bytes.
@c @sp 1
@c @item --nondetstack-redzone-size @var{size}
@c @findex --nondetstack-redzone-size (runtime option)
@c Sets the size of the redzone on the nondet stack to @var{size} kilobytes.
@c @sp 1
@c @item --nondetstack-redzone-size-kwords @var{size}
@c @findex --nondetstack-redzone-size-kwords (runtime option)
@c Sets the size of the redzone on the nondet stack to @var{size} kilobytes
@c multiplied by the word size in bytes.
@c @sp 1
@c @item --trail-redzone-size @var{size}
@c @findex --trail-redzone-size (runtime option)
@c Sets the size of the redzone on the trail to @var{size} kilobytes.
@c @sp 1
@c @item --trail-redzone-size-kwords @var{size}
@c @findex --trail-redzone-size-kwords (runtime option)
@c Sets the size of the redzone on the trail to @var{size} kilobytes
@c multiplied by the word size in bytes.
@sp 1
@item -i @var{filename}
@itemx --mdb-in @var{filename}
@findex -i (runtime option)
@findex --mdb-in (runtime option)
Read debugger input from the file or device specified by @var{filename},
rather than from standard input.
@sp 1
@item -o @var{filename}
@itemx --mdb-out @var{filename}
Print debugger output to the file or device specified by @var{filename},
@findex -o (runtime option)
@findex --mdb-out (runtime option)
rather than to standard output.
@sp 1
@item -e @var{filename}
@itemx --mdb-err @var{filename}
@findex -e (runtime option)
@findex --mdb-err (runtime option)
Print debugger error messages
to the file or device specified by @var{filename},
rather than to standard error.
@sp 1
@item -m @var{filename}
@itemx --mdb-tty @var{filename}
@findex -m (runtime option)
@findex --mdb-tty (runtime option)
Redirect all three debugger I/O streams
--- input, output, and error messages ---
to the file or device specified by @var{filename}.
@c --mdb-in-window is for use only by the mdb script, so it is
@c not documented here.
@c The documentation of --mdb-benchmark-silent is commented out because
@c this option is intended only for implementors.
@c @sp 1
@c @item --mdb-benchmark-silent
@c @findex --mdb-benchmark-silent (runtime option)
@c Redirect all output, including error messages, to /dev/null.
@c This is useful for benchmarking.
@sp 1
@item --debug-threads
@findex --debug-threads (runtime option)
@cindex Debugging Threads
@cindex Threads, Debugging
Output information to the standard error stream about the locking and
unlocking occurring in each module which has been compiled with the C macro
symbol @samp{MR_DEBUG_THREADS} defined.
@sp 1
@item --tabling-statistics
@findex --tabling-statistics (runtime option)
Prints statistics about tabling when the program terminates.
@sp 1
@item --mem-usage-report @var{prefix}
@findex --mem-usage-report (runtime option)
Print a report about the memory usage of the program when the program
terminates.
The report is printed to a new file named @file{.mem_usage_report@var{N}}
for the lowest value of @var{N} (up to 99)
which doesn't overwrite an existing file.
Note that this capability is not supported on all operating systems.
@sp 1
@item --trace-count
@findex --trace-count (runtime option)
When the program terminates, generate a trace counts file listing all the
debugger events the program executed, if the program actually executed any
debugger events.
If @env{MERCURY_OPTIONS} includes the
@samp{--trace-count-output-file @var{filename}} option, then the trace counts
are put into the file @var{filename}.
If @env{MERCURY_OPTIONS} includes
the @samp{--trace-count-summary-file @var{basename}} option, then the trace
counts are put either in the file @var{basename} (if it does not exist), or in
@var{basename.N} for the lowest value of the integer @var{N} which doesn't
overwrite an existing file.
(There is a limit on the value of @var{N}; see the option
@samp{--trace-count-summary-max} below.)
If neither option is specified, then the output will be written to a file with
the prefix @samp{.mercury_trace_counts} and a unique suffix.
Specifying both options is an error.
@sp 1
@item --coverage-test
@findex --coverage-test (runtime option)
Act as the @samp{--trace-count} option, except include @emph{all} debugger
events in the output, even the ones that were not executed.
@sp 1
@item --trace-count-if-exec @var{prog}
@findex --trace-count-if-exec (runtime option)
Act as the @samp{--trace-count} option, but only if the executable is named
@var{prog} (excluding any @file{.exe} extension on Windows).
This is to allow the collection of trace count information from only one
Mercury program even if several Mercury programs are executed with the same
setting of @env{MERCURY_OPTIONS}.
@sp 1
@item --coverage-test-if-exec @var{prog}
@findex --coverage-test-if-exec (runtime option)
Act as the @samp{--coverage-test} option, but only if the executable is named
@var{prog} (excluding any @file{.exe} extension on Windows).
This is to allow the collection of coverage test information from only one
Mercury program even if several Mercury programs are executed with the same
setting of @env{MERCURY_OPTIONS}.
@sp 1
@item --trace-count-output-file @var{filename}
@findex --trace-count-output-file (runtime option)
Documented alongside the @samp{--trace-count} option.
@sp 1
@item --trace-count-summary-file @var{basename}
@findex --trace-count-summary-file (runtime option)
Documented alongside the @samp{--trace-count} option.
@sp 1
@item --trace-count-summary-max @var{N}
@findex --trace-count-summary-max (runtime option)
If @env{MERCURY_OPTIONS} includes both
the @samp{--trace-count option}
(or one of the other options that imply @samp{--trace-count})
and the @samp{--trace-count-summary-file @var{basename}} option,
then the generated program will put the generated trace counts
either in @var{basename} (if it does not exist),
or in @var{basename.N} for the lowest value of the integer @var{N}
which doesn't overwrite an existing file.
The @samp{--trace-count-summary-max} option specifies the maximum value of this
@var{N}.
When this maximum is reached,
the program will invoke the @samp{mtc_union} program
to summarize @var{basename}, @var{basename.1}, @dots{} @var{basename.N}
into a single file @var{basename}, and delete the rest.
By imposing a limit on the total number (and hence indirectly on the total
size) of these trace count files, this mechanism allows the gathering of trace
count information from a large number of program runs.
The default maximum value of @var{N} is 20.
@c @sp 1
@c @item --trace-count-summary-cmd=@var{cmd}
@c @findex --trace-count-summary-cmd=@var{cmd}
@c This option specifies the command to use instead of mtc_union
@c for computing trace counts summaries, as shown for the above option.
@c This documentation is commented out
@c because the option is for implementors only.
@c The intended use is to override the installed version of mtc_union
@c with the version in a specific workspace, which may be more recent.
@c @sp 1
@c @item --deep-procrep-file
@c @findex --deep-procrep-file
@c This option, which is meaningful only in deep profiling grades,
@c asks that every Deep.data file being generated should be accompanied by
@c a Deep.procrep file that contains a representation of the program that
@c generated it.
@c This documentation is commented out
@c because procedure representations are not yet used.
@c @sp 1
@c @item --deep-random-write=@var{N}
@c @findex --deep-random-write=@var{N}
@c This option, which is meaningful only in deep profiling grades,
@c asks that Deep.data files (and Deep.procrep files) should be generated
@c only if by processes whose process id is evenly divisible by @var{N}.
@c This documentation is commented out because it is only for use by the
@c bootcheck script (to reduce the time taken for a bootcheck while still
@c testing the code writing out deep profiling data).
@sp 1
@item --deep-std-name
@findex --deep-std-name
This option, which is meaningful only in deep profiling grades,
asks deep profiling data to be stored
in files named @code{Deep.data} and @code{Deep.procrep}.
The default is that the runtime system puts such data
into files whose names follow the pattern
@code{@var{progname}_on_@var{date}_at_@var{time}.data} and
@code{@var{progname}_on_@var{date}_at_@var{time}.procrep} respectively.
@sp 1
@item --boehm-gc-free-space-divisor @var{N}
@findex --boehm-gc-free-space-divisor (runtime option)
This option sets the value of the free space divisor in the Boehm garbage
collector to @var{N}.
It is meaningful only when using the Boehm garbage collector.
The default value is 3. Increasing its value will reduce
heap space but increase collection time.
See the Boehm GC documentation for details.
@sp 1
@item --boehm-gc-calc-time
@findex --boehm-gc-calc-time (runtime option)
This option enables code in the Boehm garbage collector to calculate
the time spent doing garbage collection so far.
Its only effect is to enable the @samp{report_stats} predicate
in the @samp{benchmarking} module of the standard library
to report this information.
@sp 1
@item --fp-rounding-mode @var{mode}
@findex --fp-rounding-mode (runtime option)
Set the rounding mode for floating point operations to @var{mode}.
Recognised modes are @samp{downward}, @samp{upward}, @samp{to_nearest}
and @samp{toward_zero}. Exactly what modes are available and even
if it is possible to set the rounding mode is system dependent.
@end table
@end table
@c ----------------------------------------------------------------------------
@node Diagnostic output
@chapter Diagnostic output
@cindex Diagnostic output
Mercury's strong type-, mode-, and determinism systems
impose strict requirements on Mercury programs.
These systems allow the compiler to guarantee
that it will catch many of the most frequent kinds of errors
that programmers tend to make.
This improves not just program reliability,
but also programmer productivity,
since finding and fixing a bug is much easier
if the compiler hands you the location
of at least one part of the program involved in the error
on a silver platter.
However, it also means that a Mercury programmer
will typically have to see and act upon
more error and warning messages (diagnostics)
than programmers who write code in less strict languages.
This is why the compiler tries hard
to make each diagnostic as usable, informative and clear as it can.
@menu
* Verbose vs nonverbose messages:: Controlling whether explanations
are printed.
* Ordering diagnostics:: Focusing on errors in one part of a module.
* Color schemes:: Specifying what colors to use
in diagnostics.
* Enabling the use of color:: Specifying whether to use colors
in diagnostics.
@end menu
@node Verbose vs nonverbose messages
@section Verbose vs nonverbose messages
@cindex Verbosity
@cindex Verbose diagnostics
Making a diagnostic sufficiently informative for programmers new to Mercury
does in some cases require including a significant amount of explanation.
On the other hand, such explanations are not needed by programmers
who are already familiar with the issues involved,
and indeed for them, such explanations are usually nothing more than clutter.
This is why the Mercury compiler splits such error messages into two parts.
The first part just reports the facts specific to the error being reported.
The second part,
which is intended specifically to help programmers new to Mercury,
is a generic explanation of the background needed to understand the first part.
The first part is always printed,
while the second part is printed
only if the programmer asks for verbose error messages.
This can be done using the @samp{--verbose-error-messages} compiler option.
which can be abbreviated to just @samp{-E}.
If a compiler invocation prints any diagnostics that have a verbose component
that is not printed because the user has not asked for it,
the compiler will print the reminder about this fact:
@samp{For more information, recompile with `-E'.}
@node Ordering diagnostics
@section Ordering diagnostics
@cindex Ordering diagnostics
Normally, the compiler prints all the diagnostics for a module together,
in ascending order of context.
(With the exception of Mercury modules whose source files
use the @samp{source_file} pragma and/or the @samp{#@var{line}} directive,
this means that messages for lower numbered lines are printed
before messages for higher numbered lines.)
Sometimes, the output will @emph{look} unsorted
without actually @emph{being} unsorted.
This can happen because some diagnostics
report an inconsistency between two or more parts of the program.
Such diagnostics will contain one component for each such part,
and each component's text about that part
will have before it the context (filename and line number) of that part.
The sorting of diagnostics operates on
just the first context in each diagnostic;
any later contexts are ignored.
However, there are some situations in which
the compiler does indeed intentionally deviate from the above default.
One such situation occurs when
the programmer specifies the @samp{-v} option,
which asks for verbose compiler output.
In such cases, the compiler will print progress messages that specify
which phase of compilation the compiler is about to start,
and if that phase can find errors in the program,
it will print the diagnostics for the errors it finds
@emph{before} it goes on to the next phase.
The programmer can ask for the usual ordering of diagnostics
to be reversed by giving the @samp{--reverse-error-order} option.
This options makes things easier for programmers
when they want to work on the last errors in a file first.
This can be a good idea for example
if the module you are working on (e.g. by rearranging a data structure)
has its primitive operations towards the end of the module,
and you think the fixes needed to these primitives
will require changes to their signatures.
In such cases, fixing the lowest level primitives first
allows you to fix the originally reported errors for higher level operations
at the same time as you update their calls to the lower level primitives,
and reversing the order of the diagnostics
allows you to get to those errors for the tail end of the file
without having to wade through the errors for the code above.
The compiler also supports a more general mechanism
for allowing programmers to focus on fixing errors
in a particular part of the program first.
This mechanism is the @samp{--limit-error-contexts} compiler option.
This option has as its argument a comma-separated list of line number ranges.
It tells the compiler to print only diagnostics
that contain one or more contexts that fall into one of these ranges.
(A printed diagnostic
may contain some contexts that fall outside all these ranges,
as long as it has at least one context that falls inside.)
@c Actually it may have all its contexts fall outside these ranges,
@c as long as one either has a context that falls inside,
@c OR has no context at all.
@c However, I (zs) think that all the error_specs we generate
@c that contain more one component
@c *do* specify a context for every component,
@c so this distinction should not matter for users.
If a compiler invocation has this option specified
but all the diagnostics it would print in its absence
are held back by this option,
it will print a reminder about this fact.
@node Color schemes
@section Color schemes
@cindex Color schemes
The compiler tries to make diagnostics usable more quickly
by using color to direct people's attention
to the most relevant parts of diagnostics.
The compiler uses colors for the following five purposes.
We must explain these first,
before we can explain @emph{color schemes},
which are simple mappings from purposes (which we also call color @emph{roles})
to actual shades of color.
@table @asis
@item @samp{subject}
The compiler uses the @samp{subject} color
for the entity that the diagnostic is about.
Examples of such entities include
a specific variable, a specific type, or a specific predicate.
@item @samp{incorrect}
The compiler uses the @samp{incorrect} color
to emphasize either
@emph{the description} of what is wrong with the subject entity,
or @emph{the property} of the subject entity that is wrong.
@item @samp{correct}
The compiler uses the @samp{correct} color
to emphasize the expected property of the subject entity,
where that differs from its actual property.
For example, when a call passes an argument of the wrong type,
it will show the argument's actual type using the @samp{incorrect} color,
and the expected type using the @samp{correct} color.
It does this because the type is far more likely to be wrong in the call
than in the declaration of the called predicate or function.
(Of course, situations do sometimes occur
in which it is the type in the declaration that is wrong.)
@item @samp{inconsistent}
The compiler uses the @samp{inconsistent} color
when it knows that two parts of the code are inconsistent with each other,
but neither part is a priori more likely to be wrong than the other.
For example, when unifying two values of different types,
the compiler uses this color when printing the type of both values;
the compiler knows that in all likelyhood,
one type is correct and one is incorrect,
but it does not know which is which.
@item @samp{hint}
The compiler uses the @samp{hint} color when it reports observations
that may or may not explain the root of the problem it reports,
but which are worth looking into.
For example, when it reports that two actual arguments of a call
have types that do not match the types of the corresponding arguments
in the declaration of the callee,
it may give a hint that each of those actual arguments
do in fact each match the type of an argument in the callee,
just not the ones in the right positions,
implying that the actual problem may be
passing the right arguments in the wrong order.
@end table
Programmers can specify the colors
they want the compiler to use for each purpose
either by setting the environment variable @samp{MERCURY_COLOR_SCHEME}
to a string (let's call it @var{ColorScheme}),
or by specifying the compiler option @samp{--color-scheme @var{ColorScheme}}.
In both cases, @var{ColorScheme} can be either
@itemize
@item
the name of a color scheme built into the Mercury compiler, or
@item
the assignment of specific colors
for the roles that colors can play in its diagnostics.
@end itemize
The compiler currently has the following six builtin color schemes:
@itemize
@item @samp{darkmode}
@item @samp{darkmode256}
@item @samp{darkmode16}
@item @samp{lightmode}
@item @samp{lightmode256}
@item @samp{lightmode16}
@end itemize
The ``mode'' in each name is optional,
meaning that e.g. @samp{dark} names the same color scheme as @samp{darkmode}.
The schemes whose names contain ``dark''
are intended to be used on terminal screens with dark backgrounds
(including black backgrounds).
The schemes whose names contain ``light''
are intended to be used on terminal screens with light backgrounds
(including white backgrounds).
@itemize
@item
The schemes ending without numbers use 24-bit RGB colors,
which your terminal or terminal emulator @emph{probably} supports.
@item
The schemes ending in ``256'' use
the colors listed in the 8-bit color section under
@samp{https://en.wikipedia.org/wiki/ANSI_escape_code#Colors},
which your terminal or terminal emulator
is @emph{virtually certain} to support.
@item
The schemes ending in ``16'' use
the first 16 color slots listed in that 8-bit color table.
These 16 color slots differ from the other 240 colors in that table
in that most terminal emulators allow users
to select the actual colors that go into those slots.
This means that output that uses color schemes ending in ``16''
may look different on terminals with different color palette settings,
and will match the intended look only with the default color palette.
(The builtin color schemes ending in ``256''
avoid using these reassignable color slots.)
@end itemize
The other way to specify a color scheme
is to directly specify the colors you want the compiler to use
using a string such as
@samp{specified@@subject=87:correct=40:incorrect=203:inconsistent=171:hint=226}.
The rules for this form of color scheme specification are as follows.
@itemize
@item
The string must start with the string @samp{specified@@}.
@item
The rest of the string must not contain any white space,
but must consist of a colon-separated list
of one or more color assignments.
@item
Each color assignment must have the form @samp{@var{Role}=@var{Color}},
which assigns the given color to the given role.
@item
Each @var{Role} must be one of the five strings
@samp{subject},
@samp{correct},
@samp{incorrect},
@samp{inconsistent}, and
@samp{hint}.
@item
Each @var{Color} must have of the following two forms.
@itemize
@item
The first form is a decimal integer in the range 0 to 255 (both inclusive).
This selects a slot in the table in the 8-bit color section of
@samp{https://en.wikipedia.org/wiki/ANSI_escape_code#Colors}.
The caveat mentioned above about colors 0 to 15 apply here as well:
in most terminal emulators, these slots are reassignable,
so specifying one of these slots may @emph{or may not}
get you to the color in that slot in that table.
The other 240 slots are not usually reassignable.
@item
The second form is a seven-character string
where the first character is @samp{#},
and each of the following six characters is a hexadecimal digit.
Each string @samp{#RRGGBB} specifies a 24-bit RGB color,
with @samp{RR} specifying its red component,
@samp{GG} specifying its green component, and
@samp{BB} specifying its blue component.
@c XXX We also support a third alternative, named colors,
@c but these actually name color SLOTS only:
@c The color can be specified either by name or by number.
@c The name can be one of the first sixteen colors in that table, which are
@c @samp{black}, @samp{red}, @samp{green}, @samp{yellow},
@c @samp{blue}, @samp{magenta}, @samp{cyan}, @samp{white},
@c @samp{bright-black}, @samp{bright-red},
@c @samp{bright-green}, @samp{bright-yellow},
@c @samp{bright-blue}, @samp{bright-magenta},
@c @samp{bright-cyan}, and @samp{bright-white}.
@c The hyphens in names can be replaced with spaces, but the
@c resulting names will need to be quoted on the command line.
@end itemize
@item
If the color scheme has no color assignment for a given role,
then the compiler will not use color for that role.
@item
If the color scheme has two or more color assignments for the same role,
only the last one counts; the others are ignored.
@end itemize
As mentioned above,
programmers can specify color schemes
using the environment variable @samp{MERCURY_COLOR_SCHEME}
and by using the @samp{--color-scheme} compiler option.
These can specify different schemes.
The rules the compiler uses to choose the color scheme that it will use
are as follows.
@enumerate
@item
If the command line contains a @samp{--color-scheme} option,
the compiler will use its color scheme.
(If the command line contains more than one @samp{--color-scheme} option,
the compiler will use the last one.)
@item
If the command line contains no @samp{--color-scheme} option,
but the environment variable @samp{MERCURY_COLOR_SCHEME} exists
and contains a nonempty string,
then the compiler will use its color scheme.
@item
If the command line contains no @samp{--color-scheme} option,
and the environment variable @samp{MERCURY_COLOR_SCHEME} does not exist
or contains an empty string,
but the files named in any @samp{--options-file} compiler options
(or, in the absence of such options, the @samp{Mercury.options} file),
include a @samp{--color-scheme} option
among the module-specific @samp{MCFLAGS} for the current module,
then the compiler will use its color scheme.
(If the options file(s) contain more than one @samp{--color-scheme} option,
the compiler will use the last one.)
@item
In the absence of a @samp{--color-scheme} option
on the command line, in the @samp{MERCURY_COLOR_SCHEME} environment variable
@emph{and} in the options files,
the compiler will use its default color scheme, which is @samp{light16}.
This scheme works reasonably well even on dark backgrounds,
even though (as its name indicates) it was designed for light backgrounds.
(This assumes that the color slots it uses hold
either their standard colors, or something reasonably close to them.)
@end enumerate
@node Enabling the use of color
@section Enabling the use of color
@cindex Enabling the use of color
The Mercury compiler uses two separate mechanisms
@itemize
@item
to specify what colors to use for each role,
@emph{if} the use of color in diagnostics is enabled, and
@item
to decide whether the use of color in diagnostics is enabled.
@end itemize
This arrangement allow programmers to turn off the use of color temporarily
without having to specify the color scheme again in full
when they want to turn it back on again.
As with color schemes,
programmers can control whether color is enabled in diagnostics
using either a compiler option, or by using environment variables.
The compiler option is a boolean option,
which, like other boolean options, has two forms:
a positive form @samp{--color-diagnostics}, which enables the use of color,
and a negative form @samp{--no-color-diagnostics}, which disables its use.
There are two environment variables
that the Mercury compiler consults in its decision:
@samp{MERCURY_ENABLE_COLOR}, and @samp{NO_COLOR}.
As their names show, the first is specific to Mercury,
while the second is not.
It is in fact a defacto standard for disabling color;
see @samp{https://no-color.org}.
The rules the compiler uses to decide
whether the use of color in diagnostics is enabled
are as follows.
@enumerate
@item
If the command line contains a @samp{--color-diagnostics} option,
in either its positive or negative form,
then the compiler will obey it.
@item
If the command line contains no @samp{--color-diagnostics} option,
but the environment variable @samp{MERCURY_ENABLE_COLOR} exists
and contains either @samp{never} or @samp{always},
then the compiler will obey it.
The compiler also allows @samp{0} as a synonym for @samp{never},
and @samp{1} as a synonym for @samp{always}.
@item
If the command line contains no @samp{--color-diagnostics} option,
and the environment variable @samp{MERCURY_ENABLE_COLOR}
either does not exist, or contains a string other than the four listed above,
but the environment variable @samp{NO_COLOR} exists
and contains a nonempty string,
then the compiler will obey it by disabling the use of color.
@item
If the command line contains no @samp{--color-diagnostics} option
and neither environment variable has a value
that directs the compiler to obey it,
but the files named in any @samp{--options-file} compiler options,
(or, in the absence of such options, the @samp{Mercury.options} file),
include a @samp{--color-diagnostics} option,
in either its positive or negative form,
among the module-specific @samp{MCFLAGS} for the current module,
then the compiler will obey it.
@item
If the preconditions of all four of the above rules are false,
i.e. none of them decide the outcome,
then the compiler will fall back to its default.
The usual default decision is to enable the use of color,
though this can be overridden for a given installation of Mercury.
@end enumerate
@c ----------------------------------------------------------------------------
@node C compilers
@chapter Using a different C compiler
@cindex C compilers
@cindex Using a different C compiler
@cindex GNU C
@findex --cc
The Mercury compiler takes special advantage of certain extensions
provided by GNU C to generate much more efficient code. We therefore
recommend that you use GNU C for compiling Mercury programs.
However, if for some reason you wish to use another compiler,
it is possible to do so. Here is what you need to do.
@itemize @bullet
@item Create a new configuration for the Mercury system using the
@samp{mercury_config} script, specifying the different C compiler, e.g.@:
@samp{mercury_config --output-prefix=/usr/local/mercury-cc --with-cc=cc}.
@item Add the @samp{bin} directory of the new configuration to the beginning
of your PATH.
@item
You must use a grade beginning with @samp{none} or @samp{hlc}
(e.g.@: @samp{hlc.gc}).
You can specify the grade in one of three ways: by setting the
@env{MERCURY_DEFAULT_GRADE} environment variable, by adding a line
@vindex MERCURY_DEFAULT_GRADE
@samp{GRADE=@dots{}} to your @samp{Mmake} file, or by using the
@samp{--grade} option to @samp{mmc}. (You will also need to install
those grades of the Mercury library, if you have not already done so.)
@item
If your compiler is particularly strict in
enforcing ANSI compliance, you may also need to compile the Mercury
code with @samp{--no-static-ground-terms}.
@end itemize
@c ----------------------------------------------------------------------------
@node Foreign language interface
@chapter Foreign language interface
The Mercury allows the code of a procedure
to be specified in a target language
using a @code{pragma foreign_proc} declaration.
A procedure may have more than one @code{pragma foreign_proc} declarations,
provided they are in different languages.
A procedure that has some @code{pragma foreign_proc} declarations
may also have a Mercury definition.
@c NOTE This rule has not been relevant for years, as of 2025.
@c If the compiler generates code for a procedure
@c using a backend for which there are multiple applicable foreign languages,
@c it will choose the foreign language to use for each procedure
@c according to a builtin ordering.
If the language specified in a @samp{foreign_proc}
is not available for the selected backend,
it will be ignored,
and the implementation will use the procedure's Mercury definition.
If there isn't one, the compiler will generate an error.
@table @asis
@item @samp{C}
This is the only foreign language
whose @code{pragma foreign_proc}s are used when targeting C.
@item @samp{C#}
This is the only foreign language
whose @code{pragma foreign_proc}s are used when targeting C#.
@item @samp{Java}
This is the only foreign language
when whose @code{pragma foreign_proc}s are used targeting Java.
@end table
@c ----------------------------------------------------------------------------
@node Stand-alone interfaces
@chapter Stand-alone interfaces
Programs written in a language other than Mercury
should not make calls to foreign exported Mercury procedures
unless the Mercury runtime has been initialised.
(In the case where the Mercury runtime has not been initialised,
the behaviour of these calls is undefined.)
Such programs must also ensure that
any module specific initialisation is performed
before calling foreign exported procedures in Mercury modules.
Likewise, module specific finalisation may need to be performed
after all calls to Mercury procedures have been made.
A stand-alone interface provides a mechanism by which
non-Mercury programs may initialise (and shut down)
the Mercury runtime plus a specified set of Mercury libraries.
You can create a stand-alone interface by invoking the compiler
with the @samp{--generate-standalone-interface} option.
The set of Mercury libraries to be included in the stand-alone interface
is given via one of the usual mechanisms
for specifying what libraries to link against,
e.g. the @samp{--ml} and @samp{--mld} options. (@pxref{Libraries}).
The Mercury standard library is always included in this set.
In C grades,
the @samp{--generate-standalone-interface} option
causes the compiler to generate
an object file that should be linked into the executable.
This object file contains two functions:
@code{mercury_init()} and @code{mercury_terminate()}.
The compiler also generates a C header file
that contains the prototypes of these functions.
(This header file may be included in C++ programs.)
The roles of the two functions are described below.
@table @b
@item @bullet{} @code{mercury_init()}
Prototype:
@example
void mercury_init(int @var{argc}, char **@var{argv}, void *@var{stackbottom});
@end example
Initialise the Mercury runtime, standard library,
and any other Mercury libraries that were specified
when the stand-alone interface was generated.
@var{argc} and @var{argv} are the argument count and argument vector,
as would be passed to the function @code{main()} in a C program.
@var{stackbottom} is the address of the base of the stack.
In grades that use conservative garbage collection,
this is used to tell the collector where to begin tracing.
This function must be called before any Mercury procedures,
and must only be called once.
It is recommended that the value of @var{stackbottom} be set
by passing the address of a local variable
in the @code{main()} function of a program,
like this:
@example
int main(int argc, char **argv) @{
void *dummy;
mercury_init(argc, argv, &dummy);
@dots{}
@}
@end example
Note that the address of the stack base should be word aligned,
as some garbage collectors rely upon this.
(This is why the type of the dummy variable in the above example
is @code{void *}.)
If the value of @var{stackbottom} is @code{NULL},
then the collector will itself attempt to determine
the address of the base of the stack.
Note that modifying the argument vector, @var{argv},
after the Mercury runtime has been initialised
will result in undefined behaviour,
since the runtime maintains a reference into @var{argv}.
@sp 1
@item @bullet{} @code{mercury_terminate()}
Prototype:
@example
int mercury_terminate(void);
@end example
Shut down the Mercury runtime.
The value returned by this function is Mercury's exit status
(as set by the predicate @samp{io.set_exit_status/3}).
This function will also invoke any finalisers
contained in the set of libraries
for which the stand-alone interface was generated.
@end table
The basename of the object and header file are provided
as the argument of @samp{--generate-standalone-interface} option.
@c XXX Mention that stand-alone interfaces work with debugging or
@c (deep) profiling?
Stand-alone interfaces are not required if the target language is Java or C#.
For those target languages,
the Mercury runtime will be automatically initialised
when the classes or library assemblies
containing code generated by the Mercury compiler are loaded.
For an example of using a stand-alone interface, see the
@samp{samples/c_interface/standalone_c} directory in the Mercury distribution.
@c ----------------------------------------------------------------------------
@page
@node Index
@unnumbered Index
@printindex cp
@c ----------------------------------------------------------------------------
@bye