<< Prev | - Up - | Next >> |
Now, imagine that you are writing a program that needs two predicates, let's say pred1/2
and pred2/2
. You have a definition for pred1
in the file preds1.pl
and a definition of pred2
in the file preds2.pl
. No problem, you think, I'll just load them into my program by putting
:- [preds1, preds2].
at the top of the file. Unfortunately, there seem to be problems this time. You get a message that looks something like the following:
{consulting /a/troll/export/home/MP/kris/preds1.pl...}
{/a/troll/export/home/MP/kris/preds1.pl consulted, 10 msec 296 bytes}
{consulting /a/troll/export/home/MP/kris/preds2.pl...}
The procedure helperpred/2 is being redefined.
Old file: /a/troll/export/home/MP/kris/preds1.pl
New file: /a/troll/export/home/MP/kris/preds2.pl
Do you really want to redefine it? (y, n, p, or ?)
So what has happened? Well, it looks as if both files preds1.pl
and preds2.pl
are defining the predicate helperpred
. And what's worse, you can't be sure that the predicate is defined in the same way in both files. So, you can't just say "yes, override", since pred1
depends on the definition of helperpred
given in file preds1.pl
and pred2
depends on the definition given in file preds2.pl
. Furthermore, note that you are not really interested in the definition of helperpred
at all. You don't want to use it. The predicates that you are interested in, that you want to use are pred1
and pred2
. They need definitions of helperpred
, but the rest of your program doesn't.
A solution to this problem is to turn preds1.pl
and preds2.pl
into modules. Here is what this means and how it works:
Modules essentially allow you to hide predicate definitions. You are allowed to decide which predicates should be public, i.e. callable from other parts of the program, and which predicates should be private, i.e. callable only from within the module. You will not be able to call private predicates from outside the module in which they are defined, but there will also be no conflicts if two modules internally define the same predicate. In our example. helperpred
is a good candidate for becoming a private predicate, since it is only used as a helper predicate in the definition of pred1
and pred2
.
You can turn a file into a module by putting a module declaration at the top of that file. Module declarations are of the form
:- module(
ModuleName,
List_of_Predicates_to_be_Exported)
They specify the name of the module and the list of public predicates. That is, the list of predicates that one wants to export. These will be the only predicates that are accessible from outside the module.
So, by putting
:- module(preds1,[pred1/2]).
at the top of file preds1.pl
you can define the module preds1
which exports the predicate pred1/2
. And similarly, you can define the module preds2
exporting the predicate pred2/2
by putting
:- module(preds2,[pred2/3]).
at the top of file preds2.pl
. helperpred
is now hidden in the modules preds1
and preds2
, so that there is no clash when loading both modules at the same time.
Modules can be loaded with the inbuilt predicate use_module/1
. Putting :- use_module(preds1).
at the top of a file will import all predicates that were defined as public by the module. That means, all public predicates will be accessible.
If you don't need all public predicates of a module, but only some of them, you can use the two-place version of use_module
, which takes the list of predicates that you want to import as its second argument. So, by putting
:- use_module(preds1,[pred1/2]),
use_module(preds2,[pred2/3]).
at the top of your file, you will be able to use pred1
and pred2
. Of course, you can only import predicates that are also exported by the relevant module.
<< Prev | - Up - | Next >> |