1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931
|
\chapter{Modules} \label{sec:modules}
A Prolog module is a collection of predicates which defines a public
interface by means of a set of provided predicates and operators. Prolog
modules are defined by an ISO standard. Unfortunately, the standard is
considered a failure and, as far as we are aware, not implemented by any
concrete Prolog implementation. The SWI-Prolog module system syntax is
derived from the Quintus Prolog module system. The Quintus module system
has been the starting point for the module systems of a number of
mainstream Prolog systems, such as SICStus, Ciao and YAP. The underlying
primitives of the SWI-Prolog module system differ from the mentioned
systems. These primitives allow for multiple modules in a file,
hierarchical modules, emulation of other modules interfaces, etc.
This chapter motivates and describes the SWI-Prolog module system.
Novices can start using the module system after reading
\secref{defmodule} and \secref{import}. The primitives defined in these
sections suffice for basic usage until one needs to export predicates
that call or manage other predicates dynamically (e.g., use call/1,
assert/1, etc.). Such predicates are called \jargon{meta predicates} and
are discussed in \secref{metapred}. \Secref{overrule} to \secref{moduleop}
describe more advanced issues. Starting with \secref{importmodule}, we
discuss more low-level aspects of the SWI-Prolog module system that
are used to implement the visible module system, and can be used to
build other code reuse mechanisms.
\section{Why Use Modules?} \label{sec:whymodules}
In classic Prolog systems, all predicates are organised in a single
namespace and any predicate can call any predicate. Because each
predicate in a file can be called from anywhere in the program, it
becomes very hard to find the dependencies and enhance the
implementation of a predicate without risking to break the overall
application. This is true for any language, but even worse for
Prolog due to its frequent need for `helper predicates'.
A Prolog module encapsulates a set of predicates and defines an
\jargon{interface}. Modules can import other modules, which makes the
dependencies explicit. Given explicit dependencies and a well-defined
interface, it becomes much easier to change the internal organisation of
a module without breaking the overall application.
Explicit dependencies can also be used by the development environment.
The SWI-Prolog library \pllib{prolog_xref} can be used to analyse
completeness and consistency of modules. This library is used by the
built-in editor PceEmacs for syntax highlighting, jump-to-definition,
etc.
\section{Defining a Module} \label{sec:defmodule}
Modules are normally created by loading a \jargon{module file}. A module
file is a file holding a module/2 directive as its first term. The
module/2 directive declares the name and the public (i.e., externally
visible) predicates of the module. The rest of the file is loaded into
the module. Below is an example of a module file, defining reverse/2 and
hiding the helper predicate rev/3. A module can use all built-in
predicates and, by default, cannot redefine system predicates.
\begin{code}
:- module(reverse, [reverse/2]).
reverse(List1, List2) :-
rev(List1, [], List2).
rev([], List, List).
rev([Head|List1], List2, List3) :-
rev(List1, [Head|List2], List3).
\end{code}
The module is named \const{reverse}. Typically, the name of a module is
the same as the name of the file by which it is defined without the
filename extension, but this naming is not enforced. Modules are
organised in a single and flat namespace and therefore module names must
be chosen with some care to avoid conflicts. As we will see, typical
applications of the module system rarely use the name of a module
explicitly in the source text.
\begin{description}
\directive{module}{2}{+Module, +PublicList}
This directive can only be used as the first term of a source file. It
declares the file to be a \jargon{module file}, defining a module named
\arg{Module}. Note that a module name is an atom. The module exports the
predicates of \arg{PublicList}. \arg{PublicList} is a list of predicate
indicators (name/arity or name//arity pairs) or operator declarations
using the format \term{op}{Precedence, Type, Name}. Operators defined in
the export list are available inside the module as well as to modules
importing this module. See also \secref{operators}.
Compatible to Ciao Prolog, if \arg{Module} is unbound, it is unified
with the basename without extension of the file being loaded.
\directive{module}{3}{+Module, +PublicList, +Dialect}
Same as module/2. The additional \arg{Dialect} argument provides a list
of \jargon{language options}. Each atom in the list \arg{Dialect} is
mapped to a use_module/1 goal as given below. See also \secref{dialect}.
The third argument is supported for compatibility with the
\href{http://prolog-commons.org/}{Prolog Commons project}.
\begin{code}
:- use_module(library(dialect/LangOption)).
\end{code}
\end{description}
\section{Importing Predicates into a Module} \label{sec:import}
Predicates can be added to a module by \jargon{importing} them from
another module. Importing adds predicates to the namespace of a
module. An imported predicate can be called exactly the same as a
locally defined predicate, although its implementation remains part of
the module in which it has been defined.
Importing the predicates from another module is achieved using the
directives use_module/1 or use_module/2. Note that both directives take
\arg{filename(s)} as arguments. That is, modules are imported based on
their filename rather than their module name.
\begin{description}
\predicate{use_module}{1}{+Files}
Load the file(s) specified with \arg{Files} just like ensure_loaded/1.
The files must all be module files. All exported predicates from the
loaded files are imported into the module from which this predicate is
called. This predicate is equivalent to ensure_loaded/1, except that it
raises an error if \arg{Files} are not module files.
The imported predicates act as \jargon{weak symbols} in the module into
which they are imported. This implies that a local definition of a
predicate overrides (clobbers) the imported definition. If the flag
\prologflag{warn_override_implicit_import} is \const{true} (default), a
warning is printed. Below is an example of a module that uses
library(lists), but redefines flatten/2, giving it a totally different
meaning:
\begin{code}
:- module(shapes, []).
:- use_module(library(lists)).
flatten(cube, square).
flatten(ball, circle).
\end{code}
\noindent
Loading the above file prints the following message:
\begin{code}
Warning: /home/janw/Bugs/Import/t.pl:5:
Local definition of shapes:flatten/2
overrides weak import from lists
\end{code}
This warning can be avoided by (1) using use_module/2 to only import the
predicates from the \const{lists} library that are actually used in the `shapes' module, (2)
using the \exam{except([flatten/2])} option of use_module/2, (3) use
\exam{:- abolish(flatten/2).} before the local definition or (4) setting
\prologflag{warn_override_implicit_import} to \const{false}. Globally
disabling this warning is only recommended if overriding imported
predicates is common as a result of design choices or the program is
ported from a system that silently overrides imported predicates.
Note that it is always an error to import two modules with use_module/1
that export the same predicate. Such conflicts must be resolved with
use_module/2 as described above.
\predicate{use_module}{2}{+File, +ImportList}
Load \arg{File}, which must be a module file, and import the predicates
as specified by \arg{ImportList}. \arg{ImportList} is a list of
predicate indicators specifying the predicates that will be imported
from the loaded module. \arg{ImportList} also allows for renaming or
import-everything-except. See also the \const{import} option of
load_files/2. The first example below loads member/2 from the \const{lists}
library and append/2 under the name \const{list_concat}, which is how this
predicate is named in YAP. The second example loads all exports from
library \const{option} except for meta_options/3. These renaming facilities are
generally used to deal with portability issues with as few changes as possible
to the actual code. See also \secref{dialect} and
\secref{reexport}.
\begin{code}
:- use_module(library(lists), [ member/2,
append/2 as list_concat
]).
:- use_module(library(option), except([meta_options/3])).
\end{code}
\end{description}
In most cases a module is imported because some of its predicates are
being used. However, sometimes a module is imported for other
reasons, e.g., for its declarations. In such cases it is best
practice to use use_module/2 with empty ImportList. This
distinguishes an imported module that is used, although not for its
predicates, from a module that is needlessly imported.
The module/2, use_module/1 and use_module/2 directives are sufficient to
partition a simple Prolog program into modules. The SWI-Prolog graphical
cross-referencing tool gxref/0 can be used to analyse the dependencies
between non-module files and propose module declarations for each file.
\section{Controlled autoloading for modules} \label{sec:module-autoload}
SWI-Prolog by default support \jargon{autoloading} from its standard
library. Autoloading implies that when a predicate is found missing
during execution the library is searched and the predicate is imported
lazily using use_module/2. See \secref{autoload} for details.
The advantage of autoloading is that it requires less typing while it
reduces the startup time and reduces the memory footprint of an
application. It also allows moving old predicates or emulation thereof
the the module \pllib{backcomp} without affecting existing code. This
procedure keeps the libraries and system clean. We make sure that there
are not two modules that provide the same predicate as autoload
predicate.
Nevertheless, a disadvantage of this autoloader is that the dependencies
of a module on the libraries are not explicit and tooling such as
PceEmacs or gxref/0 are required to find these dependencies. Some users
want explicit control over which library predicates are accessed from
where, preferably by using use_module/2 which explicitly states which
predicates are imported from which library.\footnote{Note that built-in
predicates still add predicates for general use to all name spaces.}
Large applications typically contain source files that are not
immediately needed and often are not needed at all in many runs of the
program. This can be solved by creating an application-specific autoload
library, but with multiple parties providing autoloadable predicates the
maintenance becomes fragile. For these two reasons we added autoload/1
and autoload/2 that behave similar to use_module/1,2, but do not perform
the actual loading. The generic autoloader now proceeds as follows if
a missing predicate is encountered:
\begin{enumerate}
\item Check autoload/2 declarations. If one specifies the predicate,
import it using use_module/2.
\item Check autoload/1 declarations. If the specified file is loaded,
check its export list. Otherwise read the module declaration
of the target file to find the exports. If the target
predicate is found, import it using use_module/2.
\item Perform autoloading from the library if the \prologflag{autoload}
is \const{true}.
\end{enumerate}
\begin{description}
\predicate{autoload}{1}{:File}
\nodescription
\predicate{autoload}{2}{:File, +Imports}
Declare that possibly missing predicates in the module in which this
declaration occurs are to be resolved by using use_module/2 on
\arg{File} to (possibly) load the file and make the target predicate
available. The autoload/2 variant is tried before autoload/1. It is not
allowed for two autoload/2 declarations to provide the same predicate
and it is not allowed to define a predicate provided in this way
locally. See also require/1, which allows specifying predicates for
autoloading from their default location.
Predicates made available using autoload/2 behave as defined predicates,
which implies that any operation on them will perform autoloading if
necessary. Notably predicate_property/2, current_predicate/1 and
clause/2 are supported.
Currently, neither the existence of \arg{File}, nor whether it actually
exports the given predicates (autoload/2) is verified when the file is
loaded. Instead, the declarations are verified when searching for a
missing predicate.
If the Prolog flag \prologflag{autoload} is set to \const{false}, these
declarations are interpreted as use_module/1,2.
\end{description}
\section{Defining a meta-predicate}
\label{sec:metapred}
A meta-predicate is a predicate that calls other predicates dynamically,
modifies a predicate, or reasons about properties of a predicate. Such
predicates use either a compound term or a \jargon{predicate indicator}
to describe the predicate they address, e.g., \exam{assert(name(jan))}
or \exam{abolish(name/1)}. With modules, this simple schema no longer
works as each module defines its own mapping from name+arity to
predicate. This is resolved by wrapping the original description in a
term <module>:<term>, e.g., \exam{assert(person:name(jan))} or
\exam{abolish(person:name/1)}.
Of course, when calling assert/1 from inside a module, we expect to assert to
a predicate local to this module. In other words, we do not wish to
provide this \functor{:}{2} wrapper by hand. The meta_predicate/1
directive tells the compiler that certain arguments are terms that will
be used to look up a predicate and thus need to be wrapped (qualified)
with <module>:<term>, unless they are already wrapped.
In the example below, we use this to define maplist/3 inside a module.
The argument `2' in the meta_predicate declaration means that the
argument is module-sensitive and refers to a predicate with an arity
that is two more than the term that is passed in. The compiler only
distinguishes the values 0..9 and \chr{:}, which denote module-sensitive
arguments, from \chr{+}, \chr{-} and \chr{?}, which denote
\jargon{modes}. The values 0..9 are used by the
\jargon{cross-referencer} and syntax highlighting. Note that the
helper predicate \nopredref{maplist_}{3} does not need to be declared as
a meta-predicate because the maplist/3 wrapper already ensures that
\arg{Goal} is qualified as <module>:\arg{Goal}. See the description of
meta_predicate/1 for details.
\begin{code}
:- module(maplist, [maplist/3]).
:- meta_predicate maplist(2, ?, ?).
%% maplist(:Goal, +List1, ?List2)
%
% True if Goal can successfully be applied to all
% successive pairs of elements from List1 and List2.
maplist(Goal, L1, L2) :-
maplist_(L1, L2, Goal).
maplist_([], [], _).
maplist_([H0|T0], [H|T], Goal) :-
call(Goal, H0, H),
maplist_(T0, T, Goal).
\end{code}
\begin{description}
\prefixop{meta_predicate}{+Head, \ldots}
Define the predicates referenced by the comma-separated list \arg{Head}
as \jargon{meta-predicates}. Each argument of each head is a
\jargon{meta argument specifier}. Defined specifiers are given below.
Only 0..9, \chr{:} and \chr{^} are interpreted; the mode declarations
\chr{+}, \chr{-} and \chr{?} are ignored.
\begin{description}
\termitem{0..9}{}
The argument is a term that is used to reference a predicate
with $N$ more arguments than the given argument term. For
example: \exam{call(0)} or \exam{maplist(1, +)}.
\termitem{:}{}
The argument is module-sensitive, but does not directly refer
to a predicate. For example: \exam{consult(:)}.
\termitem{-}{}
The argument is not module-sensitive and unbound on entry.
\termitem{?}{}
The argument is not module-sensitive and the mode is unspecified.
\termitem{*}{}
The argument is not module-sensitive and the mode is unspecified.
The specification \chr{*} is equivalent to \chr{?}. It is accepted
for compatibility reasons. The predicate predicate_property/2 reports
arguments declared using \chr{*} with \chr{?}.
\termitem{+}{}
The argument is not module-sensitive and bound (i.e., nonvar)
on entry.
\termitem{^}{}
This extension is used to denote the possibly \verb$^$-annotated goal of
setof/3, bagof/3, aggregate/3 and aggregate/4. It is processed similar
to `0', but leaving the \chr{^}/2 intact.
\termitem{//}{}
The argument is a DCG body. See phrase/3.
\end{description}
Each argument that is module-sensitive (i.e., marked 0..9, \chr{:} or
\chr{^}) is qualified with the context module of the caller if it is not
already qualified. The implementation ensures that the argument is
passed as <module>:<term>, where <module> is an atom denoting the name
of a module and <term> itself is not a \functor{:}{2} term where the
first argument is an atom. Below is a simple declaration and a number of
queries.
\begin{code}
:- meta_predicate
meta(0, +).
meta(Module:Term, _Arg) :-
format('Module=~w, Term = ~q~n', [Module, Term]).
\end{code}
\begin{code}
?- meta(test, x).
Module=user, Term = test
?- meta(m1:test, x).
Module=m1, Term = test
?- m2:meta(test, x).
Module=m2, Term = test
?- m1:meta(m2:test, x).
Module=m2, Term = test
?- meta(m1:m2:test, x).
Module=m2, Term = test
?- meta(m1:42:test, x).
Module=42, Term = test
\end{code}
The meta_predicate/1 declaration is the portable mechanism for defining
meta-predicates and replaces the old SWI-Prolog specific mechanism
provided by the deprecated predicates module_transparent/1,
context_module/1 and strip_module/3. See also \secref{modulecompat}.
\end{description}
\section{Overruling Module Boundaries} \label{sec:overrule}
The module system described so far is sufficient to distribute programs
over multiple modules. There are, however, cases in which we would like
to be able to overrule this schema and explicitly call a predicate in
some module or assert explicitly into some module. Calling in a
particular module is useful for debugging from the user's top level or
to access multiple implementations of the same interface that reside in
multiple modules. Accessing the same interface from multiple modules
cannot be achieved using importing because importing a predicate with
the same name and arity from two modules results in a name conflict.
Asserting in a different module can be used to create models dynamically
in a new module. See \secref{dynamic-modules}.
Direct addressing of modules is achieved using a \functor{:}{2}
explicitly in a program and relies on the module qualification mechanism
described in \secref{metapred}. Here are a few examples:
\begin{code}
?- assert(world:done). % asserts done/0 into module world
?- world:asserta(done). % the same
?- world:done. % calls done/0 in module world
\end{code}
Note that the second example is the same due to the Prolog flag
\prologflag{colon_sets_calling_context}. The system predicate asserta/1
is called in the module \const{world}, which is possible because system
predicates are \jargon{visible} in all modules. At the same time, the
\jargon{calling context} is set to \const{world}. Because meta arguments
are qualified with the calling context, the resulting call is the same
as the first example.
\subsection{Explicit manipulation of the calling context}
\label{sec:set-calling-context}
Quintus' derived module systems have no means to separate the lookup
module (for finding predicates) from the calling context (for qualifying
meta arguments). Some other Prolog implementations (e.g., ECLiPSe and
IF/Prolog) distinguish these operations, using \functor{@}{2} for
setting the calling context of a goal. This is provided by SWI-Prolog,
currently mainly to support compatibility layers.
\begin{description}
\predicate{@}{2}{:Goal, +Module}
Execute \arg{Goal}, setting the calling context to \arg{Module}. Setting
the calling context affects meta-predicates, for which meta arguments
are qualified with \arg{Module} and transparent predicates (see
module_transparent/1). It has no implications for other predicates.
For example, the code \exam{asserta(done)@world} is the same as
\exam{asserta(world:done)}. Unlike in \exam{world:asserta(done)},
asserta/1 is resolved in the current module rather than the module
\const{world}. This makes no difference for system predicates, but
usually does make a difference for user predicates.
Not that SWI-Prolog does not define \chr{@} as an operator. Some
systems define this construct using \exam{op(900, xfx, @)}.
\end{description}
\section{Interacting with modules from the top level}
\label{sec:mtoplevel}
Debugging often requires interaction with predicates that reside in
modules: running them, setting spy points on them, etc. This can be
achieved using the <module>:<term> construct explicitly as described
above. In SWI-Prolog, you may also wish to omit the module
qualification. Setting a spy point (spy/1) on a plain predicate sets a
spy point on any predicate with that name in any module. Editing
(edit/1) or calling an unqualified predicate invokes the DWIM (Do What I
Mean) mechanism, which generally suggests the correct qualified query.
Mainly for compatibility, we provide module/1 to switch the module
with which the interactive top level interacts:
\begin{description}
\predicate{module}{1}{+Module}
The call \exam{module(\arg{Module})} may be used to switch the default
working module for the interactive top level (see prolog/0). This may
be used when debugging a module. The example below lists the clauses
of file_of_label/2 in the module \const{tex}.
\begin{code}
1 ?- module(tex).
true.
tex: 2 ?- listing(file_of_label/2).
...
\end{code}
\end{description}
\section{Composing modules from other modules}
\label{sec:reexport}
The predicates in this section are intended to create new modules from
the content of other modules. Below is an example to define a
\emph{composite} module. The example exports all public predicates
of \const{module_1}, \const{module_2} and \const{module_3}, pred/1
from \const{module_4}, all predicates from \const{module_5} except
do_not_use/1 and all predicates from \const{module_6} while renaming
pred/1 into mypred/1.
\begin{code}
:- module(my_composite, []).
:- reexport([ module_1,
module_2,
module_3
]).
:- reexport(module_4, [ pred/1 ]).
:- reexport(module_5, except([do_not_use/1])).
:- reexport(module_6, except([pred/1 as mypred])).
\end{code}
\begin{description}
\predicate{reexport}{1}{+Files}
Load and import predicates as use_module/1 and re-export all imported
predicates. The reexport declarations must immediately follow the module
declaration.
\predicate{reexport}{2}{+File, +Import}
Import from \arg{File} as use_module/2 and re-export the imported
predicates. The reexport declarations must immediately follow the module
declaration.
\end{description}
\section{Operators and modules}
\label{sec:moduleop}
Operators (\secref{operators}) are local to modules, where the initial
table behaves as if it is copied from the module \const{user} (see
\secref{resmodules}). A specific operator can be disabled inside a
module using \exam{:- op(0, Type, Name)}. Inheritance from the public
table can be restored using \exam{:- op(-1, Type, Name)}.
In addition to using the op/3 directive, operators can be declared in
the module/2 directive as shown below. Such operator declarations are
visible inside the module, and importing such a module makes the
operators visible in the target module. Exporting operators is typically
used by modules that implement sub-languages such as chr (see
\chapref{chr}). The example below is copied from the library
\pllib{clpfd}.
\begin{code}
:- module(clpfd,
[ op(760, yfx, #<==>),
op(750, xfy, #==>),
op(750, yfx, #<==),
op(740, yfx, #\/),
...
(#<==>)/2,
(#==>)/2,
(#<==)/2,
(#\/)/2,
...
]).
\end{code}
\section{Dynamic importing using import modules}
\label{sec:importmodule}
Until now we discussed the public module interface that is, at least to
some extent, portable between Prolog implementations with a module system
that is derived from Quintus Prolog. The remainder of this chapter
describes the underlying mechanisms that can be used to emulate other
module systems or implement other code-reuse mechanisms.
In addition to built-in predicates, imported predicates and locally
defined predicates, SWI-Prolog modules can also call predicates from its
\jargon{import modules}. Each module has a (possibly empty) list of
import modules. In the default setup, each new module has a single
import module, which is \const{user} for all normal user modules and
\const{system} for all system library modules. Module \const{user}
imports from \const{system} where all built-in predicates reside. These
special modules are described in more detail in \secref{resmodules}.
The list of import modules can be manipulated and queried using the
following predicates, as well as using set_module/1.
\begin{description}
\predicate[nondet]{import_module}{2}{+Module, -Import}
True if \arg{Module} inherits directly from \arg{Import}. All normal
modules only import from \const{user}, which imports from
\const{system}. The predicates add_import_module/3 and
delete_import_module/2 can be used to manipulate the import list.
See also default_module/2.
\predicate[multi]{default_module}{2}{+Module, -Default}
True if predicates and operators in \arg{Default} are visible in
\arg{Module}. Modules are returned in the same search order used for
predicates and operators. That is, \arg{Default} is first unified
with \arg{Module}, followed by the depth-first transitive closure
of import_module/2.
\predicate{add_import_module}{3}{+Module, +Import, +StartOrEnd}
If \arg{Import} is not already an import module for \arg{Module}, add
it to this list at the \const{start} or \const{end} depending on
\arg{StartOrEnd}. See also import_module/2 and delete_import_module/2.
\predicate{delete_import_module}{2}{+Module, +Import}
Delete \arg{Import} from the list of import modules for \arg{Module}.
Fails silently if \arg{Import} is not in the list.
\end{description}
One usage scenario of import modules is to define a module that is a
copy of another, but where one or more predicates have an alternative
definition.
\section{Reserved Modules and using the `user' module}
\label{sec:resmodules}
As mentioned above, SWI-Prolog contains two special modules. The first
one is the module \const{system}. This module contains all built-in
predicates. Module \const{system} has no import module. The second
special module is the module \const{user}. This module forms the initial
working space of the user. Initially it is empty. The import module of
module \const{user} is \const{system}, making all built-in predicates
available.
All other modules import from the module \const{user}. This implies they
can use all predicates imported into \const{user} without explicitly
importing them. If an application loads all modules from the
\const{user} module using use_module/1, one achieves a scoping system
similar to the C-language, where every module can access all exported
predicates without any special precautions.
\section{An alternative import/export interface}
\label{sec:altmoduleapi}
The use_module/1 predicate from \secref{import} defines import and
export relations based on the filename from which a module is loaded. If
modules are created differently, such as by asserting predicates into a
new module as described in \secref{dynamic-modules}, this interface
cannot be used. The interface below provides for import/export from
modules that are not created using a module file.
\begin{description}
\predicate{export}{1}{+PredicateIndicator, \ldots}
Add predicates to the public list of the context module. This implies
the predicate will be imported into another module if this module is
imported with use_module/[1,2]. Note that predicates are normally
exported using the directive module/2. export/1 is meant to handle
export from dynamically created modules.
\predicate{import}{1}{+PredicateIndicator, \ldots}
Import predicates \arg{PredicateIndicator} into the current context
module. \arg{PredicateIndicator} must specify the source module using
the \mbox{<module>:<pi>} construct. Note that predicates are
normally imported using one of the directives use_module/[1,2].
The import/1 alternative is meant for handling imports into dynamically
created modules. See also export/1 and export_list/2.
\end{description}
\section{Dynamic Modules} \label{sec:dynamic-modules}
So far, we discussed modules that were created by loading a
module file. These modules have been introduced to facilitate the
development of large applications. The modules are fully defined at
load-time of the application and normally will not change during
execution. Having the notion of a set of predicates as a
self-contained world can be attractive for other purposes as well.
For example, assume an application that can reason about multiple
worlds. It is attractive to store the data of a particular world in a
module, so we extract information from a world simply by invoking
goals in this world.
Dynamic modules can easily be created. Any built-in predicate that
tries to locate a predicate in a specific module will create this
module as a side-effect if it did not yet exist. For example:
\begin{code}
?- assert(world_a:consistent),
set_prolog_flag(world_a:unknown, fail).
\end{code}
These calls create a module called `world_a' and make the call
`world_a:consistent' succeed. Undefined predicates will not raise an
exception for this module (see \prologflag{unknown}).
Import and export from a dynamically created world can be achieved using
import/1 and export/1 or by specifying the import module as described in
\secref{importmodule}.
\begin{code}
?- world_b:export(solve/2). % exports solve/2 from world_b
?- world_c:import(world_b:solve/2). % and import it to world_c
\end{code}
\section{Transparent predicates: definition and context module}
\label{sec:ctxmodule}
\textit{The `module-transparent' mechanism is still underlying the
actual implementation. Direct usage by programmers is deprecated.
Please use meta_predicate/1 to deal with meta-predicates.}
The qualification of module-sensitive arguments
described in \secref{metapred} is realised using \jargon{transparent}
predicates. It is now deprecated to use this mechanism
directly. However, studying the underlying mechanism helps to
understand SWI-Prolog's modules. In some respect, the transparent
mechanism is more powerful than meta-predicate declarations.
Each predicate of the program is assigned a module, called its
\jargon{definition module}. The definition module of a predicate is
always the module in which the predicate was originally defined. Each
active goal in the Prolog system has a \jargon{context module} assigned
to it.
The context module is used to find predicates for a Prolog term. By
default, the context module is the definition module of the predicate
running the goal. For transparent predicates, however, this is the
context module of the goal inherited from the parent goal. Below, we
implement maplist/3 using the transparent mechanism. The code of
maplist/3 and \nopredref{maplist_}{3} is the same as in
\secref{metapred}, but now we must declare both the main predicate and
the helper as transparent to avoid changing the context module when
calling the helper.
\begin{code}
:- module(maplist, maplist/3).
:- module_transparent
maplist/3,
maplist_/3.
maplist(Goal, L1, L2) :-
maplist_(L1, L2, G).
maplist_([], [], _).
maplist_([H0|T0], [H|T], Goal) :-
call(Goal, H0, H),
maplist_(T0, T, Goal).
\end{code}
Note that \emph{any} call that translates terms into predicates is
subject to the transparent mechanism, not just the terms passed to
module-sensitive arguments. For example, the module below
counts the number of unique atoms returned as bindings for a variable.
It works as expected. If we use the directive
\exam{:- module_transparent count_atom_results/3.} instead,
atom_result/2 is called wrongly in the module \emph{calling}
\nopredref{count_atom_results}{3}. This can be solved using
strip_module/3 to create a qualified goal and a non-transparent helper
predicate that is defined in the same module.
\begin{code}
:- module(count_atom_results,
[ count_atom_results/3
]).
:- meta_predicate count_atom_results(-,0,-).
count_atom_results(A, Goal, Count) :-
setof(A, atom_result(A, Goal), As), !,
length(As, Count).
count_atom_results(_, _, 0).
atom_result(Var, Goal) :-
call(Goal),
atom(Var).
\end{code}
The following predicates support the module-transparent interface:
\begin{description}
\directive{module_transparent}{1}{+Preds}
\arg{Preds} is a comma-separated list of name/arity pairs (like
dynamic/1). Each goal associated with a transparent-declared predicate
will inherit the \jargon{context module} from its parent goal.
\predicate{context_module}{1}{-Module}
Unify \arg{Module} with the context module of the current goal.
context_module/1 itself is, of course, transparent.
\predicate{strip_module}{3}{+Term, -Module, -Plain}
Used in module-transparent predicates or meta-predicates to extract the referenced
module and plain term. If \arg{Term} is a module-qualified term, i.e.\
of the format \arg{Module}:\arg{Plain}, \arg{Module} and \arg{Plain}
are unified to these values. Otherwise, \arg{Plain} is unified to
\arg{Term} and \arg{Module} to the context module.
\end{description}
\section{Module properties} \label{sec:manipmodule}
The following predicates can be used to query the module system for
reflexive programming:
\begin{description}
\predicate[nondet]{current_module}{1}{?Module}
True if \arg{Module} is a currently defined module. This predicate
enumerates all modules, whether loaded from a file or created
dynamically. Note that modules cannot be destroyed in the current
version of SWI-Prolog.
\predicate{module_property}{2}{?Module, ?Property}
True if \arg{Property} is a property of \arg{Module}. Defined properties
are:
\begin{description}
\termitem{class}{-Class}
True when \arg{Class} is the class of the module. Defined
classes are
\begin{description}
\termitem{user}{}
Default for user-defined modules.
\termitem{system}{}
Module \const{system} and modules from \file{<home>/boot}.
\termitem{library}{}
Other modules from the system directories.
\termitem{temporary}{}
Module is temporary.
\termitem{test}{}
Modules that create tests.
\termitem{development}{}
Modules that only support the development environment.
\end{description}
\termitem{file}{?File}
True if \arg{Module} was loaded from \arg{File}.
\termitem{line_count}{-Line}
True if \arg{Module} was loaded from the N-th line of file.
\termitem{exports}{-ListOfPredicateIndicators}
True if \arg{Module} exports the given predicates. Predicate
indicators are in canonical form (i.e., always using name/arity
and never the DCG form name//arity). Future versions may also
use the DCG form. See also predicate_property/2. Succeeds with
an empty list if the module exports no predicates.
\termitem{exported_operators}{-ListOfOperators}
True if \arg{Module} exports the given operators. Each exported
operator is represented as a term \term{op}{Pri,Assoc,Name}.
Succeeds with an empty list if the module exports no operators.
\termitem{size}{-Bytes}
Total size in bytes used to represent the module. This includes
the module itself, its (hash) tables and the summed size of
all predicates defined in this module. See also
the \term{size}{Bytes} property in predicate_property/2.
\termitem{program_size}{-Bytes}
Memory (in bytes) used for storing the predicates of this
module. This figure includes the predicate header and clauses.
\termitem{program_space}{-Bytes}
If present, this number limits the \const{program_size}. See
set_module/1.
\termitem{last_modified_generation}{-Generation}
Integer expression the last database generation where a clause
was added or removed from a predicate that is implemented in
this module. See also predicate_property/2.
\end{description}
\predicate{set_module}{1}{:Property}
Modify properties of the module. Currently, the following properties
may be modified:
\begin{description}
\termitem{base}{+Base}
Set the default import module of the current module to \arg{Module}.
Typically, \arg{Module} is one of \const{user} or \const{system}. See
\secref{importmodule}.
\termitem{class}{+Class}
Set the class of the module. See module_property/2.
\termitem{program_space}{+Bytes}
Maximum amount of memory used to store the predicates defined inside the
module. Raises a permission error if the current usage is above the
requested limit. Setting the limit to 0 (zero) removes the limit. An
attempt to assert clauses that causes the limit to be exceeded causes a
\term{resource_error}{program_space} exception. See assertz/1 and
module_property/2.
\end{description}
\end{description}
\section{Compatibility of the Module System} \label{sec:modulecompat}
The SWI-Prolog module system is largely derived from the Quintus Prolog
module system, which is also adopted by SICStus, Ciao and YAP.
Originally, the mechanism for defining meta-predicates in SWI-Prolog was
based on the module_transparent/1 directive and strip_module/3. Since
5.7.4 it supports the de-facto standard meta_predicate/1 directive for
implementing meta-predicates, providing much better compatibility.
The support for the meta_predicate/1 mechanism, however, is considerably
different. On most systems, the \emph{caller} of a meta-predicate is
compiled differently to provide the required <module>:<term>
qualification. This implies that the meta-declaration must be available
to the compiler when compiling code that calls a meta-predicate. In
practice, this implies that other systems pose the following
restrictions on meta-predicates:
\begin{itemize}
\item Modules that provide meta-predicates for a module to be compiled
must be loaded explicitly by that module.
\item The meta-predicate directives of exported predicates must follow
the module/2 directive immediately.
\item After changing a meta-declaration, all modules that \emph{call}
the modified predicates need to be recompiled.
\end{itemize}
In SWI-Prolog, meta-predicates are also \jargon{module-transparent}, and
qualifying the module-sensitive arguments is done inside the
meta-predicate. As a result, the caller need not be aware that it is
calling a meta-predicate and none of the above restrictions hold for
SWI-Prolog. However, code that aims at portability must obey the above
rules.
Other differences are listed below.
\begin{itemize}
\item
If a module does not define a predicate, it is searched for in the
\jargon{import modules}. By default, the import module of any
user-defined module is the \const{user} module. In turn, the
\const{user} module imports from the module \const{system} that provides
all built-in predicates. The auto-import hierarchy can be changed
using add_import_module/3 and delete_import_module/2.
This mechanism can be used to realise a simple object-oriented system
or a hierarchical module system.
\item
Operator declarations are local to a module and may be exported. In
Quintus and SICStus all operators are global. YAP and Ciao also use
local operators. SWI-Prolog provides global operator declarations
from within a module by explicitly qualifying the operator name with
the \const{user} module. I.e., operators are inherited from the
\jargon{import modules} (see above).
\begin{code}
:- op(precedence, type, user:(operatorname)).
\end{code}
\end{itemize}
|