<html lang="en">
<head>
<title>The Mercury Language Reference Manual</title>
<meta http-equiv="Content-Type" content="text/html">
<meta name=description content="The Mercury Language Reference Manual">
<meta name=generator content="makeinfo 4.1">
<link href="http://texinfo.org/" rel=generator-home>
</head>
<body>
<h1>The Mercury Language Reference Manual</h1>
This file documents the Mercury programming language, version ws-ceres.
<p>Copyright (C) 1995-2003 The University of Melbourne.
<p>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.
<p>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.
<p>Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
<h2>Table of Contents</h2>
<ul>
<li><a name="toc_Top"></a>
<a href="#Top">The Mercury Language Reference Manual, version ws-ceres</a>
<li><a name="toc_Introduction"></a>
<a href="#Introduction">Introduction</a>
<li><a name="toc_Syntax"></a>
<a href="#Syntax">Syntax</a>
<ul>
<li><a href="#Syntax%20Overview">Syntax overview</a>
<li><a href="#Tokens">Tokens</a>
<li><a href="#Terms">Terms</a>
<li><a href="#Builtin%20Operators">Builtin Operators</a>
<li><a href="#Items">Items</a>
<li><a href="#Declarations">Declarations</a>
<li><a href="#Facts">Facts</a>
<li><a href="#Rules">Rules</a>
<li><a href="#Goals">Goals</a>
<li><a href="#State%20variables">State variables</a>
<li><a href="#DCG-rules">DCG-rules</a>
<li><a href="#DCG-goals">DCG-goals</a>
<li><a href="#Data-terms">Data-terms</a>
<ul>
<li><a href="#Data-functors">Data-functors</a>
<li><a href="#Record%20syntax">Record syntax</a>
<li><a href="#Unification%20expressions">Unification expressions</a>
<li><a href="#Conditional%20expressions">Conditional expressions</a>
<li><a href="#Lambda%20expressions">Lambda expressions</a>
<li><a href="#Higher-order%20function%20applications">Higher-order function applications</a>
<li><a href="#Explicit%20type%20qualification">Explicit type qualification</a>
</ul>
<li><a href="#Variable%20scoping">Variable scoping</a>
<li><a href="#Implicit%20quantification">Implicit quantification</a>
<li><a href="#Elimination%20of%20double%20negation">Elimination of double negation</a>
</ul>
<li><a name="toc_Types"></a>
<a href="#Types">Types</a>
<ul>
<li><a href="#Builtin%20types">Builtin types</a>
<li><a href="#User-defined%20types">User-defined types</a>
<ul>
<li><a href="#Discriminated%20unions">Discriminated unions</a>
<li><a href="#Equivalence%20types">Equivalence types</a>
<li><a href="#Abstract%20types">Abstract types</a>
</ul>
<li><a href="#Predicate%20and%20function%20type%20declarations">Predicate and function type declarations</a>
<li><a href="#Field%20access%20functions">Field access functions</a>
<ul>
<li><a href="#Field%20selection">Field selection</a>
<li><a href="#Field%20update">Field update</a>
<li><a href="#User-supplied%20field%20access%20function%20declarations">User-supplied field access function declarations</a>
<li><a href="#Field%20access%20examples">Field access examples</a>
</ul>
</ul>
<li><a name="toc_Modes"></a>
<a href="#Modes">Modes</a>
<ul>
<li><a href="#Insts%20modes%20and%20mode%20definitions">Insts, modes, and mode definitions</a>
<li><a href="#Predicate%20and%20function%20mode%20declarations">Predicate and function mode declarations</a>
<li><a href="#Constrained%20polymorphic%20modes">Constrained polymorphic modes</a>
<li><a href="#Different%20clauses%20for%20different%20modes">Different clauses for different modes</a>
</ul>
<li><a name="toc_Unique%20modes"></a>
<a href="#Unique%20modes">Unique modes</a>
<ul>
<li><a href="#Destructive%20update">Destructive update</a>
<li><a href="#Backtrackable%20destructive%20update">Backtrackable destructive update</a>
<li><a href="#Limitations%20of%20the%20current%20implementation">Limitations of the current implementation</a>
</ul>
<li><a name="toc_Determinism"></a>
<a href="#Determinism">Determinism</a>
<ul>
<li><a href="#Determinism%20categories">Determinism categories</a>
<li><a href="#Determinism%20checking%20and%20inference">Determinism checking and inference</a>
<li><a href="#Replacing%20compile-time%20checking%20with%20run-time%20checking">Replacing compile-time checking with run-time checking</a>
<li><a href="#Interfacing%20nondeterministic%20code%20with%20the%20real%20world">Interfacing nondeterministic code with the real world</a>
<li><a href="#Committed%20choice%20nondeterminism">Committed choice nondeterminism</a>
</ul>
<li><a name="toc_User-defined%20equality%20and%20comparison"></a>
<a href="#User-defined%20equality%20and%20comparison">User-defined equality and comparison</a>
<li><a name="toc_Higher-order"></a>
<a href="#Higher-order">Higher-order programming</a>
<ul>
<li><a href="#Creating%20higher-order%20terms">Creating higher-order terms</a>
<li><a href="#Calling%20higher-order%20terms">Calling higher-order terms</a>
<li><a href="#Higher-order%20modes">Higher-order modes</a>
</ul>
<li><a name="toc_Modules"></a>
<a href="#Modules">Modules</a>
<ul>
<li><a href="#The%20module%20system">The module system</a>
<li><a href="#An%20example%20module">An example module.</a>
<li><a href="#Sub-modules">Sub-modules</a>
<ul>
<li><a href="#Nested%20sub-modules">Nested sub-modules</a>
<li><a href="#Separate%20sub-modules">Separate sub-modules</a>
<li><a href="#Visibility%20rules">Visibility rules</a>
<li><a href="#Implementation%20bugs%20and%20limitations">Implementation bugs and limitations</a>
</ul>
</ul>
<li><a name="toc_Type%20classes"></a>
<a href="#Type%20classes">Type classes</a>
<ul>
<li><a href="#Typeclass%20declarations">Typeclass declarations</a>
<li><a href="#Instance%20declarations">Instance declarations</a>
<li><a href="#Abstract%20typeclass%20declarations">Abstract typeclass declarations</a>
<li><a href="#Abstract%20instance%20declarations">Abstract instance declarations</a>
<li><a href="#Type%20class%20constraints%20on%20predicates%20and%20functions">Type class constraints on predicates and functions</a>
<li><a href="#Type%20class%20constraints%20on%20type%20class%20declarations">Type class constraints on type class declarations</a>
<li><a href="#Type%20class%20constraints%20on%20instance%20declarations">Type class constraints on instance declarations</a>
</ul>
<li><a name="toc_Existential%20types"></a>
<a href="#Existential%20types">Existential types</a>
<ul>
<li><a href="#Existentially%20typed%20predicates%20and%20functions">Existentially typed predicates and functions</a>
<ul>
<li><a href="#Syntax%20for%20explicit%20type%20quantifiers">Syntax for explicit type quantifiers</a>
<li><a href="#Semantics%20of%20type%20quantifiers">Semantics of type quantifiers</a>
<li><a href="#Examples%20of%20correct%20code%20using%20type%20quantifiers">Examples of correct code using type quantifiers</a>
<li><a href="#Examples%20of%20incorrect%20code%20using%20type%20quantifiers">Examples of incorrect code using type quantifiers</a>
</ul>
<li><a href="#Existential%20class%20constraints">Existential class constraints</a>
<li><a href="#Existentially%20typed%20data%20types">Existentially typed data types</a>
<li><a href="#Some%20idioms%20using%20existentially%20quantified%20types">Some idioms using existentially quantified types</a>
</ul>
<li><a name="toc_Semantics"></a>
<a href="#Semantics">Semantics</a>
<li><a name="toc_Foreign%20language%20interface"></a>
<a href="#Foreign%20language%20interface">Foreign language interface</a>
<ul>
<li><a href="#Calling%20foreign%20code%20from%20Mercury">Calling foreign code from Mercury</a>
<ul>
<li><a href="#pragma%20foreign_proc">pragma foreign_proc</a>
<li><a href="#Foreign%20code%20attributes">Foreign code attributes</a>
</ul>
<li><a href="#Data%20passing%20conventions">Data passing conventions</a>
<ul>
<li><a href="#C%20data%20passing%20conventions">C data passing conventions</a>
<li><a href="#IL%20and%20C%23%20data%20passing%20conventions">IL and C# data passing conventions</a>
</ul>
<li><a href="#Using%20foreign%20types%20from%20Mercury">Using foreign types from Mercury</a>
<li><a href="#Adding%20foreign%20declarations">Adding foreign declarations</a>
<li><a href="#Adding%20foreign%20definitions">Adding foreign definitions</a>
<li><a href="#Language%20specific%20bindings">Language specific bindings</a>
<ul>
<li><a href="#Interfacing%20with%20C">Interfacing with C</a>
<ul>
<li><a href="#Using%20pragma%20foreign_proc%20for%20C">Using pragma foreign_proc for C</a>
<li><a href="#Using%20pragma%20foreign_decl%20for%20C">Using pragma foreign_decl for C</a>
<li><a href="#Using%20pragma%20foreign_code%20for%20C">Using pragma foreign_code for C</a>
<li><a href="#Using%20pragma%20foreign_type%20for%20C">Using pragma foreign_type for C</a>
</ul>
<li><a href="#Interfacing%20with%20C%23">Interfacing with C#</a>
<ul>
<li><a href="#Using%20pragma%20foreign_type%20for%20C%23">Using pragma foreign_type for C#</a>
<li><a href="#Using%20pragma%20foreign_proc%20for%20C%23">Using pragma foreign_proc for C#</a>
<li><a href="#Using%20pragma%20foreign_decl%20for%20C%23">Using pragma foreign_decl for C#</a>
<li><a href="#Using%20pragma%20foreign_code%20for%20C%23">Using pragma foreign_code for C#</a>
</ul>
<li><a href="#Interfacing%20with%20IL">Interfacing with IL</a>
<ul>
<li><a href="#Using%20pragma%20foreign_type%20for%20IL">Using pragma foreign_type for IL</a>
<li><a href="#Using%20pragma%20foreign_proc%20for%20IL">Using pragma foreign_proc for IL</a>
<li><a href="#Using%20pragma%20foreign_decl%20for%20IL">Using pragma foreign_decl for IL</a>
<li><a href="#Using%20pragma%20foreign_code%20for%20IL">Using pragma foreign_code for IL</a>
</ul>
<li><a href="#Interfacing%20with%20Managed%20C++">Interfacing with Managed C++</a>
<ul>
<li><a href="#Using%20pragma%20foreign_type%20for%20MC++">Using pragma foreign_type for MC++</a>
<li><a href="#Using%20pragma%20foreign_proc%20for%20MC++">Using pragma foreign_proc for MC++</a>
<li><a href="#Using%20pragma%20foreign_decl%20for%20MC++">Using pragma foreign_decl for MC++</a>
<li><a href="#Using%20pragma%20foreign_code%20for%20MC++">Using pragma foreign_code for MC++</a>
</ul>
</ul>
</ul>
<li><a name="toc_C%20interface"></a>
<a href="#C%20interface">C interface</a>
<ul>
<li><a href="#Calling%20C%20code%20from%20Mercury">Calling C code from Mercury</a>
<ul>
<li><a href="#pragma%20import">pragma import</a>
<li><a href="#pragma%20c_code">pragma c_code</a>
<li><a href="#Nondet%20pragma%20c_code">Nondet pragma c_code</a>
<li><a href="#C%20code%20attributes">C code attributes</a>
<li><a href="#Purity%20and%20side%20effects">Purity and side effects</a>
</ul>
<li><a href="#Including%20C%20headers">Including C headers</a>
<li><a href="#Including%20C%20code">Including C code</a>
<li><a href="#Calling%20Mercury%20code%20from%20C">Calling Mercury code from C</a>
<li><a href="#Linking%20with%20C%20object%20files">Linking with C object files</a>
<li><a href="#Passing%20data%20to%20and%20from%20C">Passing data to and from C</a>
<li><a href="#Using%20C%20pointers">Using C pointers</a>
<li><a href="#Memory%20management">Memory management</a>
<li><a href="#Trailing">Trailing</a>
<ul>
<li><a href="#Choice%20points">Choice points</a>
<li><a href="#Value%20trailing">Value trailing</a>
<li><a href="#Function%20trailing">Function trailing</a>
<li><a href="#Delayed%20goals%20and%20floundering">Delayed goals and floundering</a>
<li><a href="#Avoiding%20redundant%20trailing">Avoiding redundant trailing</a>
</ul>
</ul>
<li><a name="toc_Impurity"></a>
<a href="#Impurity">Impurity declarations</a>
<ul>
<li><a href="#Purity%20levels">Choosing the right level of purity</a>
<li><a href="#Purity%20ordering">Purity ordering</a>
<li><a href="#Impurity%20semantics">Semantics</a>
<li><a href="#Declaring%20impurity">Declaring impure functions and predicates</a>
<li><a href="#Impure%20calls">Marking a call as impure</a>
<li><a href="#Promising%20purity">Promising that a predicate is pure</a>
<li><a href="#Impurity%20Example">An example using impurity</a>
<li><a href="#Higher-order%20impurity">Using impurity with higher-order code</a>
<ul>
<li><a href="#Purity%20annotations%20on%20higher-order%20types">Purity annotations on higher-order types</a>
<li><a href="#Purity%20annotations%20on%20lambda%20expressions">Purity annotations on lambda expressions</a>
<li><a href="#Purity%20annotations%20on%20higher-order%20calls">Purity annotations on higher-order calls</a>
</ul>
</ul>
<li><a name="toc_Pragmas"></a>
<a href="#Pragmas">Pragmas</a>
<ul>
<li><a href="#Inlining">Inlining</a>
<li><a href="#Type%20specialization">Type specialization</a>
<ul>
<li><a href="#Syntax%20and%20semantics%20of%20type%20specialization%20pragmas">Syntax and semantics of type specialization pragmas</a>
<li><a href="#When%20to%20use%20type%20specialization">When to use type specialization</a>
<li><a href="#Implementation%20specific%20details">Implementation specific details</a>
</ul>
<li><a href="#Obsolescence">Obsolescence</a>
<li><a href="#Source%20file%20name">Source file name</a>
</ul>
<li><a name="toc_Implementation-dependent%20extensions"></a>
<a href="#Implementation-dependent%20extensions">Implementation-dependent extensions</a>
<ul>
<li><a href="#Fact%20tables">Fact tables</a>
<li><a href="#Tabled%20evaluation">Tabled evaluation</a>
<li><a href="#Termination%20analysis">Termination analysis</a>
<li><a href="#Aditi%20deductive%20database%20interface">Aditi deductive database interface</a>
<ul>
<li><a href="#Aditi%20overview">Aditi overview</a>
<li><a href="#Aditi%20pragma%20declarations">Aditi pragma declarations</a>
<li><a href="#Aditi%20update%20syntax">Aditi update syntax</a>
<ul>
<li><a href="#Aditi%20update%20notes">Aditi update notes</a>
<li><a href="#Insertion%20and%20deletion">Insertion and deletion</a>
<li><a href="#Bulk%20insertion%20and%20deletion">Bulk insertion and deletion</a>
<li><a href="#Modification">Modification</a>
</ul>
<li><a href="#Aditi%20glossary">Aditi glossary</a>
</ul>
</ul>
<li><a name="toc_Bibliography"></a>
<a href="#Bibliography">Bibliography</a>
<ul>
<li><a href="#%5b1%5d">[1]</a>
<li><a href="#%5b2%5d">[2]</a>
<li><a href="#%5b3%5d">[3]</a>
<li><a href="#%5b4%5d">[4]</a>
<li><a href="#%5b5%5d">[5]</a>
<li><a href="#%5b6%5d">[6]</a>
<li><a href="#%5b7%5d">[7]</a>
<li><a href="#%5b8%5d">[8]</a>
</ul>
</ul>
<p><hr>
Node:<a name="Top">Top</a>,
Up:<a rel=up href="#(mercury)">(mercury)</a>
<br>
<h2>The Mercury Language Reference Manual, version ws-ceres</h2>
<ul>
<li><a href="#Introduction">Introduction</a>: A brief introduction to Mercury.
<li><a href="#Syntax">Syntax</a>: Mercury's syntax is similar to ISO Prolog.
<li><a href="#Types">Types</a>: Mercury has a strong parametric polymorphic type system.
<li><a href="#Modes">Modes</a>: Modes allow you to specify the direction of data flow.
<li><a href="#Unique%20modes">Unique modes</a>: Unique modes allow you to specify when there is only one
reference to a particular value, so the compiler can
safely use destructive update to modify that value.
<li><a href="#Determinism">Determinism</a>: Determinism declarations let you specify that a predicate
should never fail or should never succeed more than once.
<li><a href="#User-defined%20equality%20and%20comparison">User-defined equality and comparison</a>:
User-defined types can have user-defined equality and
comparison predicates.
<li><a href="#Higher-order">Higher-order</a>: Mercury supports higher-order predicates and functions,
with closures, lambda expressions, and currying.
<li><a href="#Modules">Modules</a>: Modules allow you to divide a program into smaller parts.
<li><a href="#Type%20classes">Type classes</a>: Constrained polymorphism.
<li><a href="#Existential%20types">Existential types</a>: Support for data abstraction and heterogeneous
collections.
<li><a href="#Semantics">Semantics</a>: Declarative and operational semantics of Mercury
programs.
<li><a href="#Foreign%20language%20interface">Foreign language interface</a>: Calling code written in other programming
languages from Mercury code
<li><a href="#C%20interface">C interface</a>: The C interface allows C code to be called
from Mercury code, and vice versa.
<li><a href="#Impurity">Impurity</a>: Users can write impure Mercury code.
<li><a href="#Pragmas">Pragmas</a>: Various compiler directives, used for example to
control optimization.
<li><a href="#Implementation-dependent%20extensions">Implementation-dependent extensions</a>:
The University of Melbourne Mercury implementation
supports several extensions to the Mercury language.
<li><a href="#Bibliography">Bibliography</a>: References for further reading.
</ul>
<p><hr>
Node:<a name="Introduction">Introduction</a>,
Next:<a rel=next href="#Syntax">Syntax</a>,
Previous:<a rel=previous href="#Top">Top</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Introduction</h2>
<p>Mercury is a new general-purpose programming language, designed
and implemented by a small group of researchers at the University
of Melbourne, Australia. Mercury is based on the paradigm of
purely declarative programming, and was designed to be
useful for the development of large and robust "real-world" applications.
It improves on existing logic programming languages by providing
increased productivity, reliability and efficiency, and by avoiding the
need for non-logical program constructs. Mercury provides the
traditional logic programming syntax, but also allows the
syntactic convenience of user-defined functions, smoothly integrating
logic and functional programming into a single paradigm.
<p>Mercury requires programmers to supply
type, mode and determinism declarations for the predicates
and functions they write.
The compiler checks these declarations,
and rejects the program if it cannot prove
that every predicate or function satisfies its declarations.
This improves reliability,
since many kinds of errors simply cannot happen
in successfully compiled Mercury programs.
It also improves productivity,
since the compiler pinpoints many errors
that would otherwise require manual debugging to locate.
The fact that declarations are checked by the compiler
makes them much more useful than comments
to anyone who has to maintain the program.
The compiler also exploits the guaranteed correctness of the declarations
for significantly improving the efficiency of the code it generates.
<p>To facilitate programming-in-the-large, to allow separate compilation,
and to support encapsulation, Mercury has a simple module system.
Mercury's standard library has a variety of pre-defined modules
for common programming tasks -- see the Mercury Library Reference Manual.
<p><hr>
Node:<a name="Syntax">Syntax</a>,
Next:<a rel=next href="#Types">Types</a>,
Previous:<a rel=previous href="#Introduction">Introduction</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Syntax</h2>
<ul>
<li><a href="#Syntax%20Overview">Syntax Overview</a>:
<li><a href="#Tokens">Tokens</a>:
<li><a href="#Terms">Terms</a>:
<li><a href="#Builtin%20Operators">Builtin Operators</a>:
<li><a href="#Items">Items</a>:
<li><a href="#Declarations">Declarations</a>:
<li><a href="#Facts">Facts</a>:
<li><a href="#Rules">Rules</a>:
<li><a href="#Goals">Goals</a>:
<li><a href="#State%20variables">State variables</a>:
<li><a href="#DCG-rules">DCG-rules</a>:
<li><a href="#DCG-goals">DCG-goals</a>:
<li><a href="#Data-terms">Data-terms</a>:
<li><a href="#Variable%20scoping">Variable scoping</a>:
<li><a href="#Implicit%20quantification">Implicit quantification</a>:
<li><a href="#Elimination%20of%20double%20negation">Elimination of double negation</a>:
</ul>
<p><hr>
Node:<a name="Syntax%20Overview">Syntax Overview</a>,
Next:<a rel=next href="#Tokens">Tokens</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>Syntax overview</h3>
<p>Mercury's syntax is similar to the syntax of Prolog, with some
additional declarations for types, modes, determinism, the module system,
and pragmas, and with the distinction that function symbols may stand also
for invocations of user-defined functions as well as for data constructors.
<p>A Mercury program consists of a set of modules. Each module is a file
containing a sequence of items (declarations and clauses). Each item
is a term followed by a period. Each term is composed of a sequence
of tokens, and each token is composed of a sequence of characters.
Like Prolog, Mercury has the Definite Clause Grammar (DCG) notation
for clauses.
<p><hr>
Node:<a name="Tokens">Tokens</a>,
Next:<a rel=next href="#Terms">Terms</a>,
Previous:<a rel=previous href="#Syntax%20Overview">Syntax Overview</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>Tokens</h3>
<p>Tokens in Mercury are the same as in ISO Prolog.
The only differences are the <code>#<var>line</var></code> token, which
is used as a line number directive (see below) and the
backquote (<code>`</code>) token.
<p>The different tokens are as follows. Tokens may be separated by
whitespace or line number directives.
<dl>
<br><dt><em>line number directive</em>
<dd>A line number directive consists of the character <code>#</code>,
a positive integer specifying the line number, and then a newline.
A <code>#<var>line</var></code> directive's only role is to
specifying the line number; it is otherwise ignored by the syntax.
Line number directives may occur anywhere a token may occur.
They are used in conjunction with the <code>pragma source_file</code>
declaration to indicate that the Mercury code following was
generated by another tool; they serve to associate each line
in the Mercury code with the source file name and line number of
the original source from which the Mercury code was derived,
so that the Mercury compiler can issue more informative error
messages using the original source code locations.
A <code>#<var>line</var></code> directive specifies the line number
for the immediately following line. Line numbers for lines
after that are incremented as usual, so the second line
after a <code>#100</code> directive would be considered to be line
number 101.
<br><dt><em>string</em>
<dd>A string is a sequence of characters enclosed in double quotes (<code>"</code>).
Within a string, two adjacent double quotes stand for a single double quote.
For example, the string <code> """" </code> is a string of length one, containing
a single double quote: the outermost pair of double quotes encloses the
string, and the innermost pair stand for a single double quote.
Strings may also contain backslash escapes. <code>\a</code> stands for "alert"
(a beep character), <code>\b</code> for backspace, <code>\r</code> for carriage-return,
<code>\f</code> for form-feed, <code>\t</code> for tab, <code>\n</code> for newline,
<code>\v</code> for vertical-tab. An escaped backslash, single-quote, or
double-quote stands for itself. The sequence <code>\x</code> introduces
a hexadecimal escape; it must be followed by a sequence of hexadecimal
digits and then a closing backslash. It is replaced
with the character whose character code is identified by the hexadecimal
number. Similarly, a backslash followed by an octal digit is the
beginning of an octal escape; as with hexadecimal escapes, the sequence
of octal digits must be terminated with a closing backslash.
A backslash followed immediately by a newline is deleted; thus an
escaped newline can be used to continue a string over more than one
source line. (String literals may also contain embedded newlines.)
<br><dt><em>name</em>
<dd>A name is either an unquoted name or a quoted name.
An unquoted name is a lowercase letter followed by zero or more letters,
underscores, and digits. A quoted name is any sequence of zero or more
characters enclosed in single quotes (<code>'</code>).
Within a quoted name, two adjacent single quotes stand for a single
single quote. Quoted names can also contain
backslash escapes of the same form as for strings.
<br><dt><em>variable</em>
<dd>A variable is an uppercase letter or underscore followed by zero or
more letters, underscores, and digits.
A variable token consisting of single underscore is treated
specially: each instance of <code>_</code> denotes a distinct variable.
(In addition, variables starting with an underscore are presumed to be
"don't-care" variables; the compiler will issue a warning if a
variable that does not start with an underscore occurs only once, or if
a variable starting with an underscore occurs more than once in the
same scope.)
<br><dt><em>integer</em>
<dd>An integer is either a decimal, binary, octal, hexadecimal, or character-code
literal.
A decimal literal is any sequence of decimal digits.
A binary literal is <code>0b</code> followed by any sequence of binary digits.
An octal literal is <code>0o</code> followed by any sequence of octal digits.
A hexadecimal literal is <code>0x</code> followed by any sequence of hexadecimal
digits.
A character-code literal is <code>0'</code> followed by any single character.
<br><dt><em>float</em>
<dd>A floating point literal consists of a sequence of decimal digits,
a decimal point and a sequence of digits (the fraction part), and
the letter <code>E</code> and another sequence of decimal digits (the exponent).
The fraction part or the exponent (but not both) may be omitted.
<br><dt><em>open_ct</em>
<dd>A left parenthesis, <code>(</code>, that is not preceded by whitespace.
<br><dt><em>open</em>
<dd>A left parenthesis, <code>(</code>, that is preceded by whitespace.
<br><dt><em>close</em>
<dd>A right parenthesis, <code>)</code>.
<br><dt><em>open_list</em>
<dd>A left square bracket, <code>[</code>.
<br><dt><em>close_list</em>
<dd>A right square bracket, <code>]</code>.
<br><dt><em>open_curly</em>
<dd>A left curly bracket, <code>{</code>.
<br><dt><em>close_curly</em>
<dd>A right curly bracket, <code>}</code>.
<br><dt><em>ht_sep</em>
<dd>A "head-tail separator", i.e. a vertical bar, <code>|</code>.
<br><dt><em>comma</em>
<dd>A comma, <code>,</code>.
<br><dt><em>end</em>
<dd>A full stop (period), <code>.</code>.
<br><dt><em>eof</em>
<dd>The end of file.
</dl>
<p><hr>
Node:<a name="Terms">Terms</a>,
Next:<a rel=next href="#Builtin%20Operators">Builtin Operators</a>,
Previous:<a rel=previous href="#Tokens">Tokens</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>Terms</h3>
<p>Syntactically, terms in Mercury are exactly the same as in ISO Prolog,
except that as extensions we permit higher-order terms and the
introduction of infix operators by the use of grave accents (backquotes),
as described below,
and we support an extended set of builtin operators. See <a href="#Builtin%20Operators">Builtin Operators</a>.
Also, the constructor for list terms in Mercury is <code>[|]/2</code>, not
<code>./2</code> as in Prolog.
<p>Note, however, that the meaning of some terms in Mercury is
different to that in Prolog. See <a href="#Data-terms">Data-terms</a>.
<p>A term is either a variable or a functor.
<p>A functor is an integer, a float, a string, a name, a compound term,
or a higher-order term.
<p>A compound term is a simple compound term, a list term, a tuple term,
an operator term, or a parenthesized term.
<p>A simple compound term is a name followed without any intervening
whitespace by an open parenthesis (i.e. an open_ct token),
a sequence of argument terms separated by commas, and a close
parenthesis.
<p>A list term is an open square bracket (i.e. an open_list token)
followed by a sequence of argument terms separated by commas,
optionally followed by a vertical bar (i.e. a close_list token)
followed by a term, followed by a close square bracket (i.e. a
close_list token). An empty list term is an open_list token
followed by a close_list token. List terms are parsed as follows:
<br><pre>parse('[' ']') = [].
parse('[' List) = parse_list(List).
parse_list(Head ',' Tail) = '[|]'(parse_term(Head), parse_list(Tail)).
parse_list(Head '|' Tail ']') = '[|]'(parse_term(Head), parse_term(Tail)).
parse_list(Head ']') = '[|]'(parse_term(Head), []).
</pre>
<p>The following terms are all equivalent:
<br><pre>[1, 2, 3]
[1, 2, 3 | []]
[1, 2 | [3]]
[1 | [2, 3]]
'[|]'(1, '[|]'(2, '[|]'(3, [])))
</pre>
<p>A tuple term is a left curly bracket (i.e. an open_curly token)
followed by a sequence of argument terms separated by commas,
and a right curly bracket. For example, <code>{1, '2', "three"}</code>
is a valid tuple term.
<p>An operator term is a term specified using operator notation, as in Prolog.
Operators can also be formed by enclosing a variable or name between grave
accents (backquotes). Any variable or name may
be used as an operator in this way. If <var>fun</var> is a variable or name,
then a term of the form <code><var>X</var> `<var>fun</var>` <var>Y</var></code> is equivalent to
<code><var>fun</var>(<var>X</var>, <var>Y</var>)</code>. The operator is left associative
and binds more tightly than every operator other than <code>^</code>
(see <a href="#Builtin%20Operators">Builtin Operators</a>).
<p>A parenthesized term is just an open parenthesis
followed by a term and a close parenthesis.
<p>A higher-order term is a "closure" term, which can be any term
other than a name or an operator term, followed without
any intervening whitespace by an open parenthesis (i.e. an open_ct token),
a sequence of argument terms separated by commas, and a close
parenthesis. A higher-order term is equivalent to a simple compound term
whose functor is the empty name, and whose arguments are the
closure term followed by the argument terms of the higher-order term.
That is, a term such as <code>Term(Arg1, <small>...</small>, ArgN)</code> is
parsed as <code>''(Term, Arg1, <small>...</small>, ArgN)</code>.
Note that the closure term can be a parenthesized
term; for example, <code>(Term ^ FieldName)(Arg1, Arg2)</code>
is a higher-order term, and so it gets parsed as
if it were <code>''((Term ^ FieldName), Arg1, Arg2)</code>.
<p><hr>
Node:<a name="Builtin%20Operators">Builtin Operators</a>,
Next:<a rel=next href="#Items">Items</a>,
Previous:<a rel=previous href="#Terms">Terms</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>Builtin Operators</h3>
<p>The following table lists all of Mercury's builtin operators.
Operators with a low "Priority" bind more tightly than those
with a high "Priority". For example, given that <code>+</code> has priority
500 and <code>*</code> has priority 400, the term <code>2 * X + Y</code> would parse
as <code>(2 * X) + Y</code>.
<p>The "Specifier" field indicates what structure terms
constructed with an operator are allowed to take.
"f" represents the operator and "x" and "y" represent arguments.
"x" represents an argument whose priority must be
strictly lower that that of the operator.
"y" represents an argument whose priority is
lower or equal to that of the operator.
For example, "yfx" indicates a left-associative infix operator,
while "xfy" indicates a right-associative infix operator.
<br><pre>
Operator Specifier Priority
. yfx 10
@ xfx 50
^ xfy 99
^ fx 100
`<var>op</var>` yfx 120 <a rel=footnote href="#fn-1"><sup>1</sup></a>
** xfy 200
- fx 200
\ fx 200
* yfx 400
// yfx 400
/ yfx 400
<< yfx 400
>> yfx 400
div yfx 400
mod xfx 400
rem xfx 400
++ xfy 500
+ yfx 500
+ fx 500
-- yfx 500
- yfx 500
/\ yfx 500
\/ yfx 500
aditi_bottom_up fx 500
aditi_top_down fx 500
: yfx 600
:= xfx 650
=^ xfx 650
< xfx 700
=.. xfx 700
=:= xfx 700
=< xfx 700
== xfx 700
=\= xfx 700
= xfx 700
>= xfx 700
> xfx 700
@< xfx 700
@=< xfx 700
@>= xfx 700
@> xfx 700
\== xfx 700
\= xfx 700
~~= xfx 700
is xfx 701
and xfy 720
or xfy 740
func fx 800
impure fy 800
pred fx 800
semipure fy 800
\+ fy 900
not fy 900
when xfx 900
~~ fy 900
<=> xfy 920
<= xfy 920
=> xfy 920
all fxy 950
lambda fxy 950
some fxy 950
, xfy 1000
& xfy 1025
-> xfy 1050
; xfy 1100
then xfx 1150
if fx 1160
else xfy 1170
:: xfx 1175
==> xfx 1175
where xfx 1175
---> xfy 1179
type fx 1180
end_module fx 1199
import_module fx 1199
include_module fx 1199
instance fx 1199
inst fx 1199
mode fx 1199
module fx 1199
pragma fx 1199
promise fx 1199
rule fx 1199
typeclass fx 1199
use_module fx 1199
--> xfx 1200
:- xfx 1200
:- fx 1200
?- fx 1200
</pre>
<p><hr>
Node:<a name="Items">Items</a>,
Next:<a rel=next href="#Declarations">Declarations</a>,
Previous:<a rel=previous href="#Builtin%20Operators">Builtin Operators</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>Items</h3>
<p>Each item in a Mercury module is either a declaration or a clause.
If the top-level functor of the term is <code>:-/1</code>,
the item is a declaration, otherwise it is a clause.
There are three types of clauses.
If the top-level functor of the item is <code>:-/2</code>, the item is a rule.
If the top-level functor is <code>-->/2</code>, the item is a DCG rule.
Otherwise, the item is a fact.
There are two types of rules and facts.
If the top-level functor of the head of a rule is <code>=/2</code>, the rule
is a function rule, otherwise it is a predicate rule.
If the top-level functor of the head of a fact is <code>=/2</code>, the fact
is a function fact, otherwise it is a predicate fact.
<p><hr>
Node:<a name="Declarations">Declarations</a>,
Next:<a rel=next href="#Facts">Facts</a>,
Previous:<a rel=previous href="#Items">Items</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>Declarations</h3>
<p>The allowed declarations are:
<br><pre>:- type
:- pred
:- func
:- inst
:- mode
:- typeclass
:- instance
:- pragma
:- promise
:- module
:- interface
:- implementation
:- import_module
:- use_module
:- include_module
:- end_module
</pre>
<p>The <code>type</code>, <code>pred</code> and <code>func</code> declarations are used for the
type system,
the <code>inst</code> and <code>mode</code> declarations are for the mode system,
the <code>pragma</code> declarations are for the C interface, and for
compiler hints about inlining, and the remainder are for the module system.
They are described in more detail in their respective chapters.
<p>(The current implementation also allows <code>when/2</code> declarations,
but ignores them.
This helps when one wants to write a program
that is both a Mercury program and an NU-Prolog program.)
<p><hr>
Node:<a name="Facts">Facts</a>,
Next:<a rel=next href="#Rules">Rules</a>,
Previous:<a rel=previous href="#Declarations">Declarations</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>Facts</h3>
<p>A function fact is an item of the form <code><var>Head</var> = <var>Result</var></code>.
A predicate fact is an item of the form <code><var>Head</var></code>,
where the top-level functor of <var>Head</var>
is not <code>:-/1</code>, <code>:-/2</code>, <code>-->/2</code>, or <code>=/2</code>.
In both cases, the <var>Head</var> term must not be a variable.
The top-level functor of the <var>Head</var>
determines which predicate or function the fact belongs to;
the predicate or function must have been declared
in a preceding <code>pred</code> or <code>func</code> declaration in this module.
The <var>Result</var> (if any) and the arguments of the <var>Head</var> must
be valid data-terms (optionally annotated with a mode qualifier;
see <a href="#Different%20clauses%20for%20different%20modes">Different clauses for different modes</a>).
<p>A fact is equivalent to a rule whose body is <code>true</code>.
<p><hr>
Node:<a name="Rules">Rules</a>,
Next:<a rel=next href="#Goals">Goals</a>,
Previous:<a rel=previous href="#Facts">Facts</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>Rules</h3>
<p>A function rule is an item of the form
<code><var>Head</var> = <var>Result</var> :- <var>Body</var></code>.
A predicate rule is an item of the form
<code><var>Head</var> :- <var>Body</var></code> where the top-level
functor of <code>Head</code> is not <code>=/2</code>.
In both cases, the <var>Head</var> term must not be a variable.
The top-level functor of the <var>Head</var> determines which predicate or
function the clause belongs to; the predicate or function must have
been declared in a preceding <code>pred</code> or <code>func</code> declaration in
this module.
The <var>Result</var> and the arguments of the <var>Head</var> must be
valid data-terms (optionally annotated with a mode qualifier;
see <a href="#Different%20clauses%20for%20different%20modes">Different clauses for different modes</a>).
The <var>Body</var> must be a valid goal.
<p><hr>
Node:<a name="Goals">Goals</a>,
Next:<a rel=next href="#State%20variables">State variables</a>,
Previous:<a rel=previous href="#Rules">Rules</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>Goals</h3>
<p>A goal is a term of one of the following forms:
<dl>
<dt><code>some <var>Vars</var> <var>Goal</var></code>
<dd>An existential quantification.
<var>Vars</var> must be a list of variables.
<var>Goal</var> must be a valid goal.
<p>Each existential quantification introduces a new scope.
The variables in <var>Vars</var> are local to the goal <var>Goal</var>:
for each variable named in <var>Vars</var>,
any occurrences of variables with that name in <var>Goal</var>
are considered to name a different variable than any
variables with the same name that occur outside of the
existential quantification.
<p>Operationally, existential quantification has no effect,
so apart from its effect on variable scoping,
<code>some <var>Vars</var> <var>Goal</var></code> is the
same as <code><var>Goal</var></code>.
<p>Mercury's rules for implicit quantification (see <a href="#Implicit%20quantification">Implicit quantification</a>)
mean that variables are often implicitly existentially quantified.
There is usually no need to write existential quantifiers explicitly.
<br><dt><code>all <var>Vars</var> <var>Goal</var></code>
<dd>A universal quantification.
<var>Vars</var> must be a list of variables.
<var>Goal</var> must be a valid goal.
This is an abbreviation for <code>not (some <var>Vars</var> not <var>Goal</var>)</code>.
<br><dt><code><var>Goal1</var>, <var>Goal2</var></code>
<dd>A conjunction.
<var>Goal1</var> and <var>Goal2</var> must be valid goals.
<br><dt><code><var>Goal1</var> ; <var>Goal2</var></code>
<dd>where <var>Goal1</var> is not of the form <code>Goal1a -> Goal1b</code>:
a disjunction.
<var>Goal1</var> and <var>Goal2</var> must be valid goals.
<br><dt><code>true</code>
<dd>The empty conjunction.
Always succeeds.
<br><dt><code>fail</code>
<dd>The empty disjunction.
Always fails.
<br><dt><code>not <var>Goal</var></code>
<dt><code>\+ <var>Goal</var></code>
<dd>A negation.
The two different syntaxes have identical semantics.
<var>Goal</var> must be a valid goal.
Both forms are equivalent to <code>if <var>Goal</var> then fail else true</code>.
<br><dt><code><var>Goal1</var> => <var>Goal2</var></code>
<dd>An implication.
This is an abbreviation for <code>not (<var>Goal1</var>, not <var>Goal2</var>)</code>.
<br><dt><code><var>Goal1</var> <= <var>Goal2</var></code>
<dd>A reverse implication.
This is an abbreviation for <code>not (<var>Goal2</var>, not <var>Goal1</var>)</code>.
<br><dt><code><var>Goal1</var> <=> <var>Goal2</var></code>
<dd>A logical equivalence.
This is an abbreviation for
<code>(<var>Goal1</var> => <var>Goal2</var>), (<var>Goal1</var> <= <var>Goal2</var></code>).
<br><dt><code>if <var>CondGoal</var> then <var>ThenGoal</var> else <var>ElseGoal</var></code>
<dt><code><var>CondGoal</var> -> <var>ThenGoal</var> ; <var>ElseGoal</var></code>
<dd>An if-then-else.
The two different syntaxes have identical semantics.
<var>CondGoal</var>, <var>ThenGoal</var>, and <var>ElseGoal</var> must be valid goals.
Note that the "else" part is <em>not</em> optional.
<p>The declarative semantics of an if-then-else is given by
<code>( <var>CondGoal</var>, <var>ThenGoal</var> ; not(<var>CondGoal</var>), <var>ElseGoal</var>)</code>,
but the operational semantics are different, and it is treated
differently for the purposes of determinism inference (see <a href="#Determinism">Determinism</a>).
Operationally, it executes the <var>CondGoal</var>, and if that succeeds, then
execution continues with the <var>ThenGoal</var>; otherwise, i.e. if <var>CondGoal</var>
fails, it executes the <var>ElseGoal</var>. Note that <var>CondGoal</var> can be
nondeterministic -- unlike Prolog, Mercury's if-then-else does not commit
to the first solution of the condition if the condition succeeds.
<br><dt><code><var>Term1</var> = <var>Term2</var></code>
<dd>A unification.
<var>Term1</var> and <var>Term2</var> must be valid data-terms.
<br><dt><code><var>Term1</var> \= <var>Term2</var></code>
<dd>An inequality.
<var>Term1</var> and <var>Term2</var> must be valid data-terms.
This is an abbreviation for <code>not (<var>Term1</var> = <var>Term2</var>)</code>.
<br><dt><code>call(Closure)</code>
<dt><code>call(Closure1, Arg1)</code>
<dt><code>call(Closure2, Arg1, Arg2)</code>
<dt><code>call(Closure3, Arg1, Arg2, Arg3)</code>
<dt><small>...</small>
<dd>A higher-order predicate call.
The closure and arguments must be valid data-terms.
<code>call(Closure)</code> just calls
the specified closure. The other forms append the specified
arguments onto the argument list of the closure before calling it.
See <a href="#Higher-order">Higher-order</a>.
<br><dt><code>Var</code>
<dt><code>Var(Arg1)</code>
<dt><code>Var(Arg2)</code>
<dt><code>Var(Arg2, Arg3)</code>
<dt><small>...</small>
<dd>A higher-order predicate call.
<var>Var</var> must be a variable.
The semantics are exactly the same as for the corresponding
higher-order call using the <code>call/N</code> syntax, i.e.
<code>call(Var)</code>, <code>call(Var, Arg1)</code>, etc.
<br><dt><code>aditi_bulk_delete(<small>...</small>)</code>
<dt><code>aditi_bulk_insert(<small>...</small>)</code>
<dt><code>aditi_bulk_modify(<small>...</small>)</code>
<dt><code>aditi_delete(<small>...</small>)</code>
<dt><code>aditi_insert(<small>...</small>)</code>
<dd>
These goal forms are used for the Aditi database interface.
See <a href="#Aditi%20update%20syntax">Aditi update syntax</a>.
<br><dt><code><var>Call</var></code>
<dd>Any goal which does not match any of the above forms
must be a predicate call.
The top-level functor of the term
determines the predicate called;
the predicate must be declared in a <code>pred</code> declaration
in the module or in the interface of an imported module.
The arguments must be valid data-terms.
</dl>
<p><hr>
Node:<a name="State%20variables">State variables</a>,
Next:<a rel=next href="#DCG-rules">DCG-rules</a>,
Previous:<a rel=previous href="#Goals">Goals</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>State variables</h3>
<p>Clauses may use <code>state variables</code> as a shorthand for naming
intermediate values in a sequence. That is, where in the plain syntax one
might write
<br><pre> main(IO0, IO) :-
io__write_string("The answer is ", IO0, IO1),
io__write_int(calculate_answer(<small>...</small>), IO1, IO2),
io__nl(IO3, IO).
</pre>
using state variable syntax one could write
<br><pre> main(!IO) :-
io__write_string("The answer is ", !IO),
io__write_int(calculate_answer(<small>...</small>), !IO),
io__nl(!IO).
</pre>
<p>A state variable is written <code>!.<var>X</var></code> or <code>!:<var>X</var></code>,
denoting the "current" or "next" value of the sequence labelled
<var>X</var>. An argument <code>!<var>X</var></code> is shorthand for two state
variable arguments <code>!.<var>X</var>, !:<var>X</var></code>; that is,
<code>p(<small>...</small>, !<var>X</var>, <small>...</small>)</code> is parsed as
<code>p(<small>...</small>, !.<var>X</var>, !:<var>X</var>, <small>...</small>)</code>.
<p>Within each clause, a transformation converts state variables into
sequences of ordinary logic variables. The syntactic conversion is
described in terms of the notional <code>transform</code> function defined
next.
<p>The transformation is applied once for each state variable <var>X</var>
with some fresh variables which we shall call <var>ThisX</var> and
<var>NextX</var>.
<p>The expression
<code>substitute(<var>Term</var>, <var>X</var>, <var>ThisX</var>, <var>NextX</var>)</code>
stands for a copy of <var>Term</var> with free occurrences of <code>!.<var>X</var></code>
replaced with <var>ThisX</var> and occurrences of <code>!:<var>X</var></code>
replaced with <var>NextX</var> (a free occurrence is one not bound by the
head of a clause or lambda or by explicit quantification.)
<p>State variables obey the special scope rules.
A state variable <var>X</var> must be explicitly introduced either in the head of
the clause or lambda (in which case it may appear as either or both of
<code>!.<var>X</var></code> or <code>!:<var>X</var></code>) or in an explicit quantification (in
which case it must appear as <code>!<var>X</var></code>.) A state variable <var>X</var> in
the enclosing scope of a lambda or if-then-else expression may only be
referred to as <code>!.<var>X</var></code> (unless the enclosing <var>X</var> is masked
by a more local state variable of the same name.)
<p>For instance, the following goal employing an if-then-else expression
<br><pre> p((if q(!<var>X</var>), r(!<var>X</var>) then <var>A</var> else <var>B</var>), !<var>X</var>)
</pre>
is illegal because it implicitly refers to <code>!:<var>X</var></code> in the condition
of the if-then-else expression. However
<br><pre> p((if some[!<var>X</var>] (q(!<var>X</var>), r(!<var>X</var>)) then <var>A</var> else <var>B</var>), !<var>X</var>)
</pre>
is acceptable because the state variable <var>X</var> is locally scoped to the
condition and then-goal of the if-then-else expression, hence <code>!:<var>X</var></code>
may appear therein.
<p>There are three restrictions concerning state variables in lambdas: first,
<code>!<var>X</var></code> is not a legitimate function result, since it stands for two
arguments, rather than one; second, <code>!<var>X</var></code> may not appear as a
parameter term in the head of a lambda since there is no syntax for specifying
the modes of the two implied parameters; third, <code>!<var>X</var></code> may not appear
as an argument in a function application since this would not make sense given
the usual interpretation of state variables and functions.
<dl>
<br><dt><code><var>Head</var> :- <var>Body</var></code>
<dd>
<br><pre>transform((<var>Head</var> :- <var>Body</var>), <var>X</var>, <var>ThisX</var>, <var>NextX</var>) =
substitute(<var>Head</var>, <var>X</var>, <var>ThisX</var>, <var>NextX</var>) :- transform(<var>Body</var>, <var>X</var>, <var>ThisX</var>, <var>NextX</var>)
</pre>
<br><dt><code><var>Head</var> --> <var>Body</var></code>
<dd>
<br><pre>transform((<var>Head</var> --> <var>Body</var>), <var>X</var>, <var>ThisX</var>, <var>NextX</var>) =
substitute(<var>Head</var>, <var>X</var>, <var>ThisX</var>, <var>NextX</var>) :- transform(<var>Body</var>, <var>X</var>, <var>ThisX</var>, <var>NextX</var>)
</pre>
<br><dt><code><var>Goal1</var>, <var>Goal2</var></code>
<dd>
<br><pre>transform((<var>Goal1</var>, <var>Goal2</var>), <var>X</var>, <var>ThisX</var>, <var>NextX</var>) =
transform(<var>Goal1</var>, <var>X</var>, <var>ThisX</var>, <var>TmpX</var>), transform(<var>Goal2</var>, <var>X</var>, <var>TmpX</var>, <var>NextX</var>)
</pre>
for some fresh variable <var>TmpX</var>.
<br><dt><code><var>Goal1</var> ; <var>Goal2</var></code>
<dd>
<br><pre>transform((<var>Goal1</var> ; <var>Goal2</var>), <var>X</var>, <var>ThisX</var>, <var>NextX</var>) =
transform(<var>Goal1</var>, <var>X</var>, <var>ThisX</var>, <var>NextX</var>) ; transform(<var>Goal2</var>, <var>X</var>, <var>ThisX</var>, <var>NextX</var>)
</pre>
<br><dt><code>not <var>Goal</var></code>
<br><dt><code>\+ <var>Goal</var></code>
<dd>A negation. The two different syntaxes have identical semantics.
<br><pre>transform((not <var>Goal</var>), <var>X</var>, <var>ThisX</var>, <var>NextX</var>) =
not transform(<var>Goal1</var>, <var>X</var>, <var>ThisX</var>, <var>DummyX</var>), <var>NextX</var> = <var>ThisX</var>
</pre>
for some fresh variable <var>DummyX</var>.
<br><dt><code>if <var>Goal1</var> then <var>Goal2</var> else <var>Goal3</var></code>
<br><dt><code><var>Goal1</var> -> <var>Goal2</var> ; <var>Goal3</var></code>
<dd>An if-then-else. The two different syntaxes have identical semantics.
<br><pre>transform((if <var>Goal1</var> then <var>Goal2</var> else <var>Goal3</var>), <var>X</var>, <var>ThisX</var>, <var>NextX</var>) =
if transform(<var>Goal1</var>, <var>X</var>, <var>ThisX</var>, <var>TmpX</var>) then transform(<var>Goal2</var>, <var>X</var>, <var>TmpX</var>, <var>NextX</var>)
else transform(<var>Goal3</var>, <var>X</var>, <var>ThisX</var>, <var>NextX</var>)
</pre>
for some fresh variable <var>TmpX</var>.
<br><dt><code><var>Goal1</var> => <var>Goal2</var></code>
<br><dt><code><var>Goal2</var> <= <var>Goal1</var></code>
<dd>An implication. The two different syntaxes have identical semantics.
<br><pre>transform((<var>Goal1</var> => <var>Goal2</var>), <var>X</var>, <var>ThisX</var>, <var>NextX</var>) =
transform(<var>Goal1</var>, <var>X</var>, <var>ThisX</var>, <var>TmpX</var>) => transform(<var>Goal2</var>, <var>X</var>, <var>TmpX</var>, <var>NextX</var>),
<var>NextX</var> = <var>ThisX</var>
</pre>
for some fresh variable <var>TmpX</var>.
<br><dt><code>all <var>Vars</var> <var>Goal</var></code>
<dd>
<br><pre>transform((all <var>Vars</var> <var>Goal</var>), <var>X</var>, <var>ThisX</var>, <var>NextX</var>) =
all <var>Vars</var> transform(<var>Goal</var>, <var>X</var>, <var>ThisX</var>, <var>DummyX</var>), <var>NextX</var> = <var>ThisX</var>
</pre>
for some fresh variable <var>DummyX</var>.
<br><dt><code>some <var>Vars</var> <var>Goal</var></code>
<dd>
<br><pre>transform((some <var>Vars</var> <var>Goal</var>), <var>X</var>, <var>ThisX</var>, <var>NextX</var>) =
some <var>Vars</var> transform(<var>Goal</var>, <var>X</var>, <var>ThisX</var>, <var>NextX</var>)
</pre>
<br><dt><code><var>Call_or_Unification</var></code>
<dd>If <code>!:<var>X</var></code> does not appear in <var>Call_or_Unification</var> then
<br><pre>transform(<var>Call_or_Unification</var>, <var>X</var>, <var>ThisX</var>, <var>NextX</var>) =
substitute(<var>Call_or_Unification</var>, <var>X</var>, <var>ThisX</var>, <var>NextX</var>), <var>NextX</var> = <var>ThisX</var>
</pre>
If <code>!:<var>X</var></code> does appear in <var>Call_or_Unification</var> then
<br><pre>transform(<var>Call_or_Unification</var>, <var>X</var>, <var>ThisX</var>, <var>NextX</var>) =
substitute(<var>Call_or_Unification</var>, <var>X</var>, <var>ThisX</var>, <var>NextX</var>)
</pre>
</dl>
<p>This transformation can lead to the introduction of chains of
unifications for variables that do not otherwise play a role in the
definition. Such chains are removed transparently.
<p>The following code fragments illustrate appropriate use of state
variable syntax.
<dl>
<br><dt><b>Threading the IO state</b>
<dd>
<br><pre>main(!IO) :-
io__write_string("The 100th prime is ", !IO),
X = prime(100),
io__write_int(X, !IO),
io__nl(!IO).
</pre>
<br><dt><b>Handling accumulators (1)</b>
<dd>
<br><pre>foldl2(_, [], !A, !B).
foldl2(P, [X | Xs], !A, !B) :-
P(X, !A, !B),
foldl2(P, Xs, !A, !B).
</pre>
<br><dt><b>Handling accumulators (2)</b>
<dd>
<br><pre>iterate_while2(P, F, !A, !B) :-
( if P(!.A, !.B) then
F(!A, !B),
iterate_while2(P, F, !A, !B)
else
true
).
</pre>
</dl>
<p><hr>
Node:<a name="DCG-rules">DCG-rules</a>,
Next:<a rel=next href="#DCG-goals">DCG-goals</a>,
Previous:<a rel=previous href="#State%20variables">State variables</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>DCG-rules</h3>
<p>(DCG notation is intended for writing parsers and sequence generators
in a particular style; in the past it has also been used to thread an
implicit state variable, typically the IO state, through code. As a
matter of style, we recommend that in future DCG notation be reserved
for writing parsers and sequence generators and that state variable
syntax be used for passing state threads.)
<p>DCG-rules in Mercury have identical syntax and semantics to
DCG-rules in Prolog.
<p>A DCG-rule is an item of the form <code><var>Head</var> --> <var>Body</var></code>.
The <var>Head</var> term must not be a variable.
A DCG-rule is an abbreviation for an ordinary rule with two
additional implicit arguments appended to the arguments of <var>Head</var>.
These arguments are fresh variables which we shall call
<var>V_in</var> and <var>V_out</var>.
The <var>Body</var> must be a valid DCG-goal,
and is an abbreviation for an ordinary goal.
The next section defines a mathematical function
<code>DCG-transform(<var>V_in</var>, <var>V_out</var>, <var>DCG-goal</var>)</code>
which specifies the semantics of how DCG goals are transformed into
ordinary goals. (The <code>DCG-transform</code> function is purely for the
purposes of exposition, to define the semantics -- it is not part of the
language.)
<p><hr>
Node:<a name="DCG-goals">DCG-goals</a>,
Next:<a rel=next href="#Data-terms">Data-terms</a>,
Previous:<a rel=previous href="#DCG-rules">DCG-rules</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>DCG-goals</h3>
<p>A DCG-goal is a term of one of the following forms:
<dl>
<dt><code>some <var>Vars</var> <var>DCG-goal</var></code>
<dd>A DCG existential quantification.
<var>Vars</var> must be a list of variables.
<var>DCG-goal</var> must be a valid DCG-goal.
<p>Semantics:
<br><pre>transform(V_in, V_out, some Vars DCG_goal) =
some Vars transform(V_in, V_out, DCG_goal)
</pre>
<br><dt><code>all <var>Vars</var> <var>DCG-goal</var></code>
<dd>A DCG universal quantification.
<var>Vars</var> must be a list of variables.
<var>DCG-goal</var> must be a valid DCG-goal.
<p>Semantics:
<br><pre>transform(V_in, V_out, all Vars DCG_goal) =
all Vars transform(V_in, V_out, DCG_goal)
</pre>
<br><dt><code><var>DCG-goal1</var>, <var>DCG-goal2</var></code>
<dd>A DCG sequence.
Intuitively, this means "parse DCG-goal1 and then parse DCG-goal2"
or "do DCG-goal1 and then do DCG-goal2".
(Note that the only way this construct actually forces the desired sequencing
is by the modes of the implicit DCG arguments.)
<var>DCG-goal1</var> and <var>DCG-goal2</var> must be valid DCG-goals.
<p>Semantics:
<br><pre>transform(V_in, V_out, (DCG-goal1, DCG-goal2)) =
(transform(V_in, V_new, DCG_goal1),
transform(V_new, V_out, DCG_goal2))
</pre>
where V_new is a fresh variable.
<br><dt><code><var>DCG-goal1</var> ; <var>DCG-goal2</var></code>
<dd>A disjunction. <var>DCG-goal1</var> and <var>DCG-goal2</var> must be valid goals.
<var>DCG-goal1</var> must not be of the form <code>DCG-goal1a -> DCG-goal1b</code>.
(If it is, then the goal is an if-then-else, not a disjunction.)
<p>Semantics:
<br><pre>transform(V_in, V_out, (DCG_goal1 ; DCG_goal2)) =
( transform(V_in, V_out, DCG_goal1)
; transform(V_in, V_out, DCG_goal2) )
</pre>
<br><dt><code>{ <var>Goal</var> }</code>
<dd>A brace-enclosed ordinary goal.
<var>Goal</var> must be a valid goal.
<p>Semantics:
<br><pre>transform(V_in, V_out, { Goal }) = (Goal, V_out = V_in)
</pre>
<dt><code>[<var>Term</var>, <small>...</small>]</code>
<dd>A DCG input match.
Unifies the implicit DCG input variable V_in,
which must have type <code>list(_)</code>,
with a list whose initial elements are the terms specified
and whose tail is the implicit DCG output variable V_out.
The terms must be valid data-terms.
<p>Semantics:
<br><pre>transform(V_in, V_out, [Term1, <small>...</small>]) = (V_in = [Term, <small>...</small> | V_Out])
</pre>
<br><dt><code>[]</code>
<dd>The null DCG goal (an empty DCG input match).
Equivalent to <code>{ true }</code>.
<p>Semantics:
<br><pre>transform(V_in, V_out, []) = (V_out = V_in)
</pre>
<br><dt><code>not <var>DCG-goal</var></code>
<dt><code>\+ <var>DCG-goal</var></code>
<dd>A DCG negation.
The two different syntaxes have identical semantics.
<var>Goal</var> must be a valid goal.
<p>Semantics:
<br><pre>transform(V_in, V_out, not DCG_goal) =
(not transform(V_in, V_new, DCG_goal), V_out = V_in)
</pre>
where V_new is a fresh variable.
<br><dt><code>if <var>CondGoal</var> then <var>ThenGoal</var> else <var>ElseGoal</var></code>
<dt><code><var>CondGoal</var> -> <var>ThenGoal</var> ; <var>ElseGoal</var></code>
<dd>A DCG if-then-else.
The two different syntaxes have identical semantics.
<var>CondGoal</var>, <var>ThenGoal</var>, and <var>ElseGoal</var> must be valid DCG-goals.
<p>Semantics:
<br><pre>transform(V_in, V_out, if CondGoal then ThenGoal else ElseGoal) =
if transform(V_in, V_cond, CondGoal) then
transform(V_cond, V_out, ThenGoal)
else
transform(V_in, V_out, ElseGoal)
</pre>
<br><dt><code>=(<var>Term</var>)</code>
<dd>A DCG unification. Unifies <var>Term</var> with the implicit DCG argument.
<var>Term</var> must be a valid data-term.
<p>Semantics:
<br><pre>transform(V_in, V_out, =(Term)) = (Term = V_in, V_out = V_in)
</pre>
<br><dt><code>:=(<var>Term</var>)</code>
<dd>A DCG output unification. Unifies <var>Term</var> with the implicit DCG output
argument, ignoring the input DCG argument.
<var>Term</var> must be a valid data-term.
<p>Semantics:
<br><pre>transform(V_in, V_out, :=(Term)) = (V_out = Term)
</pre>
<br><dt><code><var>Term</var> =^ <var>field_list</var></code>
<dd>A DCG field selection.
Unifies <var>Term</var> with the result of applying the field
selection <var>field_list</var> to the implicit DCG argument.
<var>Term</var> must be a valid data-term.
<var>field_list</var> must be a valid field list.
See <a href="#Record%20syntax">Record syntax</a>.
<p>Semantics:
<br><pre>transform(V_in, V_out, Term =^ field_list) =
(Term = V_in ^ field_list, V_out = V_in)
</pre>
<br><dt><code>^ <var>field_list</var> := <var>Term</var></code>
<dd>A DCG field update.
Replaces a field in the implicit DCG argument.
<var>Term</var> must be a valid data-term.
<var>field_list</var> must be a valid field list.
See <a href="#Record%20syntax">Record syntax</a>.
<p>Semantics:
<br><pre>transform(V_in, V_out, ^ field_list := Term) =
(V_out = V_in ^ field_list := Term)
</pre>
<br><dt><code><var>DCG-call</var></code>
<dd>Any term which does not match any of the above forms
must be a DCG predicate call.
If the term is a variable <var>Var</var>,
it is treated as if it were <code>call(<var>Var</var>)</code>.
Then, the two implicit DCG arguments are appended to the specified arguments.
<p>Semantics:
<br><pre>transform(V_in, V_out, p(A1, <small>...</small>, AN)) =
p(A1, <small>...</small>, AN, V_in, V_out)
</pre>
</dl>
<p><hr>
Node:<a name="Data-terms">Data-terms</a>,
Next:<a rel=next href="#Variable%20scoping">Variable scoping</a>,
Previous:<a rel=previous href="#DCG-goals">DCG-goals</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>Data-terms</h3>
<p>Syntactically, a data-term is just a term.
<p>There are a couple of differences from Prolog.
The first one is that double-quoted strings are atomic in
Mercury, they are not abbreviations for lists of character codes.
The second is that Mercury provides several extensions to Prolog's
term syntax: Mercury terms may contain record field selection and
field update expressions, conditional (if-then-else) expressions,
function applications, higher-order function applications, lambda
expressions, and explicit type qualifications.
<p>A data-term is either a variable, a data-functor, or a special data-term.
A special data-term is a conditional expression, a record syntax expression,
a lambda expression, a higher-order function application,
or an explicit type qualification.
<ul>
<li><a href="#Data-functors">Data-functors</a>:
<li><a href="#Record%20syntax">Record syntax</a>:
<li><a href="#Unification%20expressions">Unification expressions</a>:
<li><a href="#Conditional%20expressions">Conditional expressions</a>:
<li><a href="#Lambda%20expressions">Lambda expressions</a>:
<li><a href="#Higher-order%20function%20applications">Higher-order function applications</a>:
<li><a href="#Explicit%20type%20qualification">Explicit type qualification</a>:
</ul>
<p><hr>
Node:<a name="Data-functors">Data-functors</a>,
Next:<a rel=next href="#Record%20syntax">Record syntax</a>,
Up:<a rel=up href="#Data-terms">Data-terms</a>
<br>
<h4>Data-functors</h4>
<p>A data-functor is an integer, a float, a string, a character literal
(any single-character name), a name, or a compound data-term.
A compound data-term is a compound term which does not match
the form of a special data-term (see <a href="#Data-terms">Data-terms</a>),
and whose arguments are data-terms.
If a data-functor is a name or a compound data-term, its top-level functor
must name a function, predicate, or data constructor declared
in the program or in the interface of an imported module.
<p><hr>
Node:<a name="Record%20syntax">Record syntax</a>,
Next:<a rel=next href="#Unification%20expressions">Unification expressions</a>,
Previous:<a rel=previous href="#Data-functors">Data-functors</a>,
Up:<a rel=up href="#Data-terms">Data-terms</a>
<br>
<h4>Record syntax</h4>
<p>Record syntax provides a convenient way to select or update fields
of data constructors, independent of the definition of the constructor.
Record syntax expressions are transformed into sequences of calls
to field selection or update functions (see <a href="#Field%20access%20functions">Field access functions</a>).
<p>A field specifier is a name or a compound data-term.
A field list is a list of field specifiers separated by <code>^</code>.
<code>field</code>, <code>field1 ^ field2</code> and <code>field1(A) ^ field2(B, C)</code> are
all valid field lists.
<p>If the top-level functor of a field specifier is <code><var>field</var>/N</code>,
there must be a visible selection function <code><var>field</var>/(N + 1)</code>. If the
field specifier occurs in a field update expression, there must also be a
visible update function named <code>'<var>field</var> :='/(N + 2)</code>.
<p>Record syntax expressions have one of the following forms.
There are also record syntax DCG goals (see <a href="#DCG-goals">DCG-goals</a>),
which provide similar functionality to record syntax expressions,
except that they act on the DCG arguments of a DCG clause.
<dl>
<dt><code><var>Term</var> ^ <var>field_list</var></code>
<dd>
A field selection. For each field specifier in <var>field_list</var>, apply
the corresponding selection function in turn.
<p><var>Term</var> must be a valid data-term.
<var>field_list</var> must be a valid field list.
<p>A field selection is transformed using the following rules:
<br><pre>transform(Term ^ Field(Arg1, <small>...</small>)) = Field(Arg1, <small>...</small>, Term).
transform(Term ^ Field(Arg1, <small>...</small>) ^ Rest) =
transform(Field(Arg1, <small>...</small>, Term) ^ Rest).
</pre>
<p>Examples:
<p><code>Term ^ field</code> is equivalent to <code>field(Term)</code>.
<p><code>Term ^ field(Arg)</code> is equivalent to <code>field(Arg, Term)</code>.
<p><code>Term ^ field1(Arg1) ^ field2(Arg2, Arg3)</code> is equivalent
to <code>field2(Arg2, Arg3, field1(Arg1, Term))</code>.
<br><dt><code><var>Term</var> ^ <var>field_list</var> := <var>FieldValue</var></code>
<dd>
A field update, returning a copy of <var>Term</var> with the value of
the field specified by <var>field_list</var> replaced with <var>FieldValue</var>.
<p><var>Term</var> must be a valid data-term.
<var>field_list</var> must be a valid field list.
<p>A field update is transformed using the following rules:
<br><pre>transform(Term ^ Field(Arg1, <small>...</small>) := FieldValue) =
'Field :='(Arg1, <small>...</small>, Term, FieldValue)).
transform(Term0 ^ Field(Arg1, <small>...</small>) ^ Rest := FieldValue) = Term :-
OldFieldValue = Field(Arg1, <small>...</small>, Term0),
NewFieldValue = transform(OldFieldValue ^ Rest := FieldValue),
Term = 'Field :='(Arg1, <small>...</small>, Term0, NewFieldValue).
</pre>
<p>Examples:
<p><code>Term ^ field := FieldValue</code> is equivalent
to <code>'field :='(Term, FieldValue)</code>.
<p><code>Term ^ field(Arg) := FieldValue</code> is equivalent
to <code>'field :='(Arg, Term, FieldValue)</code>.
<p><code>Term ^ field1(Arg1) ^ field2(Arg2) := FieldValue</code> is equivalent
to the code
<br><pre>OldField1 = field1(Arg1, Term),
NewField1 = 'field2 :='(Arg2, OldField1, FieldValue),
Result = 'field1 :='(Arg1, Term, NewField1)
</pre>
</dl>
<p><hr>
Node:<a name="Unification%20expressions">Unification expressions</a>,
Next:<a rel=next href="#Conditional%20expressions">Conditional expressions</a>,
Previous:<a rel=previous href="#Record%20syntax">Record syntax</a>,
Up:<a rel=up href="#Data-terms">Data-terms</a>
<br>
<h4>Unification expressions</h4>
<p>A unification expression is an expression of the form
<br><pre>X @ Y
</pre>
<p>where <var>X</var> and <var>Y</var> are data-terms.
<p>The meaning of a unification expression is that the arguments are unified,
and the expression is equivalent to the unified value.
<p>The strict sequential operational semantics (see <a href="#Semantics">Semantics</a>) of an
expression <code>X @ Y</code> is that the expression is replaced by a
fresh variable <var>Z</var>, and immediately after <var>Z</var> is evaluated,
the conjunction <code>Z = X, Z = Y</code> is evaluated.
<p>For example
<br><pre>p(X @ f(_, _), X).
</pre>
<p>is equivalent to
<br><pre>p(H1, H2) :-
H1 = X,
H1 = f(_, _),
H2 = X.
</pre>
<p>Unification expressions are most useful when writing switches
(see <a href="#Determinism%20checking%20and%20inference">Determinism checking and inference</a>). The arguments
of a unification expression are examined when checking for
switches. The arguments of an equivalent user-defined function
would not be.
<p><hr>
Node:<a name="Conditional%20expressions">Conditional expressions</a>,
Next:<a rel=next href="#Lambda%20expressions">Lambda expressions</a>,
Previous:<a rel=previous href="#Unification%20expressions">Unification expressions</a>,
Up:<a rel=up href="#Data-terms">Data-terms</a>
<br>
<h4>Conditional expressions</h4>
<p>A conditional expression is an expression of either of the two following
forms
<br><pre>(if <var>Goal</var> then <var>Expression1</var> else <var>Expression2</var>)
(<var>Goal</var> -> <var>Expression1</var> ; <var>Expression2</var>)
</pre>
<p><var>Goal</var> is a goal; <var>Expression1</var> and <var>Expression2</var> are
both data-terms. The semantics of a conditional expression is that
if <var>Goal</var> is true, then the expression has the meaning of
<var>Expression1</var>, else the expression has the meaning of <var>Expression2</var>.
<p>If <var>Goal</var> takes the form <code>some [X, Y, Z] ...</code> then the scope of
<var>X</var>, <var>Y</var>, and <var>Z</var> includes <var>Expression1</var>.
<p><hr>
Node:<a name="Lambda%20expressions">Lambda expressions</a>,
Next:<a rel=next href="#Higher-order%20function%20applications">Higher-order function applications</a>,
Previous:<a rel=previous href="#Conditional%20expressions">Conditional expressions</a>,
Up:<a rel=up href="#Data-terms">Data-terms</a>
<br>
<h4>Lambda expressions</h4>
<p>A lambda expression is a compound term of one of the following forms
<br><pre>lambda([Arg1::Mode1, Arg2::Mode2, <small>...</small>] is Det, Goal)
pred(Arg1::Mode1, Arg2::Mode2, <small>...</small>) is Det :- Goal
pred(Arg1::Mode1, Arg2::Mode2, <small>...</small>, DCGMode0, DCGMode1) is Det --> DCGGoal
func(Arg1::Mode1, Arg2::Mode2, <small>...</small>) = (Result::Mode) is Det :- Goal
func(Arg1, Arg2, <small>...</small>) = (Result) is Det :- Goal
func(Arg1, Arg2, <small>...</small>) = Result :- Goal
</pre>
<p>where Arg1, Arg2, <small>...</small> are zero or more data-terms,
Result is a data-term,
Mode1, Mode2, <small>...</small> are zero or more modes (see <a href="#Modes">Modes</a>),
DCGMode0 and DCGMode1 are modes (see <a href="#Modes">Modes</a>),
Det is a determinism (see <a href="#Determinism">Determinism</a>),
Goal is a goal (see <a href="#Goals">Goals</a>),
and DCGGoal is a DCG Goal (see <a href="#DCG-goals">DCG-goals</a>).
The <code>:- Goal</code> part is optional;
if it is not specified, then <code>:- true</code> is assumed.
A lambda expression denotes a higher-order predicate or function term
whose value is the predicate or function of the specified arguments
determined by the specified goal. See <a href="#Higher-order">Higher-order</a>.
<p>A lambda expression introduces a new scope: any variables occurring in
the arguments Arg1, Arg2, <small>...</small> are locally quantified, i.e.
any occurrences of variables with that name in the lambda
expression are considered to name a different variable than any
variables with the same name that occur outside of the
lambda expression. For variables which occur in Result or Goal,
but not in the arguments, the usual Mercury rules for implicit
quantification apply (see <a href="#Implicit%20quantification">Implicit quantification</a>).
<p>The form of lambda expression using <code>lambda</code> as its top level functor
is deprecated; please use the form using <code>pred</code> instead.
<p>The form of lambda expression using <code>--></code> as its top level functor
is a syntactic abbreviation: an expression of the form
<br><pre>pred(Var1::Mode1, Var2::Mode2, <small>...</small>, DCGMode0, DCGMode1) is Det --> DCGGoal
</pre>
<p>is equivalent to
<br><pre>pred(Var1::Mode1, Var2::Mode2, <small>...</small>,
DCGVar0::DCGMode0, DCGVar1::DCGMode1) is Det :- Goal
</pre>
<p>where DCGVar0 and DCGVar1 are fresh variables,
and Goal is the result of <code>DCG-transform(DCGVar0, DCGVar1, DCGGoal)</code>
where DCG-transform is the function specified in <a href="#DCG-goals">DCG-goals</a>.
<p><hr>
Node:<a name="Higher-order%20function%20applications">Higher-order function applications</a>,
Next:<a rel=next href="#Explicit%20type%20qualification">Explicit type qualification</a>,
Previous:<a rel=previous href="#Lambda%20expressions">Lambda expressions</a>,
Up:<a rel=up href="#Data-terms">Data-terms</a>
<br>
<h4>Higher-order function applications</h4>
<p>A higher-order function application is a compound term of one
of the following two forms
<br><pre>apply(<var>Func</var>, <var>Arg1</var>, <var>Arg2</var>, <small>...</small>, <var>ArgN</var>)
<var>FuncVar</var>(<var>Arg1</var>, <var>Arg2</var>, <small>...</small>, <var>ArgN</var>)
</pre>
<p>where <var>N</var> >= 0, <var>Func</var> is a term of type
<code>func(T1, T2, <small>...</small>, Tn) = T</code>, <var>FuncVar</var> is a variable
of that type, and
<var>Arg1</var>, <var>Arg2</var>, <small>...</small>, <var>ArgN</var> are terms of types
<code>T1</code>, <code>T2</code>, <small>...</small>, <code>Tn</code>.
The type of the higher-order function application term is <var>T</var>.
It denotes the result of applying the specified function to the
specified arguments. See <a href="#Higher-order">Higher-order</a>.
<p><hr>
Node:<a name="Explicit%20type%20qualification">Explicit type qualification</a>,
Previous:<a rel=previous href="#Higher-order%20function%20applications">Higher-order function applications</a>,
Up:<a rel=up href="#Data-terms">Data-terms</a>
<br>
<h4>Explicit type qualification</h4>
<p>Explicit type qualifications are occasionally useful
to resolve ambiguities that can arise from overloading
or polymorphic types.
<p>An explicit type qualification expression is a term of the form
<br><pre>with_type(<var>Term</var>, <var>Type</var>)
</pre>
<p>or equivalently, as it is more commonly written,
<br><pre><var>Term</var> `with_type` <var>Type</var>
</pre>
<p><var>Term</var> must be a valid data-term.
<var>Type</var> must be a valid type (see <a href="#Types">Types</a>).
<p>An explicit type qualification expression constrains
the specified term to have the specified type.
Apart from that, the meaning of an explicit type qualification
expression is just the same as the specified <var>Term</var>.
<p><hr>
Node:<a name="Variable%20scoping">Variable scoping</a>,
Next:<a rel=next href="#Implicit%20quantification">Implicit quantification</a>,
Previous:<a rel=previous href="#Data-terms">Data-terms</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>Variable scoping</h3>
<p>There are three sorts of variables in Mercury: ordinary variables,
type variables, and inst variables.
<p>Variables occurring in types are called type variables.
Variables occurring in insts or modes are called inst variables.
Variables that occur in data-terms,
and that are not inst variables
or type variables, are called ordinary variables.
<p>(Type variables can occur in data-terms in the right-hand [<var>Type</var>]
operand of an explicit type qualification.
Inst variables can occur in data-terms in the right-hand [<var>Mode</var>]
operand of an explicit mode qualification. Apart from that,
all other variables in data-terms are ordinary variables.)
<p>The three different variable sorts occupy different namespaces:
there is no semantic relationship between two variables of different sorts
(e.g. a type variable and an ordinary variable) even if they happen to
share the same name.
(However, as a matter of programming style, it is generally a
bad idea to use the same name for variables of different sorts
in the same clause.)
<p>The scope of ordinary variables is the clause or declaration in which
they occur, unless they are quantified, either explicitly
(see <a href="#Goals">Goals</a>) or implicitly (see <a href="#Implicit%20quantification">Implicit quantification</a>).
<p>The scope of type variables in a predicate or function's type
declaration extends over any explicit type qualifications
(see <a href="#Explicit%20type%20qualification">Explicit type qualification</a>) in the clauses for that
predicate or function, and over <code>pragma type_spec</code>
(see <a href="#Type%20specialization">Type specialization</a>) declarations for that predicate or
function, so that explicit type qualifications and
<code>pragma type_spec</code> declarations can refer to those
type variables. The scope of any type variables in an explicit
type qualification which do not occur in the predicate or function's
type declaration is the clause in which they occur.
<p>The scope of inst variables is the clause or declaration in which
they occur.
<p><hr>
Node:<a name="Implicit%20quantification">Implicit quantification</a>,
Next:<a rel=next href="#Elimination%20of%20double%20negation">Elimination of double negation</a>,
Previous:<a rel=previous href="#Variable%20scoping">Variable scoping</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>Implicit quantification</h3>
<p>The rule for implicit quantification in Mercury
is not the same as the usual one in mathematical logic.
In Mercury, variables that do not occur in the head of a clause
are implicitly existentially quantified around their closest enclosing scope
(in a sense to be made precise in the following paragraphs).
This allows most existential quantifiers to be omitted,
and leads to more concise code.
<p>An occurrence of a variable is <dfn>in a negated context</dfn>
if it is in a negation,
in a universal quantification,
in the condition of an if-then-else,
in an inequality,
or in a lambda expression.
<p>Two goals are <dfn>parallel</dfn>
if they are different disjuncts of the same disjunction,
or if one is the "else" part of an if-then-else
and the other goal is either the "then" part or the condition
of the if-then-else,
or if they are the goals of disjoint (distinct and non-overlapping)
lambda expressions.
<p>If a variable occurs in a negated context
and does not occur outside of that negated context other than in parallel goals
(and in the case of a variable in the condition of an if-then-else,
other than in the "then" part of the if-then-else),
then that variable is implicitly existentially quantified inside the negation.
<p><hr>
Node:<a name="Elimination%20of%20double%20negation">Elimination of double negation</a>,
Previous:<a rel=previous href="#Implicit%20quantification">Implicit quantification</a>,
Up:<a rel=up href="#Syntax">Syntax</a>
<br>
<h3>Elimination of double negation</h3>
<p>The treatment of inequality, universal quantification,
implication, and logical equivalence as abbreviations
can cause the introduction of double negations
which could make otherwise well-formed code mode-incorrect.
To avoid this problem, the language specifies that
after syntax analysis and implicit quantification,
and before mode analysis is performed,
the implementation must delete any double negations
and must replace any negations of conjunctions of negations
with disjunctions. (Both of these transformations
preserve the logical meaning and type-correctness of the code,
and they preserve or improve mode-correctness:
they never transform code fragments that would be
well-moded into ones that would be ill-moded.)
<p><hr>
Node:<a name="Types">Types</a>,
Next:<a rel=next href="#Modes">Modes</a>,
Previous:<a rel=previous href="#Syntax">Syntax</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Types</h2>
<p>The type system is based on many-sorted logic, and supports polymorphism,
type classes (see <a href="#Type%20classes">Type classes</a>), and existentially quantified types
(see <a href="#Existential%20types">Existential types</a>).
<ul>
<li><a href="#Builtin%20types">Builtin types</a>:
<li><a href="#User-defined%20types">User-defined types</a>:
<li><a href="#Predicate%20and%20function%20type%20declarations">Predicate and function type declarations</a>:
<li><a href="#Field%20access%20functions">Field access functions</a>:
</ul>
<p><hr>
Node:<a name="Builtin%20types">Builtin types</a>,
Next:<a rel=next href="#User-defined%20types">User-defined types</a>,
Up:<a rel=up href="#Types">Types</a>
<br>
<h3>Builtin types</h3>
<p>Certain special types are builtin, or are defined in the Mercury library:
<dl>
<dt>Primitive types: <code>char</code>, <code>int</code>, <code>float</code>, <code>string</code>.
<dd>There is a special syntax for constants of type <code>int</code>, <code>float</code>,
and <code>string</code>. (For <code>char</code>, the standard syntax suffices.)
<br><dt>Predicate types: <code>pred</code>, <code>pred(T)</code>, <code>pred(T1, T2)</code>, <small>...</small>
<dt>Function types: <code>(func) = T</code>, <code>func(T1) = T</code>,
<dt><code>func(T1, T2) = T</code>, <small>...</small>
<dd>These higher-order function and predicate types are used to pass procedure
addresses and closures to other predicates. See <a href="#Higher-order">Higher-order</a>.
<br><dt>Tuple types: <code>{}</code>, <code>{T}</code>, <code>{T1, T2}</code>, <small>...</small>.
<dd>A tuple type is equivalent to a discriminated union type
(see <a href="#Discriminated%20unions">Discriminated unions</a>) with declaration
<br><pre>:- type {Arg1, Arg2, <small>...</small>, ArgN}
---> { {Arg1, Arg2, <small>...</small>, ArgN} }.
</pre>
<br><dt>The universal type: <code>univ</code>.
<dd>The type <code>univ</code> is defined in the standard library module <code>std_util</code>,
along with the predicates <code>type_to_univ/2</code> and <code>univ_to_type/2</code>.
With those predicates, any type can be converted to the universal type
and back again.
The universal type is useful for situations
where you need heterogeneous collections.
<br><dt>The "state-of-the-world" type: <code>io__state</code>.
<dd>The type <code>io__state</code> is defined in the standard library module <code>io</code>,
and represents the state of the world.
Predicates which perform I/O are passed the old state of the world
and produce a new state of the world.
In this way, we can give a declarative semantics to code that performs I/O.
</dl>
<p><hr>
Node:<a name="User-defined%20types">User-defined types</a>,
Next:<a rel=next href="#Predicate%20and%20function%20type%20declarations">Predicate and function type declarations</a>,
Previous:<a rel=previous href="#Builtin%20types">Builtin types</a>,
Up:<a rel=up href="#Types">Types</a>
<br>
<h3>User-defined types</h3>
<p>New types can be introduced with <code>:- type</code> declarations.
There are several categories of derived types:
<ul>
<li><a href="#Discriminated%20unions">Discriminated unions</a>:
<li><a href="#Equivalence%20types">Equivalence types</a>:
<li><a href="#Abstract%20types">Abstract types</a>:
</ul>
<p><hr>
Node:<a name="Discriminated%20unions">Discriminated unions</a>,
Next:<a rel=next href="#Equivalence%20types">Equivalence types</a>,
Up:<a rel=up href="#User-defined%20types">User-defined types</a>
<br>
<h4>Discriminated unions</h4>
<p>These encompass both enumeration and record types in other languages.
A derived type is defined using <code>:- type <var>type</var> ---> <var>body</var></code>.
(Note there are <em>three</em> dashes in that arrow.
It should not be confused with the two-dash arrow used for DCGs
or the one-dash arrow used for if-then-else.)
If the <var>type</var> term is a functor of arity zero
(i.e. one having zero arguments),
it names a monomorphic type.
Otherwise, it names a polymorphic type;
the arguments of the functor must be distinct type variables.
The <var>body</var> term is defined as
a sequence of constructor definitions separated by semi-colons.
<p>Ordinarily, each constructor definition must be a functor whose arguments
(if any) are types. Ordinary discriminated union definitions must be
<dfn>transparent</dfn>: all type variables occurring in the <var>body</var> must
also occur in the <var>type</var>.
<p>However, constructor definitions can optionally be existentially typed.
In that case, the functor will be preceded by an existential type
quantifier and can optionally be followed by an existential type
class constraint. For details, see <a href="#Existential%20types">Existential types</a>.
Existentially typed discriminated union definitions need not be
transparent.
<p>The arguments of constructor definitions may be labelled.
These labels cause the compiler to generate functions which can
be used to conveniently select and update fields of a term
in a manner independent of the definition of the type
(see <a href="#Field%20access%20functions">Field access functions</a>). A labelled argument is of the
form <code><var>fieldname</var> :: <var>Type</var></code>. It is an error for
two fields in the same module to have the same label.
<p>Here are some examples of discriminated union definitions:
<br><pre>:- type fruit
---> apple
; orange
; banana
; pear.
:- type strange
---> foo(int)
; bar(string).
:- type employee
---> employee(
name :: string,
age :: int,
department :: string
).
:- type tree
---> empty
; leaf(int)
; branch(tree, tree).
:- type list(T)
---> []
; [T | list(T)].
:- type pair(T1, T2)
---> T1 - T2.
</pre>
<p>If the body of a discriminated union type definition
contains a term whose top-level functor is <code>';'/2</code>,
the semi-colon is normally assumed to be a separator.
This makes it difficult to define a type
whose constructors include <code>';'/2</code>.
To allow this, curly braces can be used to quote the semi-colon.
It is then also necessary to quote curly braces.
The following example illustrates this:
<br><pre>:- type tricky
---> { int ; int }
; { { int } }.
</pre>
<p>This defines a type with two constructors, <code>';'/2</code> and <code>'{}'/1</code>,
whose argument types are all <code>int</code>. We recommend against using
constructors named <code>'{}'</code> because of the possibility of confusion
with the builtin tuple types.
<p>Each discriminated union type definition introduces a distinct type.
Mercury considers two discriminated union types that have the same bodies
to be distinct types (name equivalence).
Having two different definitions of a type with the same name and arity in
the same module is an error.
<p>Constructors may be overloaded among different types:
there may be any number of constructors with a given name and arity,
so long as they all have different types.
However, there must not be more than one constructor
with the same name, arity, and result type in the same module.
(There is no particularly good reason for this restriction;
in the future we may allow several such functors
as long as they have different argument types.)
Note that excessive overloading of constructors can slow down type checking
and can make the program confusing for human readers,
so overloading should not be over-used.
<p><hr>
Node:<a name="Equivalence%20types">Equivalence types</a>,
Next:<a rel=next href="#Abstract%20types">Abstract types</a>,
Previous:<a rel=previous href="#Discriminated%20unions">Discriminated unions</a>,
Up:<a rel=up href="#User-defined%20types">User-defined types</a>
<br>
<h4>Equivalence types</h4>
<p>These are type abbreviations.
They are defined using <code>==</code> as follows.
They may be polymorphic.
<br><pre>:- type money == int.
:- type assoc_list(KeyType, ValueType)
== list(pair(KeyType, ValueType)).
</pre>
<p>Equivalence type definitions must be transparent.
Unlike discriminated union type definitions,
equivalence type definitions must not be cyclic;
that is, the type on the left hand side of the <code>==</code>
(<code>assoc_list</code> and <code>money</code> in the examples above)
must not occur on the right hand side of the <code>==</code>.
<p>Mercury treats an equivalence type
as an abbreviation for the type on the right hand side of the definition;
the two are equivalent in all respects
in scopes where the equivalence type is visible.
<p><hr>
Node:<a name="Abstract%20types">Abstract types</a>,
Previous:<a rel=previous href="#Equivalence%20types">Equivalence types</a>,
Up:<a rel=up href="#User-defined%20types">User-defined types</a>
<br>
<h4>Abstract types</h4>
<p>These are types whose implementation is hidden.
The type declarations
<br><pre>:- type t1.
:- type t2(T1, T2).
</pre>
<p>declare types <code>t1/0</code> and <code>t2/2</code> to be abstract types.
Such declarations are only useful in the interface section of a module.
This means that the type names will be exported,
but the constructors (functors) for these types will not be exported.
The implementation section of a module
must have give the definition of all the abstract types
named in the interface section of the module.
Abstract types may be defined as either discriminated union types
or as equivalence types.
<p><hr>
Node:<a name="Predicate%20and%20function%20type%20declarations">Predicate and function type declarations</a>,
Next:<a rel=next href="#Field%20access%20functions">Field access functions</a>,
Previous:<a rel=previous href="#User-defined%20types">User-defined types</a>,
Up:<a rel=up href="#Types">Types</a>
<br>
<h3>Predicate and function type declarations</h3>
<p>The argument types of each predicate
must be explicitly declared with a <code>:- pred</code> declaration.
The argument types and return type of each function must be
explicitly declared with a <code>:- func</code> declaration.
For example:
<br><pre>:- pred is_all_uppercase(string).
:- func strlen(string) = int.
</pre>
<p>Predicates and functions can be polymorphic; that is, their
declarations can include type variables. For example:
<br><pre>:- pred member(T, list(T)).
:- func length(list(T)) = int.
</pre>
<p>A predicate or function can by declared to have a given higher-order
type (see <a href="#Higher-order">Higher-order</a>) by using <code>`with_type`</code> in the type declaration.
This is useful where several predicates or functions need to have the
same type signature, which often occurs for typeclass method implementations
(see <a href="#Type%20classes">Type classes</a>), and for predicates to be passed as higher-order terms.
<p>For example,
<br><pre>:- type foldl_pred(T, U) == pred(T, U, U).
:- type foldl_func(T, U) == (func(T, U) = U).
:- pred p(int) `with_type` foldl_pred(T, U).
:- func f(int) `with_type` foldl_func(T, U).
</pre>
<p>is equivalent to
<br><pre>:- pred p(int, T, U, U).
:- pred f(int, T, U) = U.
</pre>
<p>Type variables in predicate and function declarations
are implicitly universally quantified by default;
that is, the predicate or function may be called with arguments
and (in the case of functions) return value
whose actual types are any instance of the types
specified in the declaration. For example,
the function <code>length/1</code> declared above
could be called with the argument having
type <code>list(int)</code>, or <code>list(float)</code>,
or <code>list(list(int))</code>, etc.
<p>Type variables in predicate and function declarations can
also be existentially quantified; this is discussed in
<a href="#Existential%20types">Existential types</a>.
<p>There must only be one predicate with a given name and arity in each module,
and only one function with a given name and arity in each module.
It is an error to declare the same predicate or function twice.
<p>There must be at least one clause defined for each declared predicate or
function, except for those defined using the foreign language interface
(see <a href="#Foreign%20language%20interface">Foreign language interface</a> and <a href="#C%20interface">C interface</a>).
However, Mercury implementations are permitted to provide a method
of processing Mercury programs in which such errors are not reported
until and unless the predicate or function is actually called.
(The University of Melbourne Mercury implementation provides this
with its <code>--allow-stubs</code> option. This can be useful during
program development, since it allows you to execute parts of
a program while the program's implementation is still incomplete.)
<p>Note that a predicate defined using DCG notation (see <a href="#DCG-rules">DCG-rules</a>)
will appear to be defined with two fewer arguments than it is declared
with. It will also appear to be called with two fewer arguments when
called from predicates defined using DCG notation. However, when called
from an ordinary predicate or function, it must have all the arguments
it was declared with.
<p>The compiler infers the types of data-terms, and in particular the types
of variables and overloaded constructors, functions, and predicates.
A <dfn>type assignment</dfn> is an assignment of a type
to every variable and of a particular constructor, function, or predicate
to every name in a clause.
A type assignment is <dfn>valid</dfn> if it satisfies the following conditions.
<p>Each constructor in a clause
must have been declared in at least one visible type declaration.
The type assigned to each constructor term
must match one of the type declarations for that constructor,
and the types assigned to the arguments of that constructor
must match the argument types specified in that type declaration.
<p>The type assigned to each function call term
must match the return type of one of the <code>:- func</code> declarations
for that function, and the types assigned to the arguments of that function
must match the argument types specified in that type declaration.
<p>The type assigned to each predicate argument must match
the type specified in one of the <code>:- pred</code> declarations for that predicate.
The type assigned to each head argument in a predicate clause must exactly match
the argument type specified in the corresponding <code>:- pred</code> declaration.
<p>The type assigned to each head argument in a function clause must exactly match
the argument type specified in the corresponding <code>:- func</code> declaration,
and the type assigned to the result term in a function clause must exactly
match the result type specified in the corresponding <code>:- func</code> declaration.
<p>The type assigned to each data-term with an explicit type qualification
(see <a href="#Explicit%20type%20qualification">Explicit type qualification</a>) must match the type specified
by the type qualification expression<a rel=footnote href="#fn-2"><sup>2</sup></a>.
<p>(Here "match" means to be an instance of,
i.e. to be identical to for some substitution of the type parameters,
and "exactly match" means to be identical up to renaming of type parameters.)
<p>One type assignment <var>A</var> is said to be
<dfn>more general</dfn> than another type assignment <var>B</var>
if there is a binding of the type parameters in A
that makes it identical (up to renaming of parameters) to B.
If there is more than one valid type assignment,
the compiler must choose the most general one.
If there are two valid type assignments which are not identical up to renaming
and neither of which is more general than the other,
then there is a type ambiguity, and compiler must report an error.
A clause is <dfn>type-correct</dfn>
if there is a unique (up to renaming) most general valid type assignment.
Every clause in a Mercury program must be type-correct.
<p><hr>
Node:<a name="Field%20access%20functions">Field access functions</a>,
Previous:<a rel=previous href="#Predicate%20and%20function%20type%20declarations">Predicate and function type declarations</a>,
Up:<a rel=up href="#Types">Types</a>
<br>
<h3>Field access functions</h3>
<p>Fields of constructors of discriminated union types may be
labelled (see <a href="#Discriminated%20unions">Discriminated unions</a>). These labels cause the
compiler to generate functions which can be used to select and update
fields of a term in a manner independent of the definition of the type.
<p>The Mercury language includes syntactic sugar to make it more convenient
to select and update fields inside nested terms (see <a href="#Record%20syntax">Record syntax</a>)
and to select and update fields of the DCG arguments of a
clause (see <a href="#DCG-goals">DCG-goals</a>).
<ul>
<li><a href="#Field%20selection">Field selection</a>:
<li><a href="#Field%20update">Field update</a>:
<li><a href="#User-supplied%20field%20access%20function%20declarations">User-supplied field access function declarations</a>:
<li><a href="#Field%20access%20examples">Field access examples</a>:
</ul>
<p><hr>
Node:<a name="Field%20selection">Field selection</a>,
Next:<a rel=next href="#Field%20update">Field update</a>,
Up:<a rel=up href="#Field%20access%20functions">Field access functions</a>
<br>
<h4>Field selection</h4>
<br><pre><var>field</var>(<var>Term</var>)
</pre>
<p>Each field label <code><var>field</var></code> in a constructor causes generation
of a field selection function <code><var>field</var>/1</code>, which takes a data-term
of the same type as the constructor and returns the value of the
labelled field, failing if the top-level constructor of the argument
is not the constructor containing the field.
<p>If the declaration of the field is in the interface section of the module,
the corresponding field selection function is also exported from the module.
<p>By default, this function has no declared modes -- the modes are inferred at
each call to the function. However, the type and modes of this function may be
explicitly declared, in which case it will have only the declared modes.
<p>To create a higher-order term from a field selection function, an
explicit lambda expression must be used, unless a single mode
declaration is supplied for the field selection function.
<p><hr>
Node:<a name="Field%20update">Field update</a>,
Next:<a rel=next href="#User-supplied%20field%20access%20function%20declarations">User-supplied field access function declarations</a>,
Previous:<a rel=previous href="#Field%20selection">Field selection</a>,
Up:<a rel=up href="#Field%20access%20functions">Field access functions</a>
<br>
<h4>Field update</h4>
<br><pre>'<var>field</var> :='(<var>Term</var>, <var>ValueTerm</var>)
</pre>
<p>Each field label <code><var>field</var></code> in a constructor causes generation
of a field update function <code>'<var>field</var> :='/2</code>.
The first argument of this function is a data-term of the same type as the
constructor. The second argument is a data-term of the same type as the
labelled field. The return value is a copy of the first argument with
value of the labelled field replaced by the second argument.
<code>'<var>field</var> :='/2</code> fails if the top-level constructor of the
first argument is not the constructor containing the labelled field.
<p>If the declaration of the field is in the interface section of the module,
the corresponding field update function is also exported from the module.
<p>By default, this function has no declared modes -- the modes are inferred at
each call to the function. However, the type and modes of this function may be
explicitly declared, in which case it will have only the declared modes.
<p>To create a higher-order term from a field update function, an
explicit lambda expression must be used, unless a single mode
declaration is supplied for the field update function.
<p>Some fields cannot be updated using field update functions.
For the constructor <code>unsettable/2</code> below, neither field may be updated
because the resulting term would not be well-typed. A future release
may allow multiple fields to be updated by a single expression to avoid
this problem.
<br><pre>:- type unsettable
---> some [T] unsettable(
unsettable1 :: T,
unsettable2 :: T
).
</pre>
<p><hr>
Node:<a name="User-supplied%20field%20access%20function%20declarations">User-supplied field access function declarations</a>,
Next:<a rel=next href="#Field%20access%20examples">Field access examples</a>,
Previous:<a rel=previous href="#Field%20update">Field update</a>,
Up:<a rel=up href="#Field%20access%20functions">Field access functions</a>
<br>
<h4>User-supplied field access function declarations</h4>
<p>Type and mode declarations for compiler-generated field access functions
for fields of constructors local to a module may be placed in the interface
section of the module. This allows the implementation of a type to be hidden
while still allowing client modules to use record syntax to manipulate values
of the type. Supplying a type declaration and a single mode declaration also
allows higher-order terms to be created from a field access function without
using explicit lambda expressions.
<p>Declarations for field access functions for fields occurring in the interface
section of a module must also occur in the interface section.
<p>Declarations and clauses for field access functions can also be supplied
for fields which are not a part of any type. This is useful when the data
structures of a program change so that a value which was previously stored
as part of a type is now computed each time it is requested. It also
allows record syntax to be used for type class methods.
<p>User-declared field access functions may take extra arguments.
For example, the Mercury standard library module <code>map</code> contains
the following functions:
<br><pre>:- func elem(K, map(K, V)) = V is semidet.
:- func 'elem :='(K, map(K, V), V) = map(K, V).
</pre>
Field access syntax may be used at the top-level of <code>func</code> and
<code>mode</code> declarations and in the head of clauses. For instance:
<br><pre>:- func map(K, V) ^ elem(K) = V.
:- mode in ^ in = out is semidet.
Map ^ elem(Key) = map__lookup(Map, Key).
:- func (map(K, V) ^ elem(K) := V) = V.
:- mode (in ^ in := in) = out is semidet.
(Map ^ elem(Key) := Value) = map__set(Map, Key, Value).
</pre>
<p>The Mercury standard library modules <code>array</code> and <code>bt_array</code>
define similar functions.
<p><hr>
Node:<a name="Field%20access%20examples">Field access examples</a>,
Previous:<a rel=previous href="#User-supplied%20field%20access%20function%20declarations">User-supplied field access function declarations</a>,
Up:<a rel=up href="#Field%20access%20functions">Field access functions</a>
<br>
<h4>Field access examples</h4>
<p>The examples make use of the following type declarations:
<br><pre>:- type type1
---> type1(
field1 :: type2,
field2 :: string
).
:- type type2
---> type2(
field3 :: int,
field4 :: int
).
</pre>
<p>The compiler generates some field access functions for <code>field1</code>.
The functions generated for the other fields are similar.
<br><pre>+:- func type1 ^ field1 = type2.
+type1(Field1, _) ^ field1 = Field1.
+:- func (type1 ^ field1 := type2) = type1.
+(type1(_, Field2) ^ field1 := Field1) = type1(Field1, Field2).
</pre>
<p>Using these functions and the syntactic sugar described in
<a href="#Record%20syntax">Record syntax</a>, programmers can write code such as
<br><pre>+:- func type1 ^ increment_field3 = type1.
+Term0 ^ increment_field3 =
Term0 ^ field1 ^ field3 := Term0 ^ field1 ^ field3 + 1.
</pre>
<p>The compiler expands this into
<br><pre>incremental_field3(Term0) = Term :-
OldField3 = field3(field1(Term0)),
OldField1 = field1(Term0),
NewField1 = 'field3 :='(OldField1, OldField3 + 1),
Term = 'field1 :='(Term0, NewField1).
</pre>
<p>The field access functions defined in the Mercury standard library
module <code>map</code> can be used as follows:
<br><pre>:- func update_field_in_map(map(int, type1), int, string)
= map(int, type1) is semidet.
update_field_in_map(Map, Index, Value) =
Map ^ elem(Index) ^ field2 := Value.
</pre>
<p><hr>
Node:<a name="Modes">Modes</a>,
Next:<a rel=next href="#Unique%20modes">Unique modes</a>,
Previous:<a rel=previous href="#Types">Types</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Modes</h2>
<ul>
<li><a href="#Insts%20modes%20and%20mode%20definitions">Insts modes and mode definitions</a>:
<li><a href="#Predicate%20and%20function%20mode%20declarations">Predicate and function mode declarations</a>:
<li><a href="#Constrained%20polymorphic%20modes">Constrained polymorphic modes</a>:
<li><a href="#Different%20clauses%20for%20different%20modes">Different clauses for different modes</a>:
</ul>
<p><hr>
Node:<a name="Insts%20modes%20and%20mode%20definitions">Insts modes and mode definitions</a>,
Next:<a rel=next href="#Predicate%20and%20function%20mode%20declarations">Predicate and function mode declarations</a>,
Up:<a rel=up href="#Modes">Modes</a>
<br>
<h3>Insts, modes, and mode definitions</h3>
<p>The <dfn>mode</dfn> of a predicate, or function, is a mapping
from the initial state of instantiation of the arguments of the predicate,
or the arguments and result of a function,
to their final state of instantiation.
To describe states of instantiation,
we use information provided by the type system.
Types can be viewed as regular trees with two kinds of nodes:
or-nodes representing types
and and-nodes representing constructors.
The children of an or-node are the constructors
that can be used to construct terms of that type;
the children of an and-node are the types
of the arguments of the constructors.
We attach mode information to the or-nodes of type trees.
<p>An <dfn>instantiatedness tree</dfn> is an assignment
of an <dfn>instantiatedness</dfn> -- either <dfn>free</dfn> or <dfn>bound</dfn> --
to each or-node of a type tree,
with the constraint that all descendants of a free node must be free.
<p>A term is <dfn>approximated by</dfn> an instantiatedness tree
if for every node in the instantiatedness tree,
<ul>
<li>if the node is "free",
then the corresponding node in the term (if any)
is a free variable that does not share with any other variable
(we call such variables <dfn>distinct</dfn>);
<li>if the node is "bound",
then the corresponding node in the term (if any)
is a function symbol.
</ul>
<p>When an instantiatedness tree tells us that a variable is bound,
there may be several alternative function symbols to which it could be bound.
The instantiatedness tree does not tell us which of these it is bound to;
instead for each possible function symbol it tells us exactly
which arguments of the function symbol will be free and which will be bound.
The same principle applies recursively to these bound arguments.
<p>Mercury's mode system allows users
to declare names for instantiatedness trees using declarations such as
<br><pre>:- inst listskel == bound( [] ; [free | listskel] ).
</pre>
<p>This instantiatedness tree describes lists
whose skeleton is known but whose elements are distinct variables.
As such, it approximates the term <code>[A,B]</code>
but not the term <code>[H|T]</code> (only part of the skeleton is known),
the term <code>[A,2]</code> (not all elements are variables),
or the term <code>[A,A]</code> (the elements are not distinct variables).
<p>As a shorthand, the mode system provides <code>free</code> and <code>ground</code>
as names for instantiatedness trees
all of whose nodes are free and bound respectively.
The shape of these trees is determined by
the type of the variable to which they apply.
<p>A more concise, alternative syntax exists for <code>bound</code> instantiatedness
trees:
<br><pre>:- inst maybeskel ---> no ; yes(ground).
</pre>
<p>which is equivalent to writing
<br><pre>:- inst maybeskel == bound(no ; yes(ground)).
</pre>
<p>As execution proceeds, variables may become more instantiated.
A <dfn>mode mapping</dfn> is a mapping
from an initial instantiatedness tree to a final instantiatedness tree,
with the constraint that no node of the type tree
is transformed from bound to free.
Mercury allows the user to specify mode mappings directly
by expressions such as <code>inst1 >> inst2</code>,
or to give them a name using declarations such as
<br><pre>:- mode m == inst1 >> inst2.
</pre>
<p>It is also possible to write mode declarations using <code>::</code>
and <code>-></code> instead of <code>==</code> and <code>>></code> respectively,
however this syntax is deprecated and may not be supported in future.
<p>Two standard shorthand modes are provided,
corresponding to the standard notions of inputs and outputs:
<br><pre>:- mode in == ground >> ground.
:- mode out == free >> ground.
</pre>
<p>Prolog fans who want to use the symbols <code>+</code> and <code>-</code>
can do so by simply defining them using a mode declaration:
<br><pre>:- mode (+) == in.
:- mode (-) == out.
</pre>
<p>These two modes are enough for most functions and predicates.
Nevertheless, Mercury's mode system is sufficiently
expressive to handle more complex data-flow patterns,
including those involving partially instantiated data structures.
(The current implementation does not handle
partially instantiated data structures yet.)
<p>For example, consider an
interface to a database that associates data with keys, and provides
read and write access to the items it stores. To represent accesses to
the database over a network, you would need declarations such as
<br><pre>:- type operation
---> lookup(key, data)
; set(key, data).
:- inst request
---> lookup(ground, free)
; set(ground, ground).
:- mode create_request == free >> request.
:- mode satisfy_request == request >> ground.
</pre>
<p><code>inst</code> and <code>mode</code> declarations can be parametric.
For example, the following declaration
<br><pre>:- inst maybeskel(Inst) ---> no ; yes(Inst).
</pre>
<p>defines the inst <code>listskel(Inst)</code> to be a list skeleton
whose elements have inst <code>Inst</code>; you can the use insts
such as <code>listskel(listskel(free))</code>, which represents
the instantiation state of a list of lists of free variables.
The standard library provides the parametric modes
<br><pre>:- mode in(Inst) == Inst >> Inst.
:- mode out(Inst) == free >> Inst.
</pre>
<p>so that for example the mode <code>create_request</code> defined above
could have be defined as
<br><pre>:- mode create_request == out(request).
</pre>
<p>There must not be more than one inst definition with the same name
and arity in the same module. Similarly, there must not be more
than one mode definition with the same name and arity in the same module.
<p><hr>
Node:<a name="Predicate%20and%20function%20mode%20declarations">Predicate and function mode declarations</a>,
Next:<a rel=next href="#Constrained%20polymorphic%20modes">Constrained polymorphic modes</a>,
Previous:<a rel=previous href="#Insts%20modes%20and%20mode%20definitions">Insts modes and mode definitions</a>,
Up:<a rel=up href="#Modes">Modes</a>
<br>
<h3>Predicate and function mode declarations</h3>
<p>A <dfn>predicate mode declaration</dfn>
assigns a mode mapping to each argument of a predicate.
A <dfn>function mode declaration</dfn>
assigns a mode mapping to each argument of a function,
and a mode mapping to the function result.
Each mode of a predicate or function is called a <dfn>procedure</dfn>.
For example, given the mode names defined by
<br><pre>:- mode out_listskel ==
free >> listskel.
:- mode in_listskel ==
listskel >> listskel.
</pre>
<p>the (type and) mode declarations of the function length and predicate append
are as follows:
<br><pre>:- func length(list(T)) = int.
:- mode length(in_listskel) = out.
:- mode length(out_listskel) = in.
:- pred append(list(T), list(T), list(T)).
:- mode append(in, in, out).
:- mode append(out, out, in).
</pre>
<p>Note that functions may have more than one mode, just like predicates;
functions can be reversible.
<p>Alternately, the mode declarations for <code>length</code> could use
the standard library modes <code>in/1</code> and <code>out/1</code>:
<br><pre>:- func length(list(T)) = int.
:- mode length(in(listskel)) = out.
:- mode length(out(listskel)) = in.
</pre>
<p>As for type declarations, a predicate or function can be defined
to have a given higher-order inst (see <a href="#Higher-order%20modes">Higher-order modes</a>) by using
<code>`with_inst`</code> in the mode declaration.
<p>For example,
<br><pre>:- inst foldl_pred == (pred(in, in, out) is det).
:- inst foldl_func == (func(in, in) = out is det).
:- mode p(in) `with_inst` foldl_pred.
:- mode f(in) `with_inst` foldl_func.
</pre>
<p>is equivalent to
<br><pre>:- mode p(in, in, in, out) is det.
:- mode f(in, in, in) = out is det.
</pre>
<p>(<code>is det</code> is explained in <a href="#Determinism">Determinism</a>.)
<p>If a predicate or function has only one mode, the <code>pred</code> and <code>mode</code>
declaration can be combined:
<br><pre>:- func length(list(T)::in) = (int::out).
:- pred append(list(T)::in, list(T)::in, list(T)::out).
:- pred p `with_type` foldl_pred(T, U) `with_inst` foldl_pred.
</pre>
<p>If there is no mode declaration for a function, the compiler assumes
a default mode for the function in which all the arguments have mode <code>in</code>
and the result of the function has mode <code>out</code>. (However, there
is no requirement that a function have such a mode; if there is any
explicit mode declaration, it overrides the default.)
<p>A function or predicate mode declaration is an assertion by the programmer
that for all possible argument terms and (if applicable) result term
for the function or predicate
that are approximated (in our technical sense)
by the initial instantiatedness trees of the mode declaration
and all of whose free variables are distinct,
if the function or predicate succeeds then
the resulting binding of those argument terms and (if applicable)
result term will in turn be approximated
by the final instantiatedness trees of the mode declaration,
with all free variables again being distinct.
We refer to such assertions as <dfn>mode declaration constraints</dfn>.
These assertions are checked by the compiler,
which rejects programs if it cannot prove
that their mode declaration constraints are satisfied.
<p>Note that with the usual definition of append, the mode
<br><pre>:- mode append(in_listskel, in_listskel, out_listskel).
</pre>
<p>would not be allowed, since it would create aliasing between the
different arguments -- on success of the predicate, the list elements
would be free variables but they would not be distinct.
<p>In Mercury it is always possible to call a procedure with an
argument that is is more bound than the initial inst specified for that
argument in the procedure's mode declaration. In such cases, the
compiler will insert additional unifications to ensure that the
argument actually passed to the procedure will have the inst specified.
For example, if the predicate <code>p/1</code> has mode <code>p(out)</code>, you
can still call <code>p(X)</code> if <code>X</code> is ground. The compiler will
transform this code to <code>p(Y), X = Y</code> where <code>Y</code> is a fresh
variable. It is almost as if the predicate <code>p/1</code> has another mode
<code>p(in)</code>; we call such modes "implied modes".
<p>To make this concept precise, we introduce the following definition.
A term <dfn>satisfies</dfn> an instantiatedness tree
if for every node in the instantiatedness tree,
<ul>
<li>if the node is "free",
then the corresponding node in the term (if any)
is either a distinct free variable,
or a function symbol.
<li>if the node is "bound",
then the corresponding node in the term (if any)
is a function symbol.
</ul>
<p>The <dfn>mode set</dfn> for a predicate or function
is the set of mode declarations for the predicate or function.
A mode set is an assertion by the programmer
that the predicate should only be called with argument terms
that satisfy the initial instantiatedness trees
of one of the mode declarations in the set
(i.e. the specified modes and the modes they imply
are the only allowed modes for this predicate or function).
We refer to the assertion associated with a mode set
as the <dfn>mode set constraint</dfn>;
these are also checked by the compiler.
<p>A predicate or function <var>p</var> is <dfn>well-moded
with respect to a given mode declaration</dfn>
if given that the predicates and functions called by <var>p</var>
all satisfy their mode declaration constraints,
there exists an ordering of the conjuncts in each conjunction
in the clauses of <var>p</var> such that
<ul>
<li><var>p</var> satisfies its mode declaration constraint, and
<li><var>p</var> satisfies the mode set constraint of all of the predicates and
functions it calls
</ul>
<p>We say that a predicate or function is well-moded
if it is well-moded with respect to
all the mode declarations in its mode set,
and we say that a program is well-moded
if all its predicates and functions are well-moded.
<p>The mode analysis algorithm checks one procedure at a time.
It abstractly interprets the definition of the predicate or function,
keeping track of the instantiatedness of each variable,
and selecting a mode for each call and unification in the definition.
To ensure that
the mode set constraints of called predicates and functions are satisfied,
the compiler may reorder the elements of conjunctions;
it reports an error if no satisfactory order exists.
Finally it checks that
the resulting instantiatedness of the procedure's arguments
is the same as the one given by the procedure's declaration.
<p>The mode analysis algorithm annotates each call with the mode used.
<p><hr>
Node:<a name="Constrained%20polymorphic%20modes">Constrained polymorphic modes</a>,
Next:<a rel=next href="#Different%20clauses%20for%20different%20modes">Different clauses for different modes</a>,
Previous:<a rel=previous href="#Predicate%20and%20function%20mode%20declarations">Predicate and function mode declarations</a>,
Up:<a rel=up href="#Modes">Modes</a>
<br>
<h3>Constrained polymorphic modes</h3>
<p>Mode declarations for predicates and functions may also have inst parameters.
However, such parameters must be constrained to be <em>compatible</em> with some
other inst.
In a predicate or function mode declaration,
an inst of the form <code><var>InstParam</var> =< <var>Inst</var></code>,
where <var>InstParam</var> is a variable and <var>Inst</var> is an inst,
states that
<var>InstParam</var> is constrained to be <em>compatible</em> with <var>Inst</var>,
that is,
<var>InstParam</var> represents some inst that can be used anywhere where
<var>Inst</var> is required.
If an inst parameter occurs more than once in a declaration, it must have the
same constraint on each occurrence.
<p>For example, in the mode declaration
<br><pre> :- mode append(in(list_skel(I =< ground)), in(list_skel(I =< ground)),
out(list_skel(I =< ground))).
</pre>
<p><code>I</code> is an inst parameter which is constrained to be ground.
If <code>append</code> is called with the first two arguments having an inst of, say,
<code>list_skel(bound(f))</code> then after <code>append</code> returns, all three arguments
will have inst <code>list_skel(bound(f))</code>.
If the mode of append had been simply
<br><pre> :- mode append(in(list_skel(ground)), in(list_skel(ground)),
out(list_skel(ground))).
</pre>
<p>then we would only have been able to infer an inst of <code>list_skel(ground)</code>
for the third argument, not the more specific inst.
<p>Note that attempting to call <code>append</code> when the first two arguments do not
have ground insts (e.g. <code>list_skel(bound(g(free)))</code>) is a mode error
because it violates the constraint on the inst parameter.
<p>To avoid having to repeat a constraint everywhere that an inst parameter occurs,
it is possible to list the constraints after the rest of the mode declaration,
following a <code><=</code>.
E.g. the above example could have been written as
<br><pre> :- mode append(in(list_skel(I)), in(list_skel(I)), out(list_skel(I)))
<= I =< ground.
</pre>
<p>Also, if the constraint on an inst parameter is <code>ground</code> then it
is not necessary to give the constraint in the declaration.
The example can be further shortened to
<br><pre> :- mode append(in(list_skel(I)), in(list_skel(I)), out(list_skel(I))).
</pre>
<p>Constrained polymorphic modes are particularly useful when passing
objects with higher-order types to polymorphic predicates
since they allow the higher-order mode information to be retained
(see <a href="#Higher-order">Higher-order</a>).
<p><hr>
Node:<a name="Different%20clauses%20for%20different%20modes">Different clauses for different modes</a>,
Previous:<a rel=previous href="#Constrained%20polymorphic%20modes">Constrained polymorphic modes</a>,
Up:<a rel=up href="#Modes">Modes</a>
<br>
<h3>Different clauses for different modes</h3>
<p>Because the compiler automatically reorders conjunctions to
satisfy the modes, it is often possible for a single clause
to satisfy different modes. However, occasionally reordering
of conjunctions is not sufficient; you may want to write different
code for different modes.
<p>For example, the usual code for list append
<br><pre> append([], Ys, Ys).
append([X|Xs], Ys, [X|Zs]) :- append(Xs, Ys, Zs).
</pre>
<p>works fine in most modes, but is not very satisfactory for the
<code>append(out, in, in)</code> mode of append, because although
every call in this mode only has at most one solution,
the compiler's determinism inference will not be able to
infer that. This means that using the usual code for append in
this mode will be inefficient, and the overly conservative determinism
inference may cause spurious determinism errors later.
<p>For this mode, it is better to use a completely different algorithm:
<br><pre> append(Prefix, Suffix, List) :-
list__length(List, ListLength),
list__length(Suffix, SuffixLength),
PrefixLength is ListLength - SuffixLength,
list__split_list(PrefixLength, List, Prefix, Suffix).
</pre>
<p>However, that code doesn't work in the other modes of append.
<p>To handle such cases, you can use mode annotations on clauses, which
indicate that particular clauses should only be used for particular modes.
To specify that a clause only applies to a given mode, each argument
<var>Arg</var> of the clause head should be annotated with the corresponding
argument mode <var>Mode</var>, using the <code>::</code> mode qualification operator,
i.e. <code><var>Arg</var> :: <var>Mode</var></code>.
<p>For example, if append was declared as
<br><pre> :- pred append(list(T), list(T), list(T)).
:- mode append(in, in, out).
:- mode append(out, out, in).
:- mode append(in, out, in).
:- mode append(out, in, in).
</pre>
<p>then you could implement it as
<br><pre> append(L1::in, L2::in, L3::out) :- usual_append(L1, L2, L3).
append(L1::out, L2::out, L3::in) :- usual_append(L1, L2, L3).
append(L1::in, L2::out, L3::in) :- usual_append(L1, L2, L3).
append(L1::out, L2::in, L3::in) :- other_append(L1, L2, L3).
usual_append([], Ys, Ys).
usual_append([X|Xs], Ys, [X|Zs]) :- usual_append(Xs, Ys, Zs).
other_append(Prefix, Suffix, List) :-
list__length(List, ListLength),
list__length(Suffix, SuffixLength),
PrefixLength is ListLength - SuffixLength,
list__split_list(PrefixLength, List, Prefix, Suffix).
</pre>
<p>This language feature can be used to write "impure" code that
doesn't have any consistent declarative semantics. For example,
you can easily use it to write something similar to Prolog's (in)famous
var/1 predicate:
<br><pre> :- mode var(in).
:- mode var(free>>free).
var(_::in) :- fail.
var(_::free>>free) :- true.
</pre>
<p>As you can see, in this case the two clauses are <em>not</em> equivalent.
<p>Because of this possibility, predicates or functions which are defined
using different code for different modes are by default assumed to be
impure; the programmer must either (1) carefully ensure that the
logical meaning of the clauses is the same for all modes,
in which case a <code>pragma promise_pure</code> declaration can be used
or (2) declare the predicate or function as impure.
See <a href="#Impurity">Impurity</a>.
<p>In the example with <code>append</code> above, the two ways of implementing
append do have the same declarative semantics, so we can safely use
the first approach:
<br><pre> :- pragma promise_pure(append/3).
</pre>
<p>In the example with <code>var/1</code> above, the two clauses have different
semantics, so the predicate must be declared as impure:
<br><pre> :- impure pred var(T).
</pre>
<p><hr>
Node:<a name="Unique%20modes">Unique modes</a>,
Next:<a rel=next href="#Determinism">Determinism</a>,
Previous:<a rel=previous href="#Modes">Modes</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Unique modes</h2>
<p>Mode declarations can also specify so-called "unique modes".
Mercury's unique modes are similar to "linear types" in some
functional programming languages such as Clean. They allow you to
specify when there is only one reference to a particular value, and
when there will be no more references to that value. If the compiler
knows there will be no more references to a value, it can perform
"compile-time garbage collection" by automatically inserting code
to deallocate the storage associated with that value. Even more
importantly, the compiler can also simply reuse the storage immediately,
for example by destructively updating one element of an array rather
than making a new copy of the entire array in order to change one element.
Unique modes are also the mechanism Mercury uses to provide declarative I/O.
<p>We have not yet implemented unique modes fully, and the details are
still in a state of flux. So the following should be considered
tentative.
<ul>
<li><a href="#Destructive%20update">Destructive update</a>:
<li><a href="#Backtrackable%20destructive%20update">Backtrackable destructive update</a>:
<li><a href="#Limitations%20of%20the%20current%20implementation">Limitations of the current implementation</a>:
</ul>
<p><hr>
Node:<a name="Destructive%20update">Destructive update</a>,
Next:<a rel=next href="#Backtrackable%20destructive%20update">Backtrackable destructive update</a>,
Up:<a rel=up href="#Unique%20modes">Unique modes</a>
<br>
<h3>Destructive update</h3>
<p>In addition to the insts mentioned above (<code>free</code>, <code>ground</code>,
and <code>bound(<small>...</small>)</code>), Mercury also provides "unique" insts
<code>unique</code> and <code>unique(<small>...</small>)</code> which are like <code>ground</code>
and <code>bound(<small>...</small>)</code> respectively, except that they carry the
additional constraint that there can only be one reference to the
corresponding value. There is also an inst <code>dead</code> which means
that there are no references to the corresponding value, so the compiler
is free to generate code that reuses that value.
There are three standard modes for manipulation unique values:
<br><pre>% unique output
:- mode uo == free >> unique.
% unique input
:- mode ui == unique >> unique.
% destructive input
:- mode di == unique >> dead.
</pre>
<p>Mode <code>uo</code> is used to create a unique value.
Mode <code>ui</code> is used to inspect a unique value without
losing its uniqueness.
Mode <code>di</code> is used to deallocate or reuse the memory
occupied by a value that will not be used.
<p>Note that a value is not considered <code>unique</code> if it might be
needed on backtracking. This means that unique modes are generally
only useful for code whose determinism is <code>det</code> or <code>cc_multi</code>
(see <a href="#Determinism">Determinism</a>).
<p>Unlike <code>bound</code> instantiatedness trees, there is no alternative
syntax for <code>unique</code> instantiatedness trees.
<p><hr>
Node:<a name="Backtrackable%20destructive%20update">Backtrackable destructive update</a>,
Next:<a rel=next href="#Limitations%20of%20the%20current%20implementation">Limitations of the current implementation</a>,
Previous:<a rel=previous href="#Destructive%20update">Destructive update</a>,
Up:<a rel=up href="#Unique%20modes">Unique modes</a>
<br>
<h3>Backtrackable destructive update</h3>
<blockquote>
"Well it just so happens that your friend here is only <em>mostly</em> dead.
<br>There's a big difference between mostly dead and all dead<small>...</small>
<br>Now, mostly dead is slightly alive.
<br>Now, all dead -- well, with all dead, there's usually only
one thing that you can do."
<p>"What's that?"
<p>"Go through his clothes and look for loose change!"
<p>-- from the movie "The Princess Bride".
</blockquote>
<p>To allow for backtrackable destructive updates -- that is, updates
whose effect is undone on backtracking, perhaps by recording the
overwritten values on a "trail" so that they can be restored
after backtracking -- Mercury also provides "mostly unique"
modes. The insts <code>mostly_unique</code> and <code>mostly_dead</code>
are equivalent to <code>unique</code> and <code>dead</code>,
except that only references which will be encountered during
forward execution are counted -- it is OK for <code>mostly_unique</code> or
<code>mostly_dead</code> values to be needed again on backtracking.
<p>Mercury defines some standard modes for manipulating "mostly unique"
values, just as it does for unique values:
<br><pre>% mostly unique output
:- mode muo == free >> mostly_unique.
% mostly unique input
:- mode mui == mostly_unique >> mostly_unique.
% mostly destructive input
:- mode mdi == mostly_unique >> mostly_dead.
</pre>
<p><hr>
Node:<a name="Limitations%20of%20the%20current%20implementation">Limitations of the current implementation</a>,
Previous:<a rel=previous href="#Backtrackable%20destructive%20update">Backtrackable destructive update</a>,
Up:<a rel=up href="#Unique%20modes">Unique modes</a>
<br>
<h3>Limitations of the current implementation</h3>
<p>The implementation of the mode analysis algorithm is not quite complete;
as a result, it is not possible to use nested unique modes, i.e.
modes in which anything but the top level of a variable is unique.
If you do, you will get unique mode errors when you try
to get a unique field of a unique data structure.
It is also not possible to use unique-input modes;
only destructive-input and unique-output modes work.
<p>The Mercury compiler does not (yet) reuse <code>dead</code>
values. The only destructive update in the current implementation occurs
in library modules, e.g. for I/O and arrays. We do however plan to
implement structure reuse and compile-time garbage collection
in the very near future.
<p><hr>
Node:<a name="Determinism">Determinism</a>,
Next:<a rel=next href="#User-defined%20equality%20and%20comparison">User-defined equality and comparison</a>,
Previous:<a rel=previous href="#Unique%20modes">Unique modes</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Determinism</h2>
<ul>
<li><a href="#Determinism%20categories">Determinism categories</a>:
<li><a href="#Determinism%20checking%20and%20inference">Determinism checking and inference</a>:
<li><a href="#Replacing%20compile-time%20checking%20with%20run-time%20checking">Replacing compile-time checking with run-time checking</a>:
<li><a href="#Interfacing%20nondeterministic%20code%20with%20the%20real%20world">Interfacing nondeterministic code with the real world</a>:
<li><a href="#Committed%20choice%20nondeterminism">Committed choice nondeterminism</a>:
</ul>
<p><hr>
Node:<a name="Determinism%20categories">Determinism categories</a>,
Next:<a rel=next href="#Determinism%20checking%20and%20inference">Determinism checking and inference</a>,
Up:<a rel=up href="#Determinism">Determinism</a>
<br>
<h3>Determinism categories</h3>
<p>For each mode of a predicate or function,
we categorise that mode according to how many times it can succeed,
and whether or not it can fail before producing its first solution.
<p>If all possible calls to a particular mode of a predicate or function
which return to the caller (calls which terminate, do not throw
an exception and do not cause a fatal runtime error)
<ul>
<li>have exactly one solution,
then that mode is <dfn>deterministic</dfn> (<code>det</code>);
<li>either have no solutions or have one solution,
then that mode is <dfn>semideterministic</dfn> (<code>semidet</code>);
<li>have at least one solution but may have more,
then that mode is <dfn>multisolution</dfn> (<code>multi</code>);
<li>have zero or more solutions,
then that mode is <dfn>nondeterministic</dfn> (<code>nondet</code>);
<li>fail without producing a solution,
then that mode has a determinism of <code>failure</code>.
</ul>
<p>If no possible calls to a particular mode of a predicate or
function can return to the caller, then that mode has a
determinism of <code>erroneous</code>.
<p>The determinism annotation <code>erroneous</code> is used on the library
predicates <code>require__error/1</code> and <code>exception__throw/1</code>,
but apart from that determinism annotations <code>erroneous</code> and
<code>failure</code> are generally not needed.
<p>To summarize:
<br><pre> Maximum number of solutions
Can fail? 0 1 > 1
no erroneous det multi
yes failure semidet nondet
</pre>
<p>(Note: the "Can fail?" column here indicates only whether the procedure
can fail before producing at least one solution; attempts to find a
<em>second</em> solution to a particular call, e.g. for a procedure
with determinism <code>multi</code>, are always allowed to fail.)
<p>The determinism of each mode of a predicate or function
is indicated by an annotation on the mode declaration.
For example:
<br><pre>:- pred append(list(T), list(T), list(T)).
:- mode append(in, in, out) is det.
:- mode append(out, out, in) is multi.
:- mode append(in, in, in) is semidet.
:- func length(list(T)) = int.
:- mode length(in) = out is det.
:- mode length(in(list_skel)) = out is det.
:- mode length(in) = in is semidet.
</pre>
<p>An annotation of <code>det</code> or <code>multi</code> is an assertion that
for every value each of the inputs, there exists at least one value
of the outputs for which the predicate is true, or (in the case
of functions) for which the function term is equal to the result term.
Conversely, an annotation of <code>det</code> or <code>semidet</code> is an assertion
that for every value each of the inputs, there exists at most one value
of the outputs for which the predicate is true, or (in the case
of functions) for which the function term is equal to the result term.
These assertions are called the <dfn>mode-determinism assertions</dfn>;
they can play a role in the semantics, because in certain
circumstances they may allow an implementation to perform optimizations
that would not otherwise be allowed, such as optimizing away a goal
with no outputs even though it might infinitely loop.
<p>If the mode of the predicate is given in the <code>:- pred</code> declaration
rather than in a separate <code>:- mode</code> declaration,
then the determinism annotation goes on the <code>:- pred</code> declaration
(and similarly for functions).
In particular, this is necessary
if a predicate does not have any argument variables.
If the determinism declaration is given on a <code>:- func</code> declaration
without the mode, the function is assumed to have the default mode
(see <a href="#Modes">Modes</a> for more information on default modes of functions).
<p>For example:
<br><pre>:- pred loop(int::in) is erroneous.
loop(X) :- loop(X).
:- pred p is det.
p.
:- pred q is failure.
q :- fail.
</pre>
<p>If there is no mode declaration for a function, then the default
mode for that function is considered to have been declared as <code>det</code>.
If you want to write a partial function, i.e. one whose determinism
is <code>semidet</code>, then you must explicitly declare the mode and determinism.
<p>In Mercury, a function is supposed to be a true mathematical function
of its arguments; that is, the value of the function's result should
be determined only by the values of its arguments. Hence, for
any mode of a function that specifies that all the arguments are fully
input (i.e. for which the initial inst of all the arguments is a ground inst),
the determinism of that mode can only be
<code>det</code>, <code>semidet</code>, <code>erroneous</code>, or <code>failure</code>.
<p>The determinism categories form this lattice:
<br><pre> erroneous
/ \
failure det
\ / \
semidet multi
\ /
nondet
</pre>
<p>The higher up this lattice a determinism category is,
the more the compiler knows about the number of solutions
of procedures of that determinism.
<p><hr>
Node:<a name="Determinism%20checking%20and%20inference">Determinism checking and inference</a>,
Next:<a rel=next href="#Replacing%20compile-time%20checking%20with%20run-time%20checking">Replacing compile-time checking with run-time checking</a>,
Previous:<a rel=previous href="#Determinism%20categories">Determinism categories</a>,
Up:<a rel=up href="#Determinism">Determinism</a>
<br>
<h3>Determinism checking and inference</h3>
<p>The determinism of goals
is inferred from the determinism of their component parts,
according to the rules below.
The inferred determinism of a procedure is just the inferred
determinism of the procedure's body.
<p>For procedures that are local to a module,
the determinism annotations may be omitted;
in that case, their determinism will be inferred.
(To be precise, the determinism of procedures without a determinism annotation
is defined as the least fixpoint of the transformation which,
given an initial assignment
of the determinism <code>det</code> to all such procedures,
applies those rules to infer
a new determinism assignment for those procedures.)
<p>It is an error to omit the determinism annotation
for procedures that are exported from their containing module.
<p>If a determinism annotation is supplied for a procedure,
the declared determinism is compared against the inferred determinism.
If the declared determinism is greater than or not comparable to the
inferred determinism (in the partial ordering above), it is an error.
If the declared determinism is less than the inferred determinism,
it is not an error, but the implementation may issue a warning.
<p>The determinism category of each goal
is inferred according to the following rules.
These rules work with the two components of determinism category:
whether the goal can fail without producing a solution,
and the maximum number of solutions of the goal (0, 1, or more).
If the inference process below reports that a goal can succeed more than once,
but the goal generates no outputs that are visible from outside the goal,
and the goal is not impure (see <a href="#Impurity">Impurity</a>),
then the final determinism of the goal
will be based on the goal succeeding at most once,
since the compiler will implicitly prune away any duplicate solutions.
<dl>
<dt>Calls
<dd>The determinism category of a call is the determinism
declared or inferred for the called mode of the called procedure.
<br><dt>Unifications
<dd>The determinism of a unification
is either <code>det</code>, <code>semidet</code>, or <code>failure</code>,
depending on its mode.
<p>A unification that assigns the value of one variable to another
is deterministic.
A unification that constructs a structure and assigns it to a variable
is also deterministic.
A unification that tests whether a variable has a given top function symbol
is semideterministic,
unless the compiler knows the top function symbol of that variable,
in which case its determinism is either det or failure
depending on whether the two function symbols are the same or not.
A unification that tests two variables for equality
is semideterministic,
unless the compiler knows that the two variables are aliases for one another,
in which case the unification is deterministic,
or unless the compiler knows that the two variables
have different function symbols in the same position,
in which case the unification has a determinism of failure.
<p>The compiler knows the top function symbol of a variable
if the previous part of the procedure definition
contains a unification of the variable with a function symbol,
or if the variable's type has only one function symbol.
<br><dt>Conjunctions
<dd>The determinism of the empty conjunction (the goal <code>true</code>)
is <code>det</code>.
The conjunction <code>(<var>A</var>, <var>B</var>)</code> can fail
if either <var>A</var> can fail, or if <var>A</var> can succeed at least once,
and <var>B</var> can fail.
The conjunction can succeed at most zero times
if either <var>A</var> or <var>B</var> can succeed at most zero times.
The conjunction can succeed more than once
if either <var>A</var> or <var>B</var> can succeed more than once
and both <var>A</var> and <var>B</var> can succeed at least once.
(If e.g. <var>A</var> can succeed at most zero times,
then even if <var>B</var> can succeed many times
the maximum number of solutions of the conjunction is still zero.)
Otherwise, i.e. if both <var>A</var> and <var>B</var> succeed at most once,
the conjunction can succeed at most once.
<br><dt>Switches
<dd>A disjunction is a <em>switch</em>
if each disjunct has near its start a unification that
tests the same bound variable against a different function symbol.
For example, consider the common pattern
<br><pre>(
L = [], empty(Out)
;
L = [H|T], nonempty(H, T, Out)
)
</pre>
<p>If L is input to the disjunction, then the disjunction is a switch on L.
<p>A switch can fail
if the various arms of the switch do not cover
all the function symbols in the type of the switched-on variable,
or if the code in some arms of the switch can fail,
bearing in mind that in each arm of the switch,
the unification that tests the switched-on variable
against the function symbol of that arm is considered to be deterministic.
A switch can succeed several times
if some arms of the switch can succeed several times,
possibly because there are multiple disjuncts
that test the switched-on variable against the same function symbol.
A switch can succeed at most zero times
only if all arms of the switch can succeed at most zero times.
<p>Only unifications may occur before the test of the switched-on variable
in each disjunct. Tests of the switched-on variable may occur within
existential quantification goals.
<p>The following example is a switch.
<br><pre>(
Out = 1, L = []
;
some [H, T] (
L = [H|T],
nonempty(H, T, Out)
)
)
</pre>
<p>The following example is not a switch because the call in the first
disjunct occurs before the test of the switched-on variable.
<br><pre>(
empty(Out), L = []
;
L = [H|T], nonempty(H, T, Out)
)
</pre>
<br><dt>Disjunctions
<dd>The determinism of the empty disjunction (the goal <code>fail</code>)
is <code>failure</code>.
A disjunction <code>(<var>A</var> ; <var>B</var>)</code> that is not a switch
can fail if both <var>A</var> and <var>B</var> can fail.
It can succeed at most zero times
if both <var>A</var> and <var>B</var> can succeed at most zero times.
It can succeed at most once
if one of <var>A</var> and <var>B</var> can succeed at most once
and the other can succeed at most zero times.
Otherwise, i.e. if either <var>A</var> or <var>B</var> can succeed more than once,
or if both <var>A</var> and <var>B</var> can succeed at least once,
it can succeed more than once.
<br><dt>If-then-else
<dd>
If the condition of an if-then-else cannot fail, the if-then-else
is equivalent to the conjunction of the condition and the "then" part,
and its determinism is computed accordingly.
Otherwise,
an if-then-else can fail if either the "then" part or the "else" part
can fail.
It can succeed at most zero times
if the "else" part can succeed at most zero times
and if at least one of the condition and the "then" part
can succeed at most zero times.
It can succeed more than once
if any one of the condition, the "then" part and the "else" part
can succeed more than once.
<br><dt>Negations
<dd>
If the determinism of the negated goal is <code>erroneous</code>,
then the determinism of the negation is <code>erroneous</code>.
If the determinism of the negated goal is <code>failure</code>,
the determinism of the negation is <code>det</code>.
If the determinism of the negated goal is <code>det</code> or <code>multi</code>,
the determinism of the negation is <code>failure</code>.
Otherwise, the determinism of the negation is <code>semidet</code>.
</dl>
<p><hr>
Node:<a name="Replacing%20compile-time%20checking%20with%20run-time%20checking">Replacing compile-time checking with run-time checking</a>,
Next:<a rel=next href="#Interfacing%20nondeterministic%20code%20with%20the%20real%20world">Interfacing nondeterministic code with the real world</a>,
Previous:<a rel=previous href="#Determinism%20checking%20and%20inference">Determinism checking and inference</a>,
Up:<a rel=up href="#Determinism">Determinism</a>
<br>
<h3>Replacing compile-time checking with run-time checking</h3>
<p>Note that "perfect" determinism inference is an undecidable problem,
because it requires solving the halting problem.
(For instance, in the following example
<br><pre>:- pred p(T, T).
:- mode p(in, out) is det.
p(A, B) :-
(
something_complicated(A, B)
;
B = A
).
</pre>
<p><code>p/2</code> can have more than one solution
only if <code>something_complicated</code> can succeed.)
Sometimes, the rules specified by the Mercury language
for determinism inference will infer a determinism
that is not as precise as you would like.
However, it is generally easy to overcome such problems.
The way to do this is to replace the compiler's static checking
with some manual run-time checking.
For example, if you know that a particular goal should never fail,
but the compiler infers that goal to be <code>semidet</code>,
you can check at runtime that the goal does succeed,
and if it fails, call the library predicate <code>error/1</code>.
<br><pre>:- pred q(T, T).
:- mode q(in, out) is det.
q(A, B) :-
( goal_that_should_never_fail(A, B0) ->
B = B0
;
error("goal_that_should_never_fail failed!")
).
</pre>
<p>The predicate <code>error/1</code> has determinism <code>erroneous</code>,
which means the compiler knows that it will never succeed or fail,
so the inferred determinism for the body of <code>q/2</code> is <code>det</code>.
(Checking assumptions like this is good coding style anyway.
The small amount of up-front work that Mercury requires
is paid back in reduced debugging time.)
Mercury's mode analysis knows that
computations with determinism erroneous can never succeed,
which is why it does not require the "else" part to generate
a value for <code>B</code>.
The introduction of the new variable <code>B0</code> is necessary
because the condition of an if-then-else is a negated context,
and can export the values it generates
only to the "then" part of the if-then-else,
not directly to the surrounding computation.
(If the surrounding computations had direct access
to values generated in conditions,
they might access them even if the condition failed.)
<p><hr>
Node:<a name="Interfacing%20nondeterministic%20code%20with%20the%20real%20world">Interfacing nondeterministic code with the real world</a>,
Next:<a rel=next href="#Committed%20choice%20nondeterminism">Committed choice nondeterminism</a>,
Previous:<a rel=previous href="#Replacing%20compile-time%20checking%20with%20run-time%20checking">Replacing compile-time checking with run-time checking</a>,
Up:<a rel=up href="#Determinism">Determinism</a>
<br>
<h3>Interfacing nondeterministic code with the real world</h3>
<p>Normally, attempting to call
a <code>nondet</code> or <code>multi</code> mode of a predicate
from a predicate declared as <code>semidet</code> or <code>det</code>
will cause a determinism error.
So how can we call nondeterministic code from deterministic code?
There are several alternative possibilities.
<p>If you just want to see if a nondeterministic goal is satisfiable or not,
without needing to know what variable bindings it produces,
then there is no problem -
determinism analysis considers <code>nondet</code> and <code>multi</code> goals
with no non-local output variables to be
<code>semidet</code> and <code>det</code> respectively.
<p>If you want to use the values of output variables,
then you need to ask yourself
which one of possibly many solutions to a goal do you want?
If you want all of them, you need to use the predicate
<code>solutions/2</code> in the standard library module <code>std_util</code>,
which collects all of the solutions to a goal into a list --
see <a href="#Higher-order">Higher-order</a>.
<p>If you just want one solution and don't care which,
the calling predicate should be declared <code>nondet</code> or <code>multi</code>.
The nondeterminism should then be propagated up the call tree
to the point at which it can be pruned.
In Mercury, pruning can be achieved in several ways.
<p>The first way is the one mentioned above:
if a goal has no non-local output variables
then the implementation will only attempt to satisfy the goal once.
Any potential duplicate solutions will be implicitly pruned away.
<p>The second way is to rely on the fact that
the implementation will only seek a single solution to <code>main/2</code>,
so alternative solutions to <code>main/2</code>
(and hence also to <code>nondet</code> or <code>multi</code> predicates
called directly or indirectly from <code>main/2</code>)
are implicitly pruned away.
This is one way to achieve "don't care" style nondeterminism in Mercury.
<p>The other situation in which you may want pruning
and committed choice style nondeterminism
is when you know that all the solutions returned will be equivalent.
For example, you might want to find the maximum element in a set
by iterating over the elements in the set.
Iterating over the elements in a set in an unspecified order is a
nondeterministic operation,
but no matter which order you remove them,
the maximum value in the set should be the same.
<p>If you know that there will only ever be at most one distinct
solution, then you can use the function
<code>promise_only_solution/1</code>, which is defined
as a builtin function in the Mercury standard library.
<br><pre>:- func promise_only_solution(pred(T)) = T.
:- mode promise_only_solution(pred(out) is cc_multi) = out is det.
:- mode promise_only_solution(pred(out) is cc_nondet) = out is semidet.
</pre>
<p>A call to that function, e.g. <code>promise_only_solution(Pred)</code>, constitutes a
promise on the part of the caller that the argument <code>Pred</code> has at most
one solution, i.e. that
<br><pre>not some [X1, X2] (Pred(X1), Pred(X2), X1 \= X2)
</pre>
<p>holds. <code>promise_only_solution(Pred)</code> presumes that this
assumption is satisfied, and returns the value of <code>X</code> for which
<code>Pred(X)</code> is true, if any. If the assumption is not
satisfied, then the behaviour is undefined.
<p>Note that specifying a user-defined equivalence relation
as the equality predicate for user-defined types
(see <a href="#User-defined%20equality%20and%20comparison">User-defined equality and comparison</a>)
means that the <code>promise_only_solution/1</code> function
can be used to express more general forms of equivalence.
For example, if you define a set type which represents sets as unsorted lists,
you would want to define a user-defined equivalence relation for that type,
which could sort the lists before comparing them.
The <code>promise_only_solution/1</code> function could then be used for sets
even though the lists used to represent the sets
might not be in the same order in every solution.
<p><hr>
Node:<a name="Committed%20choice%20nondeterminism">Committed choice nondeterminism</a>,
Previous:<a rel=previous href="#Interfacing%20nondeterministic%20code%20with%20the%20real%20world">Interfacing nondeterministic code with the real world</a>,
Up:<a rel=up href="#Determinism">Determinism</a>
<br>
<h3>Committed choice nondeterminism</h3>
<p>In addition to the determinism annotations described earlier, there are
"committed choice" versions of <code>multi</code>
and <code>nondet</code>, called <code>cc_multi</code> and <code>cc_nondet</code>.
These can be used instead of <code>multi</code> or <code>nondet</code> if all calls
to that mode of the predicate (or function) occur in a context in
which only one solution is needed.
<p>Such single-solution contexts are determined as follows.
<ul>
<li>The body of any procedure declared <code>cc_multi</code> or
<code>cc_nondet</code> is in a single-solution context.
For example, the program entry point <code>main/2</code> may
be declared <code>cc_multi</code>, and in that case the clauses
for <code>main</code> are in a single-solution context.
<li>Any goal with no output variables is in a single-solution context.
<li>If a conjunction is in a single-solution context, then
the right-most conjunct is in a single-solution context,
and if the right-most conjunct cannot fail,
then rest of the conjunction is also in a single-solution
context.
("Right-most" here refers to the order <em>after</em> mode reordering.)
<li>If an if-then-else is in a single-solution context, then the
"then" part and the "else" part are in single-solution contexts,
and if the "then" part cannot fail, then the condition of the
if-then-else is also in a single-solution context.
<li>For other compound goals, i.e. disjunctions, negations, and
(explicitly) existentially quantified goals, if the compound goal
is in a single-solution context, then the immediate sub-goals of that
compound goal are also in single-solution contexts.
</ul>
<p>The compiler will check that all calls to a committed-choice
mode of a predicate (or function) do indeed occur in a single-solution context.
<p>You can declare two different modes of a predicate (or function) which differ
only in "cc-ness" (i.e. one being <code>multi</code> and the other
<code>cc_multi</code>, or one being <code>nondet</code> and the other <code>cc_nondet</code>).
In that case, the compiler will select the appropriate one for each
call depending on whether the call comes from a single-solution context
or not. Calls from single-solution contexts will call the committed
choice version, while calls which are not from single-solution contexts
will call the backtracking version.
<p>There are several reasons to use committed choice determinism annotations.
One reason is for efficiency: committed choice annotations allow
the compiler to generate much more efficient code.
Another reason is for doing I/O, which is allowed only in <code>det</code>
or <code>cc_multi</code> predicates, not in <code>multi</code> predicates.
Another is for dealing with types that use non-canonical representations
(see <a href="#User-defined%20equality%20and%20comparison">User-defined equality and comparison</a>).
And there are a variety of other applications.
<p><hr>
Node:<a name="User-defined%20equality%20and%20comparison">User-defined equality and comparison</a>,
Next:<a rel=next href="#Higher-order">Higher-order</a>,
Previous:<a rel=previous href="#Determinism">Determinism</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>User-defined equality and comparison</h2>
<p>When defining abstract data types,
often it is convenient to use a non-canonical representation --
that is, one for which a single abstract value may have more than
one different possible concrete representations.
For example, you may wish to implement an abstract type <code>set</code>
by representing a set as an (unsorted) list.
<br><pre>:- module set_as_unsorted_list.
:- interface.
:- type set(T).
:- implementation.
:- import_module list.
:- type set(T) ---> set(list(T)).
</pre>
<p>In this example, the concrete representations <code>set([1,2])</code> and
<code>set([2,1])</code> would both represent the same abstract value, namely
the set containing the elements 1 and 2.
<p>For types such as this, which do not have a canonical representation,
the standard definition of equality is not the desired one; we want equality on
sets to mean equality of the abstract values, not equality of their
representations. To support such types, Mercury allows programmers to
specify a user-defined equality predicate for user-defined types:
<br><pre>:- type set(T) ---> set(list(T))
where equality is set_equals.
</pre>
<p>Here <code>set_equals</code> is the name of a user-defined predicate that
is used for equality on the type <code>set(T)</code>. It could for example
be defined in terms of a <code>subset</code> predicate.
<br><pre>:- pred set_equals(set(T)::in, set(T)::in) is semidet.
set_equals(S1, S2) :-
subset(S1, S2),
subset(S2, S1).
</pre>
<p>A comparison predicate can also be supplied.
<br><pre>:- type set(T) ---> set(list(T))
where equality is set_equals, comparison is set_compare.
:- pred set_compare(builtin__comparison_result::uo,
set(T)::in, set(T)::in) is det.
set_compare(promise_only_solution(set_compare_2(Set1, Set2)), Set1, Set2).
:- pred set_compare_2(set(T)::in, set(T)::in,
builtin__comparison_result::uo) is cc_multi.
set_compare_2(set(List1), set(List2), Result) :-
builtin__compare(Result, list__sort(List1), list__sort(List2)).
</pre>
<p>If a comparison predicate is supplied and the unification predicate
is omitted, a unification predicate is generated by the compiler
in terms of the comparison predicate. For the <code>set</code> example,
the generated predicate would be:
<br><pre>set_equals(S1, S2) :-
set_compare((=), S1, S2).
</pre>
<p>If a unification predicate is supplied without a comparison predicate,
the compiler will generate a comparison predicate which throws an
exception of type <code>require__software_error</code> when called.
<p>A type declaration for a type <code>foo(T1, <small>...</small>, TN)</code> may contain a
<code>where equality is <var>equalitypred</var></code> specification only if it
declares a discriminated union type or a foreign type
(see <a href="#Using%20foreign%20types%20from%20Mercury">Using foreign types from Mercury</a>) and the
following conditions are satisfied:
<ul>
<li><var>equalitypred</var> must be the name of a predicate with signature
<br><pre>:- pred <var>equalitypred</var>(foo(T1, <small>...</small>, TN)::in,
foo(T1, <small>...</small>, TN)::in) is semidet.
</pre>
<p>It is legal for the type, mode and determinism to be more permissive:
the type or the mode's initial insts may be more general
(e.g. the type of the equality predicate could be just the polymorphic
type <code>pred(T, T)</code>) and the mode's final insts or the determinism
may be more specific (e.g. the determinism of the equality predicate
could be any of <code>det</code>, <code>failure</code> or <code>erroneous</code>).
</p><li>The equality predicate must be "pure" (see <a href="#Impurity">Impurity</a>).
<li>The equality predicate must be defined in the same module as the type.
<li>If the type is exported the equality predicate must also be exported.
<li><var>equalitypred</var> should be an equivalence relation; that is, it must be
symmetric, reflexive, and transitive. However, the compiler is not required
to check this<a rel=footnote href="#fn-3"><sup>3</sup></a>.
</ul>
<p>Types with user-defined equality can only be used in limited ways.
Because there multiple representations for the same abstract
value, any attempt to examine the representation of such a value
is a conceptually non-deterministic operation.
In Mercury this is modelled using committed choice nondeterminism.
<p>The semantics of specifying <code>where equality is <var>equalitypred</var></code>
on the type declaration for a type <var>T</var> are as follows:
<ul>
<li>If the program contains any deconstruction unification or switch
on a variable of type <var>T</var> that could fail, other than unifications
with mode <code>(in, in)</code>, then it is a compile-time error.
<li>If the program contains any deconstruction unification or switch
on a variable of type <var>T</var> that cannot fail, then that operation
has determinism <code>cc_multi</code>.
<li>Any attempts to examine the representation of a variable of type <var>T</var>
using facilities of the standard library (e.g. <code>argument</code>/3
and <code>functor/3</code> in <code>std_util</code>) that do not have determinism
<code>cc_multi</code> or <code>cc_nondet</code> will result in a run-time error.
<li>In addition to the usual equality axioms,
the declarative semantics of the program will contain the axiom
<code><var>X</var> = <var>Y</var> <=> <var>equalitypred</var>(X, Y)</code> for all
<var>X</var> and <var>Y</var> of type <code>T</code>.
<li>Any <code>(in, in)</code> unifications for type <var>T</var> are computed using the
specified predicate <var>equalitypred</var>.
</ul>
<p>A type declaration for a type <code>foo(T1, <small>...</small>, TN)</code> may contain a
<code>where comparison is <var>comparepred</var></code> specification only if it
declares a discriminated union type or a foreign type
(see <a href="#Using%20foreign%20types%20from%20Mercury">Using foreign types from Mercury</a>) and the
following conditions are satisfied:
<ul>
<li><var>comparepred</var> must be the name of a predicate with signature
<br><pre>:- pred <var>comparepred</var>(builtin__comparison_result::uo,
foo(T1, <small>...</small>, TN)::in, foo(T1, <small>...</small>, TN)::in) is det.
</pre>
<p>As with equality predicates, it is legal for the type, mode and
determinism to be more permissive.
</p><li>The comparison predicate must also be "pure" (see <a href="#Impurity">Impurity</a>).
<li>The comparison predicate must be defined in the same module as the type.
<li>If the type is exported the comparison predicate must also be exported.
<li>The relation
<br><pre>compare_eq(X, Y) :- <var>comparepred</var>((=), X, Y).
</pre>
must be an equivalence relation; that is, it must be symmetric,
reflexive, and transitive. The compiler is not required to check this.
<li>The relations
<br><pre>compare_leq(X, Y) :- <var>comparepred</var>(R, X, Y), (R = (=) ; R = (<)).
compare_geq(X, Y) :- <var>comparepred</var>(R, X, Y), (R = (=) ; R = (>)).
</pre>
must be total order relations: that is they must be antisymmetric,
reflexive and transitive. The compiler is not required to check this.
</ul>
<p>For each type for which the declaration has a
<code>where comparison is <var>comparepred</var></code> specification,
any calls to the standard library predicate <code>builtin__compare/3</code>
with arguments of that type are evaluated as if they were calls
to <var>comparepred</var>.
<p>A type declaration may contain a
<code>where equality is <var>equalitypred</var>, comparison is <var>comparepred</var></code>
specification only if in addition to the conditions above,
<code>all [X, Y] (<var>comparepred</var>((=), X, Y) <=> <var>equalitypred</var>(X, Y))</code>.
The compiler is not required to check this.
<p><hr>
Node:<a name="Higher-order">Higher-order</a>,
Next:<a rel=next href="#Modules">Modules</a>,
Previous:<a rel=previous href="#User-defined%20equality%20and%20comparison">User-defined equality and comparison</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Higher-order programming</h2>
<p>Mercury supports higher-order functions and predicates with currying,
closures, and lambda expressions.
(To be pedantic, it would be more accurate to
say that Mercury supports higher-order procedures: in Mercury, when you
construct a higher-order term, you only get one mode of
a predicate or function; if you want multiple modes, you must pass multiple
higher-order procedures.)
<ul>
<li><a href="#Creating%20higher-order%20terms">Creating higher-order terms</a>:
<li><a href="#Calling%20higher-order%20terms">Calling higher-order terms</a>:
<li><a href="#Higher-order%20modes">Higher-order modes</a>:
</ul>
<p><hr>
Node:<a name="Creating%20higher-order%20terms">Creating higher-order terms</a>,
Next:<a rel=next href="#Calling%20higher-order%20terms">Calling higher-order terms</a>,
Up:<a rel=up href="#Higher-order">Higher-order</a>
<br>
<h3>Creating higher-order terms</h3>
<p>To create a higher-order predicate or function term, you can use
a lambda expression, or, if the predicate or function has only one
mode and it is not a zero-arity function, you can just use its name.
For example, if you have declared a predicate
<br><pre>:- pred sum(list(int), int).
:- mode sum(in, out) is det.
</pre>
<p>the following three unifications have the same effect:
<br><pre>X = lambda([List::in, Length::out] is det, sum(List, Length))
Y = (pred(List::in, Length::out) is det :- sum(List, Length))
Z = sum
</pre>
<p>In the above example, the type of <code>X</code>, <code>Y</code>, and <code>Z</code> is
<code>pred(list(int), int)</code>, which means a predicate of two
arguments of types <code>list(int)</code> and <code>int</code> respectively.
<p>The syntax using <code>lambda</code> is deprecated;
please use the syntax using <code>pred</code> instead.
[The syntax using <code>lambda</code> was supported to enable programs to work
in both Mercury and Prolog, because the syntax using <code>pred</code>
can't be easily emulated in Prolog. Now that we have implemented
better debugging environments for Mercury, there is no need for this.]
<p>Similarly, given
<br><pre>:- func scalar_product(int, list(int)) = list(int).
:- mode scalar_product(in, in) = out is det.
</pre>
<p>the following three unifications have the same effect:
<br><pre>X = (func(Num, List) = NewList :- NewList = scalar_product(Num, List))
Y = (func(Num::in, List::in) = (NewList::out) is det
:- NewList = scalar_product(Num, List))
Z = scalar_product
</pre>
<p>In the above example, the type of <code>X</code>, <code>Y</code>, and <code>Z</code> is
<code>func(int, list(int)) = list(int)</code>, which means a function of two
arguments, whose types are <code>int</code> and <code>list(int)</code>,
with a return type of <code>int</code>.
As with <code>:- func</code> declarations, if the modes and determinism
of the function are omitted in a higher-order function term, then
the modes default to <code>in</code> for the arguments, <code>out</code> for the
function result, and the determinism defaults to <code>det</code>.
<p>If the predicate or function has more than one mode, you must use an explicit
lambda expression to specify which mode you want.
<p>You can also create higher-order function terms of non-zero arity
and higher-order predicate terms by "currying",
i.e. specifying the first few arguments to a predicate or function, but
leaving the remaining arguments unspecified. For example, the
unification
<br><pre>Sum123 = sum([1,2,3])
</pre>
<p>binds <code>Sum123</code> to a higher-order predicate term of type <code>pred(int)</code>.
Similarly, the unification
<br><pre>Double = scalar_product(2)
</pre>
<p>binds <code>Double</code> to a higher-order function term of type
<code>func(list(int)) = list(int)</code>.
<p>For higher-order predicate expressions that thread an accumulator
pair, we have syntax that allows you to use DCG notation in the
goal of the expression. For example,
<br><pre>Pred = (pred(Strings::in, Num::out, di, uo) is det -->
io__write_string("The strings are: "),
{ list__length(Strings, Num) },
io__write_strings(Strings),
io__nl
)
</pre>
<p>is equivalent to
<br><pre>Pred = (pred(Strings::in, Num::out, IO0::di, IO::uo) is det :-
io__write_string("The strings are: ", IO0, IO1),
list__length(Strings, Num),
io__write_strings(Strings, IO1, IO2),
io__nl(IO2, IO)
)
</pre>
<p>Higher-order function terms of zero arity can only be created using
an explicit lambda expression; you have to use e.g. <code>(func) = foo</code>
rather than plain <code>foo</code>, because the latter denotes the result
of evaluating the function, rather than the function itself.
<p>Note that when constructing a higher-order term, you cannot just use
the name of a builtin language construct such as <code>=</code>, <code>\=</code>,
<code>call</code>, or <code>apply</code>, and nor can such constructs be curried.
Instead, you must either use an explicit lambda expression,
or you must write a forwarding predicate or function.
For example, instead of
<br><pre>list__filter([1,2,3], \=(2), List)
</pre>
<p>you must write either
<br><pre>list__filter([1,2,3], (pred(X::in) is semidet :- X \= 2), List)
</pre>
<p>or
<br><pre>list__filter([1,2,3], not_equal(2), List)
</pre>
<p>where you have defined <code>not_equal</code> using
<br><pre>:- pred not_equal(T::in, T::in) is semidet.
not_equal(X, Y) :- X \= Y.
</pre>
<p>Another case when this arises is when want to curry a higher-order
term. Suppose, for example, that you have a higher-order predicate
term <code>OldPred</code> of type <code>pred(int, char, float)</code>, and you want
to construct a new higher-order predicate term <code>NewPred</code> of type
<code>pred(char, float)</code> from <code>OldPred</code> by supplying a value for
for just the first argument. The solution is the same: use
an explicit lambda expression or a forwarding predicate.
In either case, the body of the lambda expression or the forwarding
predicate must contain a higher-order call with all the arguments
supplied.
<p><hr>
Node:<a name="Calling%20higher-order%20terms">Calling higher-order terms</a>,
Next:<a rel=next href="#Higher-order%20modes">Higher-order modes</a>,
Previous:<a rel=previous href="#Creating%20higher-order%20terms">Creating higher-order terms</a>,
Up:<a rel=up href="#Higher-order">Higher-order</a>
<br>
<h3>Calling higher-order terms</h3>
<p>Once you have created a higher-order predicate term (sometimes known
as a closure), the next thing you want to do is to call it.
For predicates, you use the builtin goal call/N:
<dl>
<dt><code>call(Closure)</code>
<dt><code>call(Closure1, Arg1)</code>
<dt><code>call(Closure2, Arg1, Arg2)</code>
<dt><small>...</small>
<dd>A higher-order predicate call. <code>call(Closure)</code> just calls the
specified higher-order predicate term. The other forms append the
specified arguments onto the argument list of the closure before
calling it.
</dl>
<p>For example, the goal
<br><pre>call(Sum123, Result)
</pre>
<p>would bind <code>Result</code> to the sum of <code>[1, 2, 3]</code>, i.e. to 6.
<p>For functions, you use the builtin expression apply/N:
<dl>
<dt><code>apply(Closure)</code>
<dt><code>apply(Closure1, Arg1)</code>
<dt><code>apply(Closure2, Arg1, Arg2)</code>
<dt><small>...</small>
<dd>A higher-order function application. Such a term denotes the
result of invoking the specified higher-order function term with
the specified arguments.
</dl>
<p>For example, given the definition of <code>Double</code> above, the goal
<br><pre>List = apply(Double, [1, 2, 3])
</pre>
<p>would be equivalent to
<br><pre>List = scalar_product(2, [1, 2, 3])
</pre>
<p>and so for a suitable implementation of the function
<code>scalar_product/2</code> this would bind <code>List</code> to
<code>[2, 4, 6]</code>.
<p>One extremely useful higher-order predicate in the Mercury standard
library is <code>solutions/2</code>, which has the following declaration:
<br><pre>:- pred solutions(pred(T), list(T)).
:- mode solutions(pred(out) is nondet, out) is det.
</pre>
<p>The term which you pass to <code>solutions/2</code> is a higher-order
predicate term. You can pass the name of a one-argument predicate,
or you can pass a several-argument predicate with all but one
of the arguments supplied (a closure). The declarative semantics of
<code>solutions/2</code> can be defined as follows:
<br><pre>solutions(Pred, List) is true iff
all [X] (call(Pred, X) <=> list__member(X, List))
and List is sorted.
</pre>
<p>where <code>call(Pred, X)</code> invokes the higher-order predicate term
<code>Pred</code> with argument <code>X</code>,
and where <code>list__member/2</code> is the standard
library predicate for list membership. In other words,
<code>solutions(Pred, List)</code> finds all the values of <code>X</code>
for which <code>call(Pred, X)</code> is true, collects these solutions
in a list, sorts the list, and returns that list as its result.
Here's an example: the standard library defines a predicate
<code>list__perm(List0, List)</code>
<br><pre>:- pred list__perm(list(T), list(T)).
:- mode list__perm(in, out) is nondet.
</pre>
<p>which succeeds iff List is a permutation of List0.
Hence the following call to solutions
<br><pre>solutions(list__perm([3,1,2]), L)
</pre>
<p>should return all the possible permutations of the list <code>[3,1,2]</code>
in sorted order:
<br><pre>L = [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]].
</pre>
<p>See also <code>unsorted_solutions/2</code> and <code>solutions_set/2</code>, which
are defined in the standard library module <code>std_util</code> and documented
in the Mercury Library Reference Manual.
<p><hr>
Node:<a name="Higher-order%20modes">Higher-order modes</a>,
Previous:<a rel=previous href="#Calling%20higher-order%20terms">Calling higher-order terms</a>,
Up:<a rel=up href="#Higher-order">Higher-order</a>
<br>
<h3>Higher-order modes</h3>
<p>In Mercury, the mode and determinism of a higher-order predicate or function
term are part of that term's <em>inst</em>, not its <em>type</em>.
This allows a single higher-order predicate to work on argument
predicates of different modes and determinism, which is particularly
useful for library predicates such as <code>list__map</code> and <code>list__foldl</code>.
<p>The language contains builtin <code>inst</code> values
<br><pre>pred is <var>Determinism</var>
pred(<var>Mode</var>) is <var>Determinism</var>
pred(<var>Mode1</var>, <var>Mode2</var>) is <var>Determinism</var>
<small>...</small>
(func) = <var>Mode</var> is <var>Determinism</var>
func(<var>Mode1</var>) = <var>Mode</var> is <var>Determinism</var>
func(<var>Mode1</var>, <var>Mode2</var>) = <var>Mode</var> is <var>Determinism</var>
<small>...</small>
</pre>
<p>These insts represent the instantiation state of variables bound
to higher-order predicate and function terms with the appropriate mode
and determinism.
For example, <code>pred(out) is det</code> represents the instantiation state
of being bound to a higher-order predicate term which is <code>det</code>
and accepts one output argument; the term <code>sum([1,2,3])</code> from the
example above is one such higher-order predicate term which matches
this instantiation state.
<p>As a convenience, the language also contains builtin <code>mode</code> values
of the same name (and they are what we have been using in the examples
up to now). These modes map from the corresponding <code>inst</code> to
itself. It is as if they were defined by
<br><pre>:- mode (pred is <var>Determinism</var>) == in(pred is <var>Determinism</var>).
:- mode (pred(<var>Inst</var>) is <var>Determinism</var>) ==
in(pred(<var>Inst</var>) is <var>Determinism</var>).
<small>...</small>
</pre>
<p>using the parametric inst <code>in/1</code> mentioned in <a href="#Modes">Modes</a>
which maps an inst to itself.
<p>If you want to define a predicate which returns a higher-order predicate
term, you would use a mode such as <code>free >> pred(<small>...</small>) is <small>...</small></code>,
or <code>out(pred(<small>...</small>) is <small>...</small> )</code>. For example:
<br><pre>:- pred foo(pred(int)).
:- mode foo(free >> pred(out) is det) is det.
foo(sum([1,2,3])).
</pre>
<p>Note that in Mercury it is an error to attempt to unify two
higher-order terms. This is because equivalence of
higher-order terms is undecidable in the general case.
<p>For example, given the definition of <code>foo</code> above, the goal
<br><pre> foo((pred(X::out) is det :- X = 6))
</pre>
<p>is illegal. If you really want to compare higher-order predicates
for equivalence, you must program it yourself; for example,
the above goal could legally be written as
<br><pre> P = (pred(X::out) is det :- X = 6),
foo(Q),
all [X] (call(P, X) <=> call(Q, X)).
</pre>
<p>Note that the compiler will only catch direct attempts at higher-order
unifications; indirect attempts (via polymorphic predicates, for
example <code>(list__append([], [P], [Q])</code> may result in an error at
run-time rather than at compile-time.
<p>In order to call a higher-order term, the compiler must know its higher-order
inst. This can cause problems when higher-order terms are placed into a
polymorphic collection type and then extracted, since the declared mode for the
extraction will typically be <code>out</code> and the higher-order inst information
will be lost.
To partially alleviate this problem, and to make higher-order functional
programming easier, if the term to be called has a function
type, but no higher-order inst information, we assume that it has the default
higher-order function inst
<code>func(in, <small>...</small>, in) = out is <var>Determinism</var></code>.
<p>As a consequence of this, it is a mode error to pass a higher-order function
term that does not match this standard mode to somewhere where its higher-order
inst information may be lost, such as to a polymorphic predicate where the
argument mode is <code>in</code>.
<p><hr>
Node:<a name="Modules">Modules</a>,
Next:<a rel=next href="#Type%20classes">Type classes</a>,
Previous:<a rel=previous href="#Higher-order">Higher-order</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Modules</h2>
<ul>
<li><a href="#The%20module%20system">The module system</a>:
<li><a href="#An%20example%20module">An example module</a>:
<li><a href="#Sub-modules">Sub-modules</a>:
</ul>
<p><hr>
Node:<a name="The%20module%20system">The module system</a>,
Next:<a rel=next href="#An%20example%20module">An example module</a>,
Up:<a rel=up href="#Modules">Modules</a>
<br>
<h3>The module system</h3>
<p>The Mercury module system is relatively simple and straightforward.
<p>Each module must start with a <code>:- module <var>ModuleName</var></code>
declaration, specifying the name of the module.
<p>An <code>:- interface.</code> declaration indicates
the start of the module's interface section:
this section specifies the entities that are exported by this module.
Mercury provides support for abstract data types, by allowing the
definition of a type to be kept hidden, with the interface
only exporting the type name.
The interface section may contain definitions of types,
type classes, data constructors, instantiation states, and
modes, and declarations for abstract data types, abstract type class
instances, functions, predicates, and (sub-)modules.
The interface section may not contain definitions for functions or
predicates (i.e. clauses), or definitions of (sub-)modules.
<p>An <code>:- implementation.</code> declaration indicates
the start of the module's implementation section.
Any entities declared in this section are local to the module
(and its sub-modules) and cannot be used by other modules.
The implementation section must contain definitions
for all abstract data types, abstract instance declarations,
functions, predicates, and sub-modules exported by the module,
as well as for all local types, type class instances, functions,
predicates, and sub-modules.
The implementation section can be omitted if it is empty.
<p>The module may optionally end with a <code>:- end_module <var>ModuleName</var></code>
declaration; the name specified in the <code>end_module</code> must be the
same as that in the corresponding <code>module</code> declaration.
<p>If a module wishes to make use of entities exported by other modules,
then it must explicitly import those modules using one or more
<code>:- import_module <var>Modules</var></code> or <code>:- use_module <var>Modules</var></code>
declarations, in order to make those declarations visible.
In both cases, <var>Modules</var> is a comma-separated list of
fully-qualified module names.
These declarations may occur either in the interface or the implementation
section. If the imported entities are used in the interface section,
then the corresponding <code>import_module</code> or <code>use_module</code>
declaration must also be in the interface section. If the imported
entities are only used in the implementation section, the
<code>import_module</code> or <code>use_module</code> declaration should be in
the implementation section.
<p>The names of predicates, functions, constructors, constructor fields,
types, modes, insts, type classes,
and (sub-)modules can be explicitly module qualified using the <code>.</code>
operator, e.g. <code>module.name</code> or <code>module.submodule.name</code>.
This is useful both for readability and for resolving name conflicts.
Uses of entities imported using <code>use_module</code> declarations
<em>must</em> be explicitly module qualified.
<p>Currently we also support <code>__</code> and <code>:</code> as alternative
module qualifiers,
so you can write <code>module__name</code> or <code>module:name</code> instead
of <code>module.name</code>.
We intend to change the use of <code>:</code> to being a type
qualifier instead in a future version, its use as a module qualifier
is therefore deprecated.
<p>Certain optimizations require information or source code for predicates
defined in other modules to be as effective as possible. At the moment,
inlining and higher-order specialization are the only optimizations that
the Mercury compiler can perform across module boundaries.
<p>One module must export a predicate <code>main/2</code>, which
must be declared as either
<br><pre>:- pred main(io__state::di, io__state::uo) is det.
</pre>
<p>or
<br><pre>:- pred main(io__state::di, io__state::uo) is cc_multi.
</pre>
<p>(or any declaration equivalent to one of the two above).
<p>Mercury has a standard library which includes modules for
lists, stacks, queues, priority queues, sets, bags (multi-sets),
maps (dictionaries), random number generation, input/output
and filename and directory handling.
See the Mercury Library Reference Manual for details.
<p><hr>
Node:<a name="An%20example%20module">An example module</a>,
Next:<a rel=next href="#Sub-modules">Sub-modules</a>,
Previous:<a rel=previous href="#The%20module%20system">The module system</a>,
Up:<a rel=up href="#Modules">Modules</a>
<br>
<h3>An example module.</h3>
<p>For illustrative purposes, here is the definition of a
simple module for managing queues:
<br><pre>:- module queue.
:- interface.
% Declare an abstract data type.
:- type queue(T).
% Declare some predicates which operate on the abstract data type.
:- pred empty_queue(queue(T)).
:- mode empty_queue(out) is det.
:- mode empty_queue(in) is semidet.
:- pred put(queue(T), T, queue(T)).
:- mode put(in, in, out) is det.
:- pred get(queue(T), T, queue(T)).
:- mode get(in, out, out) is semidet.
:- implementation.
% Queues are implemented as lists. We need the `list' module
% for the declaration of the type list(T), with its constructors
% '[]'/0 % and '.'/2, and for the declaration of the predicate
% list__append/3.
:- import_module list.
% Define the queue ADT.
:- type queue(T) == list(T).
% Declare the exported predicates.
empty_queue([]).
put(Queue0, Elem, Queue) :-
list__append(Queue0, [Elem], Queue).
get([Elem | Queue], Elem, Queue).
:- end_module queue.
</pre>
<p><hr>
Node:<a name="Sub-modules">Sub-modules</a>,
Previous:<a rel=previous href="#An%20example%20module">An example module</a>,
Up:<a rel=up href="#Modules">Modules</a>
<br>
<h3>Sub-modules</h3>
<p>As mentioned above, modules may contain sub-modules.
There are two kinds of sub-modules, called nested sub-modules
and separate sub-modules; the difference is that nested sub-modules
are defined in the same source file as the containing module,
whereas separate sub-modules are defined in separate source files.
Implementations should support separate compilation of separate sub-modules.
<p>A module may not contain more than one sub-module with the same name.
<ul>
<li><a href="#Nested%20sub-modules">Nested sub-modules</a>:
<li><a href="#Separate%20sub-modules">Separate sub-modules</a>:
<li><a href="#Visibility%20rules">Visibility rules</a>:
<li><a href="#Implementation%20bugs%20and%20limitations">Implementation bugs and limitations</a>:
</ul>
<p><hr>
Node:<a name="Nested%20sub-modules">Nested sub-modules</a>,
Next:<a rel=next href="#Separate%20sub-modules">Separate sub-modules</a>,
Up:<a rel=up href="#Sub-modules">Sub-modules</a>
<br>
<h4>Nested sub-modules</h4>
<p>Nested sub-modules within a module are delimited by
matching <code>:- module</code> and <code>:- end_module</code> declarations.
(Note that <code>:- end_module</code> for nested sub-modules
are mandatory, not optional, even if the nested sub-module
is the last thing in the source file.
Also note that the module name in a <code>:- module</code> or <code>:- end_module</code>
declaration need not be fully-qualified.)
The sequence of items thus delimited is known as a sub-module item sequence.
<p>The interface and implementation parts of a nested sub-module
may be specified in two different sub-module declarations.
If a sub-module item sequence includes an interface section,
then it is a declaration of that sub-module;
if it includes an implementation section,
then it is a definition of that sub-module;
and if includes both, then it is both declaration and definition.
<p>It is an error to declare a sub-module twice, or to define it twice.
It is an error to define a sub-module without declaring it.
As mentioned earlier, it is an error to define a sub-module in the
interface section of its parent module.
<p>If a sub-module is declared but not explicitly defined,
then there is an implicit definition with an empty implementation section
for that sub-module (this will result in an error, if the interface
section includes declarations but not definitions for any types,
predicates, modes, or (doubly) nested sub-modules).
<p><hr>
Node:<a name="Separate%20sub-modules">Separate sub-modules</a>,
Next:<a rel=next href="#Visibility%20rules">Visibility rules</a>,
Previous:<a rel=previous href="#Nested%20sub-modules">Nested sub-modules</a>,
Up:<a rel=up href="#Sub-modules">Sub-modules</a>
<br>
<h4>Separate sub-modules</h4>
<p>Separate sub-modules are declared using
<code>:- include_module <var>Modules</var></code> declarations.
Each <code>:- include_module</code> declaration specifies a comma-separated list
of sub-modules.
<br><pre>:- include_module <var>Module1</var>, <var>Module2</var>, <small>...</small>, <var>ModuleN</var>.
</pre>
<p>Each of the named sub-modules in an <code>:- include_module</code> declaration
must be defined in a separate source file.
The mapping between module names and source file names is
implementation-defined. (For a module named <code>foo.bar.baz</code>,
The University of Melbourne Mercury implementation requires the source
to be located in a file named <code>foo.bar.baz.m</code>, <code>bar.baz.m</code>,
or <code>baz.m</code>.)
The separate source file must contain the declaration (interface)
and definition (implementation) of the sub-module.
It must start with a <code>:- module</code> declaration
which matches that in the <code>:- include_module</code> declaration
in the parent, followed by the interface and (if necessary)
implementation sections, and it may optionally end with a <code>:- end_module</code>
declaration. (Note: the module names in the <code>:- module</code>,
<code>:- end_module</code>, and <code>:- include_module</code> declarations
need not be fully-qualified. However,
if the file name used for a particular module does
not include all the module qualifiers, then the University of Melbourne
Mercury implementation requires the module name in the <code>:- module</code>
declaration for that module to be fully qualified.)
<p>The semantics of separate sub-modules are identical to those of nested
sub-modules. The procedure to transform a separate sub-module into a
nested sub-module is as follows:
<ol type=1 start=1>
</p><li>Replace the <code>:- include_module <var>submodule</var></code> declaration with
the interface section of the sub-module enclosed within
<code>:- module <var>submodule</var></code> and <code>:- end_module <var>submodule</var></code>
declarations.
<li>Place the implementation section of the sub-module enclosed within
<code>:- module <var>submodule</var></code> and <code>:- end_module <var>submodule</var></code>
declarations in the implementation section of the parent module.
</ol>
<p>For example
<br><pre>:- module x.
:- interface.
:- include_module y.
:- end_module x.
</pre>
<p>is equivalent to
<br><pre>:- module x.
:- interface.
:- module y.
% interface section of module <code>y</code>
:- end_module y.
:- implementation.
:- module y.
% implementation section of module <code>y</code>
:- end_module y.
:- end_module x.
</pre>
<p><hr>
Node:<a name="Visibility%20rules">Visibility rules</a>,
Next:<a rel=next href="#Implementation%20bugs%20and%20limitations">Implementation bugs and limitations</a>,
Previous:<a rel=previous href="#Separate%20sub-modules">Separate sub-modules</a>,
Up:<a rel=up href="#Sub-modules">Sub-modules</a>
<br>
<h4>Visibility rules</h4>
<p>Any declarations in the parent module, including those in the
parent module's implementation section, are visible in the parent's
sub-modules, including indirect sub-modules (i.e. sub-sub-modules, etc.).
Similarly, declarations in the interfaces of any modules imported using an
<code>:- import_module</code> or a <code>:- use_module</code> in the parent module
are visible in the parent's sub-modules, including indirect sub-modules.
<p>Declarations in a child module are not visible in the parent module,
or in "sibling" modules (other children of the same parent), or in
other unrelated modules unless the child is explicitly imported using
an <code>:- import_module</code> or <code>:- use_module</code> declaration. It
is an error to import a module without importing all of its parent
modules.
<p>Note that a sub-module for which the <code>:- module</code> or
<code>:- include_module</code> declaration occurs only in the implementation
section of the parent module may only be imported or used by its
parent module or by sub-modules of its parent module.
<p>Note that as mentioned previously, all <code>:- import_module</code> and
<code>:- use_module</code> declarations must use fully-qualified module
names.
<p><hr>
Node:<a name="Implementation%20bugs%20and%20limitations">Implementation bugs and limitations</a>,
Previous:<a rel=previous href="#Visibility%20rules">Visibility rules</a>,
Up:<a rel=up href="#Sub-modules">Sub-modules</a>
<br>
<h4>Implementation bugs and limitations</h4>
<p>The current implementation of sub-modules has a couple of minor
limitations.
<ul>
<li>The compiler sometimes reports spurious errors if you
define an equivalence type in a sub-module and export it
as abstract type.
<li>Using <code>mmake</code> to do parallel makes (e.g. <code>mmake --jobs 2</code>)
doesn't always work correctly if you're using nested sub-modules.
(The work-around is to use separate sub-modules instead of nested
sub-modules, i.e. to put the sub-modules in separate source files.)
</ul>
<p><hr>
Node:<a name="Type%20classes">Type classes</a>,
Next:<a rel=next href="#Existential%20types">Existential types</a>,
Previous:<a rel=previous href="#Modules">Modules</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Type classes</h2>
<p>Mercury supports constrained polymorphism in the form of type classes.
Type classes allow the programmer to write predicates and functions which
operate on variables of any type (or sequence of types) for which a certain
set of operations is defined.
<ul>
<li><a href="#Typeclass%20declarations">Typeclass declarations</a>:
<li><a href="#Instance%20declarations">Instance declarations</a>:
<li><a href="#Abstract%20typeclass%20declarations">Abstract typeclass declarations</a>:
<li><a href="#Abstract%20instance%20declarations">Abstract instance declarations</a>:
<li><a href="#Type%20class%20constraints%20on%20predicates%20and%20functions">Type class constraints on predicates and functions</a>:
<li><a href="#Type%20class%20constraints%20on%20type%20class%20declarations">Type class constraints on type class declarations</a>:
<li><a href="#Type%20class%20constraints%20on%20instance%20declarations">Type class constraints on instance declarations</a>:
</ul>
<p><hr>
Node:<a name="Typeclass%20declarations">Typeclass declarations</a>,
Next:<a rel=next href="#Instance%20declarations">Instance declarations</a>,
Up:<a rel=up href="#Type%20classes">Type classes</a>
<br>
<h3>Typeclass declarations</h3>
<p>A <dfn>type class</dfn> is a name for a set of types (or a set of sequences of
types) for which certain predicates and/or functions, called the <dfn>methods</dfn>
of that type class, are defined.
A <code>typeclass</code> declaration defines a new type class, and
specifies the set of predicates and/or functions
that must be defined on a type (or sequence of types) for it (them) to be
considered to be an instance of that type class.
<p>The <code>typeclass</code> declaration gives the name of the type class that
it is defining, the
names of the type variables which are parameters to the type class, and the
operations (i.e. methods) which form the interface of the type class.
<p>For example,
<br><pre>:- typeclass point(T) where [
% coords(Point, X, Y):
% X and Y are the cartesian coordinates of Point
pred coords(T, float, float),
mode coords(in, out, out) is det,
% translate(Point, X_Offset, Y_Offset) = NewPoint:
% NewPoint is Point translated X_Offset units in the X direction
% and Y_Offset units in the Y direction
func translate(T, float, float) = T
].
</pre>
<p>declares the type class <code>point</code>, which
represents points in two dimensional space.
<p><code>pred</code>, <code>func</code> and <code>mode</code> declarations are the only
legal declarations inside a <code>typeclass</code> declaration. The mode and
determinism of type class methods must be explicitly declared or
(for functions) defaulted, not inferred. In other words, for each
predicate declared in a type class, there must be at least one mode
declaration, and each mode declaration in a type class must include
an explicit determinism annotation. Functions with no explicit mode
declaration get the usual default mode (see <a href="#Modes">Modes</a>): all arguments
have mode <code>in</code>, the result has mode <code>out</code>, and the determinism
is <code>det</code>.
<p>The number of parameters to the type class (e.g. <code>T</code>) is not limited.
For example, the following is allowed:
<br><pre>:- typeclass a(T1, T2) where [<small>...</small>].
</pre>
<p>The parameters must be distinct variables.
Each <code>typeclass</code> declaration must have at least one parameter.
<p>It is OK for a <code>typeclass</code> declaration to declare no methods,
e.g.
<br><pre>:- typeclass foo(T) where [].
</pre>
<p>There must not be more than one type class declaration with the
same name and arity in the same module.
<p><hr>
Node:<a name="Instance%20declarations">Instance declarations</a>,
Next:<a rel=next href="#Abstract%20typeclass%20declarations">Abstract typeclass declarations</a>,
Previous:<a rel=previous href="#Typeclass%20declarations">Typeclass declarations</a>,
Up:<a rel=up href="#Type%20classes">Type classes</a>
<br>
<h3>Instance declarations</h3>
<p>Once the interface of the type class has been defined in the <code>typeclass</code>
declaration, we can use an <code>instance</code> declaration to define how a
particular type (or sequence of types) satisfies the interface declared
in the <code>typeclass</code> declaration.
<p>An instance declaration has the form
<br><pre>:- instance <var>classname</var>(<var>typename</var>(<var>typevar</var>, <small>...</small>), <small>...</small>)
where [<var>methoddefinition</var>, <var>methoddefinition</var>, <small>...</small>].
</pre>
<p>An <code>instance</code> declaration gives a type for each parameter of the
type class. Each of these types must be either a type with no arguments, or
a polymorphic type whose arguments are all distinct type variables.
For example <code>int</code>, <code>list(T)</code> and <code>bintree(K,V)</code> are allowed,
but <code>T</code>, <code>list(int)</code> and <code>bintree(T,T)</code> are not.
The types in an instance declaration must not be abstract types which
are elsewhere defined as equivalence types.
A program may not contain more than one instance
declaration for a particular type (or sequence of types, in
the case of a multi-parameter type class) and typeclass.
These restrictions ensure that there are no overlapping
instance declarations, i.e. for each typeclass there is at
most one instance declaration that may be applied to any
type (or sequence of types).
<p>Each <var>methoddefinition</var> entry in the <code>where [<small>...</small>]</code> part
of an <code>instance</code> declaration defines the implementation of one of
the class methods for this instance. There are two ways of defining
methods. The first way is to define a method by giving the name of
the predicate or function which implements that method. In this
case, the <var>methoddefinition</var> must have one of the following forms:
<br><pre>pred(<var>methodname</var>/<var>arity</var>) is <var>predname</var>
func(<var>methodname</var>/<var>arity</var>) is <var>funcname</var>
</pre>
<p>The <var>predname</var> or <var>funcname</var> must name a function or
predicate of the specified arity whose type, modes, determinism, and
purity are at least as permissive as the declared type, modes,
determinism, and purity of the class method with the specified
<var>methodname</var> and <var>arity</var>, after the types of the arguments
in the instance declaration have been substituted in place of the
parameters in the type class declaration.
<p>The second way of defining methods is by listing the clauses for the
definition inside the instance declaration. A <var>methoddefinition</var>
can be a clause. These clauses are just like the clauses used to
define ordinary predicates or functions (see <a href="#Items">Items</a>), and so they
can be facts, rules, or DCG rules. The only difference is that in instance
declarations, clauses are separated by commas rather than being terminated
by periods, and so rules and DCG rules in instance declarations must
normally be enclosed in parentheses. As with ordinary predicates,
you can have more than one clause for each method. The clauses must
satisfy the declared type, modes, determinism and purity for the
method, after the types of the arguments in the instance declaration
have been substituted in place of the parameters in the type class
declaration.
<p>These two ways are mutually exclusive: each method must be defined
either by a single naming definition (using the <code>pred(<small>...</small>) is
<var>predname</var></code> or <code>func(<small>...</small>) is <var>funcname</var></code> form),
or by a set of one or more clauses, but not both.
<p>Here's an example of an instance declaration and the different kinds
of method definitions that it can contain:
<br><pre>:- typeclass foo(T) where [
func method1(T, T) = int,
func method2(T) = int,
pred method3(T::in, int::out) is det,
pred method4(T::in, io__state::di, io__state::uo) is det,
func method5(bool, T) = T
].
:- instance foo(int) where [
% method defined by naming the implementation
func(method1/2) is (+),
% method defined by a fact
method2(X) = X + 1,
% method defined by a rule
(method3(X, Y) :- Y = X + 2),
% method defined by a DCG rule
(method4(X) --> io__print(X), io__nl),
% method defined by multiple clauses
method5(no, _) = 0,
(method5(yes, X) = Y :- X + Y = 0)
].
</pre>
<p>Each <code>instance</code> declaration must define an implementation for
every method declared in the corresponding <code>typeclass</code> declaration.
It is an error to define more than one implementation for the same
method within a single <code>instance</code> declaration.
<p>Any call to a method must have argument types (and in the case of functions,
return type) which are constrained to be a member of that method's
type class, or which match one of the instance declarations visible at
the point of the call. A method call will invoke the
predicate or function specified for that method in the
instance declaration that matches the types of the arguments
to the call.
<p>Note that even if a type class has no methods, an explicit instance
declaration is required for a type to be considered an instance
of that type class.
<p>Here's an example of some code using an instance declaration:
<br><pre>:- type coordinate
---> coordinate(
float, % X coordinate
float % Y coordinate
).
:- instance point(coordinate) where [
pred(coords/3) is coordinate_coords,
func(translate/3) is coordinate_translate
].
:- pred coordinate_coords(coordinate, float, float).
:- mode coordinate_coords(in, out, out) is det.
coordinate_coords(coordinate(X, Y), X, Y).
:- func coordinate_translate(coordinate, float, float) = coordinate.
coordinate_translate(coordinate(X, Y), Dx, Dy) = coordinate(X + Dx, Y + Dy).
</pre>
<p>We have now made the <code>coordinate</code> type an instance of the <code>point</code>
type class. If we introduce a new type, <code>coloured_coordinate</code> which
represents a point in two dimensional space with a colour associated with it,
it can also become an instance of the type class:
<br><pre>:- type rgb
---> rgb(
int,
int,
int
).
:- type coloured_coordinate
---> coloured_coordinate(
float,
float,
rgb
).
:- instance point(coloured_coordinate) where [
pred(coords/3) is coloured_coordinate_coords,
func(translate/3) is coloured_coordinate_translate
].
:- pred coloured_coordinate_coords(coloured_coordinate, float, float).
:- mode coloured_coordinate_coords(in, out, out) is det.
coloured_coordinate_coords(coloured_coordinate(X, Y, _), X, Y).
:- func coloured_coordinate_translate(coloured_coordinate, float, float)
= coloured_coordinate.
coloured_coordinate_translate(coloured_coordinate(X, Y, Colour), Dx, Dy)
= coloured_coordinate(X + Dx, Y + Dy, Colour).
</pre>
<p>If we call <code>translate/3</code> with the first argument having type
<code>coloured_coordinate</code>, this will invoke
<code>coloured_coordinate_translate</code>.
Likewise, if we call <code>translate/3</code> with the first argument having type
<code>coordinate</code>, this will invoke <code>coordinate_translate</code>.
<p>Further instances of the type class could be made, e.g. a type that represents
the point using polar coordinates.
<p><hr>
Node:<a name="Abstract%20typeclass%20declarations">Abstract typeclass declarations</a>,
Next:<a rel=next href="#Abstract%20instance%20declarations">Abstract instance declarations</a>,
Previous:<a rel=previous href="#Instance%20declarations">Instance declarations</a>,
Up:<a rel=up href="#Type%20classes">Type classes</a>
<br>
<h3>Abstract typeclass declarations</h3>
<p>Abstract typeclass declarations are typeclass declarations whose
definitions are hidden. An abstract typeclass declaration has the
same form as a typeclass declaration, but without the
<code>where[<small>...</small>]</code> part. An abstract typeclass declaration
defines a name for a set of (sequences of) types, but does not define
what methods must be implemented for instances of the type class.
<p>Like abstract type declarations, abstract typeclass declarations are
only useful in the interface section of a module. Each abstract
typeclass declaration must be accompanied by a corresponding
non-abstract typeclass declaration that defines the methods for
that type class.
<p>Non-abstract instance declarations can only be made in scopes where
the non-abstract typeclass declaration is visible.
<p><hr>
Node:<a name="Abstract%20instance%20declarations">Abstract instance declarations</a>,
Next:<a rel=next href="#Type%20class%20constraints%20on%20predicates%20and%20functions">Type class constraints on predicates and functions</a>,
Previous:<a rel=previous href="#Abstract%20typeclass%20declarations">Abstract typeclass declarations</a>,
Up:<a rel=up href="#Type%20classes">Type classes</a>
<br>
<h3>Abstract instance declarations</h3>
<p>Abstract instance declarations are instance declarations whose
implementations are hidden. An abstract instance declaration has the
same form as an instance declaration, but without the <code>where
[<small>...</small>]</code> part. An abstract instance declaration declares that
a sequence of types is an instance of a particular type class without
defining how the type class methods are implemented for those types.
Like abstract type declarations,
abstract instance declarations are only useful in the interface
section of a module. Each abstract instance declaration must
be accompanied by a corresponding non-abstract instance declaration
that defines how the type class methods are implemented.
<p>Here's an example:
<br><pre>:- module hashable.
:- interface.
:- import_module int, string.
:- typeclass hashable(T) where [func hash(T) = int].
:- instance hashable(int).
:- instance hashable(string).
:- implementation.
:- instance hashable(int) where [func(hash/1) is hash_int].
:- instance hashable(string) where [func(hash/1) is hash_string].
:- func hash_int(int) = int.
hash_int(X) = X.
:- func hash_string(string) = int.
hash_string(S) = H :-
% use the standard library predicate string__hash/2
string__hash(S, H).
:- end_module hashable.
</pre>
<p><hr>
Node:<a name="Type%20class%20constraints%20on%20predicates%20and%20functions">Type class constraints on predicates and functions</a>,
Next:<a rel=next href="#Type%20class%20constraints%20on%20type%20class%20declarations">Type class constraints on type class declarations</a>,
Previous:<a rel=previous href="#Abstract%20instance%20declarations">Abstract instance declarations</a>,
Up:<a rel=up href="#Type%20classes">Type classes</a>
<br>
<h3>Type class constraints on predicates and functions</h3>
<p>Mercury allows a type class constraint to appear as part of a predicate or
function's type signature. This constrains the values that can be taken
by type variables in the signature to belong to particular type classes.
<p>A type class constraint is of the form:
<br><pre> <= <var>Typeclass</var>(<var>Type</var>, <small>...</small>), <small>...</small>
</pre>
<p>where <var>Typeclass</var> is the name of a type class and <var>Type</var> is
a type.
Any variable that appears in <var>Type</var> must also appear in
the predicate's or function's type signature.
Each type class constraint in a predicate or function declaration must contain
at least one variable.
<p>For example
<br><pre>:- pred distance(P1, P2, float) <= (point(P1), point(P2)).
:- mode distance(in, in, out) is det.
distance(A, B, Distance) :-
coords(A, Xa, Ya),
coords(B, Xb, Yb),
XDist = Xa - Xb,
YDist = Ya - Yb,
Distance = sqrt(XDist*XDist + YDist*YDist).
</pre>
<p>In the above example, the <code>distance</code> predicate is able to calculate the
distance between any two points, regardless of their representation, as long
as the <code>coords</code> operation has been defined. These
constraints are checked at compile time.
<p><hr>
Node:<a name="Type%20class%20constraints%20on%20type%20class%20declarations">Type class constraints on type class declarations</a>,
Next:<a rel=next href="#Type%20class%20constraints%20on%20instance%20declarations">Type class constraints on instance declarations</a>,
Previous:<a rel=previous href="#Type%20class%20constraints%20on%20predicates%20and%20functions">Type class constraints on predicates and functions</a>,
Up:<a rel=up href="#Type%20classes">Type classes</a>
<br>
<h3>Type class constraints on type class declarations</h3>
<p>Type class constraints may also appear in <code>typeclass</code> declarations,
meaning that one type class is a "superclass" of another.
<p>The arguments of a constraint on a type class declaration must be either type
variables or ground types.
Each constraint must contain at least one variable argument and
all variables that appear in the arguments
must also be arguments to the type class in question.
<p>For example, the following declares the <code>ring</code> type class, which describes
types with a particular set of numerical operations defined:
<br><pre>:- typeclass ring(T) where [
func zero = (T::out) is det, % '+' identity
func one = (T::out) is det, % '*' identity
func plus(T::in, T::in) = (T::out) is det, % '+'/2 (forward mode)
func mult(T::in, T::in) = (T::out) is det, % '*'/2 (forward mode)
func negative(T::in) = (T::out) is det % '-'/1 (forward mode)
].
</pre>
<p>We can now add the following declaration:
<br><pre>:- typeclass euclidean(T) <= ring(T) where [
func div(T::in, T::in) = (T::out) is det,
func mod(T::in, T::in) = (T::out) is det
].
</pre>
<p>This introduces a new type class, <code>euclidean</code>, of which <code>ring</code> is a
superclass. The operations defined by the <code>euclidean</code> type class are
<code>div</code>, <code>mod</code>, as well as all those defined by the <code>ring</code>
type class. Any type declared to be an instance of <code>euclidean</code> must also
be declared to be an instance of <code>ring</code>.
<p>Typeclass constraints on type class declarations gives rise to a superclass
relation. This relation must be acyclic. That is, it is an error if a type
class is its own (direct or indirect) superclass.
<p><hr>
Node:<a name="Type%20class%20constraints%20on%20instance%20declarations">Type class constraints on instance declarations</a>,
Previous:<a rel=previous href="#Type%20class%20constraints%20on%20type%20class%20declarations">Type class constraints on type class declarations</a>,
Up:<a rel=up href="#Type%20classes">Type classes</a>
<br>
<h3>Type class constraints on instance declarations</h3>
<p>Typeclass constraints may also be placed upon instance declarations.
The arguments of such constraints must be either type variables or ground
types.
Each constraint must contain at least one variable argument and all
variables that appear in the arguments
must be type variables that appear in the types in the instance declaration.
<p>For example, consider the following declaration of a type class of types that
may be printed:
<br><pre>:- typeclass portrayable(T) where [
pred portray(T::in, io__state::di, io__state::uo) is det
].
</pre>
<p>The programmer could declare instances such as
<br><pre>:- instance portrayable(int) where [
pred(portray/3) is io__write_int
].
:- instance portrayable(char) where [
pred(portray/3) is io__write_char
].
</pre>
<p>However, when it comes to writing the instance declaration for a type such as
<code>list(T)</code>, we want to be able print out the list elements using the
<code>portray/3</code> for the particular type of the list elements. This can be
achieved by placing a type class constraint on the <code>instance</code> declaration,
as in the following example:
<br><pre>:- instance portrayable(list(T)) <= portrayable(T) where [
pred(portray/3) is portray_list
].
:- pred portray_list(list(T), io__state, io__state) <= portrayable(T).
:- mode portray_list(in, di, uo) is det.
portray_list([]) -->
[].
portray_list([X|Xs]) -->
portray(X),
io__write_char(' '),
portray_list(Xs).
</pre>
<p>For abstract instance declarations, the type class constraints on an
abstract instance declaration must exactly match the type class
constraints on the corresponding non-abstract instance declaration that
defines that instance.
<p><hr>
Node:<a name="Existential%20types">Existential types</a>,
Next:<a rel=next href="#Semantics">Semantics</a>,
Previous:<a rel=previous href="#Type%20classes">Type classes</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Existential types</h2>
<p>Existentially quantified type variables (or simply "existential types"
for short) are useful tools for data abstraction. In combination with
type classes, they allow you to write code in an "object oriented"
style that is similar to the use of interfaces in Java or abstract
base classes in C++.
<p>Mercury supports existential type quantifiers on predicate and function
declarations, and in data type definitions. You can put type class
constraints on existentially quantified type variables.
<ul>
<li><a href="#Existentially%20typed%20predicates%20and%20functions">Existentially typed predicates and functions</a>:
<li><a href="#Existential%20class%20constraints">Existential class constraints</a>:
<li><a href="#Existentially%20typed%20data%20types">Existentially typed data types</a>:
<li><a href="#Some%20idioms%20using%20existentially%20quantified%20types">Some idioms using existentially quantified types</a>:
</ul>
<p><hr>
Node:<a name="Existentially%20typed%20predicates%20and%20functions">Existentially typed predicates and functions</a>,
Next:<a rel=next href="#Existential%20class%20constraints">Existential class constraints</a>,
Up:<a rel=up href="#Existential%20types">Existential types</a>
<br>
<h3>Existentially typed predicates and functions</h3>
<ul>
<li><a href="#Syntax%20for%20explicit%20type%20quantifiers">Syntax for explicit type quantifiers</a>:
<li><a href="#Semantics%20of%20type%20quantifiers">Semantics of type quantifiers</a>:
<li><a href="#Examples%20of%20correct%20code%20using%20type%20quantifiers">Examples of correct code using type quantifiers</a>:
<li><a href="#Examples%20of%20incorrect%20code%20using%20type%20quantifiers">Examples of incorrect code using type quantifiers</a>:
</ul>
<p><hr>
Node:<a name="Syntax%20for%20explicit%20type%20quantifiers">Syntax for explicit type quantifiers</a>,
Next:<a rel=next href="#Semantics%20of%20type%20quantifiers">Semantics of type quantifiers</a>,
Up:<a rel=up href="#Existentially%20typed%20predicates%20and%20functions">Existentially typed predicates and functions</a>
<br>
<h4>Syntax for explicit type quantifiers</h4>
<p>Type variables in type declarations for polymorphic predicates or functions
are normally universally quantified.
However, it is also possible to existentially quantify such
type variables, by using an explicit existential quantifier of
the form <code>some <var>Vars</var></code> before the <code>pred</code> or <code>func</code>
declaration, where <var>Vars</var> is a list of variables.
<p>For example:
<br><pre>% Here the type variables `T' is existentially quantified
:- some [T] pred foo(T).
% Here the type variables `T1' and `T2' are existentially quantified.
:- some [T1, T2] func bar(int, list(T1), set(T2)) = pair(T1, T2).
% Here the type variable `T2' is existentially quantified,
% but the type variables `T1' and `T3' are universally quantified.
:- some [T2] pred foo(T1, T2, T3).
</pre>
<p>Explicit universal quantifiers, of the form <code>all <var>Vars</var></code>,
are also permitted on <code>pred</code> and <code>func</code> declarations,
although they are not necessary, since universal quantification is
the default. (If both universal and existential quantifiers
are present, the universal quantifiers must precede the existential
quantifiers.) For example:
<br><pre>% Here the type variable `T2' is existentially quantified,
% but the type variables `T1' and `T3' are universally quantified.
:- all [T3] some [T2] pred foo(T1, T2, T3).
</pre>
<p><hr>
Node:<a name="Semantics%20of%20type%20quantifiers">Semantics of type quantifiers</a>,
Next:<a rel=next href="#Examples%20of%20correct%20code%20using%20type%20quantifiers">Examples of correct code using type quantifiers</a>,
Previous:<a rel=previous href="#Syntax%20for%20explicit%20type%20quantifiers">Syntax for explicit type quantifiers</a>,
Up:<a rel=up href="#Existentially%20typed%20predicates%20and%20functions">Existentially typed predicates and functions</a>
<br>
<h4>Semantics of type quantifiers</h4>
<p>If a type variable in the type declaration for a polymorphic predicate
or function is universally quantified, this means the caller will
determine the value of the type variable, and the callee must be defined
so that it will work for <em>all</em> types which are an instance of its
declared type.
<p>For an existentially quantified type variable, the situation is the
converse: the <em>callee</em> must determine the value of the type variable,
and all <em>callers</em> must be defined so as to work for all types
which are an instance of the called procedure's declared type.
<p>When type checking a predicate or function, if a variable has a type
that occurs as a universally quantified type variable in the predicate
or function declaration, or a type that occurs as an existentially
quantified type variable in the declaration of one of the predicates
or functions that it calls, then its type is treated as an opaque type.
This means that there are very few things which it is legal to do with
such a variable -- basically you can only pass it to another procedure
expecting the same type, unify it with another value of the same
type, put it in a polymorphic data structure, or pass it to a
polymorphic procedure whose argument type is universally quantified.
(Note, however, that the standard library includes some quite powerful
procedures such as <code>io__write</code> which can be useful in this context.)
<p>A non-variable type (i.e. a type that is not a type variable)
is considered <em>more general</em> than an
existentially quantified type variable. Type inference will therefore
never infer an existentially quantified type for a predicate or
function unless that predicate or function calls (directly or indirectly)
a predicate or function which was explicitly declared to have an
existentially quantified type.
<p>Note that an existentially typed procedure is not allowed to have
different types for its existentially typed arguments in different clauses
(even mode-specific clauses) or in different subgoals of a single clause;
however, the same effect can be achieved in other ways
(see <a href="#Some%20idioms%20using%20existentially%20quantified%20types">Some idioms using existentially quantified types</a>).
<p>For procedures involving calls to existentially-typed predicates or functions,
the compiler's mode analysis must take account of the modes for type
variables in all polymorphic calls.
Universally quantified type variables have mode <code>in</code>,
whereas existentially quantified type variables have mode <code>out</code>.
As usual, the compiler's mode analysis will attempt to reorder the
elements of conjunctions in order to satisfy the modes.
<p><hr>
Node:<a name="Examples%20of%20correct%20code%20using%20type%20quantifiers">Examples of correct code using type quantifiers</a>,
Next:<a rel=next href="#Examples%20of%20incorrect%20code%20using%20type%20quantifiers">Examples of incorrect code using type quantifiers</a>,
Previous:<a rel=previous href="#Semantics%20of%20type%20quantifiers">Semantics of type quantifiers</a>,
Up:<a rel=up href="#Existentially%20typed%20predicates%20and%20functions">Existentially typed predicates and functions</a>
<br>
<h4>Examples of correct code using type quantifiers</h4>
<p>Here are some examples of type-correct code using universal and
existential types.
<br><pre>/* simple examples */
:- pred foo(T).
foo(_).
% ok
:- pred call_foo.
call_foo :- foo(42).
% ok (T = int)
:- some [T] pred e_foo(T).
e_foo(X) :- X = 42.
% ok (T = int)
:- pred call_e_foo.
call_e_foo :- e_foo(_).
% ok
/* examples using higher-order functions */
:- func bar(T, T, func(T) = int) = int.
bar(X, Y, F) = F(X) + F(Y).
% ok
:- func call_bar = int.
call_bar = bar(2, 3, (func(X) = X*X)).
% ok (T = int)
% returns 13 (= 2*2 + 3*3)
:- some [T] pred e_bar(T, T, func(T) = int).
:- mode e_bar(out, out, out(func(in) = out is det)).
e_bar(2, 3, (func(X) = X * X)).
% ok (T = int)
:- func call_e_bar = int.
call_e_bar = F(X) + F(Y) :- e_bar(X, Y, F).
% ok
% returns 13 (= 2*2 + 3*3)
</pre>
<p><hr>
Node:<a name="Examples%20of%20incorrect%20code%20using%20type%20quantifiers">Examples of incorrect code using type quantifiers</a>,
Previous:<a rel=previous href="#Examples%20of%20correct%20code%20using%20type%20quantifiers">Examples of correct code using type quantifiers</a>,
Up:<a rel=up href="#Existentially%20typed%20predicates%20and%20functions">Existentially typed predicates and functions</a>
<br>
<h4>Examples of incorrect code using type quantifiers</h4>
<p>Here are some examples of code using universal and
existential types that contains type errors.
<br><pre>/* simple examples */
:- pred bad_foo(T).
bad_foo(42).
% type error
:- some [T] pred e_foo(T).
e_foo(42).
% ok
:- pred bad_call_e_foo.
bad_call_e_foo :- e_foo(42).
% type error
:- some [T] pred e_bar1(T).
e_bar1(42).
e_bar1(42).
e_bar1(43).
% ok (T = int)
:- some [T] pred bad_e_bar2(T).
bad_e_bar2(42).
bad_e_bar2("blah").
% type error (cannot unify types `int' and `string')
:- some [T] pred bad_e_bar3(T).
bad_e_bar3(X) :- e_foo(X).
bad_e_bar3(X) :- e_foo(X).
% type error (attempt to bind type variable `T' twice)
</pre>
<p><hr>
Node:<a name="Existential%20class%20constraints">Existential class constraints</a>,
Next:<a rel=next href="#Existentially%20typed%20data%20types">Existentially typed data types</a>,
Previous:<a rel=previous href="#Existentially%20typed%20predicates%20and%20functions">Existentially typed predicates and functions</a>,
Up:<a rel=up href="#Existential%20types">Existential types</a>
<br>
<h3>Existential class constraints</h3>
<p>Existentially quantified type variables are especially useful in
combination with type class constraints.
<p>Type class constraints can be either universal or existential.
Universal type class constraints are written using <code><=</code>,
as described in <a href="#Type%20class%20constraints%20on%20predicates%20and%20functions">Type class constraints on predicates and functions</a>;
they signify a constraint that the <em>caller</em> must satisfy.
Existential type class constraints are written in the same syntax
as universal constraints, but using <code>=></code> instead of <code><=</code>;
they signify a constraint that the <em>callee</em> must satisfy.
(If a declaration has both universal and existential constraints,
then the existential constraints must precede the universal constraints.)
<p>For example:
<br><pre>% Here `c1(T2)' and `c2(T1, T2)' are existential constraints,
% and `c3(T1)' is a universal constraint,
:- all [T1] some [T2] ((pred p(T1, T2) => (c1(T2), c2(T1, T2))) <= c3(T1)).
</pre>
<p>In general, constraints that constrain any existentially quantified
type variables should be existential constraints, and constraints that
constrain only universally quantified type variables should be
universal constraints. (The only time exceptions to this rule would
make any sense at all would be if there were instance declarations that
were visible in the definition of the caller but which due to module
visibility issues were not in the definition of the callee, or vice
versa. But even then, any exception to this rule would have to involve
a rather obscure coding style, which we do not recommend.)
<p><hr>
Node:<a name="Existentially%20typed%20data%20types">Existentially typed data types</a>,
Next:<a rel=next href="#Some%20idioms%20using%20existentially%20quantified%20types">Some idioms using existentially quantified types</a>,
Previous:<a rel=previous href="#Existential%20class%20constraints">Existential class constraints</a>,
Up:<a rel=up href="#Existential%20types">Existential types</a>
<br>
<h3>Existentially typed data types</h3>
<p>Type variables occurring in the body of a discriminated union type
definition may be existentially quantified. Constructor definitions
within discriminated union type definitions may be preceded by
an existential type quantifier and followed by one or more existential
type class constraints.
<p>For example:
<br><pre>% A simple heterogeneous list type
:- type list_of_any
---> nil_any
; some [T] cons_any(T, list_of_any).
% A heterogeneous list type with a type class constraint
:- typeclass showable(T) where [ func show(T) = string ].
:- type showable_list
---> nil
; some [T] (cons(T, showable_list) => showable(T)).
% A different way of doing the same kind of thing, this
% time using the standard type list(T).
:- type showable ---> some [T] (s(T) => showable(T)).
:- type list_of_showable == list(showable).
% Here's an arbitrary example involving multiple
% type variables and multiple constraints
:- typeclass foo(T1, T2) where [ /* ... */ ].
:- type bar(T)
---> f1
; f2(T)
; some [T]
f4(T)
; some [T1, T2]
(f4(T1, T2, T) => showable(T1), showable(T2))
; some [T1, T2]
(f5(list(T1), T2) => fooable(T1, list(T2)))
.
</pre>
<p>Construction and deconstruction of existentially quantified data types
are inverses: when constructing a value of an existentially quantified
data type, the "existentially quantified" functor acts for purposes
of type checking like a universally quantified function: the caller
will determine the values of the type variables.
Conversely, for deconstruction the functor acts like an
existentially quantified function: the caller must be defined so
as to work for all possible values of the existentially quantified
type variables which satisfy the declared type class constraints.
<p>In order to make this distinction clear to the compiler,
whenever you want to construct a value using an existentially
quantified functor, you must prepend <code>new </code> onto the functor name.
This tells the compiler to treat it as though it were universally
quantified: the caller can bind that functor's existentially quantified
type variables to any type which satisfies the declared type class
constraints. Conversely, any occurrence without the <code>new </code> prefix
must be a deconstruction, and is therefore existentially quantified:
the caller must not bind the existentially quantified type variables,
but the caller is allowed to depend on those type variables satisfying
the declared type class constraints, if any.
<p>For example, the function <code>make_list</code> constructs a value of type
<code>list_of_showable</code> containing a sequence of values of different types,
all of which are instances of the <code>showable</code> class
<br><pre>:- instance showable(int).
:- instance showable(float).
:- instance showable(string).
:- func make_list = showable_list.
make_list = List :-
Int = 42,
Float = 1.0,
String = "blah",
List = 'new cons'(Int,
'new cons'(Float,
'new cons'(String, nil))).
</pre>
<p>while the function <code>process_list</code> below applies the <code>show</code>
method of the <code>showable</code> class to the values in such a list.
<br><pre>:- func process_list(list_of_showable) = list(string).
process_list(nil) = "".
process_list(cons(Head, Tail)) = [show(Head) | process_list(Tail)].
</pre>
<p><hr>
Node:<a name="Some%20idioms%20using%20existentially%20quantified%20types">Some idioms using existentially quantified types</a>,
Previous:<a rel=previous href="#Existentially%20typed%20data%20types">Existentially typed data types</a>,
Up:<a rel=up href="#Existential%20types">Existential types</a>
<br>
<h3>Some idioms using existentially quantified types</h3>
<p>The standard library module <code>std_util</code> provides an abstract
type named <code>univ</code> which can hold values of any type.
You can form heterogeneous containers (containers that can hold values of
different types at the same time) by using data structures
that contain <code>univ</code>s, e.g. <code>list(univ)</code>.
<p>The interface to <code>std_util</code> includes the following:
<br><pre>% `univ' is a type which can hold any value.
:- type univ.
% The function univ/1 takes a value of any type and constructs
% a `univ' containing that value (the type will be stored along
% with the value)
:- func univ(T) = univ.
% The function univ_value/1 takes a `univ' argument and extracts
% the value contained in the `univ' (together with its type).
% This is the inverse of the function univ/1.
:- some [T] func univ_value(univ) = T.
</pre>
<p>The <code>univ</code> type in the standard library is in fact a simple
example of an existentially typed data type. It could be implemented
as follows:
<br><pre>:- implementation.
:- type univ ---> some [T] mkuniv(T).
univ(X) = 'new mkuniv'(X).
univ_value(mkuniv(X)) = X.
</pre>
<p>An existentially typed procedure is not allowed to have different
types for its existentially typed arguments in different clauses or
or in different subgoals of a single clause. For instance, both
of the following examples are illegal:
<br><pre>:- some [T] pred bad_example(string, T).
bad_example("foo", 42).
bad_example("bar", "blah").
% type error (cannot unify `int' and `string')
:- some [T] pred bad_example2(string, T).
bad_example2(Name, Value) :-
( Name = "foo", Value = 42
; Name = "bar", Value = "blah"
).
% type error (cannot unify `int' and `string')
</pre>
<p>However, using <code>univ</code>,
it is possible for an existentially typed function to return
values of different types at each invocation.
<br><pre>:- some [T] pred good_example(string, T).
good_example(Name, univ_value(Univ)) :-
( Name = "foo", Univ = univ(42)
; Name = "bar", Univ = univ("blah")
).
</pre>
<p>Using <code>univ</code> doesn't work if you also want to use type class constraints.
If you want to use type class constraints, then you must define your own
existentially typed data type, analogous to <code>univ</code>, and use that:
<br><pre>:- type univ_showable ---> some [T] (mkshowable(T) => showable(T)).
:- some [T] pred harder_example(string, T) => showable(T).
harder_example(Name, Showable) :-
( Name = "bar", Univ = 'new mkshowable'(42)
; Name = "bar", Univ = 'new mkshowable'("blah")
),
Univ = mkshowable(Showable).
</pre>
<p>The issue can also arise for mode-specific clauses
(see <a href="#Different%20clauses%20for%20different%20modes">Different clauses for different modes</a>).
For instance, the following example is illegal:
<br><pre>:- some [T] pred bad_example3(string, T).
:- mode bad_example3(in(bound("foo")), out) is det.
:- mode bad_example3(in(bound("bar")), out) is det.
:- pragma promise_pure(bad_example3/2).
bad_example3("foo"::in(bound("foo")), 42::out).
bad_example3("bar"::in(bound("bar")), "blah"::out).
% type error (cannot unify `int' and `string')
</pre>
<p>The solution is similar, although in this case an intermediate
predicate is required:
<br><pre>:- some [T] pred good_example3(string, T).
:- mode good_example3(in(bound("foo")), out) is det.
:- mode good_example3(in(bound("bar")), out) is det.
good_example3(Name, univ_value(Univ)) :-
good_example3_univ(Name, Univ).
:- pred good_example3_univ(string, univ).
:- mode good_example3_univ(in(bound("foo")), out) is det.
:- mode good_example3_univ(in(bound("bar")), out) is det.
:- pragma promise_pure(good_example3_univ/2).
good_example3_univ("foo"::in(bound("foo")), univ(42)::out).
good_example3_univ("bar"::in(bound("bar")), univ("blah")::out).
</pre>
<p><hr>
Node:<a name="Semantics">Semantics</a>,
Next:<a rel=next href="#Foreign%20language%20interface">Foreign language interface</a>,
Previous:<a rel=previous href="#Existential%20types">Existential types</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Semantics</h2>
<p>A legal Mercury program is one that complies with the syntax,
type, mode, determinism, and module system rules specified in earlier chapters.
If a program does not comply with those rules,
the compiler must report an error.
<p>For each legal Mercury program,
there is an associated predicate calculus theory
whose language is specified by the type declarations in the program
and whose axioms are the completion of the clauses for all predicates
in the program,
plus the usual equality axioms extended with the completion of the
equations for all functions in the program,
plus axioms corresponding to the mode-determinism assertions
(see <a href="#Determinism">Determinism</a>),
plus axioms specifying the semantics of library predicates and functions.
The declarative semantics of a legal Mercury program
is specified by this theory.
<p>Mercury implementations must be sound:
the answers they compute must be true in every model of the theory.
Mercury implementations are not required to be complete:
they may fail to compute an answer in finite time,
or they may exhaust the resource limitations of the execution
environment, even though an answer is provable in the theory.
However, there are certain minimum requirements that they
must satisfy with respect to completeness.
<p>There is an operational semantics of Mercury programs called the
<dfn>strict sequential</dfn> operational semantics. In this semantics,
the program is executed top-down, starting from <code>main/2</code>,
and function calls within a goal, conjunctions and disjunctions are all
executed in depth-first left-to-right order.
Conjunctions and function calls are "minimally" reordered as required
by the modes:
the order is determined by selecting the first mode-correct sub-goal
(conjunct or function call),
executing that, then selecting the first of the remaining sub-goals
which is now mode-correct, executing that, and so on.
(There is no interleaving of different individual conjuncts or function calls,
however; the sub-goals are reordered, not split and interleaved.)
Function application is strict, not lazy.
<p>Mercury implementations are required to provide a method of processing
Mercury programs which is equivalent to the strict sequential
operational semantics.
<p>There is another operational semantics of Mercury programs called
the <dfn>strict commutative</dfn> operational semantics. This semantics
is equivalent to the strict sequential operational semantics except
that there is no requirement that function calls, conjunctions and disjunctions
be executed left-to-right; they may be executed in any order, and may
even be interleaved. Furthermore, the order may even be different each
time a particular goal is entered.
<p>As well as providing the strict sequential operational semantics,
Mercury implementations may optionally provide additional
implementation-defined operational semantics, provided that
any such implementation-defined operational semantics are
at least as complete as the strict commutative operational
semantics. An implementation-defined semantics
is "at least as complete" as the strict commutative
semantics if and only if the implementation-defined
semantics guarantees to compute an answer in finite time for
any program for which an answer would be computed in finite time for all
possible executions under the strict commutative semantics
(i.e. for all possible orderings of conjunctions and disjunctions).
<p>Thus, to summarize, there are in fact a variety of different operational
semantics for Mercury. In one of them, the strict sequential semantics, there
is no nondeterminism -- the behaviour is always specified exactly.
Programs are executed top-down using SLDNF (or something equivalent),
mode analysis does "minimal" reordering (in a precisely defined sense),
function calls, conjunctions and disjunctions are executed depth-first
left-to-right, and function evaluation is strict. All implementations
are required to support the strict sequential semantics, so that a
program which works on one implementation using this semantics will be
guaranteed to work on any other implementation. However,
implementations are also allowed to support other operational
semantics, which may have non-determinism, so long as they are sound
with respect to the declarative semantics, and so long as they meet a
minimum level of completeness (they must be at least as complete as the
strict commutative semantics, in the sense that every program which
terminates for all possible orderings must must also terminate in any
implementation-defined operational semantics).
<p>This compromise allows Mercury to be used in several different ways.
Programmers who care more about ease of programming and portability
than about efficiency can use the strict sequential semantics, and
can then be guaranteed that if their program works on one correct
implementation, it will work on all correct implementations. Compiler
implementors who want to write optimizing implementations that do lots
of clever code reorderings and other high-level transformations or that
want to offer parallelizing implementations which take maximum
advantage of parallelism can define different semantic models.
Programmers who care about efficiency more than portability can write
code for these implementation-defined semantic models. Programmers who
care about efficiency <em>and</em> portability can achieve this by writing
code for the commutative semantics.
Of course, this is not
quite as easy as using the strict sequential semantics, since it is
in general not sufficient to test your programs on just one
implementation if you are to be sure that it will be able to use the
maximally efficient operational semantics on any implementation.
However, if you do write code which works for all possible executions
under commutative semantics (i.e. for all possible orderings of
conjunctions and disjunctions), then you can be guaranteed that it
will work correctly on every implementation, under every possible
implementation-defined semantics.
<p>The University of Melbourne Mercury implementation offers eight
different semantics, which can be selected with different
combinations of the <code>--no-reorder-conj</code>, <code>--no-reorder-disj</code>,
and <code>--fully-strict</code> options. (The <code>--fully-strict</code> option
prevents the compiler from improving completeness by optimizing away infinite
loops or calls to <code>require__error/1</code> or <code>exception__throw/1</code>.)
The default semantics are the commutative semantics. Enabling all of these
options gives you the the strict sequential semantics. Enabling just some
of them gives you a semantics somewhere in between.
<p>Future implementations of Mercury may wish to offer other operational semantics.
For example, they may wish to provide semantics in which function
evaluation is lazy, rather than strict; semantics with a guaranteed
fair search rule; and so forth.
<p><hr>
Node:<a name="Foreign%20language%20interface">Foreign language interface</a>,
Next:<a rel=next href="#C%20interface">C interface</a>,
Previous:<a rel=previous href="#Semantics">Semantics</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Foreign language interface</h2>
<ul>
<li><a href="#Calling%20foreign%20code%20from%20Mercury">Calling foreign code from Mercury</a>: How to implement a Mercury predicate
or function as a call to code
written in a different
programming language.
<li><a href="#Using%20foreign%20types%20from%20Mercury">Using foreign types from Mercury</a>: How to use a type defined in
a different programming language
in Mercury code.
<li><a href="#Data%20passing%20conventions">Data passing conventions</a>: How Mercury types are passed to
different languages.
<li><a href="#Adding%20foreign%20declarations">Adding foreign declarations</a>: How to add declarations of
entities in other programming
languages.
<li><a href="#Adding%20foreign%20definitions">Adding foreign definitions</a>: How to add definitions of
entities in other programming
languages.
<li><a href="#Language%20specific%20bindings">Language specific bindings</a>: Information specific to each
foreign language.
</ul>
<p>This chapter documents the new foreign language interface.
This is intended as a successor to the existing C interface for Mercury,
which is documented in <a href="#C%20interface">C interface</a>.
However, the new foreign language interface is not yet complete
(it does not yet include equivalents to
<code>pragma import</code> and <code>pragma export</code> in the C interface)
and is not as well tested as the existing C interface.
Furthermore, it is possible that incompatible changes will be needed in
future versions of this interface.
<p>In view of this, we currently support both the old C interface
and the new foreign language interface. We advise people writing new
code to use the new foreign language interface, but existing code
that uses the old C interface can continue to do so, and we do not
recommended rewriting such code at this point in time.
<p><hr>
Node:<a name="Calling%20foreign%20code%20from%20Mercury">Calling foreign code from Mercury</a>,
Next:<a rel=next href="#Using%20foreign%20types%20from%20Mercury">Using foreign types from Mercury</a>,
Up:<a rel=up href="#Foreign%20language%20interface">Foreign language interface</a>
<br>
<h3>Calling foreign code from Mercury</h3>
<p>Mercury procedures can be implemented using fragments of foreign language
code using <code>pragma foreign_proc</code>.
<ul>
<li><a href="#pragma%20foreign_proc">pragma foreign_proc</a>: Defining Mercury procedures using foreign code.
<li><a href="#Foreign%20code%20attributes">Foreign code attributes</a>: Describing properties of foreign
functions or code.
</ul>
<p><hr>
Node:<a name="pragma%20foreign_proc">pragma foreign_proc</a>,
Next:<a rel=next href="#Foreign%20code%20attributes">Foreign code attributes</a>,
Up:<a rel=up href="#Calling%20foreign%20code%20from%20Mercury">Calling foreign code from Mercury</a>
<br>
<h4>pragma foreign_proc</h4>
<p>A declaration of the form
<br><pre>:- pragma foreign_proc("<var>Lang</var>", <var>Pred</var>(<var>Var1</var>::<var>Mode1</var>, <var>Var2</var>::<var>Mode2</var>, <small>...</small>),
<var>Attributes</var>, <var>Foreign_Code</var>).
</pre>
<p>or
<br><pre>:- pragma foreign_proc("<var>Lang</var>", <var>Func</var>(<var>Var1</var>::<var>Mode1</var>, <var>Var2</var>::<var>Mode2</var>, <small>...</small>) = (<var>Var</var>::<var>Mode</var>),
<var>Attributes</var>, <var>Foreign_Code</var>).
</pre>
<p>means that any calls to the specified mode of <var>Pred</var> or <var>Func</var>
will result in execution of the foreign code given in <var>Foreign_Code</var>
written in language <var>Lang</var>, if <var>Lang</var> is selected as the foreign
language code by this implementation.
See the "Foreign Language Interface" chapter of the
Mercury User's Guide, for more information about how the implementation
selects the appropriate <code>foreign_proc</code> to use.
<p>The foreign code fragment may refer to the specified variables
(<var>Var1</var>, <var>Var2</var>, <small>...</small>, and <var>Var</var>)
directly by name.
It is an error for a variable to occur more than once in the argument list.
These variables will have foreign language types
corresponding to their Mercury types, as determined by language and
implementation specific rules.
<p>All <code>foreign_proc</code> implementations are assumed to be impure.
If they are actually pure or semipure, they must be explicitly
promised as such by the user (either by using foreign language
attributes specified below, or a promise_pure or promise_semipure pragma
as specified in <a href="#Impurity">Impurity</a>.
<p>Additional restrictions on the foreign language interface code
depend on the foreign language and compilation options.
For more information, including the list of supported foreign languages and
the strings used to identify them, see the language specific information
in the "Foreign Language Interface" chapter of the
Mercury User's Guide.
<p>If there is a <code>pragma foreign_proc</code> declaration for any
mode of a predicate or function, then there must be either a
clause or a <code>pragma foreign_proc</code>
declaration for every mode of that predicate or function.
<p>Here's an example of code using <code>pragma foreign_proc</code>:
The following code defines a Mercury function
<code>sin/1</code> which calls the C function <code>sin()</code> of the same name.
<br><pre>:- func sin(float) = float.
:- pragma foreign_proc("C", sin(X::in) = (Sin::out),
[may_call_mercury],
"Sin = sin(X);").
</pre>
<p>If the foreign language code does not recursively invoke Mercury code,
as in the above example, then you can use <code>will_not_call_mercury</code>
in place of <code>may_call_mercury</code> in the declarations above.
This allows the compiler to use a slightly more efficient calling convention.
(If you use this form, and the C code <em>does</em> invoke Mercury code,
then the behaviour is undefined -- your program may misbehave or crash.)
<p>If there are both Mercury definitions and foreign_proc definitions for
a procedure and/or foreign_proc definitions for different languages,
it is implementation defined which definition is used.
<p>For pure and semipure procedures, the declarative semantics of the
foreign_proc definitions must be the same as that of the Mercury code.
The only thing that is allowed to differ is the efficiency (including
the possibility of non-termination) and the order of solutions.
<p><hr>
Node:<a name="Foreign%20code%20attributes">Foreign code attributes</a>,
Previous:<a rel=previous href="#pragma%20foreign_proc">pragma foreign_proc</a>,
Up:<a rel=up href="#Calling%20foreign%20code%20from%20Mercury">Calling foreign code from Mercury</a>
<br>
<h4>Foreign code attributes</h4>
<p>As described above,
<code>pragma foreign_proc</code>
declarations may include a list of attributes describing properties
of the given foreign function or code.
All Mercury implementations must support the attributes listed below.
They may also support additional attributes.
<p>The attributes which must be supported by all implementations
are as follows:
<dl>
<br><dt><code>may_call_mercury</code>/<code>will_not_call_mercury</code>
<dd>This attribute declares whether or not execution inside this foreign
language code may call back into Mercury or not. The default, in case
neither is specified, is <code>may_call_mercury</code>.
Specifying <code>will_not_call_mercury</code> may allow the compiler to
generate more efficient code.
If you specify <code>will_not_call_mercury</code>,
but the foreign language code <em>does</em> invoke Mercury code, then the
behaviour is undefined.
<br><dt><code>promise_pure</code>/<code>promise_semipure</code>
<dd>This attribute promises that the purity of the given predicate or
function definition is pure or semipure.
It is equivalent to a corresponding <code>pragma promise_pure</code>
or <code>pragma promise_semipure</code> declaration (see <a href="#Impurity">Impurity</a>).
If omitted, the clause specified by the <code>foreign_proc</code> is
assumed to be impure.
<br><dt><code>thread_safe</code>/<code>not_thread_safe</code>
<dd>This attribute declares whether or not it is safe for multiple threads
to execute this foreign language code concurrently.
The default, in case neither is specified, is <code>not_thread_safe</code>.
If the foreign language code is declared <code>thread_safe</code>, then the
Mercury implementation is permitted to execute the code concurrently
from multiple threads without taking any special precautions. If the
foreign language code is declared
<code>not_thread_safe</code>,
then the Mercury implementation must not invoke the code concurrently from
multiple threads. If the Mercury implementation does use multithreading,
then it must take appropriate steps to prevent this.
(The experimental multithreaded version of the current
University of Melbourne Mercury implementation protects
<code>not_thread_safe</code> code using a mutex:
C code that is not thread-safe has code inserted around it to obtain
and release a mutex. All non-thread-safe foreign language code shares a
single mutex.)
</dl>
<p>Additional attributes which are supported by the Melbourne Mercury
compiler are as follows:
<dl>
<br><dt><code>max_stack_size(Size)</code>
<dd>This attribute declares the maximum stack usage of a particular piece of
code. The unit that <code>Size</code> is measured in depends upon foreign language
being used.
Currently this attribute is only used (and is in fact required) by the
<code>IL</code> foreign language interface, and is measured in units of stack
items.
</dl>
<p><hr>
Node:<a name="Data%20passing%20conventions">Data passing conventions</a>,
Next:<a rel=next href="#Adding%20foreign%20declarations">Adding foreign declarations</a>,
Previous:<a rel=previous href="#Using%20foreign%20types%20from%20Mercury">Using foreign types from Mercury</a>,
Up:<a rel=up href="#Foreign%20language%20interface">Foreign language interface</a>
<br>
<h3>Data passing conventions</h3>
<p>For each supported foreign language,
we explain how to map a Mercury type to a type in that foreign language.
We also map the Mercury parameter passing convention
to the foreign language's parameter passing convention.
<ul>
<li><a href="#C%20data%20passing%20conventions">C data passing conventions </a>:
<li><a href="#IL%20and%20C%23%20data%20passing%20conventions">IL and C# data passing conventions </a>:
</ul>
<p><hr>
Node:<a name="C%20data%20passing%20conventions">C data passing conventions</a>,
Next:<a rel=next href="#IL%20and%20C%23%20data%20passing%20conventions">IL and C# data passing conventions</a>,
Up:<a rel=up href="#Data%20passing%20conventions">Data passing conventions</a>
<br>
<h4>C data passing conventions</h4>
<p>This section is currently documented in <a href="#Passing%20data%20to%20and%20from%20C">Passing data to and from C</a>.
<p><hr>
Node:<a name="IL%20and%20C%23%20data%20passing%20conventions">IL and C# data passing conventions</a>,
Previous:<a rel=previous href="#C%20data%20passing%20conventions">C data passing conventions</a>,
Up:<a rel=up href="#Data%20passing%20conventions">Data passing conventions</a>
<br>
<h4>IL and C# data passing conventions</h4>
<p>The Mercury types <code>int</code>, <code>float</code>, <code>char</code>,
and <code>string</code> are mapped to the Common Language Runtime types
<code>System.Int32</code>, <code>System.Double</code>, <code>System.Char</code> and
<code>System.String</code> respectively, which correspond to the C# types
<code>int</code>, <code>double</code>, <code>char</code>, and <code>string</code>,
and to the IL assembler types
<code>int</code>, <code>float64</code>, <code>char</code> and <code>string</code>.
<p>Mercury variables whose type is a type variable will be passed as
<code>System.Object</code>.
Mercury array types are mapped to CLR array types.
When compiling with <code>--no-high-level-data</code>, all other Mercury variables
are passed as <code>System.Object[]</code>.
When compiling with <code>--high-level-data</code>,
Mercury variables whose type is a Mercury discriminated union type
will be passed as a CLR type whose type name is determined from
the Mercury type name (ignoring any type parameters) followed by
an underscore and then the type arity,
expressed as a decimal integer.
Mercury module qualifiers are converted to CLR namespace qualifiers.
For example the Mercury type <code>foo__bar__baz/1</code> will be passed as the CLR
type <code>foo.bar.baz_1</code>.
Note an extra namespace qualifier, <code>mercury</code>, will be prepended to the
beginning of names residing in the Mercury standard library.
Mercury variables whose type is a Mercury equivalence type
will be passed as the representation of the right hand side of the
equivalence type.
<p>This mapping is subject to change and you should try to avoid writing
code that relies heavily upon a particular representation of Mercury
terms.
<p>Mercury arguments declared with input modes are passed by value to the
IL or C# function.
For output arguments,
the Mercury implementation will pass to the IL or C# function a reference to
the location in which to store the result; for example, a Mercury output
argument of type <code>int</code> would map to a C# <code>ref int</code>
function parameter. (Note that we map to <code>ref int</code>, not <code>out int</code>;
for procedures that can fail, output arguments only need to be set if the
procedure succeeds.)
If the Mercury procedure can fail,
then its IL or C# function should return a truth value of type
<code>bool</code> (i.e. <code>System.Bool</code>) indicating success or failure:
<code>true</code> indicates success, and <code>false</code> indicates failure.
If the Mercury procedure is a Mercury function that cannot fail,
and the function result has an output mode,
then the IL function should return the Mercury function result value.
Otherwise the function result is appended as an extra argument.
Arguments of type <code>io__state</code> or <code>store__store(_)</code> are not
passed at all;
that's because these types represent mutable state, and in IL
modifications to mutable state are done via side effects,
rather than argument passing.
<p><hr>
Node:<a name="Using%20foreign%20types%20from%20Mercury">Using foreign types from Mercury</a>,
Next:<a rel=next href="#Data%20passing%20conventions">Data passing conventions</a>,
Previous:<a rel=previous href="#Calling%20foreign%20code%20from%20Mercury">Calling foreign code from Mercury</a>,
Up:<a rel=up href="#Foreign%20language%20interface">Foreign language interface</a>
<br>
<h3>Using foreign types from Mercury</h3>
<p>Types defined in a foreign language can be accessed in Mercury using
a declaration of the form
<br><pre>:- pragma foreign_type(<var>Lang</var>, <var>MercuryTypeName</var>, <var>ForeignTypeDescriptor</var>).
</pre>
<p>This defines <var>MercuryTypeName</var> as a synonym for type
<var>ForeignTypeDescriptor</var> defined in the foreign language <var>Lang</var>.
You must declare <var>MercuryTypeName</var> using a (possibly abstract)
<code>:- type</code> declaration as usual. The <code>pragma foreign_type</code> must
not have wider visibility than the type declaration (if the
<code>pragma foreign_type</code> declaration is in the interface,
the <code>:- type</code> declaration must be also).
<p><var>ForeignTypeDescriptor</var> defines how the Mercury type is mapped for a
particular foreign language. Specific syntax is given in the language
specific information below.
<p><var>MercuryTypeName</var> is treated as an abstract type at all times in
Mercury code.
However, if <var>MercuryTypeName</var> is one of the parameters of a
foreign_proc for <var>Lang</var>, and the <code>pragma foreign_type</code> declaration
is visible to the foreign_proc, it will be passed to that foreign_proc as
specified by <var>ForeignTypeDescriptor</var>.
<p>Multiple foreign language definitions may be given for the same type --
the appropriate definition will be used for the appropriate language (see the
language specific information below for details). All definitions
must have the same visibility. A Mercury definition, which must define
a discriminated union type, may also be given. The constructors for the
type will only be visible in Mercury clauses for predicates or functions with
<code>pragma foreign_proc</code> clauses for all of the languages for which there
are <code>foreign_type</code> declarations for the type.
<p>As with discriminated union types, programmers can specify the unification
and comparison predicates to use for values of the type using the following
syntax (see <a href="#User-defined%20equality%20and%20comparison">User-defined equality and comparison</a>):
<br><pre>:- pragma foreign_type(<var>Lang</var>, <var>MercuryTypeName</var>, <var>ForeignTypeDescriptor</var>)
where equality is <var>EqualityPred</var>, comparison is <var>ComparePred</var>.
</pre>
<p>You can use Mercury foreign language interfacing declarations
which specify language <var>X</var> to interface to types that are actually
written in a different language <var>Y</var> provided that <var>X</var> and <var>Y</var>
have compatible interface conventions. Support for this kind of
compatibility is described in the language specific information below.
<p><hr>
Node:<a name="Adding%20foreign%20declarations">Adding foreign declarations</a>,
Next:<a rel=next href="#Adding%20foreign%20definitions">Adding foreign definitions</a>,
Previous:<a rel=previous href="#Data%20passing%20conventions">Data passing conventions</a>,
Up:<a rel=up href="#Foreign%20language%20interface">Foreign language interface</a>
<br>
<h3>Adding foreign declarations</h3>
<p>Foreign language declarations (such as type declarations, header file
inclusions or macro definitions) can included in the Mercury source file as
part of a <code>foreign_decl</code> declaration of the form
<br><pre>:- pragma foreign_decl("<var>Lang</var>", <var>DeclCode</var>).
</pre>
<p>This declaration will have effects equivalent to including the specified
<var>DeclCode</var> in an automatically-generated source file of the specified
programming language, in a place appropriate for declarations,
and linking that source file with the Mercury program
(after having compiled it with a compiler for the specified programming
language, if appropriate).
<p>Entities declared in <code>pragma foreign_decl</code> declarations are
visible in <code>pragma foreign_code</code> and <code>pragma foreign_proc</code>
declarations that specify the same foreign language and occur in in the
same Mercury module.
<p>To make the declarations for Mercury predicates or functions
exported to a foreign language using a <code>pragma export</code>
declaration visible to foreign code in a <code>pragma foreign_code</code>
or <code>pragma foreign_proc</code> declaration, use a declaration of the form
<br><pre>:- pragma foreign_import_module("<var>Lang</var>", <var>ImportedModule</var>).
</pre>
<p>where <var>ImportedModule</var> is the name of the module containing
the <code>pragma export</code> declarations.
<p>If <var>Lang</var> is <code>"C"</code> this is equivalent to
<br><pre>:- pragma foreign_decl("C", "#include ""<var>ImportedModule</var>.mh""").
</pre>
<p>where <code><var>ImportedModule</var>.mh</code> is the automatically generated
header file containing the C declarations for the predicates
and functions exported to C.
<p><code>pragma foreign_import_module</code> should be used instead of the
explicit <code>#include</code> because <code>pragma foreign_import_module</code>
tells the implementation that <code><var>ImportedModule</var>.mh</code> must be built
before the object file for the module containing the
<code>pragma foreign_import_module</code> declaration.
<p>A cycle of <code>pragma foreign_import_module</code>, where the language is either
<code>"MC++"</code> or <code>"C#"</code>, is not permitted.
<p><hr>
Node:<a name="Adding%20foreign%20definitions">Adding foreign definitions</a>,
Next:<a rel=next href="#Language%20specific%20bindings">Language specific bindings</a>,
Previous:<a rel=previous href="#Adding%20foreign%20declarations">Adding foreign declarations</a>,
Up:<a rel=up href="#Foreign%20language%20interface">Foreign language interface</a>
<br>
<h3>Adding foreign definitions</h3>
<p>Definitions of foreign language entities (such as functions or global
variables) may be included using a declaration of the form
<br><pre>:- pragma foreign_code("<var>Lang</var>", <var>Code</var>).
</pre>
<p>This declaration will have effects equivalent to including the specified
<var>Code</var> in an automatically-generated source file of the specified
programming language, in a place appropriate for definitions,
and linking that source file with the Mercury program
(after having compiled it with a compiler for the specified programming
language, if appropriate).
<p>Entities declared in <code>pragma foreign_code</code> declarations are
visible in <code>pragma foreign_proc</code> declarations that specify the same
foreign language and occur in in the same Mercury module.
<p><hr>
Node:<a name="Language%20specific%20bindings">Language specific bindings</a>,
Previous:<a rel=previous href="#Adding%20foreign%20definitions">Adding foreign definitions</a>,
Up:<a rel=up href="#Foreign%20language%20interface">Foreign language interface</a>
<br>
<h3>Language specific bindings</h3>
<ul>
<li><a href="#Interfacing%20with%20C">Interfacing with C </a>: How to write code to interface with C
<li><a href="#Interfacing%20with%20C%23">Interfacing with C# </a>: How to write code to interface with C#
<li><a href="#Interfacing%20with%20IL">Interfacing with IL </a>: How to write code to interface with IL
<li><a href="#Interfacing%20with%20Managed%20C++">Interfacing with Managed C++ </a>: How to write code to interface with
Managed C++
</ul>
<p>All Mercury implementations should support interfacing with C.
The set of other languages supported is implementation-defined.
A suitable compiler or assembler for the foreign language
must be available on the system.
<p>The University of Melbourne Mercury implementation supports
interfacing with the following languages:
<dl>
<br><dt><code>C</code>
<dd>Use the string <code>"C"</code> to set the foreign language to C.
<br><dt><code>C#</code>
<dd>Use the string <code>"C#"</code> to set the foreign language to C#.
<br><dt><code>IL</code>
<dd>Use the string <code>"IL"</code> to set the foreign language to IL.
IL (sometimes also known as CIL or MSIL) is the Intermediate Language
for the .NET Common Language Runtime.
<br><dt><code>Managed C++</code>
<dd>Use the string <code>"MC++"</code> to set the foreign language to Managed C++.
Managed C++ is C++ with Microsoft's extensions to support interfacing
with and generating code for the .NET Common Language Runtime.
</dl>
<p><hr>
Node:<a name="Interfacing%20with%20C">Interfacing with C</a>,
Next:<a rel=next href="#Interfacing%20with%20C%23">Interfacing with C#</a>,
Up:<a rel=up href="#Language%20specific%20bindings">Language specific bindings</a>
<br>
<h4>Interfacing with C</h4>
<ul>
<li><a href="#Using%20pragma%20foreign_proc%20for%20C">Using pragma foreign_proc for C </a>: Calling C code from Mercury
<li><a href="#Using%20pragma%20foreign_decl%20for%20C">Using pragma foreign_decl for C </a>: Including C declarations in Mercury
<li><a href="#Using%20pragma%20foreign_code%20for%20C">Using pragma foreign_code for C </a>: Including C code in Mercury
<li><a href="#Using%20pragma%20foreign_type%20for%20C">Using pragma foreign_type for C </a>: Declaring C types in Mercury
</ul>
<p><hr>
Node:<a name="Using%20pragma%20foreign_proc%20for%20C">Using pragma foreign_proc for C</a>,
Next:<a rel=next href="#Using%20pragma%20foreign_decl%20for%20C">Using pragma foreign_decl for C</a>,
Up:<a rel=up href="#Interfacing%20with%20C">Interfacing with C</a>
<br>
<h5>Using pragma foreign_proc for C</h5>
<p>The input and output variables will have C types corresponding
to their Mercury types, as determined by the rules specified in
<a href="#C%20data%20passing%20conventions">C data passing conventions</a>.
<p>The C code fragment may declare local variables, but it should not
declare any labels or static variables unless there is also a Mercury
<code>pragma no_inline</code> declaration for the procedure.
The reason for this is that otherwise the Mercury implementation may
inline the procedure by duplicating the C code fragment for each call.
If the C code fragment declared a static variable, inlining it in this
way could result in the program having multiple instances of the static
variable, rather than a single shared instance. If the C code fragment
declared a label, inlining it in this way could result in an error due
to the same label being defined twice inside a single C function.
<p>C code in a <code>pragma foreign_proc</code> declaration
for any procedure whose determinism indicates that it could fail
must assign a truth value to the macro <code>SUCCESS_INDICATOR</code>.
For example:
<br><pre>:- pred string__contains_char(string, character).
:- mode string__contains_char(in, in) is semidet.
:- pragma foreign_proc("C",
string__contains_char(Str::in, Ch::in),
[will_not_call_mercury, promise_pure],
"SUCCESS_INDICATOR = (strchr(Str, Ch) != NULL);").
</pre>
<p><code>SUCCESS_INDICATOR</code> should not be used other than as the target of
an assignment.
(For example, it may be <code>#define</code>d to a register, so you should not
try to take its address.)
Procedures whose determinism indicates that that they cannot fail
should not access <code>SUCCESS_INDICATOR</code>.
<p>Arguments whose mode is input will have their values set by the
Mercury implementation on entry to the C code. If the procedure
succeeds, the C code must set the values of all output arguments
before returning. If the procedure fails, the C code need only
set <code>SUCCESS_INDICATOR</code> to false (zero).
<p><hr>
Node:<a name="Using%20pragma%20foreign_decl%20for%20C">Using pragma foreign_decl for C</a>,
Next:<a rel=next href="#Using%20pragma%20foreign_code%20for%20C">Using pragma foreign_code for C</a>,
Previous:<a rel=previous href="#Using%20pragma%20foreign_proc%20for%20C">Using pragma foreign_proc for C</a>,
Up:<a rel=up href="#Interfacing%20with%20C">Interfacing with C</a>
<br>
<h5>Using pragma foreign_decl for C</h5>
<p>Any macros, function prototypes, or other C declarations
that are used in <code>foreign_code</code> or <code>foreign_proc</code>
pragmas must be included using a <code>foreign_decl</code> declaration of the form
<br><pre>:- pragma foreign_decl("C", <var>HeaderCode</var>).
</pre>
<p><var>HeaderCode</var> can be a C <code>#include</code> line, for example
<br><pre>:- pragma foreign_decl("C", "#include <math.h>")
</pre>
<p>or
<br><pre>:- pragma foreign_decl("C", "#include ""tcl.h""").
</pre>
<p>or it may contain any C declarations, for example
<br><pre>:- pragma foreign_decl("C", "
extern int errno;
#define SIZE 200
struct Employee {
char name[SIZE];
};
extern int bar;
extern void foo(void);
").
</pre>
<p>Mercury automatically includes certain headers such as <code><stdlib.h></code>,
but you should not rely on this, as the set of headers which Mercury
automatically includes is subject to change.
<p>If a Mercury predicate or function exported using
a <code>pragma export</code> declaration is to be used within a
<code>:- pragma foreign_code</code> or <code>:- pragma foreign_proc</code>
declaration the header file for the module containing the
<code>pragma export</code> declaration should be included using a
<code>pragma foreign_import_module</code> declaration, for example
<br><pre>:- pragma foreign_import_module("C", exporting_module).
</pre>
<p><hr>
Node:<a name="Using%20pragma%20foreign_code%20for%20C">Using pragma foreign_code for C</a>,
Next:<a rel=next href="#Using%20pragma%20foreign_type%20for%20C">Using pragma foreign_type for C</a>,
Previous:<a rel=previous href="#Using%20pragma%20foreign_decl%20for%20C">Using pragma foreign_decl for C</a>,
Up:<a rel=up href="#Interfacing%20with%20C">Interfacing with C</a>
<br>
<h5>Using pragma foreign_code for C</h5>
<p>Definitions of C functions or global variables may be
included using a declaration of the form
<br><pre>:- pragma foreign_code("C", <var>Code</var>).
</pre>
<p>For example,
<br><pre>:- pragma foreign_code("C", "
int bar = 42;
void foo(void) {}
").
</pre>
<p>Such code is copied verbatim into the generated C file.
<p><hr>
Node:<a name="Using%20pragma%20foreign_type%20for%20C">Using pragma foreign_type for C</a>,
Previous:<a rel=previous href="#Using%20pragma%20foreign_code%20for%20C">Using pragma foreign_code for C</a>,
Up:<a rel=up href="#Interfacing%20with%20C">Interfacing with C</a>
<br>
<h5>Using pragma foreign_type for C</h5>
<p>The C <code>pragma foreign_type</code> declaration is of the form:
<br><pre>:- pragma foreign_type(c, <var>MercuryTypeName</var>, <var>CForeignType</var>).
</pre>
<p>The <var>CForeignType</var> can be any C type name that obeys the following
restrictions.
Function types, array types, and incomplete types are not allowed.
The type name must be such that when declaring a variable in C of that
type, that no part of the type name is required after the variable name.
(This rule prohibits, for example, function pointer types such as
<code>void (*)(void)</code>. However, it would be OK to use a typedef name
which was defined as a function pointer type.)
<p>If the <var>MercuryTypeName</var> is the type of a parameter of a procedure
defined using <code>pragma foreign_proc</code>,
it will be passed to the foreign_proc's foreign language code
as <var>CForeignType</var>.
<p>Furthermore, any Mercury procedure exported with <code>pragma export</code>
will use <var>CForeignType</var> as the type for any
parameters whose Mercury type is <var>MercuryTypeName</var>.
<p>Also see the section on using C pointers (see <a href="#Using%20C%20pointers">Using C pointers</a>) for
information on how to use the c_pointer type with the C interface.
<p><hr>
Node:<a name="Interfacing%20with%20C%23">Interfacing with C#</a>,
Next:<a rel=next href="#Interfacing%20with%20IL">Interfacing with IL</a>,
Previous:<a rel=previous href="#Interfacing%20with%20C">Interfacing with C</a>,
Up:<a rel=up href="#Language%20specific%20bindings">Language specific bindings</a>
<br>
<h4>Interfacing with C#</h4>
<ul>
<li><a href="#Using%20pragma%20foreign_type%20for%20C%23">Using pragma foreign_type for C# </a>: Declaring C# types in Mercury
<li><a href="#Using%20pragma%20foreign_proc%20for%20C%23">Using pragma foreign_proc for C# </a>: Calling C# code from Mercury
<li><a href="#Using%20pragma%20foreign_decl%20for%20C%23">Using pragma foreign_decl for C# </a>: Including C# declarations in Mercury
<li><a href="#Using%20pragma%20foreign_code%20for%20C%23">Using pragma foreign_code for C# </a>: Including C# code in Mercury
</ul>
<p><hr>
Node:<a name="Using%20pragma%20foreign_type%20for%20C%23">Using pragma foreign_type for C#</a>,
Next:<a rel=next href="#Using%20pragma%20foreign_proc%20for%20C%23">Using pragma foreign_proc for C#</a>,
Up:<a rel=up href="#Interfacing%20with%20C%23">Interfacing with C#</a>
<br>
<h5>Using pragma foreign_type for C#</h5>
<p>There is currently no direct support for using C# types from Mercury;
however, the types for IL are compatible with C#, and so the foreign_type
support for IL can be used instead.
See the section on using pragma foreign_type for IL
(see <a href="#Using%20pragma%20foreign_type%20for%20IL">Using pragma foreign_type for IL</a>).
<p><hr>
Node:<a name="Using%20pragma%20foreign_proc%20for%20C%23">Using pragma foreign_proc for C#</a>,
Next:<a rel=next href="#Using%20pragma%20foreign_decl%20for%20C%23">Using pragma foreign_decl for C#</a>,
Previous:<a rel=previous href="#Using%20pragma%20foreign_type%20for%20C%23">Using pragma foreign_type for C#</a>,
Up:<a rel=up href="#Interfacing%20with%20C%23">Interfacing with C#</a>
<br>
<h5>Using pragma foreign_proc for C#</h5>
<p>The C# code from C# pragma foreign_proc declarations will be placed in
the bodies of static member functions of an automatically-generated C# class.
Since such C# code will become part of a static member function,
it must not refer to the <code>this</code> keyword.
It may however refer to static member variables or static member
functions declared with <code>pragma foreign_code</code>.
<p>The input and output variables for a C# <code>pragma foreign_proc</code> will
have C# types corresponding to their Mercury types. The exact rules
for mapping Mercury types to C# types are described in
<a href="#IL%20and%20C%23%20data%20passing%20conventions">IL and C# data passing conventions</a>.
<p>C# code in a <code>pragma foreign_proc</code> declaration
for any procedure whose determinism indicates that it could fail
must assign a value of type bool to the variable <code>succeeded</code>.
For example:
<br><pre>:- pred string__contains_char(string, character).
:- mode string__contains_char(in, in) is semidet.
:- pragma foreign_proc("C#",
string__contains_char(Str::in, Ch::in),
[will_not_call_mercury, promise_pure],
"succeeded = (Str.IndexOf(Ch) != -1);").
</pre>
<p>C# code for procedures whose determinism indicates that that they cannot fail
should not access <code>succeeded</code>.
<p>Arguments whose mode is input will have their values set by the
Mercury implementation on entry to the C# code. If the procedure
succeeds, the C# code must set the values of all output arguments
before returning. If the procedure fails, the C# code need only
set <code>succeeded</code> to false.
<p><hr>
Node:<a name="Using%20pragma%20foreign_decl%20for%20C%23">Using pragma foreign_decl for C#</a>,
Next:<a rel=next href="#Using%20pragma%20foreign_code%20for%20C%23">Using pragma foreign_code for C#</a>,
Previous:<a rel=previous href="#Using%20pragma%20foreign_proc%20for%20C%23">Using pragma foreign_proc for C#</a>,
Up:<a rel=up href="#Interfacing%20with%20C%23">Interfacing with C#</a>
<br>
<h5>Using pragma foreign_decl for C#</h5>
<p><code>pragma foreign_decl</code> declarations for C# can be used to provide
any top-level C# declarations (e.g. <code>using</code> declarations
or auxiliary class definitions) which are needed by C# code in
<code>pragma foreign_proc</code> declarations in that module.
<p>For example:
<br><pre>:- pragma foreign_decl("C#", "
using System;
").
:- pred hello(io__state::di, io__state::uo) is det.
:- pragma foreign_decl("C#",
hello(_IO0::di, _IO::uo),
[will_not_call_mercury],
"
// here we can refer directly to Console rather than System.Console
Console.WriteLine(""hello world"");
").
</pre>
<p><hr>
Node:<a name="Using%20pragma%20foreign_code%20for%20C%23">Using pragma foreign_code for C#</a>,
Previous:<a rel=previous href="#Using%20pragma%20foreign_decl%20for%20C%23">Using pragma foreign_decl for C#</a>,
Up:<a rel=up href="#Interfacing%20with%20C%23">Interfacing with C#</a>
<br>
<h5>Using pragma foreign_code for C#</h5>
<p>The C# code from <code>pragma foreign_proc</code> declarations for C# will be
placed in the bodies of static member functions of an
automatically-generated C# class. <code>pragma foreign_code</code>
can be used to define additional members of this automatically-generated
class, which can then be referenced by <code>pragma foreign_proc</code>
declarations for C# from that module.
<p>For example:
<br><pre>:- pragma foreign_code("C#", "
static int counter = 0;
").
:- impure pred incr_counter is det.
:- pragma foreign_proc("C#", incr_counter,
[will_not_call_mercury], "counter++;").
:- semipure func get_counter = int.
:- pragma foreign_proc("C#",
get_counter = (Result::out),
[will_not_call_mercury, promise_semipure],
"Result = counter;").
</pre>
<p><hr>
Node:<a name="Interfacing%20with%20IL">Interfacing with IL</a>,
Next:<a rel=next href="#Interfacing%20with%20Managed%20C++">Interfacing with Managed C++</a>,
Previous:<a rel=previous href="#Interfacing%20with%20C%23">Interfacing with C#</a>,
Up:<a rel=up href="#Language%20specific%20bindings">Language specific bindings</a>
<br>
<h4>Interfacing with IL</h4>
<ul>
<li><a href="#Using%20pragma%20foreign_type%20for%20IL">Using pragma foreign_type for IL </a>: Declaring IL types in Mercury
<li><a href="#Using%20pragma%20foreign_proc%20for%20IL">Using pragma foreign_proc for IL </a>: Calling IL code from Mercury
<li><a href="#Using%20pragma%20foreign_decl%20for%20IL">Using pragma foreign_decl for IL </a>: Including IL declarations in Mercury
<li><a href="#Using%20pragma%20foreign_code%20for%20IL">Using pragma foreign_code for IL </a>: Including IL code in Mercury
</ul>
<p><hr>
Node:<a name="Using%20pragma%20foreign_type%20for%20IL">Using pragma foreign_type for IL</a>,
Next:<a rel=next href="#Using%20pragma%20foreign_proc%20for%20IL">Using pragma foreign_proc for IL</a>,
Up:<a rel=up href="#Interfacing%20with%20IL">Interfacing with IL</a>
<br>
<h5>Using pragma foreign_type for IL</h5>
<p>The IL <code>pragma foreign_type</code> declaration is of the form:
<br><pre>:- pragma foreign_type(il, <var>MercuryTypeName</var>, <var>DotNetForeignType</var>).
</pre>
<p>If the <var>MercuryTypeName</var> is the type of a parameter of a procedure
defined using <code>pragma foreign_proc</code> for any of the .NET CLR
languages, it will be passed to the foreign_proc's foreign language code
as <var>DotNetForeignType</var>.
<p>Furthermore, any Mercury procedure exported with <code>pragma export</code>
will use <var>DotNetForeignType</var> as the .NET CLR parameter type for
parameters whose Mercury type is <var>MercuryTypeName</var>.
<p>The IL assembler syntax is used to specify type names for all the .NET CLR
languages (IL, C# and Managed C++) supported by Mercury's
<code>foreign_proc</code> mechanism.
This syntax is documented in the ECMA specifications for .NET.
The .NET CLR backend supports reference and value types
using <code>pragma foreign_type</code>, where DotNetForeignType is
specified using the syntax
<code>"class [AssemblyName]ReferenceTypeName"</code> for reference types and
<code>"valuetype [AssemblyName]ValueTypeName"</code> for value types.
Note that extra whitespace is not handled -- there should only be a single
space between the class keyword and the assembly specifier.
Value types which have a special name (such as <code>int32</code>) can be
named using their valuetype syntax or their special name;
they will be marshalled using their special name
(as is required by section 7.2 of Partition II of the ECMA CLI documentation).
<p>For example:
<br><pre>:- type xmldoc.
:- pragma foreign_type(il, xmldoc, "class [System.Xml]System.Xml.XmlDocument").
:- type int32.
:- pragma foreign_type(il, int32, "valuetype [mscorlib]System.Int32").
</pre>
<p>ensures that on the .NET CLR backend the Mercury type <code>xmldoc</code> is
marshalled by the backend as <code>System.Xml.XmlDocument</code> from assembly
<code>System.Xml</code>, and that the Mercury type <code>int32</code> will be
marshalled by the backend as the CLR type <code>int32</code>.
<p>The following example shows how one can use the marshalled data from C#.
<br><pre>:- pred loadxml(string::in, xmldoc::di, xmldoc::uo) is det.
:- pragma foreign_proc("C#", load(String::in, XML0::di, XML::uo),
[will_not_call_mercury, promise_pure],
"
XML0.LoadXml(String);
XML = XML0;
").
</pre>
<p><hr>
Node:<a name="Using%20pragma%20foreign_proc%20for%20IL">Using pragma foreign_proc for IL</a>,
Next:<a rel=next href="#Using%20pragma%20foreign_decl%20for%20IL">Using pragma foreign_decl for IL</a>,
Previous:<a rel=previous href="#Using%20pragma%20foreign_type%20for%20IL">Using pragma foreign_type for IL</a>,
Up:<a rel=up href="#Interfacing%20with%20IL">Interfacing with IL</a>
<br>
<h5>Using pragma foreign_proc for IL</h5>
<p>Variables can be accessed from IL by using ldloc (for input parameters)
and stloc (for output parameters).
Do not use ret or jmp instructions or tail calls within the handwritten
IL code.
The stack must be empty at the end of the IL code.
<br><pre>:- pred add(int::in, int::in, int::out) det.
:- pragma foreign_proc("il", add(X::in, Y::in, Z::out), [max_stack_size(2)], "
ldloc X
ldloc Y
add
stloc Z
").
</pre>
<p>IL code for procedures whose determinism indicates they could fail
is currently not supported.
<p>Arguments whose mode is input will have their values set by the
Mercury implementation on entry to the IL code. If the procedure
succeeds, the IL code must set the values of all output arguments
before returning.
<p>Each of the head variables will be represented by the Common Language
Runtime types as specified in <a href="#IL%20and%20C%23%20data%20passing%20conventions">IL and C# data passing conventions</a>.
<p><hr>
Node:<a name="Using%20pragma%20foreign_decl%20for%20IL">Using pragma foreign_decl for IL</a>,
Next:<a rel=next href="#Using%20pragma%20foreign_code%20for%20IL">Using pragma foreign_code for IL</a>,
Previous:<a rel=previous href="#Using%20pragma%20foreign_proc%20for%20IL">Using pragma foreign_proc for IL</a>,
Up:<a rel=up href="#Interfacing%20with%20IL">Interfacing with IL</a>
<br>
<h5>Using pragma foreign_decl for IL</h5>
<p><code>pragma foreign_decl</code> is currently not supported for IL.
<p><hr>
Node:<a name="Using%20pragma%20foreign_code%20for%20IL">Using pragma foreign_code for IL</a>,
Previous:<a rel=previous href="#Using%20pragma%20foreign_decl%20for%20IL">Using pragma foreign_decl for IL</a>,
Up:<a rel=up href="#Interfacing%20with%20IL">Interfacing with IL</a>
<br>
<h5>Using pragma foreign_code for IL</h5>
<p><code>pragma foreign_code</code> is currently not supported for IL.
<p><hr>
Node:<a name="Interfacing%20with%20Managed%20C++">Interfacing with Managed C++</a>,
Previous:<a rel=previous href="#Interfacing%20with%20IL">Interfacing with IL</a>,
Up:<a rel=up href="#Language%20specific%20bindings">Language specific bindings</a>
<br>
<h4>Interfacing with Managed C++</h4>
<ul>
<li><a href="#Using%20pragma%20foreign_type%20for%20MC++">Using pragma foreign_type for MC++</a>: Declaring MC++ types in Mercury
<li><a href="#Using%20pragma%20foreign_proc%20for%20MC++">Using pragma foreign_proc for MC++</a>: Calling MC++ code from Mercury
<li><a href="#Using%20pragma%20foreign_decl%20for%20MC++">Using pragma foreign_decl for MC++</a>: Including MC++ declarations in Mercury
<li><a href="#Using%20pragma%20foreign_code%20for%20MC++">Using pragma foreign_code for MC++</a>: Including MC++ code in Mercury
</ul>
<p><hr>
Node:<a name="Using%20pragma%20foreign_type%20for%20MC++">Using pragma foreign_type for MC++</a>,
Next:<a rel=next href="#Using%20pragma%20foreign_proc%20for%20MC++">Using pragma foreign_proc for MC++</a>,
Up:<a rel=up href="#Interfacing%20with%20Managed%20C++">Interfacing with Managed C++</a>
<br>
<h5>Using pragma foreign_type for MC++</h5>
<p>There is no direct support for using MC++ types from Mercury; however, the
types for IL are compatible with MC++, and so the foreign_type
support for IL can be used instead.
See the section on using pragma foreign_type for IL
(see <a href="#Using%20pragma%20foreign_type%20for%20IL">Using pragma foreign_type for IL</a>).
<p><hr>
Node:<a name="Using%20pragma%20foreign_proc%20for%20MC++">Using pragma foreign_proc for MC++</a>,
Next:<a rel=next href="#Using%20pragma%20foreign_decl%20for%20MC++">Using pragma foreign_decl for MC++</a>,
Previous:<a rel=previous href="#Using%20pragma%20foreign_type%20for%20MC++">Using pragma foreign_type for MC++</a>,
Up:<a rel=up href="#Interfacing%20with%20Managed%20C++">Interfacing with Managed C++</a>
<br>
<h5>Using pragma foreign_proc for MC++</h5>
<p>The MC++ code from MC++ pragma foreign_proc declarations will be copied into
static member functions of an automatically-generated MC++ class.
Since such MC++ code will become part of a static member function,
it must not refer to the <code>this</code> keyword.
It may however refer to static member variables or static member
functions declared with <code>pragma foreign_code</code>.
<p>The input and output variables for an MC++ <code>pragma foreign_proc</code> will
have MC++ types corresponding to their Mercury types. The exact rules
for mapping Mercury types to MC++ types are determined by the rules
for mapping Mercury types to IL (see <a href="#IL%20and%20C%23%20data%20passing%20conventions">IL and C# data passing conventions</a>)
and the rules relating IL types to MC++ types.
<p>MC++ code in a <code>pragma foreign_proc</code> declaration
for any procedure whose determinism indicates that it could fail
must assign a value of type bool to the variable <code>succeeded</code>.
For example:
<br><pre>:- pred string__contains_char(string, character).
:- mode string__contains_char(in, in) is semidet.
:- pragma foreign_proc("MC++", string__contains_char(Str::in, Ch::in),
[will_not_call_mercury, promise_pure],
"succeeded = (Str->IndexOf(Ch) != -1);").
</pre>
<p>MC++ code for procedures whose determinism indicates that that they cannot fail
should not access <code>succeeded</code>.
<p>Arguments whose mode is input will have their values set by the
Mercury implementation on entry to the MC++ code. If the procedure
succeeds, the MC++ code must set the values of all output arguments
before returning. If the procedure fails, the MC++ code need only
set <code>succeeded</code> to false.
<p><hr>
Node:<a name="Using%20pragma%20foreign_decl%20for%20MC++">Using pragma foreign_decl for MC++</a>,
Next:<a rel=next href="#Using%20pragma%20foreign_code%20for%20MC++">Using pragma foreign_code for MC++</a>,
Previous:<a rel=previous href="#Using%20pragma%20foreign_proc%20for%20MC++">Using pragma foreign_proc for MC++</a>,
Up:<a rel=up href="#Interfacing%20with%20Managed%20C++">Interfacing with Managed C++</a>
<br>
<h5>Using pragma foreign_decl for MC++</h5>
<p><code>pragma foreign_decl</code> declarations for MC++ can be used to provide
any top-level MC++ declarations (e.g. <code>#include</code> or <code>#using</code>)
which are needed by code in <code>pragma foreign_proc</code> declarations for MC++.
<p>For example:
<br><pre>:- pragma foreign_decl("MC++", "
#include <stdio.h>
#using <mscorlib.dll>
#define MY_CONSTANT 42
// ...
").
</pre>
<p><hr>
Node:<a name="Using%20pragma%20foreign_code%20for%20MC++">Using pragma foreign_code for MC++</a>,
Previous:<a rel=previous href="#Using%20pragma%20foreign_decl%20for%20MC++">Using pragma foreign_decl for MC++</a>,
Up:<a rel=up href="#Interfacing%20with%20Managed%20C++">Interfacing with Managed C++</a>
<br>
<h5>Using pragma foreign_code for MC++</h5>
<p>The MC++ code from <code>pragma foreign_proc</code> declarations for MC++ will be
placed in the bodies of static member functions of an
automatically-generated C# class. <code>pragma foreign_code</code>
can be used to define additional members of this automatically-generated
class, which can then be referenced by <code>pragma foreign_proc</code>
declarations for MC++ from that module.
<p>For example:
<br><pre>:- pragma foreign_code("MC++", "
static int counter = 0;
").
:- impure pred incr_counter is det.
:- pragma foreign_proc("MC++", incr_counter,
[will_not_call_mercury], "counter++;").
:- semipure func get_counter = int.
:- pragma foreign_proc("MC++", get_counter = (Result::out),
[will_not_call_mercury, promise_semipure], "Result = counter;").
</pre>
<p><hr>
Node:<a name="C%20interface">C interface</a>,
Next:<a rel=next href="#Impurity">Impurity</a>,
Previous:<a rel=previous href="#Foreign%20language%20interface">Foreign language interface</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>C interface</h2>
<ul>
<li><a href="#Calling%20C%20code%20from%20Mercury">Calling C code from Mercury</a>: How to implement a Mercury predicate
or function as a call to C code.
<li><a href="#Including%20C%20headers">Including C headers</a>: Using functions with prototypes from a
non-standard header file.
<li><a href="#Including%20C%20code">Including C code</a>: Including definitions of C
functions in your Mercury code.
<li><a href="#Linking%20with%20C%20object%20files">Linking with C object files</a>: Linking with C object files and
libraries.
<li><a href="#Calling%20Mercury%20code%20from%20C">Calling Mercury code from C</a>: How to export a Mercury function or
predicate for use by C code.
<li><a href="#Passing%20data%20to%20and%20from%20C">Passing data to and from C</a>: Exchanging simple data types between
Mercury and C.
<li><a href="#Using%20C%20pointers">Using C pointers</a>: Maintaining a reference to C data
structures in Mercury code.
<li><a href="#Memory%20management">Memory management</a>: Caveats about passing dynamically
allocated memory to or from C.
<li><a href="#Trailing">Trailing</a>: Undoing side-effects on backtracking.
</ul>
<p>This chapter documents the original C interface.
In the long term we are planning to phase out support for this interface
in favour of the new foreign language interface documented in
<a href="#Foreign%20language%20interface">Foreign language interface</a>.
<p>The Mercury distribution includes a number of examples of the
use of the C interface that show how to interface C++ with Mercury
and how to set up <code>Mmake</code> files to automate the build process.
See the <code>samples/c_interface</code> directory in the Mercury distribution.
<p><hr>
Node:<a name="Calling%20C%20code%20from%20Mercury">Calling C code from Mercury</a>,
Next:<a rel=next href="#Including%20C%20headers">Including C headers</a>,
Up:<a rel=up href="#C%20interface">C interface</a>
<br>
<h3>Calling C code from Mercury</h3>
<p>There are two slightly different mechanisms for calling C code from Mercury:
<code>pragma import</code> and <code>pragma c_code</code>. <code>pragma import</code>
allows you to call C functions from Mercury. <code>pragma c_code</code>
allows you to implement Mercury procedures using arbitrary fragments
of C code. <code>pragma import</code> is usually simpler, but
<code>pragma c_code</code> is a bit more flexible.
<ul>
<li><a href="#pragma%20import">pragma import</a>: Importing C functions.
<li><a href="#pragma%20c_code">pragma c_code</a>: Defining Mercury procedures using C code.
<li><a href="#Nondet%20pragma%20c_code">Nondet pragma c_code</a>: Using <code>pragma c_code</code> for Mercury procedures
that can have more than one solution.
<li><a href="#C%20code%20attributes">C code attributes</a>: Describing properties of C functions or C code.
<li><a href="#Purity%20and%20side%20effects">Purity and side effects</a>: Explains when side effects are allowed.
</ul>
<p><hr>
Node:<a name="pragma%20import">pragma import</a>,
Next:<a rel=next href="#pragma%20c_code">pragma c_code</a>,
Up:<a rel=up href="#Calling%20C%20code%20from%20Mercury">Calling C code from Mercury</a>
<br>
<h4>pragma import</h4>
<p>A declaration of the form
<br><pre>:- pragma import(<var>Pred</var>(<var>Mode1</var>, <var>Mode2</var>, <small>...</small>),
<var>Attributes</var>, "<var>C_Name</var>").
</pre>
<p>or
<br><pre>:- pragma import(<var>Func</var>(<var>Mode1</var>, <var>Mode2</var>, <small>...</small>) = <var>Mode</var>,
<var>Attributes</var>, "<var>C_Name</var>").
</pre>
<p>imports a C function for use by Mercury.
<var>Pred</var> or <var>Func</var> must specify the name of a previously declared
Mercury predicate or function, and <var>Mode1</var>, <var>Mode2</var>, <small>...</small>,
and (for functions) <var>Mode</var> must specify one of the
modes of that predicate or function. There must be no clauses
for the specified Mercury procedure; instead, any calls to that
procedure will be executed by calling the C function named
<var>C_Name</var>. The <var>Attributes</var> argument is optional; if present,
it specifies properties of the given C function (see <a href="#C%20code%20attributes">C code attributes</a>).
<p>For example, the following code imports the C function <code>cos()</code>
as the Mercury function <code>cos/1</code>:
<br><pre>:- func cos(float) = float.
:- pragma import(cos(in) = out, [will_not_call_mercury], "cos").
</pre>
<p>The interface to the C function for a given Mercury procedure is
determined as follows. Mercury types are converted to C types and
passed according to the rules in <a href="#Passing%20data%20to%20and%20from%20C">Passing data to and from C</a>.
<p>If you use <code>pragma import</code> for a polymorphically typed Mercury procedure,
the compiler will prepend one <code>type_info</code> argument to the parameters
passed to the C function for each polymorphic type variable in the
Mercury procedure's type signature. The values passed in these arguments
will be the same as the values that would be obtained using the Mercury
<code>type_of</code> function in the Mercury standard library module <code>std_util</code>.
These values may be useful in case the C function wishes to in turn call
another polymorphic Mercury procedure (see <a href="#Calling%20Mercury%20code%20from%20C">Calling Mercury code from C</a>).
<p>You may not give a <code>pragma import</code> declaration for a procedure
with determinism <code>nondet</code> or <code>multi</code>.
(It is however possible to define a <code>nondet</code> or <code>multi</code> procedure
using <code>pragma c_code</code>. See <a href="#Nondet%20pragma%20c_code">Nondet pragma c_code</a>.)
<p><hr>
Node:<a name="pragma%20c_code">pragma c_code</a>,
Next:<a rel=next href="#Nondet%20pragma%20c_code">Nondet pragma c_code</a>,
Previous:<a rel=previous href="#pragma%20import">pragma import</a>,
Up:<a rel=up href="#Calling%20C%20code%20from%20Mercury">Calling C code from Mercury</a>
<br>
<h4>pragma c_code</h4>
<p>A declaration of the form
<br><pre>:- pragma c_code(<var>Pred</var>(<var>Var1</var>::<var>Mode1</var>, <var>Var2</var>::<var>Mode2</var>, <small>...</small>),
<var>Attributes</var>, <var>C_Code</var>).
</pre>
<p>or
<br><pre>:- pragma c_code(<var>Func</var>(<var>Var1</var>::<var>Mode1</var>, <var>Var2</var>::<var>Mode2</var>, <small>...</small>) = (<var>Var</var>::<var>Mode</var>),
<var>Attributes</var>, <var>C_Code</var>).
</pre>
<p>means that any calls to the specified mode of <var>Pred</var> or <var>Func</var>
will result in execution of the C code given in <var>C_Code</var>.
The C code fragment may refer to the specified variables
(<var>Var1</var>, <var>Var2</var>, <small>...</small>, and <var>Var</var>)
directly by name. These variables will have C types corresponding
to their Mercury types, as determined by the rules specified in
<a href="#Passing%20data%20to%20and%20from%20C">Passing data to and from C</a>. It is an error for a variable
to occur more than once in the argument list.
<p>The C code fragment may declare local variables, but it should not
declare any labels or static variables unless there is also a Mercury
<code>pragma no_inline</code> declaration (see <a href="#Inlining">Inlining</a>) for the procedure.
The reason for this is that otherwise the Mercury implementation may
inline the procedure by duplicating the C code fragment for each call.
If the C code fragment declared a static variable, inlining it in this
way could result in the program having multiple instances of the static
variable, rather than a single shared instance. If the C code fragment
declared a label, inlining it in this way could result in an error due
to the same label being defined twice inside a single C function.
<p>If there is a <code>pragma import</code> or <code>pragma c_code</code> declaration for a
mode of a predicate or function, then there must not be any clauses for that
predicate or function, and there must be a <code>pragma c_code</code>
or <code>pragma import</code> declaration for every mode of the predicate or function.
<p>For example, the following piece of code defines a Mercury function
<code>sin/1</code> which calls the C function <code>sin()</code> of the same name.
<br><pre>:- func sin(float) = float.
:- pragma c_code(sin(X::in) = (Sin::out),
[may_call_mercury],
"Sin = sin(X);").
</pre>
<p>If the C code does not recursively invoke Mercury code,
as in the above example, then you can use <code>will_not_call_mercury</code>
in place of <code>may_call_mercury</code> in the declarations above.
This allows the compiler to use a slightly more efficient calling convention.
(If you use this form, and the C code <em>does</em> invoke Mercury code,
then the behaviour is undefined -- your program may misbehave or crash.)
<p>The C code in a <code>pragma c_code</code> declaration
for any procedure whose determinism indicates that it could fail
must assign a truth value to the macro <code>SUCCESS_INDICATOR</code>.
For example:
<br><pre>:- pred string__contains_char(string, character).
:- mode string__contains_char(in, in) is semidet.
:- pragma c_code(string__contains_char(Str::in, Ch::in),
[will_not_call_mercury],
"SUCCESS_INDICATOR = (strchr(Str, Ch) != NULL);").
</pre>
<p><code>SUCCESS_INDICATOR</code> should not be used other than as the target of
an assignment.
(For example, it may be <code>#define</code>d to a register, so you should not
try to take its address.)
Procedures whose determinism indicates that that they cannot fail
should not access <code>SUCCESS_INDICATOR</code>.
<p>Arguments whose mode is input will have their values set by the
Mercury implementation on entry to the C code. If the procedure
succeeds, the C code must set the values of all output arguments
before returning. If the procedure fails, the C code need only
set <code>SUCCESS_INDICATOR</code> to false (zero).
<p><hr>
Node:<a name="Nondet%20pragma%20c_code">Nondet pragma c_code</a>,
Next:<a rel=next href="#C%20code%20attributes">C code attributes</a>,
Previous:<a rel=previous href="#pragma%20c_code">pragma c_code</a>,
Up:<a rel=up href="#Calling%20C%20code%20from%20Mercury">Calling C code from Mercury</a>
<br>
<h4>Nondet pragma c_code</h4>
<p>For procedures that can return more than one result on backtracking,
i.e. those with determinism <code>nondet</code> or <code>multi</code>,
the form of <code>pragma c_code</code> declaration described previously
does not suffice. Instead, you should use a declaration of the form
shown below:
<br><pre>:- pragma c_code(<var>Pred</var>(<var>Var1</var>::<var>Mode1</var>, <var>Var2</var>::<var>Mode2</var>, <small>...</small>),
<var>Attributes</var>, local_vars(<var>LocalVars</var>), first_code(<var>FirstCode</var>),
retry_code(<var>RetryCode</var>), common_code(<var>CommonCode</var>)).
</pre>
<p>or
<br><pre>:- pragma c_code(<var>Func</var>(<var>Var1</var>::<var>Mode1</var>, <var>Var2</var>::<var>Mode2</var>, <small>...</small>) = (<var>Var</var>::<var>Mode</var>),
<var>Attributes</var>, local_vars(<var>LocalVars</var>), first_code(<var>FirstCode</var>),
retry_code(<var>RetryCode</var>), common_code(<var>CommonCode</var>)).
</pre>
<p>Here <var>FirstCode</var>, <var>RetryCode</var>, and <var>CommonCode</var> are all
Mercury strings containing C code.
<var>FirstCode</var> will be executed whenever the Mercury procedure is called.
<var>RetryCode</var> will be executed whenever a given call to the procedure
is re-entered on backtracking to find subsequent solutions.
The <code>common_code(<var>CommonCode</var>)</code> argument is optional; if present,
<var>CommonCode</var> will be executed after each execution of
<var>FirstCode</var> or <var>RetryCode</var>.
<p>The code that is executed on each call or retry should finish by
executing one of the three macros <code>FAIL</code>, <code>SUCCEED</code>, or
<code>SUCCEED_LAST</code>. The <code>FAIL</code> macro indicates that the call has
failed; the call will not be retried. The <code>SUCCEED</code> macro
indicates that the call has succeeded, and that there may be more
solutions; the call may be retried on backtracking. The
<code>SUCCEED_LAST</code> macro indicates that the call has succeeded, but
that there are no more solutions after this one; the call will not be
retried.
<p><var>LocalVars</var> is a sequence of struct member declarations which are
used to hold any state which needs to be preserved in case of backtracking
or passed between the different C code fragments.
The code fragments <var>FirstCode</var>, <var>RetryCode</var>, and <var>CommonCode</var>
may use the macro <code>LOCALS</code>, which is defined to be a pointer to a struct
containing the fields specified by <var>LocalVars</var>, to access this saved state.
<p>Note <var>RetryCode</var> and <var>CommonCode</var> may not access the input
variables -- only <var>FirstCode</var> should access the input variables.
If <var>RetryCode</var> or <var>CommonCode</var> need to access any of the input
variables, then <var>FirstCode</var> should copy the values needed to the
<var>LocalVars</var>.
<p>The following example shows how you can use a state variable to
keep track of the next alternative to return.
<br><pre>%
% This example implements the equivalent of
% foo(X) :- X = 20 ; X = 10 ; X = 42 ; X = 99 ; fail.
%
:- pred foo(int).
:- mode foo(out) is multi.
:- pragma c_code(foo(X::out), [will_not_call_mercury, thread_safe],
local_vars("
int state;
"),
first_code("
LOCALS->state = 1;
"),
retry_code("
LOCALS->state++;
"),
common_code("
switch (LOCALS->state) {
case 1: X = 20; SUCCEED; break;
case 2: X = 10; SUCCEED; break;
case 3: X = 42; SUCCEED; break;
case 4: X = 99; SUCCEED; break;
case 5: FAIL; break;
}
")
).
</pre>
<p>The next example is a more realistic example;
it shows how you could implement the reverse
mode of <code>string__append</code>, which returns
all possible ways of splitting a string into
two pieces, using <code>pragma c_code</code>.
<br><pre>:- pred string__append(string, string, string).
:- mode string__append(out, out, in) is multi.
:- pragma c_code(string__append(S1::out, S2::out, S3::in),
[will_not_call_mercury, thread_safe],
local_vars("
String s;
size_t len;
size_t count;
"),
first_code("
LOCALS->s = S3;
LOCALS->len = strlen(S3);
LOCALS->count = 0;
"),
retry_code("
LOCALS->count++;
"),
common_code("
S1 = copy_substring(LOCALS->s, 0, LOCALS->count);
S2 = copy_substring(LOCALS->s, LOCALS->count,
LOCALS->len);
if (LOCALS->count < LOCALS->len) {
SUCCEED;
} else {
SUCCEED_LAST;
}
")
).
</pre>
<p><hr>
Node:<a name="C%20code%20attributes">C code attributes</a>,
Next:<a rel=next href="#Purity%20and%20side%20effects">Purity and side effects</a>,
Previous:<a rel=previous href="#Nondet%20pragma%20c_code">Nondet pragma c_code</a>,
Up:<a rel=up href="#Calling%20C%20code%20from%20Mercury">Calling C code from Mercury</a>
<br>
<h4>C code attributes</h4>
<p>As described above, <code>pragma import</code> and <code>pragma c_code</code>
declarations may include a list of attributes describing properties
of the given C function or C code.
All Mercury implementations must support the attributes listed below.
They may also support additional attributes.
<p>The attributes which must be supported by all implementations
are as follows:
<dl>
<br><dt><code>may_call_mercury</code>/<code>will_not_call_mercury</code>
<dd>This attribute declares whether or not execution inside this C code may
call back into Mercury or not. The default, in case neither is specified,
is <code>may_call_mercury</code>. Specifying <code>will_not_call_mercury</code>
may allow the compiler to generate more efficient code.
If you specify <code>will_not_call_mercury</code>,
but the C code <em>does</em> invoke Mercury code, then the behaviour is
undefined.
<br><dt><code>thread_safe</code>/<code>not_thread_safe</code>
<dd>This attribute declares whether or not it is safe for multiple threads
to execute this C code concurrently.
The default, in case neither is specified, is <code>not_thread_safe</code>.
If the C code is declared <code>thread_safe</code>, then the Mercury implementation
is permitted to execute the code concurrently from multiple threads without
taking any special precautions. If the C code is declared
<code>not_thread_safe</code>,
then the Mercury implementation must not invoke the code concurrently from
multiple threads. If the Mercury implementation does use multithreading,
then it must take appropriate steps to prevent this.
(The experimental multithreaded version of the current
University of Melbourne Mercury implementation protects
<code>not_thread_safe</code> code using a mutex:
C code that is not thread-safe has code inserted around it to obtain
and release a mutex. All non-thread-safe C code shares a single mutex.)
</dl>
<p><hr>
Node:<a name="Purity%20and%20side%20effects">Purity and side effects</a>,
Previous:<a rel=previous href="#C%20code%20attributes">C code attributes</a>,
Up:<a rel=up href="#Calling%20C%20code%20from%20Mercury">Calling C code from Mercury</a>
<br>
<h4>Purity and side effects</h4>
<p>Note that procedures implemented in C using either
<code>pragma import</code> or <code>pragma c_code</code> must still be "pure",
unless declared otherwise (see <a href="#Impurity">Impurity</a>), and they must
be type-correct and mode-correct. (Determinism-correctness
is also required, but it follows from the rules already stated
above.) Pure or semipure procedures may perform destructive update on their
arguments only if those arguments have an appropriate
unique mode declaration.
Impure predicates may perform destructive update on data pointed to by
C pointer arguments, even without unique modes. But they cannot
destructively update the arguments themselves.
Procedures may perform I/O only if their arguments
include an <code>io__state</code> pair (see the <code>io</code> chapter
of the Mercury Library Reference Manual), or if they are declared impure
(see <a href="#Impurity">Impurity</a>).
The Mercury implementation is allowed to assume that
these rules are followed, and to optimize accordingly.
If the C code is not type-correct, mode-correct,
determinism-correct, and purity-correct with respect
to its Mercury declaration, then the behaviour is
undefined.
<p>For example, the following code defines a predicate
<code>c_write_string/3</code>, which has a similar effect to
the Mercury library predicate <code>io__write_string/3</code>:
<br><pre>:- pred c_write_string(string, io__state, io__state).
:- mode c_write_string(in, di, uo) is det.
:- pragma c_code(c_write_string(S::in, IO0::di, IO::uo),
[may_call_mercury],
"puts(S); IO = IO0;").
</pre>
<p>In this example, the I/O is done via side effects inside the C code,
but the Mercury interface includes <code>io__state</code> arguments
to ensure that the predicate has a proper declarative
semantics. If the <code>io__state</code> arguments were
left off, then the Mercury implementation might apply
undesirable optimizations (e.g. reordering, duplicate
call elimination, tabling, lazy evaluation, <small>...</small>)
to this procedure, which could effect the behaviour
of the program in unpredictable ways.
<p>Impure C code relaxes some of these restrictions.
Impure C code may perform I/O and although it cannot update its
arguments directly (unless they have an appropriate unique mode, e.g.
<code>di</code>) it may update something pointed to by its arguments.
Impure C code procedures must still be type correct and mode correct.
<p><hr>
Node:<a name="Including%20C%20headers">Including C headers</a>,
Next:<a rel=next href="#Including%20C%20code">Including C code</a>,
Previous:<a rel=previous href="#Calling%20C%20code%20from%20Mercury">Calling C code from Mercury</a>,
Up:<a rel=up href="#C%20interface">C interface</a>
<br>
<h3>Including C headers</h3>
<p>Any macros, function prototypes, or other C declarations
that are used in <code>c_code</code> pragmas must be included using a
<code>c_header_code</code> declaration of the form
<br><pre>:- pragma c_header_code(<var>HeaderCode</var>).
</pre>
<p><var>HeaderCode</var> can be a C <code>#include</code> line, for example
<br><pre>:- pragma c_header_code("#include <math.h>")
</pre>
<p>or
<br><pre>:- pragma c_header_code("#include ""tcl.h""").
</pre>
<p>or it may contain any C declarations, for example
<br><pre>:- pragma c_header_code("
extern int errno;
#define SIZE 200
struct Employee {
char name[SIZE];
}
extern int bar;
extern void foo(void);
").
</pre>
<p>Mercury automatically includes certain headers such as <code><stdlib.h></code>,
but you should not rely on this, as the set of headers which Mercury
automatically includes is subject to change.
<p><hr>
Node:<a name="Including%20C%20code">Including C code</a>,
Next:<a rel=next href="#Linking%20with%20C%20object%20files">Linking with C object files</a>,
Previous:<a rel=previous href="#Including%20C%20headers">Including C headers</a>,
Up:<a rel=up href="#C%20interface">C interface</a>
<br>
<h3>Including C code</h3>
<p>Definitions of C functions or global variables may be
included using a declaration of the form
<br><pre>:- pragma c_code(<var>Code</var>).
</pre>
<p>For example,
<br><pre>:- pragma c_code("
int bar = 42;
void foo(void) {}
").
</pre>
<p>Such code is copied verbatim into the generated C file.
<p><hr>
Node:<a name="Calling%20Mercury%20code%20from%20C">Calling Mercury code from C</a>,
Next:<a rel=next href="#Passing%20data%20to%20and%20from%20C">Passing data to and from C</a>,
Previous:<a rel=previous href="#Linking%20with%20C%20object%20files">Linking with C object files</a>,
Up:<a rel=up href="#C%20interface">C interface</a>
<br>
<h3>Calling Mercury code from C</h3>
<p>It is also possible to export Mercury procedures to C,
so that you can call Mercury code from C (or from
other languages that can interface to C, e.g. C++).
<p>A declaration of the form
<br><pre>:- pragma export(<var>Pred</var>(<var>Mode1</var>, <var>Mode2</var>, <small>...</small>), "<var>C_Name_1</var>").
</pre>
<p>or
<br><pre>:- pragma export(<var>Func</var>(<var>Mode1</var>, <var>Mode2</var>, <small>...</small>) = <var>Mode</var>, "<var>C_Name_2</var>").
</pre>
<p>exports a procedure for use by C.
<p>For each Mercury module containing <code>pragma export</code> declarations,
the Mercury implementation will automatically create a header file
for that module which declares a C function <var>C_Name</var>()
for each of the <code>pragma export</code> declarations.
Each such C function is the C interface to the specified mode of
the specified Mercury predicate or function.
<p>The interface to a Mercury procedure is determined as follows.
(The rules here are just the converse of the rules for <code>pragma import</code>).
Mercury types are converted to C types according to the rules in
<a href="#Passing%20data%20to%20and%20from%20C">Passing data to and from C</a>.
Input arguments are passed by value. For output arguments, the
caller must pass the address in which to store the result.
If the Mercury procedure can fail, then its C interface function
returns a truth value indicating success or failure.
If the Mercury procedure is a Mercury function that cannot fail, and
the function result has an output mode, then the C interface
function will return the Mercury function result value.
Otherwise the function result is appended as an extra argument.
Arguments of type <code>io__state</code> or <code>store__store(_)</code>
are not passed at all; that's because these types represent mutable state,
and in C modifications to mutable state are done via side effects,
rather than argument passing.
<p>Calling polymorphically typed Mercury procedures from C is a little bit
more difficult than calling ordinary (monomorphically typed) Mercury procedures.
The simplest method is to just create monomorphic forwarding
procedures that call the polymorphic procedures, and export them,
rather than exporting the polymorphic procedures.
<p>If you do export a polymorphically typed Mercury procedure, the compiler
will prepend one <code>type_info</code> argument to the parameter list of
the C interface function for each polymorphic type variable in the
Mercury procedure's type signature. The caller must arrange to pass
in appropriate <code>type_info</code> values corresponding to the types
of the other arguments passed. These <code>type_info</code> arguments can
be obtained using the Mercury <code>type_of</code> function in the Mercury
standard library module <code>std_util</code>.
<p>To use the C declarations produced for <code>pragma export</code> declarations
in C code within a Mercury module, use a <code>pragma c_import_module</code>
declaration, for example
<br><pre>:- pragma c_import_module(imported_module).
</pre>
<p>This is equivalent to
<br><pre>:- pragma c_header_code("#include ""imported_module.h""").
</pre>
<p>but it tells the implementation that the object file for the
module containing the <code>pragma c_import_module</code> declaration
should not be built before <code>imported_module.h</code> is built.
<p><hr>
Node:<a name="Linking%20with%20C%20object%20files">Linking with C object files</a>,
Next:<a rel=next href="#Calling%20Mercury%20code%20from%20C">Calling Mercury code from C</a>,
Previous:<a rel=previous href="#Including%20C%20code">Including C code</a>,
Up:<a rel=up href="#C%20interface">C interface</a>
<br>
<h3>Linking with C object files</h3>
<p>A Mercury implementation should allow you to link with
object files or libraries that were produced by compiling C code.
The exact mechanism for linking with C object files is
implementation-dependent. The following text describes how
it is done for the University of Melbourne Mercury implementation.
<p>To link an existing object file into your Mercury code,
set the <code>Mmake</code> variable <code>MLOBJS</code> in the
<code>Mmake</code> file in the directory in which you are working.
To link an existing library into your Mercury code,
set the <code>Mmake</code> variable <code>MLLIBS</code>.
For example, the following will link in the object file
<code>my_functions.o</code> from the current directory and
the library file <code>libfancy_library.a</code>, or perhaps its
shared version <code>fancy_library.so</code>, from the directory
<code>/usr/local/contrib/lib</code>.
<br><pre>MLOBJS = my_functions.o
MLFLAGS = -R/usr/local/contrib/lib -L/usr/local/contrib/lib
MLLIBS = -lfancy_library
</pre>
<p>As illustrated by the example, the values for <code>MLFLAGS</code> and
<code>MLLIBS</code> variables are similar to those taken by the Unix linker.
<p>For more information, see the "Libraries" chapter of the
Mercury User's Guide, and the <code>man</code> pages for <code>mmc</code> and <code>ml</code>.
<p><hr>
Node:<a name="Passing%20data%20to%20and%20from%20C">Passing data to and from C</a>,
Next:<a rel=next href="#Using%20C%20pointers">Using C pointers</a>,
Previous:<a rel=previous href="#Calling%20Mercury%20code%20from%20C">Calling Mercury code from C</a>,
Up:<a rel=up href="#C%20interface">C interface</a>
<br>
<h3>Passing data to and from C</h3>
<p>For each of the Mercury types <code>int</code>, <code>float</code>, <code>char</code>,
and <code>string</code>, there is a C typedef for the corresponding type in C:
<code>MR_Integer</code>, <code>MR_Float</code>, <code>MR_Char</code>,
and <code>MR_String</code> respectively.
<p>In the current implementation, <code>MR_Integer</code> is a typedef for an
integral type whose size is the same size as a pointer; <code>MR_Float</code> is
a typedef for <code>double</code> (unless the program and the Mercury library
was compiled with <code>-DUSE_SINGLE_PREC_FLOAT</code>, in which case it is
a typedef for <code>float</code>); <code>MR_Char</code> is a typedef for <code>char</code>;
and <code>MR_String</code> is a typedef for <code>MR_Char *</code>.
<p>Mercury variables of type <code>int</code>, <code>float</code>, <code>char</code>, or
<code>string</code> are passed to and from C as C variables whose type is
given by the corresponding typedef. Mercury variables of any other
type are passed as a <code>MR_Word</code>, which in the current implementation
is a typedef for an unsigned type whose size is the same size as a pointer.
(Note: it would in fact be better for each Mercury type to map to a distinct
abstract type in C, since that would be more type-safe, and thus we may
change this in a future release. We advise programmers who are manipulating
Mercury types in C code to use typedefs for each user-defined Mercury type,
and to treat each such type as an abstract data type. This is good style
and it will also minimize any compatibility problems if and when we do change
this.)
<p>Mercury arguments declared with input modes are passed by value to the
C function.
For output arguments,
the Mercury implementation will pass to the C function an address in
which to store the result.
If the Mercury procedure can fail,
then its C function should return a truth value of type
<code>MR_Integer</code> indicating success or failure:
non-zero indicates success, and zero indicates failure.
If the Mercury procedure is a Mercury function that cannot fail,
and the function result has an output mode,
then the C function should return the Mercury function result value.
Otherwise the function result is appended as an extra argument.
Arguments of type <code>io__state</code> or <code>store__store(_)</code> are not
passed at all;
that's because these types represent mutable state,
and in C modifications to mutable state are done via side effects,
rather than argument passing.
<p>Mercury lists can be manipulated by C code using the following macros,
which are defined by the Mercury implementation.
<br><pre>MR_list_is_empty(list) /* test if a list is empty */
MR_list_head(list) /* get the head of a list */
MR_list_tail(list) /* get the tail of a list */
MR_list_empty() /* create an empty list */
MR_list_cons(head,tail) /* construct a list with the given head and tail */
</pre>
<p>Note that the use of these macros is subject to some caveats
(see <a href="#Memory%20management">Memory management</a>).
<p><hr>
Node:<a name="Using%20C%20pointers">Using C pointers</a>,
Next:<a rel=next href="#Memory%20management">Memory management</a>,
Previous:<a rel=previous href="#Passing%20data%20to%20and%20from%20C">Passing data to and from C</a>,
Up:<a rel=up href="#C%20interface">C interface</a>
<br>
<h3>Using C pointers</h3>
<p>The inbuilt Mercury type <code>c_pointer</code> can be used to pass C pointers
between C functions which are called from Mercury. For example:
<br><pre>:- module pointer_example.
:- interface.
:- type complicated_c_structure.
% Initialise the abstract C structure that we pass around in Mercury.
:- pred initialise_complicated_structure(complicated_c_structure::uo) is det.
% Perform a calculation on the C structure.
:- pred do_calculation(int::in, complicated_structure::di,
complicated_structure::uo) is det.
:- implementation.
% Our C structure is implemented as a c_pointer.
:- type complicated_c_structure --->
complicated_c_structure(c_pointer).
:- pragma c_header_code("
extern struct foo *init_struct(void);
extern struct foo *perform_calculation(int, struct foo *);
");
:- pragma c_code(initialise_complicated_structure(Structure::uo),
[may_call_mercury],
"Structure = init_struct();").
:- pragma c_code(do_calculation(Value::in, Structure0::di, Structure::uo,
[may_call_mercury],
"Structure = perform_calculation(Value, Structure0);").
</pre>
<p><hr>
Node:<a name="Memory%20management">Memory management</a>,
Next:<a rel=next href="#Trailing">Trailing</a>,
Previous:<a rel=previous href="#Using%20C%20pointers">Using C pointers</a>,
Up:<a rel=up href="#C%20interface">C interface</a>
<br>
<h3>Memory management</h3>
<p>Passing pointers to dynamically-allocated memory from Mercury to code
written in other languages, or vice versa, is in general
implementation-dependent.
<p>The current Mercury implementation supports two different methods of memory
management: conservative garbage collection, or no garbage collection.
(With the latter method, heap storage is reclaimed only on backtracking.)
<p>Conservative garbage collection makes inter-language calls simplest.
When using conservative garbage collection, heap storage is reclaimed
automatically. Pointers to dynamically-allocated memory can be passed
to and from C without taking any special precautions.
<p>When using no garbage collection, you must be careful not to retain
pointers to memory on the Mercury heap after Mercury has backtracked
to before the point where that memory was allocated.
You must also avoid the use of the macros
<code>MR_list_empty()</code> and <code>MR_list_cons()</code>.
(The reason for this is that they may access Mercury's <code>MR_hp</code> register,
which might not be valid in C code. Using them in the bodies of
procedures defined using <code>pragma c_code</code> with
<code>will_not_call_mercury</code> would probably work, but we don't advise it.)
Instead, you can write Mercury functions to perform these actions
and use <code>pragma export</code> to access them from C.
This alternative method also works with conservative garbage collection.
<p>Future Mercury implementations may use non-conservative methods
of garbage collection. For such implementations, it will be necessary
to explicitly register pointers passed to C with the garbage collector.
The mechanism for doing this has not yet been decided on.
It would be desirable to provide a single memory management interface
for use when interfacing with other languages that can work for all
methods of memory management, but more implementation experience is
needed before we can formulate such an interface.
<p><hr>
Node:<a name="Trailing">Trailing</a>,
Previous:<a rel=previous href="#Memory%20management">Memory management</a>,
Up:<a rel=up href="#C%20interface">C interface</a>
<br>
<h3>Trailing</h3>
<p>In certain compilation grades (see the "Compilation model options"
section of the Mercury User's Guide), the University of Melbourne
Mercury implementation supports trailing. Trailing is a means
of having side-effects, such as destructive updates to data structures,
undone on backtracking. The basic idea is that during forward
execution, whenever you perform a destructive modification to
a data structure that may still be live on backtracking,
you should record whatever information is necessary to restore it
on a stack-like data structure called the "trail". Then, if
a computation fails, and execution backtracks to before those
those updates were performed, the Mercury runtime engine will
traverse the trail back to the most recent choice point,
undoing all those updates.
<p>The interface used is a set of C functions (which are actually
implemented as macros) and types. Typically these will be
called from C code within <code>pragma c_code</code> declarations
in Mercury code.
<p>For examples of the use of this interface, see the modules
<code>extras/trailed_update/tr_array.m</code> and
<code>extras/clpr/cfloat.m</code> in the Mercury distribution.
<ul>
<li><a href="#Choice%20points">Choice points</a>:
<li><a href="#Value%20trailing">Value trailing</a>:
<li><a href="#Function%20trailing">Function trailing</a>:
<li><a href="#Delayed%20goals%20and%20floundering">Delayed goals and floundering</a>:
<li><a href="#Avoiding%20redundant%20trailing">Avoiding redundant trailing</a>:
</ul>
<p><hr>
Node:<a name="Choice%20points">Choice points</a>,
Next:<a rel=next href="#Value%20trailing">Value trailing</a>,
Up:<a rel=up href="#Trailing">Trailing</a>
<br>
<h4>Choice points</h4>
<p>A "choice point" is a point in the computation to
which execution might backtrack when a goal fails or
throws an exception. The "current"
choice point is the one that was most recently
encountered; that is also the one to which execution
will branch if the current computation fails.
<p>When you trail an update, the Mercury engine will ensure that if
execution ever backtracks to the choice point that was current
at the time of trailing, then the update will be undone.
<p>If the Mercury compiler determines that it will never
need to backtrack to a particular choice point, then it will
"prune" away that choice point. If a choice point is pruned,
the trail entries for those updates will not necessarily be discarded,
because in general they may still be necessary in case we backtrack
to a prior choice point.
<p><hr>
Node:<a name="Value%20trailing">Value trailing</a>,
Next:<a rel=next href="#Function%20trailing">Function trailing</a>,
Previous:<a rel=previous href="#Choice%20points">Choice points</a>,
Up:<a rel=up href="#Trailing">Trailing</a>
<br>
<h4>Value trailing</h4>
<p>The simplest form of trailing is value trailing.
This allows you to trail updates to memory and have
the Mercury runtime engine automatically undo them
on backtracking.
<dl>
<dt><b> <code>MR_trail_value()</code></b>
<dd>Prototype:
<br><pre>void MR_trail_value(MR_Word *<var>address</var>, MR_Word <var>value</var>);
</pre>
<p>Ensures that if future execution backtracks to the
current choice point, then <var>value</var> will be placed in <var>address</var>.
<br><p>
<br><dt><b> <code>MR_trail_current_value()</code></b>
<dd>Prototype:
<br><pre>void MR_trail_current_value(MR_Word *<var>address</var>);
</pre>
<p>Ensures that if future execution backtracks to the
current choice point, the value currently in <var>address</var>
will be restored.
<p><code>MR_trail_current_value(<var>address</var>)</code> is equivalent to
<code>MR_trail_value(<var>address</var>, *<var>address</var>)</code>.
</dl>
<p><hr>
Node:<a name="Function%20trailing">Function trailing</a>,
Next:<a rel=next href="#Delayed%20goals%20and%20floundering">Delayed goals and floundering</a>,
Previous:<a rel=previous href="#Value%20trailing">Value trailing</a>,
Up:<a rel=up href="#Trailing">Trailing</a>
<br>
<h4>Function trailing</h4>
<p>For more complicated uses of trailing, you can store the address
of a C function on the trail and have the Mercury runtime call your
function back whenever future execution backtracks to the current choice point
or earlier, or whenever that choice point is pruned, because execution
commits to never backtracking over that point,
or whenever that choice point is garbage collected.
<p>Note the garbage collector in the current Mercury implementation
does not garbage-collect the trail; this case is mentioned
only so that we can cater for possible future extensions.
<dl>
<dt><b> <code>MR_trail_function()</code></b>
<dd>Prototype:
<br><pre>typedef enum {
MR_undo,
MR_exception,
MR_retry,
MR_commit,
MR_solve,
MR_gc
} MR_untrail_reason;
void MR_trail_function(
void (*<var>untrail_func</var>)(MR_Word, MR_untrail_reason),
void *<var>value</var>
);
</pre>
<p>A call to <code>MR_trail_function(<var>untrail_func</var>, <var>value</var>)</code>
adds an entry to the function trail.
The Mercury implementation ensures that
if future execution ever backtracks to current choicepoint,
or backtracks past the current choicepoint to some earlier choicepoint,
then <code>(*<var>untrail_func</var>)(<var>value</var>, <var>reason</var>)</code> will be called,
where <var>reason</var> will be <code>MR_undo</code> if the backtracking was due to
a goal failing, <code>MR_exception</code> if the backtracking was due to
a goal throwing an exception, or <code>MR_retry</code> if the backtracking
was due to the use of the "retry" command in <code>mdb</code>, the Mercury debugger,
or any similar user request in a debugger.
The Mercury implementation also ensures that if the current choice point is
pruned because execution commits to never backtracking to it,
then <code>(*<var>untrail_func</var>)(<var>value</var>, MR_commit)</code> will be called.
It also ensures that if execution requires that the current goal be
solvable, then <code>(*<var>untrail_func</var>)(<var>value</var>, MR_solve)</code>
will be called. This happens in calls to <code>solutions/2</code>, for example.
(<code>MR_commit</code> is used for "hard" commits, i.e. when we commit
to a solution and prune away the alternative solutions; <code>MR_solve</code>
is used for "soft" commits, i.e. when we must commit to a solution
but do not prune away all the alternatives.)
<p>MR_gc is currently not used --
it is reserved for future use.
</dl>
<p>Typically if the <var>untrail_func</var> is called with <var>reason</var> being
<code>MR_undo</code>, <code>MR_exception</code>, or <code>MR_retry</code>, then it should undo
the effects of the update(s) specified by <var>value</var>, and then free any
resources associated with that trail entry. If it is called with <var>reason</var>
being <code>MR_commit</code> or <code>MR_solve</code>, then it should not undo the
update(s); instead, it may check for floundering (see the next section).
In the <code>MR_commit</code> case it may, in some cases, be possible to
also free resources associated with the trail entry.
If it is called with anything else (such as <code>MR_gc</code>),
then it should probably abort execution with an error message.
<p><hr>
Node:<a name="Delayed%20goals%20and%20floundering">Delayed goals and floundering</a>,
Next:<a rel=next href="#Avoiding%20redundant%20trailing">Avoiding redundant trailing</a>,
Previous:<a rel=previous href="#Function%20trailing">Function trailing</a>,
Up:<a rel=up href="#Trailing">Trailing</a>
<br>
<h4>Delayed goals and floundering</h4>
<p>Another use for the function trail is check for floundering
in the presence of delayed goals.
<p>Often, when implementing certain kinds of constraint solvers, it may
not be possible to actually solve all of the constraints at the time
they are added. Instead, it may be necessary to simply delay their
execution until a later time, in the hope the constraints may become
solvable when more information is available. If you do implement a
constraint solver with these properties, then at certain points in
the computation -- for example, after executing a negated goal -- it
is important for the system to check that their are no outstanding
delayed goals which might cause failure, before execution commits
to this execution path. If there are any such delayed goals, the
computation is said to "flounder". If the check for floundering was
omitted, then it could lead to unsound behaviour, such as a negation
failing even though logically speaking it ought to have succeeded.
<p>The check for floundering can be implemented using the function trail,
by simply calling <code>MR_trail_function()</code> to add a function trail
entry whenever you create a delayed goal, and putting the appropriate
check for floundering in the <code>MR_commit</code> and <code>MR_solve</code> cases
of your function.
The Mercury distribution includes some examples of this:
see the <code>ML_cfloat_untrail_func()</code>
function in the file <code>extras/clpr/cfloat.m</code> and the
<code>ML_var_untrail_func()</code> function in the file
<code>extras/trailed_update/var.m</code>.)
If your function does detect floundering, then it should print
an error message and then abort execution.
<p><hr>
Node:<a name="Avoiding%20redundant%20trailing">Avoiding redundant trailing</a>,
Previous:<a rel=previous href="#Delayed%20goals%20and%20floundering">Delayed goals and floundering</a>,
Up:<a rel=up href="#Trailing">Trailing</a>
<br>
<h4>Avoiding redundant trailing</h4>
<p>If a mutable data structure is updated multiple times, and each update
is recorded on the trail using the functions described above, then
some of this trailing may be redundant. It is generally not necessary
to record enough information to recover the original state of the
data structure for <em>every</em> update on the trail; instead, it is
enough to record the original state of each updated data structure
just once for each choice point occurring after the data structure
is allocated, rather than once for each update.
<p>The functions described below provide a means to avoid
redundant trailing.
<dl>
<dt><b> <code>MR_ChoicepointId</code></b>
<dd>Declaration:
<br><pre>typedef <small>...</small> MR_ChoicepointId;
</pre>
<p>The type <code>MR_ChoicepointId</code> is an abstract type used
to hold the identity of a choice point. Values of this
type can be compared using C's <code>==</code> operator
or using <code>MR_choicepoint_newer()</code>.
<br><p>
<br><dt><b> <code>MR_current_choicepoint_id()</code></b>
<dd>Prototype:
<br><pre>MR_ChoicepointId MR_current_choicepoint_id(void);
</pre>
<p><code>MR_current_choicepoint_id()</code> returns a value indicating
the identity of the most recent choice point; that is, the
point to which execution would backtrack if the current computation
failed.
The value remains meaningful if the choicepoint is pruned
away by a commit, but is not meaningful after backtracking
past the point where the choicepoint was created (since
choicepoint ids may be reused after backtracking).
<br><p>
<br><dt><b> <code>MR_null_choicepoint_id()</code></b>
<dd>Prototype:
<br><pre>MR_ChoicepointId MR_null_choicepoint_id(void);
</pre>
<p><code>MR_null_choicepoint_id()</code> returns a "null" value that is
distinct from any value ever returned by <code>MR_current_choicepoint_id</code>.
(Note that <code>MR_null_choicepoint_id()</code>
is a macro that is guaranteed to be suitable for use as a
static initializer, so that it can for example be used to
provide the initial value of a C global variable.)
<br><p>
<br><dt><b> <code>MR_choicepoint_newer()</code></b>
<dd>Prototype:
<br><pre>bool MR_choicepoint_newer(MR_ChoicepointId, MR_ChoicepointId);
</pre>
<p><code>MR_choicepoint_newer(x, y)</code> true iff the choicepoint indicated by
<code>x</code> is newer than (i.e. was created more recently than) the
choicepoint indicated by <code>y</code>. The null ChoicepointId is considered
older than any non-null ChoicepointId. If either of the choice points
have been backtracked over, the behaviour is undefined.
</dl>
<p>The way these functions are generally used is as follows.
When you create a mutable data structure, you should call
<code>MR_current_choicepoint_id()</code> and save the value it returns
as a <code>prev_choicepoint</code> field in your data structure.
(If your mutable data structure
is a C global variable, then you can use MR_null_choicepoint_id()
for the initial value of this <code>prev_choicepoint</code> field.)
When you are about to modify your mutable data structure,
you can then call <code>MR_current_choicepoint_id()</code> again and
compare the result from that call with the value saved in
the <code>prev_choicepoint</code> field in the data structure
using <code>MR_choicepoint_newer()</code>.
If the current choicepoint is newer, then you must trail the update,
and update the <code>prev_choicepoint</code> field with the new value;
furthermore, you must also take care that on backtracking the
previous value of the <code>prev_choicepoint</code> field in your data
structure is restored to its previous value, by trailing that update too.
But if <code>MR_current_choice_id()</code> is not newer than the
<code>prev_choicepoint</code> field, then you can safely perform
the update to your data structure without trailing it.
<p>For an example, see the sample module below.
<p>Note that there is a cost to this -- you have to include
an extra field in your data structure for each part of
the data structure which you might update, you
need to perform a test for each update to decide whether
or not to trail it, and if you do need to trail the update,
then you have an extra field that you need to trail.
Whether or not the benefits from avoiding redundant trailing
outweigh these costs will depend on your application.
<br><pre>:- module trailing_example.
:- interface.
:- type int_ref.
% Create a new int_ref with the specified value.
:- pred new_int_ref(int_ref::uo, int::in) is det.
% update_int_ref(Ref0, Ref, OldVal, NewVal):
% Ref0 has value OldVal and Ref has value NewVal.
:- pred update_int_ref(int_ref::mdi, int_ref::muo,
int::out, int::in) is det.
:- implementation.
:- type int_ref ---> int_ref(c_pointer).
:- pragma import(new_int_ref(uo, in),
"new_int_ref").
:- pragma import(update_int_ref(mdi, muo, out, in),
"update_int_ref").
:- pragma c_header_code("
typedef MR_Word Mercury_IntRef;
void new_int_ref(Mercury_IntRef *ref, MR_Integer value);
void update_int_ref(Mercury_IntRef ref0, Mercury_IntRef *ref,
MR_Integer *old_value, MR_Integer new_value);
").
:- pragma c_code("
typedef struct {
MR_ChoicepointId prev_choicepoint;
MR_Integer data;
} C_IntRef;
void
new_int_ref(Mercury_IntRef *ref, MR_Integer value)
{
C_IntRef *x = malloc(sizeof(C_IntRef));
x->prev_choicepoint = MR_current_choicepoint_id();
x->data = value;
*ref = (Mercury_IntRef) x;
}
void
update_int_ref(Mercury_IntRef ref0, Mercury_IntRef *ref,
MR_Integer *old_value, MR_Integer new_value)
{
C_IntRef *x = (C_IntRef *) ref0;
*old_value = x->data;
/* check whether we need to trail this update */
if (MR_choicepoint_newer(MR_current_choicepoint_id(),
x->prev_choicepoint))
{
/* trail both x->data and x->prev_choicepoint,
since we're about to update them both*/
assert(sizeof(x->data) == sizeof(MR_Word));
assert(sizeof(x->prev_choicepoint) == sizeof(MR_Word));
MR_trail_current_value((MR_Word *)&x->data);
MR_trail_current_value((MR_Word *)&x->prev_choicepoint);
/* update x->prev_choicepoint to indicate that
x->data's previous value has been trailed
at this choice point */
x->prev_choicepoint = MR_current_choicepoint_id();
}
x->data = new_value;
*ref = ref0;
}
").
</pre>
<p><hr>
Node:<a name="Impurity">Impurity</a>,
Next:<a rel=next href="#Pragmas">Pragmas</a>,
Previous:<a rel=previous href="#C%20interface">C interface</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Impurity declarations</h2>
<p>In order to efficiently implement certain predicates, it is occasionally
necessary to venture outside pure logic programming. Other predicates
cannot be implemented at all within the paradigm of logic programming,
for example, all solutions predicates. Such predicates are often
written using the C interface. Sometimes, however, it would be more
convenient, or more efficient, to write such predicates using the
facilities of Mercury. For example, it is much more convenient to
access arguments of compound Mercury terms in Mercury than in C, and the
ability of the Mercury compiler to specialize code can make higher-order
predicates written in Mercury significantly more efficient than similar
C code.
<p>One important aim of Mercury's impurity system is to make the
distinction between the pure and impure code very clear. This is done
by requiring every impure predicate or function to be so declared, and
by requiring every call to an impure predicate or function to be flagged as
such.
Predicates or functions that are implemented in terms of impure predicates
or functions are assumed to be impure themselves unless they are
explicitly promised to be pure.
<p>Please note that the facilities described here are needed only very
rarely. The main intent is for implementing language primitives such as
the all solutions predicates, or for implementing interfaces to foreign
language libraries using the foreign language interface. Any other use of
<code>impure</code> or <code>semipure</code> probably indicates either a weakness in
the Mercury standard library, or the programmer's lack of familiarity
with the standard library. Newcomers to Mercury are hence encouraged to
<strong>skip this section</strong>.
<ul>
<li><a href="#Purity%20levels">Purity levels</a>: Choosing the right level of purity.
<li><a href="#Purity%20ordering">Purity ordering</a>: How purity levels are ordered
<li><a href="#Impurity%20semantics">Impurity semantics</a>: What impure code means.
<li><a href="#Declaring%20impurity">Declaring impurity</a>: Declaring predicates impure.
<li><a href="#Impure%20calls">Impure calls</a>: Marking a call as impure.
<li><a href="#Promising%20purity">Promising purity</a>: Promising that a predicate is pure.
<li><a href="#Impurity%20Example">Impurity Example</a>: A simple example using impurity.
<li><a href="#Higher-order%20impurity">Higher-order impurity</a>: Using impurity with higher-order code.
</ul>
<p><hr>
Node:<a name="Purity%20levels">Purity levels</a>,
Next:<a rel=next href="#Purity%20ordering">Purity ordering</a>,
Up:<a rel=up href="#Impurity">Impurity</a>
<br>
<h3>Choosing the right level of purity</h3>
<p>Mercury distinguishes three "levels" of purity:
<dl>
<dt><dfn>pure</dfn>
<dd>For pure procedures, the set of solutions depends only on the
values of the input arguments.
They do not interact with the "real" world (i.e., do any
input/output) without taking an io__state (see <a href="#Types">Types</a>) as input and
returning one as output, and do not change the value of any data
structure that will not be undone on backtracking (unless the data
structure would be unreachable on backtracking). Note that equality
axioms are important when considering the value of data structures.
The declarative semantics of pure predicates is never affected by the
invocation of other predicates.
It is possible for the invocation of pure predicates to affect the
operational behaviour of non-pure predicates and vice versa.
<p>By default, Mercury predicates and functions are pure.
Without using the foreign language interface, writing mode-specific
clauses or calling other impure predicates and functions it is
impossible to write impure code in Mercury.
<br><dt><dfn>semipure</dfn>
<dd>Semipure predicates are just like pure predicates, except that their
declarative semantics may be affected by the invocation of impure
predicates. That is, they are sensitive to the state of the computation
other than as reflected by their input arguments, though they do not
affect the state themselves.
<br><dt><dfn>impure</dfn>
<dd>Impure predicates may perform I/O or modify hidden state,
even if these side effects alter the operational semantics
of other code. However, impure predicates may not change
the declarative semantics of pure code.
They must be type-, mode-, determinism- and uniqueness correct.
</dl>
<p><hr>
Node:<a name="Purity%20ordering">Purity ordering</a>,
Next:<a rel=next href="#Impurity%20semantics">Impurity semantics</a>,
Previous:<a rel=previous href="#Purity%20levels">Purity levels</a>,
Up:<a rel=up href="#Impurity">Impurity</a>
<br>
<h3>Purity ordering</h3>
<p>The three levels of purity have a total ordering defined upon them
(which we will simply call the purity), where <code>pure > semipure > impure</code>.
<p><hr>
Node:<a name="Impurity%20semantics">Impurity semantics</a>,
Next:<a rel=next href="#Declaring%20impurity">Declaring impurity</a>,
Previous:<a rel=previous href="#Purity%20ordering">Purity ordering</a>,
Up:<a rel=up href="#Impurity">Impurity</a>
<br>
<h3>Semantics</h3>
<p>It is important to the proper operation of impure and semipure code, to
the flexibility of the compiler to optimize pure code, and to the
semantics of the Mercury language, that a clear distinction be drawn
between ordinary Mercury code and imperative code written with Mercury
syntax. How this distinction is drawn will be explained below; the
purpose of this section is to explain the semantics of programs with
impure predicates.
<p>A <em>declarative</em> semantics of impure Mercury code would be largely
useless, because the declarative semantics cannot capture the intent of
the programmer. Impure predicates are executed for their side-effects,
which by definition are not part of their declarative semantics. Thus
it is the <em>operational</em> semantics of impure predicates that Mercury
must specify, and Mercury compilers must respect.
<p>The operational semantics of a Mercury predicate which invokes
<em>impure</em> code is a modified form of the <em>strict sequential</em>
semantics (see <a href="#Semantics">Semantics</a>). <em>Impure</em> goals may not be reordered
relative to any other goals; not even "minimal" reordering as implied
by the modes is permitted. If any such reordering is needed, this is a
mode error. However, <em>pure</em> and <em>semipure</em> goals may be
reordered as the compiler desires (within the bounds of the semantics
the user has specified for the program) as long as they are not moved
across an impure goal. Execution of impure goals is strict: they must
be executed if they are reached, even if it can be determined that that
computation cannot lead to successful termination.
<p>Semipure goals can be given a "contextual" declarative semantics.
They cannot have any side-effects, so it is expected that, given the
context in which they are called (relative to any impure goals in the
program), their declarative semantics fully captures the intent of the
programmer. Thus a semipure goal has a perfectly consistent declarative
semantics, until an impure goal is reached. After that, it has another
(possibly different) declarative semantics, until the next impure goal
is executed, and so on. Mercury compilers must respect this contextual
nature of the semantics of semipure goals; within a single context, a
compiler may treat a semipure goal as if it were pure.
<p><hr>
Node:<a name="Declaring%20impurity">Declaring impurity</a>,
Next:<a rel=next href="#Impure%20calls">Impure calls</a>,
Previous:<a rel=previous href="#Impurity%20semantics">Impurity semantics</a>,
Up:<a rel=up href="#Impurity">Impurity</a>
<br>
<h3>Declaring impure functions and predicates</h3>
<p>Every Mercury predicate or function has exactly two purity values
associated with it.
One is the <em>declared</em> purity of the predicate or function, which is
given by the programmer.
The other value is the <em>inferred</em> purity,
which is calculated from the purity of goals in the body of the
predicate or function.
<p>A predicate is declared to be impure or semipure by preceding the word
<code>pred</code> in its <code>pred</code> declaration with <code>impure</code>
or <code>semipure</code>, respectively.
Similarly, a function is declared impure or semipure by preceding the
word <code>func</code> in its <code>func</code> declaration with <code>impure</code> or
<code>semipure</code>.
That is, a declaration of the form:
<br><pre>:- impure pred <var>Pred</var>(<var>Arguments</var><small>...</small>).
:- semimpure pred <var>Pred</var>(<var>Arguments</var><small>...</small>).
</pre>
<p>or
<br><pre>:- impure func <var>Func</var>(<var>Arguments</var><small>...</small>) = Result.
:- semipure func <var>Func</var>(<var>Arguments</var><small>...</small>) = Result.
</pre>
<p>declares the predicate <var>Pred</var> to be impure and the function
<var>Func</var> to be semipure, respectively.
<p>Type class methods may also be declared as <code>impure</code> or
<code>semipure</code> by preceeding the word <code>pred</code> or <code>func</code> with the
appropriate purity level. An instance of the type class must provide
method implementations that are at least as pure as the method
declaration.
<p><hr>
Node:<a name="Impure%20calls">Impure calls</a>,
Next:<a rel=next href="#Promising%20purity">Promising purity</a>,
Previous:<a rel=previous href="#Declaring%20impurity">Declaring impurity</a>,
Up:<a rel=up href="#Impurity">Impurity</a>
<br>
<h3>Marking a call as impure</h3>
<p>Every call to a Mercury predicate or function also has exactly two
purity values associated with it.
One is the declared purity of the call, which is
given by the programmer as an annotation of the call.
The other value is the inferred purity,
which is the purity of the predicate or function.
<p>It is an error for the declared purity of a goal to be more pure than
the inferred purity; the compiler should flag this as an error.
The compiler should issue a warning if the declared purity of a goal is
less pure than its inferred purity.
<p>If a predicate is impure or semipure, all calls to it must be preceded
with the word <code>impure</code> or <code>semipure</code>, respectively.
<p>If a function is impure or semipure, it must be called as part of a
simple unification with a variable, and this unification must be
prefixed by the word <code>impure</code> or <code>semipure</code>, respectively.
<p>Note that only predicate calls and unifications of variables with
functions need to (and are permitted to) be prefixed
with <code>impure</code> or <code>semipure</code>. Compound goals never need this.
See <a href="#Impurity%20Example">Impurity Example</a> for an example of this syntax.
<p>The requirement that impure or semipure calls be marked with
<code>impure</code> or <code>semipure</code> allows someone
reading the code to tell which goals are not pure, making code which
relies on side effects somewhat less mysterious. Furthermore, it means
that if a call is <em>not</em> preceded by <code>impure</code> or
<code>semipure</code>, then the reader can rely on the call having a proper
declarative semantics, without hidden side-effects.
<p><hr>
Node:<a name="Promising%20purity">Promising purity</a>,
Next:<a rel=next href="#Impurity%20Example">Impurity Example</a>,
Previous:<a rel=previous href="#Impure%20calls">Impure calls</a>,
Up:<a rel=up href="#Impurity">Impurity</a>
<br>
<h3>Promising that a predicate is pure</h3>
<p>Predicates that are implemented in terms of impure or semipure predicates are
assumed to have the least of the purity of the goals in their body.
The declared purity of a predicate must not be more pure
than the inferred purity; if it is, the compiler must generate an error.
If the declared purity is less pure than the inferred purity, the
compiler should issue a warning (this is similar to the above case for
goals).
Because the inferred purity of the predicate is calculated from the
declared purity of the calls it executes, the lowest purity bound is
propagated up from callee to caller through the program.
<p>In some cases the impurity of a predicate's body is an implementation
detail which should not be exposed to callers. These predicates are
pure or semipure even though they call impure or semipure predicates.
The only way for the programmer to stop the propagation of impurity is to
explicitly promise that the predicate or function is pure or semipure.
<p>Of course, the Mercury compiler cannot verify that the predicate's
purity matches the promise, so it is the programmer's responsibility
to ensure this. If a predicate is promised pure or semipure and is not,
the behaviour of the program is undefined.
<p>The programmer may promise that a predicate or function is pure or semipure
using the <code>promise_pure</code> and <code>promise_semipure</code> pragmas:
<br><pre>:- pragma promise_pure(<var>Name</var>/<var>Arity</var>).
:- pragma promise_semipure(<var>Name</var>/<var>Arity</var>).
</pre>
<p>Programmers should be very careful about mixing code that is promised
pure with impure predicates or functions that may manipulate the
same hidden state (for example, the impure predicates used to implement
a predicate that is promised pure); the <code>promise pure</code> declaration
is supposed to promise that impure code cannot change the declarative
semantics of pure code. The module system can be used to minimize the
possibility of making errors with such code, by keeping impure
predicates or functions behind the interface where code is promised
pure.
<p><hr>
Node:<a name="Impurity%20Example">Impurity Example</a>,
Next:<a rel=next href="#Higher-order%20impurity">Higher-order impurity</a>,
Previous:<a rel=previous href="#Promising%20purity">Promising purity</a>,
Up:<a rel=up href="#Impurity">Impurity</a>
<br>
<h3>An example using impurity</h3>
<p>The following example illustrates how a pure predicate may be
implemented using impure code. Note that this code is not reentrant,
and so is not useful as is. It is meant only as an example.
<br><pre>:- pragma c_header_code("#include <limits.h>").
:- pragma c_header_code("MR_Integer max;").
:- impure pred init_max is det.
:- pragma c_code(init_max,
[will_not_call_mercury],
"max = INT_MIN;").
:- impure pred set_max(int::in) is det.
:- pragma c_code(set_max(X::in),
[will_not_call_mercury],
"if (X > max) max = X;").
:- semipure func get_max = (int::out) is det.
:- pragma c_code(get_max = (X::out),
[will_not_call_mercury],
"X = max;").
:- pragma promise_pure(max_solution/2).
:- pred max_solution(pred(int), int).
:- mode max_solution(pred(out) is multi, out) is det.
max_solution(Generator, Max) :-
impure init_max,
( Generator(X),
impure set_max(X),
fail
; semipure Max = get_max
).
</pre>
<p><hr>
Node:<a name="Higher-order%20impurity">Higher-order impurity</a>,
Previous:<a rel=previous href="#Impurity%20Example">Impurity Example</a>,
Up:<a rel=up href="#Impurity">Impurity</a>
<br>
<h3>Using impurity with higher-order code</h3>
<p>Higher-order code can manipulate impure or semipure predicates and functions,
provided that explicit purity annotations are used in three places:
on the higher-order types, on lambda expressions, and on higher-order calls.
(There are no purity annotations on higher-order insts and modes, however.)
<ul>
<li><a href="#Purity%20annotations%20on%20higher-order%20types">Purity annotations on higher-order types</a>:
<li><a href="#Purity%20annotations%20on%20lambda%20expressions">Purity annotations on lambda expressions</a>:
<li><a href="#Purity%20annotations%20on%20higher-order%20calls">Purity annotations on higher-order calls</a>:
</ul>
<p><hr>
Node:<a name="Purity%20annotations%20on%20higher-order%20types">Purity annotations on higher-order types</a>,
Next:<a rel=next href="#Purity%20annotations%20on%20lambda%20expressions">Purity annotations on lambda expressions</a>,
Up:<a rel=up href="#Higher-order%20impurity">Higher-order impurity</a>
<br>
<h4>Purity annotations on higher-order types</h4>
<p>Ordinary higher-order types, such as <code>pred(T1, T2)</code> and
<code>func(T1, T2) = T</code>, represent only pure predicates or pure functions.
But for each ordinary higher-order type <var>Foo</var>, there are two corresponding
types <code>semipure <var>Foo</var></code> and <code>impure <var>Foo</var></code>. These types
can be used for higher-order code that needs to manipulate impure or
semipure procedures. For example the type <code>impure func(int) = int</code>
represents impure functions from <code>int</code> to <code>int</code>.
<p>There are no implicit conversions and no subtyping relationship between
ordinary higher-order types and the corresponding impure or semipure
higher-order types. However, a value of an ordinary higher-order
type can be explicit "converted" to a value of an impure (or semipure)
higher-order type by wrapping it in an impure (or semipure)
lambda expression that just calls the pure higher-order term.
<p><hr>
Node:<a name="Purity%20annotations%20on%20lambda%20expressions">Purity annotations on lambda expressions</a>,
Next:<a rel=next href="#Purity%20annotations%20on%20higher-order%20calls">Purity annotations on higher-order calls</a>,
Previous:<a rel=previous href="#Purity%20annotations%20on%20higher-order%20types">Purity annotations on higher-order types</a>,
Up:<a rel=up href="#Higher-order%20impurity">Higher-order impurity</a>
<br>
<h4>Purity annotations on lambda expressions</h4>
<p>Purity annotations are required on lambda expressions that call
semipure or impure code.
Lambda expressions can be declared as <code>semipure</code> or <code>impure</code>
by including such an annotation before the <code>pred</code> or <code>func</code>
identifier in the lambda expression. Such lambda expressions have
the corresponding <code>semipure</code> or <code>impure</code> higher-order type.
For example, the expression
<br><pre> (impure func(X) = Y :- semipure get_max(Y), impure set_max(X))
</pre>
<p>is an example of an impure function lambda expression with type
<code>(impure func(int) = int)</code>, and the expression
<br><pre> (impure pred(X::in, Y::out) is det :-
semipure get_max(Y),
impure set_max(X))
</pre>
is an example of an impure predicate lambda expression
with type <code>impure pred(int, int)</code>.
<p><hr>
Node:<a name="Purity%20annotations%20on%20higher-order%20calls">Purity annotations on higher-order calls</a>,
Previous:<a rel=previous href="#Purity%20annotations%20on%20lambda%20expressions">Purity annotations on lambda expressions</a>,
Up:<a rel=up href="#Higher-order%20impurity">Higher-order impurity</a>
<br>
<h4>Purity annotations on higher-order calls</h4>
<p>Any calls to impure or semipure higher-order terms must be explicitly
annotated as such. For impure or semipure higher-order predicates,
the annotation is indicated by putting <code>impure</code> or <code>semipure</code>
before the call. For example:
<br><pre> :- func foo(impure pred(int)) = int.
:- mode foo(in(pred(out) is det)) = out is det.
foo(ImpurePred) = X1 + X2 :-
% using higher-order syntax
impure ImpurePred(X1),
% using the call/N syntax
impure call(ImpurePred, X2).
</pre>
<p>For calling impure or semipure higher-order functions, the notation is
different than what you might expect. In addition to using an <code>impure</code>
or <code>semipure</code> operator on the unification which invokes the higher-order
function application, you must also use <code>impure_apply</code>
or <code>semipure_apply</code> rather than using <code>apply</code> or higher-order syntax.
For example:
<br><pre> :- func map(impure func(T1) = T2, list(T1)) = list(T2).
map(_ImpureFunc, []) = [].
map(ImpureFunc, [X|Xs]) = [Y|Ys] :-
impure Y = impure_apply(ImpureFunc, X),
impure Ys = map(ImpureFunc, Ys).
</pre>
<p><hr>
Node:<a name="Pragmas">Pragmas</a>,
Next:<a rel=next href="#Implementation-dependent%20extensions">Implementation-dependent extensions</a>,
Previous:<a rel=previous href="#Impurity">Impurity</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Pragmas</h2>
<p>The pragma declarations described below are a standard part of the
Mercury language, as are the pragmas for controlling the C interface
(see <a href="#C%20interface">C interface</a>) and impurity (see <a href="#Impurity">Impurity</a>).
As an extension, implementations may also choose to support additional
pragmas with implementation-dependent semantics
(see <a href="#Implementation-dependent%20extensions">Implementation-dependent extensions</a>).
<ul>
<li><a href="#Inlining">Inlining</a>: Pragmas can be used to suggest or prevent
procedure inlining.
<li><a href="#Type%20specialization">Type specialization</a>: Pragmas can be used to produce specialized
versions of polymorphic procedures.
<li><a href="#Obsolescence">Obsolescence</a>: Library developers can declare old versions
of predicates or functions to be obsolete.
<li><a href="#Source%20file%20name">Source file name</a>: The <code>source_file</code> pragma and
<code>#<var>line</var></code> directives provide support
for preprocessors and other tools that
generate Mercury code.
</ul>
<p><hr>
Node:<a name="Inlining">Inlining</a>,
Next:<a rel=next href="#Type%20specialization">Type specialization</a>,
Up:<a rel=up href="#Pragmas">Pragmas</a>
<br>
<h3>Inlining</h3>
<p>A declaration of the form
<br><pre>:- pragma inline(<var>Name</var>/<var>Arity</var>).
</pre>
<p>is a hint to the compiler that all calls to the predicate(s) or function(s)
with name <var>Name</var> and arity <var>Arity</var> should be inlined.
<p>The current Mercury implementation is smart enough to inline
simple predicates even without this hint.
<p>A declaration of the form
<br><pre>:- pragma no_inline(<var>Name</var>/<var>Arity</var>).
</pre>
<p>ensures the compiler will not inline this predicate. This may be used
simply for performance concerns (inlining can cause unwanted code bloat
in some cases) or to prevent possibly dangerous inlining when using
low-level C code.
<p><hr>
Node:<a name="Type%20specialization">Type specialization</a>,
Next:<a rel=next href="#Obsolescence">Obsolescence</a>,
Previous:<a rel=previous href="#Inlining">Inlining</a>,
Up:<a rel=up href="#Pragmas">Pragmas</a>
<br>
<h3>Type specialization</h3>
<p>The overhead of polymorphism can in some cases be significant, especially
where polymorphic predicates make heavy use of class method calls or the
built-in unification and comparison routines. To avoid this, the programmer
can suggest to the compiler that a specialized version of a procedure should
be created for a specific set of argument types.
<ul>
<li><a href="#Syntax%20and%20semantics%20of%20type%20specialization%20pragmas">Syntax and semantics of type specialization pragmas</a>:
<li><a href="#When%20to%20use%20type%20specialization">When to use type specialization</a>:
<li><a href="#Implementation%20specific%20details">Implementation specific details</a>:
</ul>
<p><hr>
Node:<a name="Syntax%20and%20semantics%20of%20type%20specialization%20pragmas">Syntax and semantics of type specialization pragmas</a>,
Next:<a rel=next href="#When%20to%20use%20type%20specialization">When to use type specialization</a>,
Up:<a rel=up href="#Type%20specialization">Type specialization</a>
<br>
<h4>Syntax and semantics of type specialization pragmas</h4>
<p>A declaration of the form
<br><pre>:- pragma type_spec(<var>Name</var>/<var>Arity</var>, <var>Subst</var>).
:- pragma type_spec(<var>Name</var>(<var>Modes</var>), <var>Subst</var>).
</pre>
<p>suggests to the compiler that a specialized version of predicate(s)
or function(s) with name <var>Name</var> and arity <var>Arity</var> should be
created with the type substitution given by <var>Subst</var> applied to the
argument types. The second form of the declaration only suggests
specialization of the specified mode of the predicate or function.
<p>The substitution is written as a conjunction of bindings of the form
<code><var>TypeVar</var> = <var>Type</var></code>, for example <code>K = int</code> or
<code>(K = int, V = list(int))</code>.
<p>The declarations
<br><pre>:- pred map__lookup(map(K, V), K, V).
:- pragma type_spec(map__lookup/3, K = int).
</pre>
<p>give a hint to the compiler that a version of <code>map__lookup/3</code> should
be created for integer keys.
<p>Implementations are free to ignore <code>pragma type_spec</code> declarations.
Implementations are also free to perform type specialization
even in the absence of any <code>pragma type_spec</code> declarations.
<p><hr>
Node:<a name="When%20to%20use%20type%20specialization">When to use type specialization</a>,
Next:<a rel=next href="#Implementation%20specific%20details">Implementation specific details</a>,
Previous:<a rel=previous href="#Syntax%20and%20semantics%20of%20type%20specialization%20pragmas">Syntax and semantics of type specialization pragmas</a>,
Up:<a rel=up href="#Type%20specialization">Type specialization</a>
<br>
<h4>When to use type specialization</h4>
<p>The set of types for which a predicate or function should be specialized is
best determined by profiling your application. Overuse of type specialization
will result in code bloat.
<p>Type specialization of predicates or functions which
unify or compare polymorphic variables is most effective when
the specialized types are built-in types such as <code>int</code>, <code>float</code>
and <code>string</code>, or enumeration types, since their unification and
comparison procedures are simple and can be inlined.
<p>Predicates or functions which make use of type class method calls
may also be candidates for specialization. Again, this is most effective
when the called type class methods are simple enough to be inlined.
<p><hr>
Node:<a name="Implementation%20specific%20details">Implementation specific details</a>,
Previous:<a rel=previous href="#When%20to%20use%20type%20specialization">When to use type specialization</a>,
Up:<a rel=up href="#Type%20specialization">Type specialization</a>
<br>
<h4>Implementation specific details</h4>
<p>The University of Melbourne Mercury compiler performs user-requested type
specializations when invoked with <code>--user-guided-type-specialization</code>,
which is enabled at optimization level <code>-O2</code> or higher.
<p><hr>
Node:<a name="Obsolescence">Obsolescence</a>,
Next:<a rel=next href="#Source%20file%20name">Source file name</a>,
Previous:<a rel=previous href="#Type%20specialization">Type specialization</a>,
Up:<a rel=up href="#Pragmas">Pragmas</a>
<br>
<h3>Obsolescence</h3>
<p>A declaration of the form
<br><pre>:- pragma obsolete(<var>Name</var>/<var>Arity</var>).
</pre>
<p>declares that the predicate(s) or function(s)
with name <var>Name</var> and arity <var>Arity</var> are "obsolete":
it instructs the compiler to issue a warning whenever the named
predicate(s) or function(s) are used.
<p><code>pragma obsolete</code> declarations are intended for use by library
developers, to allow gradual (rather than abrupt) evolution of library
interfaces. If a library developer changes the interface of a library
predicate, they should leave the old version of that predicate in the
library, but mark it as obsolete using a <code>pragma obsolete</code>
declaration, and document how library users should modify their code to
suit the new interface. The users of the library will then get a
warning if they use obsolete features, and can consult the library
documentation to determine how to fix their code. Eventually, when the
library developer deems that users have had sufficient warning, they
can remove the old version entirely.
<p><hr>
Node:<a name="Source%20file%20name">Source file name</a>,
Previous:<a rel=previous href="#Obsolescence">Obsolescence</a>,
Up:<a rel=up href="#Pragmas">Pragmas</a>
<br>
<h3>Source file name</h3>
<p>The <code>source_file</code> pragma and <code>#<var>line</var></code> directives provide
support for preprocessors and other tools that generate Mercury code.
The tool can insert these directives into the generated Mercury code
to allow the Mercury compiler to report diagnostics (error and warning
messages) at the original source code location, rather than at the
location in the automatically generated Mercury code.
<p>A <code>source_file</code> pragma is a declaration of the form
<br><pre>:- pragma source_file(<var>Name</var>).
</pre>
<p>where <var>Name</var> is a string that specifies the name of the source file.
<p>For example, if a preprocessor generated a file <code>foo.m</code> based on a
input file <code>foo.m.in</code>, and it copied lines 20, 30, and 31 from
<code>foo.m.in</code>, the following directives would ensure that any
error or warnings for those lines copied from <code>foo.m</code> were reported
at their original source locations in <code>foo.m.in</code>.
<br><pre>:- module foo.
:- pragma source_file("foo.m.in").
#20
% this line comes from line 20 of foo.m
#30
% this line comes from line 30 of foo.m
% this line comes from line 31 of foo.m
:- pragma source_file("foo.m").
#10
% this automatically generated line is line 10 of foo.m
</pre>
<p>Note that if a generated file contains some text which is copied from a
source file, and some which is automatically generated, it is a good
idea to use <code>pragma source_file</code> and <code>#<var>line</var></code> directives
to reset the source file name and line number to point back to the
generated file for the automatically generated text, as in the above
example.
<p><hr>
Node:<a name="Implementation-dependent%20extensions">Implementation-dependent extensions</a>,
Next:<a rel=next href="#Bibliography">Bibliography</a>,
Previous:<a rel=previous href="#Pragmas">Pragmas</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Implementation-dependent extensions</h2>
<p>The University of Melbourne Mercury implementation supports the following
extensions to the Mercury language:
<ul>
<li><a href="#Fact%20tables">Fact tables</a>: Support for very large tables of facts.
<li><a href="#Tabled%20evaluation">Tabled evaluation</a>: Support for automatically recording previously
calculated results and detecting or avoiding
certain kinds of infinite loops.
<li><a href="#Termination%20analysis">Termination analysis</a>: Support for automatic proofs of termination.
<li><a href="#Aditi%20deductive%20database%20interface">Aditi deductive database interface</a>:
Support for bottom-up evaluation of Mercury
predicates.
</ul>
<p><hr>
Node:<a name="Fact%20tables">Fact tables</a>,
Next:<a rel=next href="#Tabled%20evaluation">Tabled evaluation</a>,
Up:<a rel=up href="#Implementation-dependent%20extensions">Implementation-dependent extensions</a>
<br>
<h3>Fact tables</h3>
<p>Large tables of facts can be compiled using a different algorithm that
is more efficient and produces more efficient code.
<p>A declaration of the form
<br><pre>:- pragma fact_table(<var>Name</var>/<var>Arity</var>, <var>FileName</var>).
</pre>
<p>tells the compiler that the predicate or function with name <var>Name</var>
and arity <var>Arity</var> is defined by a set of facts in an external file
<var>FileName</var>. Defining large tables of facts in this way allows the
compiler to use a more efficient algorithm for compiling them.
This algorithm uses less memory than would normally be required
to compile the facts so much larger tables are possible.
<p>Each mode is indexed on all its input arguments so the compiler can
produce very efficient code using this technique.
<p>In the current implementation, the table of facts is compiled into a
separate C file named <code><var>FileName</var>.c</code>. The compiler will
automatically generate the correct dependencies for this file when the
command <code>mmake <var>main_module</var>.depend</code> is invoked. This ensures
that the C file will be compiled to <code><var>FileName</var>.o</code> and then
linked with the other object files when <code>mmake <var>main_module</var></code>
is invoked.
<p>The main limitation of the <code>fact_table</code> pragma is that
in the current implementation,
predicates or functions defined as fact tables can only have
arguments of types <code>string</code>, <code>int</code> or <code>float</code>.
<p>Another limitation is that the <code>--high-level-code</code> back-end does
not support <code>pragma fact_table</code> for procedures with determinism
<code>nondet</code> or <code>multi</code>.
<p><hr>
Node:<a name="Tabled%20evaluation">Tabled evaluation</a>,
Next:<a rel=next href="#Termination%20analysis">Termination analysis</a>,
Previous:<a rel=previous href="#Fact%20tables">Fact tables</a>,
Up:<a rel=up href="#Implementation-dependent%20extensions">Implementation-dependent extensions</a>
<br>
<h3>Tabled evaluation</h3>
<p>(Note: "Tabled evaluation" has no relation to the "fact tables"
described above.)
<p>Ordinarily, the results of each procedure call are not recorded;
if the same procedure is called with the same arguments,
then the answer(s) must be recomputed again.
For some procedures, this recomputation can be very wasteful.
<p>With tabled evaluation, the implementation keeps a table containing the
previously computed results of the specified procedure; at each
procedure call, the implementation will search the table to check
whether the answer(s) have already been computed and if so, the answers
will be returned directly from the tables rather than being recomputed.
This can result in much faster execution, at the cost of additional
space to record answers in the table.
<p>The implementation can optionally also check at runtime for the situation
where a procedure calls itself recursively with the same arguments,
which would normally result in a infinite loop; if this situation is
encountered, it can (at the programmer's option) either throw an
exception, or avoid the infinite loop by computing solutions
using the "minimal model" semantics.
<p>The current Mercury implementation thus supports three different
pragmas for tabling, to cover these three cases: <code>pragma memo</code>
does no loop checking, <code>pragma loop_check</code> checks for loops
and throws an exception if a loop is detected, while
<code>pragma minimal_model</code> computes the "minimal model" semantics.
<p><strong>Warning:</strong>
The current implementation of <code>pragma minimal_model</code> is broken:
the generated code sometimes produces incorrect results. It should
not be used. Also the current implementation of all three pragmas
is broken for procedures with determinism <code>nondet</code> or <code>multi</code>.
The <code>pragma memo</code> and <code>pragma loop_check</code> declarations
should not be used on such procedures.
<p>The syntax for each of these declarations is
<br><pre>:- pragma memo(<var>Name</var>/<var>Arity</var>).
:- pragma loop_check(<var>Name</var>/<var>Arity</var>).
:- pragma minimal_model(<var>Name</var>/<var>Arity</var>).
</pre>
<p>where <var>Name</var>/<var>Arity</var> specifies the predicate or
function to which the declaration applies. The declaration
applies to all modes of the predicate and/or function named.
At most one of these declarations may be specified
for any given predicate or function.
<p>Note that a <code>pragma minimal_model</code> declaration
changes the declarative semantics of the specified predicate or
function: instead of using the completion of the clauses
as the basis for the semantics, as is normally the case
in Mercury, the declarative semantics that is used is
the "minimal model" semantics. Anything which is
true or false in the completion semantics is also true
or false (respectively) in the minimal model semantics,
but there are goals for which the minimal model specifies
that the result is true or false, whereas the completion semantics
leaves the result unspecified.
For these goals, the usual Mercury semantics requires the
implementation to either loop or report an error message,
but the minimal model semantics requires a particular
answer to be returned.
In particular, the minimal model semantics says that any
call that is not true in <em>all</em> models is false.
<p>Programmers should therefore use a <code>pragma minimal_model</code>
declaration only in cases where their intended interpretation for a
procedure coincides with the minimal model for that procedure.
Fortunately, however, this is usually what programmers intend.
<p>For more information on tabling, see K. Sagonas's PhD thesis
<cite>The SLG-WAM: A Search-Efficient Engine for Well-Founded Evaluation
of Normal Logic Programs.</cite> See <a href="#%5b4%5d">[4]</a>.
The operational semantics of procedures with a <code>pragma minimal_model</code>
declaration corresponds to what Sagonas calls "SLGd resolution".
<p>In the general case, the execution mechanism required by
minimal model tabling is quite complicated, requiring
the ability to delay goals and then wake them up again.
The Mercury implementation uses a technique based on copying
relevant parts of the stack to the heap when delaying goals,
similar to the one described in
<cite>CAT: the copying approach to tabling</cite>,
by B. Demoen and K. Sagonas. See <a href="#%5b5%5d">[5]</a>.
This ensures that code which does not use tabling does not pay any
runtime overheads from the more complicated execution mechanism
required by (minimal model) tabling.
<p><strong>Please note:</strong>
the current implementation of tabling does not support all the
possible compilation grades (see the "Compilation model options"
section of the Mercury User's Guide) allowed by the Mercury
implementation. In particular, if you enable the use of trailing,
or if you select a garbage collection method other than the default
(conservative), then any use of tabling will result in a
"Sorry, not implemented" error at runtime.
<p><strong>Reminder</strong>: the current implementation of
<code>pragma minimal_model</code> is broken,
and the current implementation of <code>pragma memo</code>
and <code>pragma loop_check</code> is broken for procedures
with determinism <code>nondet</code> or <code>multi</code>.
<p><hr>
Node:<a name="Termination%20analysis">Termination analysis</a>,
Next:<a rel=next href="#Aditi%20deductive%20database%20interface">Aditi deductive database interface</a>,
Previous:<a rel=previous href="#Tabled%20evaluation">Tabled evaluation</a>,
Up:<a rel=up href="#Implementation-dependent%20extensions">Implementation-dependent extensions</a>
<br>
<h3>Termination analysis</h3>
<p>The compiler includes a termination analyser which can be used to prove
termination of predicates and functions. Details of the analysis is
available in "Termination Analysis for Mercury" by Chris Speirs, Zoltan
Somogyi and Harald Sondergaard. See <a href="#%5b1%5d">[1]</a>.
<p>The analysis is based around an algorithm proposed by Gerhard Groger
and Lutz Plumer in their paper "Handling of mutual recursion in
automatic termination proofs for logic programs." See <a href="#%5b2%5d">[2]</a>.
<p>For an introduction to termination analysis for logic programs, please
refer to "Termination Analysis for Logic Programs" by Chris Speirs.
See <a href="#%5b3%5d">[3]</a>.
<p>Information about the termination properties of a predicate or function
can be given to the compiler. Pragmas are also available to require
the compiler to prove termination of a given predicate or function, or
to give an error message if it cannot do so.
<p>The analyser is enabled by the option <code>--enable-termination</code>, which
can be abbreviated to <code>--enable-term</code>. When termination analysis
is enabled, any predicates or functions with a <code>check_termination</code>
pragma defined on them will have their termination checked, and if
termination cannot be proved, the compiler will emit an error message
detailing the reason that termination could not be proved.
<p>The option <code>--check-termination</code> option, which may be abbreviated
to <code>--check-term</code> or <code>--chk-term</code>, forces the compiler to
check the termination of all predicates in the module.
It is common for the compiler to be unable to prove termination of some
predicates and functions because they call other predicates which could
not be proved to terminate or because they use language features (such
as higher order calls) which cannot be usefully analysed.
In this case, the compiler only emits a warning for these
predicates and functions if the <code>--verbose-check-termination</code>
option is enabled. For every predicate or function that the compiler
cannot prove the termination of, a warning message is emitted, but
compilation continues. The <code>--check-termination</code> option implies
the <code>--enable-termination</code> option.
<p>The accuracy of the termination analysis is substantially degraded if
intermodule optimization is not enabled. Unless intermodule
optimization is enabled, the compiler must assume that any imported
predicate may not terminate.
<p>Currently the compiler assumes that all procedures defined using the C
interface (<code>pragma c_code</code>) terminate for all input.
If this is not the case, a <code>pragma does_not_terminate</code> declaration
should be used to inform the compiler that this C code may not terminate.
<p>The following declarations can be used to inform the compiler of the
termination properties of a predicate or function, or to force the
compiler to prove termination of a given predicate or function.
<br><pre>:- pragma terminates(<var>Name</var>/<var>Arity</var>).
</pre>
<p>This declaration may be used to inform the compiler that this predicate
or function is guaranteed to terminate for any input. This is useful
when the compiler cannot prove termination of some predicates or
functions which are in turn preventing the compiler from proving
termination of other predicates or functions. This declaration
affects not only the predicate specified but also
any other predicates that are mutually recursive with it.
<br><pre>:- pragma does_not_terminate(<var>Name</var>/<var>Arity</var>).
</pre>
<p>This declaration may be used to inform the compiler that this predicate
does not necessarily terminate. This is useful for procedures defined
using the C interface, which the compiler assumes to terminate by
default. This declaration affects not only the predicate specified
but also any other predicates that are mutually recursive with it.
<br><pre>:- pragma check_termination(<var>Name</var>/<var>Arity</var>).
</pre>
<p>This pragma forces the compiler to prove termination of this predicate.
If it cannot prove the termination of the specified predicate or
function then the compiler will quit with an error message.
<p><hr>
Node:<a name="Aditi%20deductive%20database%20interface">Aditi deductive database interface</a>,
Previous:<a rel=previous href="#Termination%20analysis">Termination analysis</a>,
Up:<a rel=up href="#Implementation-dependent%20extensions">Implementation-dependent extensions</a>
<br>
<h3>Aditi deductive database interface</h3>
<ul>
<li><a href="#Aditi%20overview">Aditi overview</a>:
<li><a href="#Aditi%20pragma%20declarations">Aditi pragma declarations</a>: Controlling Aditi compilation.
<li><a href="#Aditi%20update%20syntax">Aditi update syntax</a>: Changing the contents of Aditi relations.
<li><a href="#Aditi%20glossary">Aditi glossary</a>: Glossary of Aditi terms.
</ul>
<p><hr>
Node:<a name="Aditi%20overview">Aditi overview</a>,
Next:<a rel=next href="#Aditi%20pragma%20declarations">Aditi pragma declarations</a>,
Up:<a rel=up href="#Aditi%20deductive%20database%20interface">Aditi deductive database interface</a>
<br>
<h4>Aditi overview</h4>
<p>The University of Melbourne Mercury implementation includes support for
compiling Mercury predicates for bottom-up evaluation using the Aditi2
deductive database system. The Aditi system is not yet publicly available,
so this is currently not very useful to anyone other than the Mercury and
Aditi developers. For more information see the Aditi web site
at <http://www.cs.mu.oz.au/aditi>.
<p>Evaluation by a deductive database system is useful for predicates which
use large amounts of data, since the database system can use efficient join
algorithms instead of backtracking. Also, some predicates which loop when
executed top-down may terminate when executed bottom-up by the database (this
effect can also be achieved using tabling (see <a href="#Tabled%20evaluation">Tabled evaluation</a>)).
Bottom-up evaluation computes the answers to a predicate a set at a time,
rather than a tuple at a time as in the normal top-down execution of a
Mercury program.
<p>There are several restrictions on predicates to be evaluated using Aditi.
Argument types may not include polymorphic, higher-order or abstract types.
Type classes are not supported within database predicates. The argument
modes must not contain partially instantiated insts. Aditi predicates must
be stratified (see <a href="#Aditi%20glossary">Aditi glossary</a>) and must not be mutually recursive
with predicates in other modules.
<p>Every predicate with a <code>pragma aditi</code> or
<code>pragma base_relation</code> declaration must have an input
argument of type <code>aditi__state</code>. This ensures that Aditi predicates
are only called from within transactions and that updates and database
calls are ordered correctly, in the same way that <code>io__state</code> arguments
are used to ensure ordering of I/O operations. Within the clauses for
predicates with a <code>pragma aditi</code> declaration variables with
type <code>aditi__state</code> may only be passed to other database predicates --
they may not be packaged into terms or passed to top-down Mercury predicates.
This allows the compiler to remove all instances of <code>aditi__state</code>
variables from database predicates, and enforces the restriction that
top-down Mercury code called from within the database cannot call bottom-up
code, which is currently impossible for Aditi to handle.
<p>Some useful predicates are defined in <code>$ADITI_HOME/doc/aditi.m</code>
in the Aditi distribution.
<p>The Aditi interface currently has the major restriction that recursive or
imported top-down Mercury predicates or functions cannot be called from
predicates with <code>pragma aditi</code> declarations.
The following predicates and functions from the standard library
can be called from Aditi:
<p><code>builtin__compare/3</code>,
<p><code>int:'<'/2</code>,
<code>int:'>'/2</code>,
<code>int:'=<'/2</code>,
<code>int:'>='/2</code>,
<code>int__abs/2</code>,
<code>int__max/3</code>,
<code>int__min/3</code>,
<code>int__to_float/2</code>,
<code>int__pow/2</code>,
<code>int__log2/2</code>,
<code>int:'+'/2</code>,
<code>int:'+'/1</code>,
<code>int:'-'/2</code>,
<code>int:'-'/1</code>,
<code>int:'*'/2</code>,
<code>int:'//'/2</code>,
<code>int__rem/2</code>,
<p><code>float:'<'/2</code>,
<code>float:'>'/2</code>,
<code>float:'>='/2</code>,
<code>float:'=<'/2</code>,
<code>float__abs/1</code>,
<code>float__abs/2</code>,
<code>float__max/2</code>,
<code>float__max/3</code>,
<code>float__min/2</code>,
<code>float__min/3</code>,
<code>float__pow/2</code>,
<code>float__log2/2</code>,
<code>float__float/1</code>,
<code>float__truncate_to_int/1</code>,
<code>float__truncate_to_int/2</code>,
<code>float:'+'/2</code>,
<code>float:'+'/1</code>,
<code>float:'-'/2</code>,
<code>float:'-'/1</code>,
<code>float:'*'/2</code>,
<code>float:'/'/2</code>,
<p><code>math__ceiling/1</code>,
<code>math__round/1</code>,
<code>math__floor/1</code>,
<code>math__sqrt/1</code>,
<code>math__pow/2</code>,
<code>math__exp/1</code>,
<code>math__ln/1</code>,
<code>math__log10/1</code>,
<code>math__log2/1</code>,
<code>math__sin/1</code>,
<code>math__cos/1</code>,
<code>math__tan/1</code>,
<code>math__asin/1</code>,
<code>math__acos/1</code>,
<code>math__atan/1</code>,
<code>math__sinh/1</code>,
<code>math__cosh/1</code>,
<code>math__tanh/1</code>,
<p><code>string__length/2</code>.
<p><hr>
Node:<a name="Aditi%20pragma%20declarations">Aditi pragma declarations</a>,
Next:<a rel=next href="#Aditi%20update%20syntax">Aditi update syntax</a>,
Previous:<a rel=previous href="#Aditi%20overview">Aditi overview</a>,
Up:<a rel=up href="#Aditi%20deductive%20database%20interface">Aditi deductive database interface</a>
<br>
<h4>Aditi pragma declarations</h4>
<p>The following pragma declarations control compilation of Aditi predicates.
<br><pre>:- pragma aditi(<var>Name</var>/<var>Arity</var>).
</pre>
<p>This predicate should be evaluated using the Aditi deductive database.
<br><pre>:- pragma base_relation(<var>Name</var>/<var>Arity</var>).
</pre>
<p>This predicate is an Aditi base relation.
<br><pre>:- pragma supp_magic(<var>Name</var>/<var>Arity</var>).
:- pragma context(<var>Name</var>/<var>Arity</var>).
</pre>
<p>Perform either the supplementary magic sets or context transformations.
One of these transformations must be performed on every Aditi predicate.
<code>supp_magic</code> is the default.
There are restrictions on predicates to which the context transformation
can be applied; these are described in <cite>Right-, left-, and multi-linear
rule transformations that maintain context information.</cite> See <a href="#%5b6%5d">[6]</a>.
<br><pre>:- pragma naive(<var>Name</var>/<var>Arity</var>).
:- pragma psn(<var>Name</var>/<var>Arity</var>).
</pre>
<p>Specify naive or predicate semi-naive evaluation (see <a href="#Aditi%20glossary">Aditi glossary</a>)
for the predicate.
<code>psn</code> is the default.
<br><pre>:- pragma aditi_memo(<var>Name</var>/<var>Arity</var>).
:- pragma aditi_no_memo(<var>Name</var>/<var>Arity</var>).
</pre>
<p>The Aditi deductive database can store the results of procedures within
a transaction to avoid unnecessary recomputations. This is unrelated to
the type of memoing described in <a href="#Tabled%20evaluation">Tabled evaluation</a>.
<code>aditi_no_memo</code> is the default.
Memoing is not yet implemented, so any <code>pragma aditi_memo</code>
declarations will be ignored.
<br><pre>:- pragma owner(<var>Name</var>/<var>Arity</var>, <var>UserName</var>).
</pre>
<p>The predicate is owned by the named user. A predicate in the database
is identified by owner, module name, predicate name and arity. The owner
field is used for security checks. If no <code>pragma owner</code>
declaration is given, the owner is taken from the <code>--aditi-user</code>
option, which defaults to the value of the environment variable <code>USER</code>,
or "guest" if that is not set.
<br><pre>:- pragma aditi_index(<var>Name</var>/<var>Arity</var>, <var>IndexType</var>, <var>Attributes</var>).
</pre>
<p>The base relation has the given B-tree index. B-tree indexes allow efficient
retrieval of a tuple or range of tuples from a base relation.
<code><var>IndexType</var></code> must be one of <code>unique_B_tree</code> or
<code>non_unique_B_tree</code>. <code><var>Attributes</var></code> is a list of argument
numbers (argument numbers are counted from one).
<p><hr>
Node:<a name="Aditi%20update%20syntax">Aditi update syntax</a>,
Next:<a rel=next href="#Aditi%20glossary">Aditi glossary</a>,
Previous:<a rel=previous href="#Aditi%20pragma%20declarations">Aditi pragma declarations</a>,
Up:<a rel=up href="#Aditi%20deductive%20database%20interface">Aditi deductive database interface</a>
<br>
<h4>Aditi update syntax</h4>
<p>The Melbourne Mercury compiler provides special syntax to specify updates
of Aditi base relations.
<p>Note: Only error checking is implemented for Aditi updates -- no code is
generated yet.
<ul>
<li><a href="#Aditi%20update%20notes">Aditi update notes</a>:
<li><a href="#Insertion%20and%20deletion">Insertion and deletion</a>:
<li><a href="#Bulk%20insertion%20and%20deletion">Bulk insertion and deletion</a>:
<li><a href="#Modification">Modification</a>:
</ul>
<p><hr>
Node:<a name="Aditi%20update%20notes">Aditi update notes</a>,
Next:<a rel=next href="#Insertion%20and%20deletion">Insertion and deletion</a>,
Up:<a rel=up href="#Aditi%20update%20syntax">Aditi update syntax</a>
<br>
<h5>Aditi update notes</h5>
<p>All Aditi update goals have determinism <code>det</code>.
<p>There must be a <code>pragma base_relation</code> declaration for
any relation to be updated.
<p>It is currently up to the application to ensure that any modifications
do not violate the determinism of a base relation. If any modification
does violate the determinism of a base relation, then the behaviour
is undefined. However, updates of relations with unique B-tree indexes
are checked to ensure that a key is not given multiple values. The transaction
will abort if this occurs.
<p>Predicate and function names in Aditi update goals may be module qualified.
<p>The examples make use of the following declarations:
<br><pre>:- pred p(aditi__state::aditi_mui, int::out, int::out) is nondet.
:- pragma base_relation(p/3).
:- func f(aditi__state::aditi_mui, int::out) = (int::out) is nondet.
:- pragma base_relation(f/2).
:- pred ancestor(aditi__state::aditi_mui, int::out, int::out) is nondet.
:- pragma aditi(ancestor/3).
</pre>
<p><hr>
Node:<a name="Insertion%20and%20deletion">Insertion and deletion</a>,
Next:<a rel=next href="#Bulk%20insertion%20and%20deletion">Bulk insertion and deletion</a>,
Previous:<a rel=previous href="#Aditi%20update%20notes">Aditi update notes</a>,
Up:<a rel=up href="#Aditi%20update%20syntax">Aditi update syntax</a>
<br>
<h5>Insertion and deletion</h5>
<br><pre>aditi_insert(<var>PredName</var>(<var>Arg1</var>, <var>Arg2</var>, <small>...</small>), <var>DB0</var>, <var>DB</var>).
aditi_insert(<var>FuncName</var>(<var>Arg1</var>, <var>Arg2</var>, <small>...</small>) = <var>RetVal</var>, <var>DB0</var>, <var>DB</var>).
</pre>
<br><p>
<p>Insert the specified tuple into a relation.
<br><p>
<br><pre>aditi_delete(<var>PredName</var>(<var>Arg1</var>, <var>Arg2</var>, <small>...</small>), <var>DB0</var>, <var>DB</var>).
aditi_delete(<var>FuncName</var>(<var>Arg1</var>, <var>Arg2</var>, <small>...</small>) = <var>RetVal</var>, <var>DB0</var>, <var>DB</var>).
</pre>
<br><p>
<p>Delete the specified tuple from a relation.
<br><p>
<ul>
<li><code><var>PredName</var></code> must be the name of a predicate.
<li><code><var>FuncName</var></code> must be the name of a function.
<li><code><var>Arg1</var></code>, <code><var>Arg2</var></code>, <small>...</small> and <code><var>RetVal</var></code>
must be data-terms.
<p>The tuple to be inserted must have the same type signature as the relation
being inserted into. All the arguments of the tuple (including the return value
of a function) have mode <code>in</code>, except the <code>aditi__state</code> argument
which has mode <code>unused</code>.
</p><li><code><var>DB0</var></code> and <code><var>DB</var></code> must be data-terms of type
<code>aditi__state</code>. They have mode <code>aditi_di, aditi_uo</code>.
</ul>
<br><p>
<p>Note that <code><var>PredName</var>(<var>Arg1</var>, <var>Arg2</var>, <small>...</small>)</code>
in an <code>aditi_insert</code> or <code>aditi_delete</code> goal is not a
higher-order term.
<code>Pred = p(DB0, X, Y), aditi_insert(Pred, DB0, DB)</code>
is a syntax error.
<br><p>
<p>Examples:
<br><pre>insert_example_1(DB0, DB) :-
aditi_insert(p(_, 1, 2), DB0, DB).
insert_example_2(DB0, DB) :-
aditi_insert(f(_, 1) = 2, DB0, DB).
delete_example_1(DB0, DB) :-
aditi_delete(p(_, 1, 2), DB0, DB).
delete_example_2(DB0, DB) :-
aditi_delete(f(_, 1) = 2, DB0, DB).
</pre>
<p><hr>
Node:<a name="Bulk%20insertion%20and%20deletion">Bulk insertion and deletion</a>,
Next:<a rel=next href="#Modification">Modification</a>,
Previous:<a rel=previous href="#Insertion%20and%20deletion">Insertion and deletion</a>,
Up:<a rel=up href="#Aditi%20update%20syntax">Aditi update syntax</a>
<br>
<h5>Bulk insertion and deletion</h5>
<br><pre>aditi_bulk_insert((<var>PredName</var>(<var>Arg1</var>, <var>Arg2</var>, <small>...</small>) :- <var>Goal</var>), <var>DB0</var>, <var>DB</var>).
aditi_bulk_insert((<var>FuncName</var>(<var>Arg1</var>, <var>Arg2</var>, <small>...</small>) = <var>RetVal</var> :- <var>Goal</var>), <var>DB0</var>, <var>DB</var>).
aditi_bulk_insert(<var>PredOrFunc</var> <var>Name</var>/<var>Arity</var>, <var>Closure</var>, <var>DB0</var>, <var>DB</var>).
</pre>
<br><p>
<p>Insert all solutions of <code><var>Goal</var></code> or <code><var>Closure</var></code> into
the named relation.
<br><p>
<br><pre>aditi_bulk_delete((<var>PredName</var>(<var>Arg1</var>, <var>Arg2</var>, <small>...</small>) :- <var>Goal</var>), <var>DB0</var>, <var>DB</var>).
aditi_bulk_delete((<var>FuncName</var>(<var>Arg1</var>, <var>Arg2</var>, <small>...</small>) = <var>RetVal</var> :- <var>Goal</var>), <var>DB0</var>, <var>DB</var>).
aditi_bulk_delete(<var>PredOrFunc</var> <var>Name</var>/<var>Arity</var>, <var>Closure</var>, <var>DB0</var>, <var>DB</var>).
</pre>
<br><p>
<p>Delete all solutions of <code><var>Goal</var></code> or <code><var>Closure</var></code>
from the named relation.
<br><p>
<ul>
<li><code><var>PredOrFunc</var></code> must be either <code>pred</code> or <code>func</code>.
If it is <code>pred</code>, then <code><var>Name</var></code> must be the name of
a predicate, and if it is <code>func</code>, then <code><var>Name</var></code>
must be the name of a function.
<li><code><var>Arity</var></code> must be the arity of the predicate or function
being updated.
<li><code><var>Goal</var></code> must be a Mercury goal.
<li><code><var>Closure</var></code> must be a data-term which has a higher-order type with
the same type signature as the base relation being updated.
<p>The <code>aditi__state</code> argument of <code><var>Closure</var></code> must have
mode <code>aditi_mui</code>. All other arguments must have mode <code>out</code>.
The determinism of <code><var>Closure</var></code> must be <code>nondet</code>.
<p><code><var>Closure</var></code> must be evaluable bottom-up by the Aditi
system -- the predicate or function passed must have a
<code>pragma aditi</code> declaration. Lambda expressions can be
marked as evaluable by Aditi using an <code>aditi_bottom_up</code> annotation
on the lambda expression.
</p><li><code><var>DB0</var></code> and <code><var>DB</var></code> must be data-terms of type
<code>aditi__state</code>. They have mode <code>aditi_di, aditi_uo</code>.
</ul>
<br><p>
<p>The form
<br><pre>aditi_bulk_insert((<var>PredName</var>(<var>DB1</var>, <var>Arg2</var>, <small>...</small>) :- <var>Goal</var>), <var>DB0</var>, <var>DB</var>).
</pre>
<p>is equivalent to
<br><pre>Closure = (aditi_bottom_up
pred(<var>DB1</var>::aditi_mui, <var>Arg2</var>::out, <small>...</small>) is nondet :- <var>Goal</var>),
aditi_bulk_insert(<var>PredOrFunc</var> <var>Name</var>/<var>Arity</var>, <var>Closure</var>, <var>DB0</var>, <var>DB</var>).
</pre>
<p>and likewise for the function version. For instance, the examples
bulk_insert_example_1, bulk_insert_example_2 and bulk_insert_example_3
below are all equivalent.
<p>Similarly, the form
<br><pre>aditi_bulk_delete((<var>PredName</var>(<var>Arg1</var>, <var>Arg2</var>, <small>...</small>) :- <var>Goal</var>), <var>DB0</var>, <var>DB</var>).
</pre>
<p>is equivalent to
<br><pre>DeleteClosure = (aditi_bottom_up
pred(<var>DB1</var>::aditi_mui, <var>Arg2</var>::out, <small>...</small>) is nondet :-
<var>PredName</var>(<var>DB1</var>, <var>Arg2</var>, <small>...</small>),
<var>Goal</var>
),
aditi_bulk_delete(<var>PredOrFunc</var> <var>Name</var>/<var>Arity</var>, <var>Closure</var>, <var>DB0</var>, <var>DB</var>).
</pre>
<p>and likewise for the function version. For instance
bulk_delete_example_1 and bulk_delete_example_2 below are equivalent.
<br><p>
<br><p>
<p>Examples:
<br><pre>bulk_insert_example_1(DB0, DB) :-
aditi_bulk_insert(p(DB1, X, Y) :- ancestor(DB1, X, Y), DB0, DB).
bulk_insert_example_2(DB0, DB) :-
aditi_bulk_insert(pred p/3, ancestor, DB0, DB).
bulk_insert_example_3(DB0, DB) :-
InsertP = (aditi_bottom_up
pred(DB1::aditi_mui, X::out, Y::out) is nondet :-
ancestor(DB1, X, Y)
),
aditi_bulk_insert(pred p/3, InsertP, DB0, DB).
bulk_delete_example_1 -->
aditi_bulk_delete(
(p(DB1, X, _) :-
X > 1,
X < 5
)).
bulk_delete_example_2(DB0, DB) :-
DeleteP = (aditi_bottom_up
pred(DB1::aditi_mui, X::out, Y::out) is nondet :-
p(DB1, X, Y),
X > 1,
X < 5
),
aditi_bulk_delete(DeleteP, DB0, DB).
bulk_delete_example_3(DB0, DB) :-
aditi_bulk_delete(f(DB1, X) = _Y :- X = 1, DB0, DB).
bulk_delete_example_4(DB0, DB) :-
DeleteQ = (aditi_bottom_up
func(DB1::aditi_mui, X::out) = (Y::out) is nondet :-
q(DB1, X) = Y,
X > 1,
X < 5
),
aditi_bulk_delete(func f/2, DeleteQ, DB0, DB).
</pre>
<p>The type of <code>InsertP</code> is
<code>aditi_bottom_up pred(aditi__state, int, int)</code>.
Its inst is <code>pred(aditi_mui, out, out) is nondet</code>,
as for a normal lambda expression.
<p>Note that in <code>bulk_delete_example_1</code> the extra set of parentheses around
the goal are needed, otherwise the second goal in the conjunction in the
deletion goal would be parsed as an extra argument
of the <code>aditi_bulk_delete</code> call, resulting in a syntax error.
<p><hr>
Node:<a name="Modification">Modification</a>,
Previous:<a rel=previous href="#Bulk%20insertion%20and%20deletion">Bulk insertion and deletion</a>,
Up:<a rel=up href="#Aditi%20update%20syntax">Aditi update syntax</a>
<br>
<h5>Modification</h5>
<br><pre>aditi_bulk_modify(
(<var>PredName</var>(<var>OldArg1</var>, <var>OldArg2</var>, <small>...</small>) ==>
<var>PredName</var>(<var>NewArg1</var>, <var>NewArg2</var>, <small>...</small>) :-
<var>Goal</var>
),
<var>DB0</var>, <var>DB</var>).
aditi_bulk_modify(
((<var>FuncName</var>(<var>OldArg1</var>, <var>OldArg2</var>, <small>...</small>) = <var>OldRetVal</var>) ==>
(<var>FuncName</var>(<var>NewArg1</var>, <var>NewArg2</var>, <small>...</small>) = <var>NewRetVal</var>) :-
<var>Goal</var>
),
<var>DB0</var>, <var>DB</var>).
aditi_bulk_modify(<var>PredOrFunc</var> <var>PredName</var>/<var>Arity</var>, <var>Closure</var>, <var>DB0</var>, <var>DB</var>).
</pre>
<br><p>
<p>Modify tuples for which <code><var>Goal</var></code> or <code><var>Closure</var></code> succeeds,
leaving any other tuples unchanged.
<br><p>
<ul>
<li><code><var>PredName</var></code> must be the name of a predicate.
<li><code><var>FuncName</var></code> must be the name of a function.
<li><code><var>PredOrFunc</var></code> must be either <code>pred</code> or <code>func</code>.
If it is <code>pred</code>, then <code><var>Name</var></code> must be the name of
a predicate, and if it is <code>func</code>, then <code><var>Name</var></code>
must be the name of a function.
<li><code><var>Arity</var></code> must be the arity of the predicate or function
being updated.
<li><code><var>OldArg1</var></code>, <code><var>OldArg2</var></code>, <small>...</small>, <code><var>OldRetVal</var></code>,
<code><var>NewArg1</var></code>, <code><var>NewArg2</var></code>, <small>...</small>, and <code><var>NewRetVal</var></code>
must be data-terms.
<p>The original tuple is given by the first set of arguments, which
have mode <code>out</code>. The updated tuple is given by the second set
of arguments, which have mode <code>out</code>. The <code>aditi__state</code>
argument for the original tuple has mode <code>aditi_mui</code>.
The <code>aditi__state</code> argument for the updated tuple has mode
<code>unused</code>.
<p>The argument types of each tuple must match the argument types
of the base relation being modified.
</p><li><code><var>Goal</var></code> must be a Mercury goal.
<li><code><var>Closure</var></code> must be a data-term which has a higher-order type.
<p>When modifying a predicate with type declaration
<code>:- pred p(aditi__state, <var>Type1</var>, <small>...</small>)</code>, <code><var>Closure</var></code>
must have type
<code>aditi_bottom_up pred(aditi__state, <var>Type1</var>, <small>...</small>, aditi__state, <var>Type1</var>, <small>...</small>)</code>,
and inst
<code>pred(aditi_mui, out, <small>...</small>, unused, out, <small>...</small>) is nondet</code>.
<p>When modifying a function with type declaration
<code>:- func p(aditi__state, <var>Type1</var>, <small>...</small>) = <var>Type2</var></code>,
<code><var>Closure</var></code> must have type
<code>aditi_bottom_up pred(aditi__state, <var>Type1</var>, <small>...</small>, <var>Type2</var>, aditi__state, <var>Type1</var>, <small>...</small>, <var>Type2</var>)</code>,
and inst
<code>pred(aditi_mui, out, <small>...</small>, out, unused, out, <small>...</small>, out) is nondet</code>.
<p>It is an error for the closure to return a solution for which the arguments
corresponding to the original tuple do not match a tuple in the relation
being modified.
</p><li><code><var>DB0</var></code> and <code><var>DB</var></code> must be data-terms of type
<code>aditi__state</code>. They have mode <code>aditi_di, aditi_uo</code>.
</ul>
<br><p>
<br><p>
<p>The forms using <code>==></code> can be considered as syntactic sugar for the
form using <var>PredOrFunc</var> <var>PredName</var>/<var>Arity</var>:
<br><pre>aditi_bulk_modify(
(<var>PredName</var>(<var>DB1</var>, <var>OldArg1</var>, <var>OldArg2</var>, <small>...</small>) ==>
<var>PredName</var>(<var>_DB</var>, <var>NewArg1</var>, <var>NewArg2</var>, <small>...</small>) :-
<var>Goal</var>
),
<var>DB0</var>, <var>DB</var>).
</pre>
<p>is equivalent to
<br><pre>ModifyClosure =
(aditi_bottom_up pred(<var>DB1</var>::aditi_mui, <var>OldArg1</var>::out, <var>OldArg2</var>::out, <small>...</small>,
<var>_DB</var>::unused, <var>NewArg1</var>::out, <var>NewArg2</var>::out, <small>...</small>) is nondet :-
<var>PredName</var>(<var>DB1</var>, <var>OldArg1</var>, <var>OldArg2</var>, <small>...</small>),
<var>Goal</var>
),
aditi_bulk_modify(pred <var>PredName</var>/<var>PredArity</var>, ModifyClosure, DB0, DB).
</pre>
<p>and likewise for the function version.
<p>The bulk modify operation
<br><pre>aditi_bulk_modify(pred p/3, Closure, DB0, DB).
</pre>
<p>is almost equivalent to a bulk delete followed by a bulk insert:
<br><pre>DeleteClosure =
(aditi_bottom_up pred(DB1::aditi_mui, X1::out, Y1::out) is nondet :-
Closure(DB1, X1, Y1, _, _)
),
InsertClosure =
(aditi_bottom_up pred(DB1::aditi_mui, X2::out, Y2::out) is nondet :-
Closure(DB1, _, _, X2, Y2)
),
aditi_bulk_delete(pred p/3, DeleteClosure, DB0, DB1),
aditi_bulk_insert(pred p/3, InsertClosure, DB1, DB).
</pre>
<p>However, they are not quite equivalent,
because in the bulk modify operation <var>InsertClosure</var>
is executed using the contents of <code>p/3</code> before the deletion
is applied.
<br><p>
<br><p>
<p>Examples:
<br><pre>bulk_modify_example_1(DB0, DB) :-
aditi_bulk_modify(
(p(DB1, X, Y0) ==> p(_DB, X, Y) :-
X > 2,
X < 5,
Y = Y0 + 1
), DB0, DB).
bulk_modify_example_2(DB0, DB) :-
aditi_bulk_modify(
(f(_DB0, X) = Y0 ==> f(_DB, X) = Y :-
X > 2, X < 5, Y = Y0 + 1
), DB0, DB).
bulk_modify_example_3(DB0, DB) :-
ModifyP = (aditi_bottom_up pred(DB1::aditi_mui, X::in, Y0::in,
_::unused, X::out, Y::out) is nondet :-
p(DB1, X, Y0),
X > 2,
X < 5,
Y = Y0 + 1
),
aditi_bulk_modify(pred p/3, ModifyP, DB0, DB).
bulk_modify_example_4(DB0, DB) :-
ModifyF = (aditi_bottom_up pred(DB1::aditi_mui, X::in, Y0::in,
_::unused, X::out, Y::out) is nondet :-
f(DB1, X) = Y0,
X > 2, X < 5, Y = Y0 + 1
),
aditi_bulk_modify(func f/2, ModifyQ, DB0, DB).
bulk_modify_example_5 -->
aditi_bulk_modify(
(p(_DB0, X, Y0) ==> p(_DB, X, Y) :-
X > 2, X < 5, Y = Y0 + 1
)).
</pre>
<p>Note that in <code>bulk_modify_example_5</code> the extra set of parentheses around
the goal are needed, otherwise the second and third goals in
the conjunction in the modification goal would be parsed as extra arguments
of the <code>aditi_bulk_modify</code> call, resulting in a syntax error.
<p>The type of <code>ModifyP</code> is
<code>aditi_bottom_up pred(aditi__state, int, int, aditi__state, int, int)</code>.
Its inst is <code>pred(aditi_mui, out, out, unused, out, out) is nondet</code>,
as for a normal lambda expression.
<p><hr>
Node:<a name="Aditi%20glossary">Aditi glossary</a>,
Previous:<a rel=previous href="#Aditi%20update%20syntax">Aditi update syntax</a>,
Up:<a rel=up href="#Aditi%20deductive%20database%20interface">Aditi deductive database interface</a>
<br>
<h4>Aditi glossary</h4>
<dl>
<br><dt>Aditi-RL
<dd>Aditi Relational Language is used by the Aditi system to execute queries.
The basic instructions in Aditi-RL are relational database operations such as
<code>join</code>, <code>select</code> and <code>project</code>.
<br><dt>aggregate
<dd>Aggregates are used to compute a value such as a sum over all the solutions
for a predicate. Aggregates can be computed over Aditi predicates using
<code>aditi__aggregate_compute_initial</code> defined in
<code>$ADITI_HOME/doc/aditi.m</code> in the Aditi distribution.
<br><dt>base relation
<dd>A base relation is a predicate consisting of a set of facts
stored in a database. There must be no clauses for a base relation.
<br><dt>derived relation
<dd>A derived relation is an Aditi predicate for which there are clauses.
Derived relations are compiled to Aditi-RL for execution by an Aditi database.
<br><dt>predicate semi-naive evaluation
<dd>When a recursive predicate is called, the Aditi system produces the set of all
solutions using fixed point iteration. The set of solutions is initialised
to those tuples which can be derived using the non-recursive rules of the
predicate. In each iteration, new tuples are derived for the predicate using
the recursive rules for the predicate and the tuples derived in previous
iterations. Evaluation finishes when no new tuples are generated.
Predicate semi-naive evaluation (see <a href="#%5b8%5d">[8]</a>) is a method of evaluating
recursive predicates which uses just the new tuples in each iteration
where possible. This improves efficiency by reducing the size of joins.
<br><dt>schema
<dd>A schema is a representation of the types of the attributes of a relation.
<br><dt>stratification
<dd>A program is stratified if no predicate can call itself through a negation
or an aggregate.
<br><dt>transaction
<dd>A transaction is a database operation which is executed atomically. If
part of a transaction fails, the database reverts to its original state
before the transaction. For details on how transactions are implemented
in Mercury, see <cite>Database transactions in a purely declarative logic
programming language</cite> <a href="#%5b7%5d">[7]</a> and <code>$ADITI_HOME/doc/aditi.m</code> in the
Aditi distribution.
</dl>
<p><hr>
Node:<a name="Bibliography">Bibliography</a>,
Previous:<a rel=previous href="#Implementation-dependent%20extensions">Implementation-dependent extensions</a>,
Up:<a rel=up href="#Top">Top</a>
<br>
<h2>Bibliography</h2>
<ul>
<li><a href="#%5b1%5d">[1]</a>: Spiers, Somogyi, and Sondergaard,
<cite>Termination Analysis for Mercury</cite>.
<li><a href="#%5b2%5d">[2]</a>: Groger and Plumer, <cite>Handling of mutual recursion in
automatic termination proofs for logic programs</cite>.
<li><a href="#%5b3%5d">[3]</a>: Spiers, <cite>Termination Analysis for logic programs</cite>.
<li><a href="#%5b4%5d">[4]</a>: Sagonas, <cite>The SLG-WAM: A Search-Efficient Engine
for Well-Founded Evaluation of Normal Logic Programs</cite>.
<li><a href="#%5b5%5d">[5]</a>: Demoen and Sagonas, <cite>CAT: the copying approach to tabling</cite>.
<p>
</p><li><a href="#%5b6%5d">[6]</a>: Kemp, Ramamohanarao and Somogyi,
<cite>Right-, left-, and multi-linear rule transformations
that maintain context information</cite>.
<li><a href="#%5b7%5d">[7]</a>: Kemp, Conway, Harris, Henderson, Ramamohanarao and Somogyi
<cite>Database transactions in a purely declarative
logic programming language</cite>.
<li><a href="#%5b8%5d">[8]</a>: Ramakrishnan, Srivistava and Sudarshan,
<cite>Rule ordering in bottom-up fixpoint evaluation
of logic programs</cite>.
</ul>
<p><hr>
Node:<a name="%5b1%5d">[1]</a>,
Next:<a rel=next href="#%5b2%5d">[2]</a>,
Up:<a rel=up href="#Bibliography">Bibliography</a>
<br>
<h3>[1]</h3>
<p>Chris Speirs, Zoltan Somogyi and Harald Sondergaard, <cite>Termination
Analysis for Mercury</cite>. In P. Van Hentenryck, editor, <cite>Static
Analysis: Proceedings of the 4th International Symposium</cite>, Lecture
Notes in Computer Science. Springer, 1997. A longer version is
available for download from
<http://www.cs.mu.oz.au/publications/tr_db/mu_97_09.ps.gz>.
<p><hr>
Node:<a name="%5b2%5d">[2]</a>,
Next:<a rel=next href="#%5b3%5d">[3]</a>,
Previous:<a rel=previous href="#%5b1%5d">[1]</a>,
Up:<a rel=up href="#Bibliography">Bibliography</a>
<br>
<h3>[2]</h3>
<p>Gerhard Groger and Lutz Plumer, <cite>Handling of mutual recursion in
automatic termination proofs for logic programs.</cite> In K. Apt, editor,
<cite>The Proceedings of the Joint International Conference and Symposium on
Logic Programming</cite>, pages 336-350. MIT Press, 1992.
<p><hr>
Node:<a name="%5b3%5d">[3]</a>,
Next:<a rel=next href="#%5b4%5d">[4]</a>,
Previous:<a rel=previous href="#%5b2%5d">[2]</a>,
Up:<a rel=up href="#Bibliography">Bibliography</a>
<br>
<h3>[3]</h3>
<p>Chris Speirs, <cite>Termination Analysis for Logic Programs</cite>,
Technical Report 97/23, Department of Computer Science, The University
of Melbourne, Melbourne, Australia, 1997. Available from
<http://www.cs.mu.oz.au/mercury/papers/mu_97_23.ps.gz>.
<p><hr>
Node:<a name="%5b4%5d">[4]</a>,
Next:<a rel=next href="#%5b5%5d">[5]</a>,
Previous:<a rel=previous href="#%5b3%5d">[3]</a>,
Up:<a rel=up href="#Bibliography">Bibliography</a>
<br>
<h3>[4]</h3>
<p>K. Sagonas, <cite>The SLG-WAM: A Search-Efficient Engine
for Well-Founded Evaluation of Normal Logic Programs</cite>,
PhD thesis, SUNY at Stony Brook, 1996. Available from <br>
<http://www.cs.kuleuven.ac.be/~kostis/Thesis/thesis.ps.gz>.
<p><hr>
Node:<a name="%5b5%5d">[5]</a>,
Next:<a rel=next href="#%5b6%5d">[6]</a>,
Previous:<a rel=previous href="#%5b4%5d">[4]</a>,
Up:<a rel=up href="#Bibliography">Bibliography</a>
<br>
<h3>[5]</h3>
<p>B. Demoen and K. Sagonas, <cite>CAT: the copying approach to tabling</cite>,
submitted for publication,
Katholieke Universiteit Leuven, 1998.
<p><hr>
Node:<a name="%5b6%5d">[6]</a>,
Next:<a rel=next href="#%5b7%5d">[7]</a>,
Previous:<a rel=previous href="#%5b5%5d">[5]</a>,
Up:<a rel=up href="#Bibliography">Bibliography</a>
<br>
<h3>[6]</h3>
<p>David B. Kemp and Kotagiri Ramamohanarao and Zoltan Somogyi.
<cite>Right-, left-, and multi-linear rule transformations that maintain
context information</cite>,
The Proceedings of the Sixteenth Conference on Very Large Databases, pages
380-391, August 1990.
Available from <http://www.cs.mu.oz.au/mercury/papers/tr90-2.ps.gz>.
<p><hr>
Node:<a name="%5b7%5d">[7]</a>,
Next:<a rel=next href="#%5b8%5d">[8]</a>,
Previous:<a rel=previous href="#%5b6%5d">[6]</a>,
Up:<a rel=up href="#Bibliography">Bibliography</a>
<br>
<h3>[7]</h3>
<p>David B. Kemp, Thomas Conway, Evan Harris, Fergus Henderson,
Kotagiri Ramamohanarao and Zoltan Somogyi,
<cite>Database transactions in a purely declarative
logic programming language</cite>,
Technical Report 96/45, Department of Computer Science,
University of Melbourne, December 1996,
Available from <http://www.cs.mu.OZ.AU/publications/tr_db/mu_96_45.ps.gz>.
<p><hr>
Node:<a name="%5b8%5d">[8]</a>,
Previous:<a rel=previous href="#%5b7%5d">[7]</a>,
Up:<a rel=up href="#Bibliography">Bibliography</a>
<br>
<h3>[8]</h3>
<p>R. Ramakrishnan, D. Srivistava and S. Sudarshan,
<cite>Rule ordering in bottom-up fixpoint evaluation of logic programs</cite>.
In <cite>Proceedings of the Sixteenth International Conference on
Very Large Data Bases</cite>, page 359-371, August 1990.
<hr><h4>Footnotes</h4>
<ol type="1">
<li><a name="fn-1"></a>
<p>Operator term (see <a href="#Terms">Terms</a>).</p>
<li><a name="fn-2"></a>
<p>The type of an explicitly
type qualified term may be an instance of the type specified by the
qualifier. This allows explicit type qualifications to constrain the
types of two data-terms to be identical, without knowing the exact types
of the data-terms. It also allows type qualifications to refer to the
types of the results of existentially typed predicates or functions.</p>
<li><a name="fn-3"></a>
<p>If <var>equalitypred</var> is not an equivalence relation,
then the program is inconsistent: its declarative semantics
contains a contradiction, because the additional axioms for the user-defined
equality contradict the standard equality axioms. That implies that the
implementation may compute any answer at all (see <a href="#Semantics">Semantics</a>),
i.e. the behaviour of the program is undefined.</p>
</ol><hr>
</body></html>