The Mercury User's Guide

Copyright (C) 1995 University of Melbourne.

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.

Introduction

This document describes the compilation environment of Mercury. It describes how to use `mc', the Mercury compiler; how to use `mmake', the "Mercury make" program, a tool built on top of ordinary or GNU make to simplify the handling of Mercury programs; and how to use Prolog to debug Mercury programs.

We strongly recommend that programmers use `mmake' rather than invoking `mc' directly, because `mmake' is generally easier to use and avoids unnecessary recompilation.

Mercury is a compiled language like C or Pascal, not an interpreted one like Prolog or Lisp. Therefore the debugging of Mercury programs requires a dedicated Mercury debugger program, since there is no interpreter to serve in its place. Until the Mercury debugger is complete, Mercury programmers may wish to use a Prolog system to execute their Mercury programs in order to gain access to this facility. The feasibility of this technique is dependent upon the program being written in the intersection of the Prolog and Mercury languages, which is possible because the two languages have almost the same syntax. The Mercury implementation allows you to run a Mercury program using NU-Prolog or SICStus Prolog (see section Using Prolog).

File naming conventions

Mercury source files should be named `*.m'. Each Mercury source file must contain a single Mercury module whose name should be the same as the filename without the `.m' extension.

Files ending in `.int' and `.int2' are interface files; these are generated automatically by the compiler, using the `--make-interface' option. (The `.int' files are for direct dependencies, while the `.int2' files are a shorter version used for indirect dependencies.)

Since the interface of a module changes less often than its implementation, the `.int' and `.int2' files will remain unchanged on many compilations. To avoid unnecessary recompilations of the clients of the module, the timestamps on the `.int' and `.int2' files are updated only if their contents change. A `.date' file associated with the module is used as a date stamp; it is used when deciding whether the interface files need to be regenerated.

Files ending in `.d' are automatically-generated Makefile fragments which contain the dependencies for a module. Files ending in `.dep' are automatically-generated Makefile fragments which contain the rules for an entire program.

In the source code for the Mercury runtime library, we use a few files ending in `.mod'; these are preprocessed using the perl script `mod2c' to produce C files. Originally the Mercury compiler also produced `.mod' files, but now we compile directly to C.

As usual, `.c' files are C source code, `.o' files are object code, `.no' files are NU-Prolog object code, and `.ql' files are SICStus Prolog object code.

Using the Mercury compiler

Following a long Unix tradition, the Mercury compiler is called `mc'. Some of its options (e.g. `-c', `-o', and `-I') have a similar meaning to that in other Unix compilers.

Arguments to `mc' that name Mercury source files may omit the `.m' suffix.

To compile a program which consists of just a single module, use the command

mc module.m

Unlike traditional Unix compilers, however, `mc' will put the executable into a file called `module', not `a.out'.

To compile a module to object code without creating an executable, use the command

mc -c module.m

`mc' will put the object code into a file called `module.o'. It also will leave the intermediate C code in a file called `module.c'.

Before you can compile a module, you must make the interface files for the modules that it imports (directly or indirectly). You can create the interface files for one or more modules using the command

mc -i module1.m module2.m ...

Given that 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

mc module1.m module2.m ...

This will by default put the resulting executable in `module1', but you can use the `-o filename' option to specify a different name for the output file, if you so desire.

The other way to create an executable for a multi-module program is to compile each module separately using `mc -c', and then link the resulting object files together. The linking is a two stage process.

First, you must create and compile an 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:

c2init module1.c module2.c ... > main_module_init.c,
mgnuc -c main_module_init.c

The `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 `mgnuc' command is the Mercury GNU C compiler; it is a shell script that invokes the GNU C compiler (or some other C compiler if GNU C is not available) with the options appropriate for compiling the C programs generated by Mercury.

You then link the object code of each module with the object code of the initialization file to yield the executable:

ml -o main_module module1.o module2.o ... main_module2_init.o

`ml', the Mercury linker, is another shell script that invokes a C compiler with options appropriate for Mercury, this time for linking. `ml' also pipes any error messages from the linker through `mdemangle', the Mercury symbol demangler, so that error messages refer to predicate names in the Mercury source code rather than to the names used in the intermediate C code.

The above command puts the executable in the file `main_module'. The same command line without the `-o' option would put the executable into the file `a.out'.

`mc' and `ml' both accept a `-v' (verbose) option. You can use that option to see what is actually going on. For the full set of options of `mc', see section Invocation.

Once you have created an executable for a Mercury program, the scheme for invoking it is

./executable runtime-options -- arguments

The `--' separates the options to the Mercury runtime from the options to your program. Invoking the program with `-h' will list the available runtime-options. The most useful of these are the options that set the size of the stacks.

The det stack and the nondet stack are allocated fixed sizes at program start-up. The default size is 512k for the det stack and 128k for the nondet stack, but these can be overridden with the `-sd' and `-sn' options, 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.

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 40 Mb, but this can be overridden with the `-sh' option.

Using Prolog

Since the current Mercury implementation does not yet provide any useful support for debugging, we recommend that you use a Prolog system for debugging your Mercury programs. However, there is no point in using a Prolog debugger to track down a bug that can be detected statically by the Mercury compiler. The command

mc -e module1.m ...

causes the Mercury compiler to perform all its syntactic and semantic checks on the named modules, but not to generate any code.

In our experience, omitting that step is not wise. If you do omit it, you often waste a lot of time debugging problems that the compiler could have detected for you.

Using NU-Prolog

You can compile a Mercury source module using NU-Prolog via the command

mnc module1.m ...

`mnc' is the Mercury variant of `nc', the NU-Prolog compiler. It adapts nc to compile Mercury programs, e.g. by defining do-nothing predicates for the various Mercury declarations (which are executed by nc).

Some invocations of `mnc' will result in warnings such as

Warning: main is a system predicate.
It shouldn't be used as a non-terminal.

Such warnings should be ignored.

`mnc' compiles the modules it is given into NU-Prolog bytecode, stored in files with a `.no' suffix. You can link these together using the command

mnl -o main_module module1.no ...

Ignore any warnings such as

Warning: main/2 redefined
Warning: solutions/2 redefined
Warning: !/0 redefined

`mnl', the Mercury NU-Prolog linker, will put the executable (actually a shell script invoking a save file) into the file `main_module.nu'. This can be executed normally using

./main_module.nu arguments

Alternatively, one can execute such programs using `mnp', the Mercury version of np, the NU-Prolog interpreter. The command

mnp

will start up the Mercury NU-Prolog interpreter. Inside the interpreter, you can load your source files with a normal consulting command such as

['module.m'].

You can also use the `--debug' option to `mnl' when linking. This will produce an executable whose entry point is the NU-Prolog interpreter, rather than main/2 in your program.

In both cases, you can start executing your program by typing

r("program-name arguments").

at the prompt of the NU-Prolog interpreter.

All the NU-Prolog debugging commands work as usual. The most useful ones are the trace and spy commands at the main prompt to turn on complete or selective tracing respectively, and the l (leap), s (skip), and r (redo) commands of the tracer. For more information, see the NU-Prolog documentation.

By default the debugger only displays the top levels of terms; you can use the `|' command to enter an interactive term browser. (Within the term browser, type `h.' for help.)

Using SICStus Prolog

Using SICStus Prolog is similar to using NU-Prolog, except that the commands to use are `msc', `msl', and `msp' rather than `mnc', `mnl', and `mnp'.

Due to shortcomings in SICStus Prolog (in particular, the lack of backslash escapes in character strings), you need to use `sicstus_conv' to convert Mercury `.m' files to the `.pl' files that SICStus Prolog expects before you can load them into the interpreter. The command to use is just

sicstus_conv module.m

Hazards of using Prolog

There are some Mercury programs which are not valid Prolog programs. In particular, Mercury will always reorder goals to ensure that they are mode-correct (or report a mode error if it cannot do so), but Prolog systems will not always do so, and will sometimes just silently give the wrong result. For example, in Mercury the following predicate will usually succeed, whereas in Prolog it will always fail.

:- pred p(list(int)::in, list(int)::out) is semidet.
p(L0, L) :-
        L \= [],
        q(L0, L).

:- pred q(list(int)::in, list(int)::out) is det.

The reason is that in Mercury, the test `L \= []' is reordered to after the call to q/2, but in Prolog, it executes even though L is not bound, and consequently the test always fails.

NU-Prolog has logical alternatives to the non-logical Prolog operations, and since Mercury supports both syntaxes, you can use NU-Prolog's logical alternatives to avoid this problem. However, during the development of the Mercury compiler we had to abandon their use for efficiency reasons.

Another hazard is that NU-Prolog does not have a garbage collector.

Using Mmake

Mmake, short for "Mercury Make", is a tool for building Mercury programs that is built on top of ordinary or GNU Make (1). With Mmake, building even a complicated Mercury program consisting of a number of modules is as simple as

mmake main-module.depend
mmake main-module

Mmake only recompiles those files that need to be recompiled, based on automatically generated dependency information. Most of the dependencies are stored in `.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 `.dep' files which are more expensive to recompute. The `mmake main-module.depend' command which recreates the `main-module.dep' file needs to be repeated only when you add or remove a module from your program, and there is no danger of getting an inconsistent executable if you forget this step -- instead you will get a compile or link error.

`mmake' allows you to build more than one program in the same directory. Each program must have its own `.dep' file, and therefore you must run `mmake program.depend' for each program.

If there is a file called `Mmake' in the current directory, Mmake will include that file in its automatically-generated Makefile. The `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 `prefix/lib/mercury/mmake/Mmake.rules' (where prefix is `/usr/local' by default) as well as the rules in the automatically-generated `.dep' files. These rules define the following targets:

`main-module.depend'
Creates the file `main-module.dep' from `main-module.m' and the modules it imports. This step must be performed first.
`main-module.ints'
Ensure that the interface files for main-module and its imported modules are up-to-date. (If the underlying `make' program does not handle transitive dependencies, this step may be necessary before attempting to make `main-module' or `main-module.check'; if the underlying `make' is GNU Make, this step should not be necessary.)
`main-module.check'
Perform semantic checking on main-module and its imported modules. Error messages are placed in `.err' files.
`main-module'
Compiles and links main-module using the Mercury compiler. Error messages are placed in `.err2' files.
`main-module.nu'
Compiles and links main-module using NU-Prolog.
`main-module.nu.debug'
Compiles and links main-module using NU-Prolog. The resulting executable will start up in the NU-Prolog interpreter rather than calling main/2.
`main-module.sicstus'
Compiles and links main-module using SICStus Prolog.
`main-module.sicstus.debug'
Compiles and links main-module using SICStus Prolog. The resulting executable will start up in the SICStus Prolog interpreter rather than calling main/2.
`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 `.c', `.s', `.o', `.no', `.ql', `.err', and `.err' files belonging to the named main-module or its imported modules.
`main-module.realclean'
Removes all the automatically generated files. In addition to the files removed by main-module.clean, this removes the `.date', `.int', `.int2', `.d', and `.dep' belonging to one of the modules of the program, and also the various possible executables for the program --- `main-module', `main-module.nu', `main-module.nu.save', `main-module.nu.debug', `main-module.nu.debug.save', `main-module.sicstus', and `main-module.sicstus.debug'.
`clean'
This makes `main-module.clean' for every main-module for which there is a `main-module.dep' file in the current directory.
`realclean'
This makes `main-module.realclean' for every main-module for which there is a `main-module.dep' file in the current directory.

The variables used by the builtin rules are defined in `prefix/lib/mercury/mmake/Mmake.vars'.

Invocation

This section contains a brief description of all the options available for `mc', the Mercury compiler. Sometimes this list is a little out-of-date; use `mc --help' to get the most up-to-date list.

Invocation overview

mc is invoked as

mc [options] modules

For module names, the trailing `.m' is optional.

Options are either short (single-letter) options preceded by a single `-', or long options preceded by `--'. Options are case-sensitive. We call options that do not take arguments flags. Single-letter flags may be grouped with a single `-', e.g. `-vVc'. Single-letter flags may be negated by appending another trailing `-', e.g. `-v-'. Long flags may be negated by preceding them with `no-', e.g. `--no-verbose'.

Warning options

-w
--inhibit-warnings
Disable all warning messages.

--no-warn-singleton-variables
Don't warn about variables which only occur once.

--no-warn-missing-det-decls
For predicate that are local to a module (those that are not exported), don't issue a warning if the `pred' or `mode' declaration does not have a determinism annotation. Use this option if you want the compiler to perform automatic determinism inference for non-exported predicates.

--no-warn-det-decls-too-lax
Don't warn about determinism declarations which could have been stricter.

Verbosity options

-v
--verbose
Output progress messages at each stage in the compilation.

-V
--very_verbose
Output very verbose progress messages.

-E
--verbose-error-messages
Explain error messages. Asks the compiler to give you a more detailed explanation of any errors it finds in your program.

-S
--statistics
Output messages about the compiler's time/space usage. At the moment this option implies `--no-trad-passes', so you get information at the boundaries between phases of the compiler.

-T
--debug-types
Output detailed debugging traces of the type checking.

-N
--debug-modes
Output detailed debugging traces of the mode checking.

--vndebug <n>
Output detailed debugging traces of the value numbering optimization pass. The different bits in the number argument of this option control the printing of different types of tracing messages.

Output options

These options are mutually exclusive. If more than one of these options is specified, only the first in this list will apply. If none of these options are specified, the default action is to compile and link the modules named on the command line to produce an executable.

-M
--generate-dependencies
Output `Make'-style dependencies for the module and all of its dependencies to `module.dep'.

-i
--make-interface
Write the module interface to `module.int'. Also write the short interface to `module.int2'.

-G
--convert-to-goedel
Convert the Mercury code to Goedel. Output to file `module.loc'. The translation is not perfect; some Mercury constructs cannot be easily translated into Goedel.

-P
--pretty-print
--convert-to-mercury
Convert to Mercury. Output to file `module.ugly'. This option acts as a Mercury ugly-printer. (It would be a pretty-printer, except that comments are stripped and nested if-then-elses are indented too much -- so the result is rather ugly.)

--typecheck-only
Just check the syntax and type-correctness of the code. Don't invoke the mode analysis and later passes of the compiler. When converting Prolog code to Mercury, it can sometimes be useful to get the types right first and worry about modes second; this option supports that approach.

-e
--errorcheck-only
Check the module for errors, but do not generate any code.

-C
--compile-to-c
--compile-to-C
Generate C code in `module.c', but not object code.

-c
--compile-only
Generate C code in `module.c' and object code in `module.o' but do not attempt to link the named modules.

Auxiliary output options

--auto-comments
Output comments in the `module.c' file. This is primarily useful for trying to understand how the generated C code relates to the source code, e.g. in order to debug the compiler.

-l
--line-numbers
Output source line numbers in the generated code. Only works with the -G and -M options.

--show-dependency-graph
Write out the dependency graph to module.dependency_graph.

-d stage
--dump-hlds stage
Dump the HLDS (intermediate representation) after the specified stage number or stage name to `module.hlds_dump.num-name'. Stage numbers range from 0 to 17. Multiple dump options accumulate.

-D
--verbose-dump-hlds
With `--dump-hlds', dumps some additional info.

Code generation options

--no-trad-passes
Generate code by phases, not by predicates.

-s grade
--grade grade
Select the compilation model. This is a convenient way of selecting a setting for the `--c-optimize', `--gc', `--gcc-global-registers', `--gcc-non-local-gotos', `--asm-labels', and `--debug' options simultaneously. The grade should be one of `debug', `none', `reg', `jump', `asm_jump', `fast', or `asm_fast', or one of those with `.gc' appended.

--gc {none, conservative, accurate}
--garbage-collection {none, conservative, accurate}
Specify which method of garbage collection to use (default: `conservative'). `accurate' is not yet implemented.

--no-follow-code
Don't migrate builtin goals into branched goals.

--no-follow-vars
Don't optimize the assignment of registers in branched goals.

--no-reclaim-heap-on-nondet-failure
Don't reclaim heap on backtracking in nondet code.

--no-reclaim-heap-on-semidet-failure
Don't reclaim heap on backtracking in semidet code.

--use-macro-for-redo-fail
Emit the fail or redo macro instead of a branch to the fail or redo code in the runtime system.

--no-gcc-global-registers
Don't use GNU C's global register variables extension.

--no-gcc-non-local-gotos
Don't use GNU C's "labels as values" extension.

--no-asm-labels
Don't use inline assembler labels.

--tags {none, low, high}
Specify whether to use the low bits or the high bits of each word as tag bits (default: low).

--num-tag-bits n
Use n tag bits. This is only used with `--tags high'. With `--tags low', the number of tag bits to use is determined by the auto-configuration script.

--cc compiler-name
Specify which C compiler to use.

--c-include-directory dir
Specify the directory containing the Mercury C header files.

--cflags options
Specify options to be passed to the C compiler.

-o filename
--output-file filename
Specify the name of the final executable. (The default executable name is the same as the name of the first module on the command line, but without the `.m' extension.)

--link-flags options
Specify options to be passed to `ml', the Mercury linker.

--debug
Pass the `-g' flag to the C compiler, instead of `-DSPEED', to enable debugging of the generated C code. This option also implies `--no-c-optimize'. This option is probably not useful to anyone except the Mercury implementors.

Optimization options

--no-optimize
Disable the optimization passes.

--no-optimize-peep
Disable local peephole optimizations.

--no-optimize-jumps
Disable elimination of jumps to jumps.

--no-optimize-fulljumps
Disable elimination of jumps to ordinary code.

--no-optimize-labels
Disable elimination of dead labels and code.

--optimize-value-number
Perform value numbering. Use of this option together with conservative garbage collection requires a collector compiled with `-DALL_INTERIOR_POINTERS'.

--no-optimize-frames
Disable stack frame optimizations.

--optimize-repeat n
Iterate most optimizations at most n times (default: 3).

--optimize-vnrepeat n
Iterate value numbering at most n times (default: 1).

--no-static-ground-terms
Disable the optimization of constructing constant ground terms at compile time and storing them as static constants.

--no-smart-indexing
Generate switches as a simple if-then-else chains; disable string hashing and integer table-lookup indexing.

--req-density percentage
The jump table generated for an atomic switch must have at least this percentage of full slots (default: 25).

--dense-switch-size size
The jump table generated for an atomic switch must have at least this many entries (default: 4).

--string-switch-size size
The hash table generated for a string switch must have at least this many entries (default: 8).

--tag-switch-size size
The number of alternatives in a tag switch must be at least this number (default: 8).

--no-middle-rec
Disable the middle recursion optimization.

--no-inlining
Disable the inlining of simple procedures.

--no-common-goal
Disable optimization of common goals. At the moment this optimization detects only common deconstruction unifications. Disabling this optimization reduces the class of predicates that the compiler considers to be deterministic.

--procs-per-c-function n
Don't put the code for more than n Mercury procedures in a single C function. The default value of n is one. Increasing n can produce slightly more efficient code, but makes compilation slower. Setting n to the special value zero has the effect of putting all the procedures in a single function, which produces the most efficient code but tends to severely stress the C compiler.

--no-c-optimize
Don't enable the C compiler's optimizations.

Miscellaneous options

-b builtin
--builtin-module builtin
Use builtin instead of `mercury_builtin' as the module which always gets automatically imported.

-I dir
--search-directory dir
Append dir to the list of directories to be searched for imported modules.

-?
-h
--help
Print a usage message.

Environment Variables

The shell scripts in the Mercury compilation environment will use the following environment variables if they are set. There should be little need to use these, because the default values will generally work fine.

MERCURY_C_INCL_DIR
Directory for the Mercury C header files (`*.h').

MERCURY_INT_DIR
Directory for the Mercury library interface files (`*.int' and `*.int2').

MERCURY_NC_BUILTIN
Filename of the Mercury `nc'-compatibility file (nc_builtin.nl).

MERCURY_C_LIB_DIR
Base directory containing the Mercury libraries (`libmer.a' and possibly `libmer.so') for each configuration and grade. The libraries for each configuration and grade should be in the subdirectory config/grade of $MERCURY_C_LIB_DIR.

MERCURY_MOD_LIB_DIR
The directory containing the .init files in the Mercury library. They are used to create the initialization file `*_init.c'.

MERCURY_MOD_LIB_MODS
The names of the .init files in the Mercury library.

MERCURY_NU_LIB_DIR
Directory for the NU-Prolog object files (`*.no') for the NU-Prolog Mercury library.

MERCURY_NU_LIB_OBJS
List of the NU-Prolog object files (`*.no') for the Mercury library.

MERCURY_COMPILER
Filename of the Mercury Compiler.

MERCURY_INTERPRETER
Filename of the Mercury Interpreter.

MERCURY_MKINIT
Filename of the program to create the `*_init.c' file.

MERCURY_DEFAULT_GRADE
The default grade to use if no `--grade' option is specified.