The current structure of the module system has been designed with 
some specific organisations for large programs in mind. Many large 
programs define a basic library layer on top of which the actual program 
itself is defined. The module user, acting as the default 
module for all other modules of the program can be used to distribute 
these definitions over all program module without introducing the need 
to import this common layer each time explicitly. It can also be used to 
redefine built-in predicates if this is required to maintain 
compatibility to some other Prolog implementation. Typically, the 
loadfile of a large application looks like this:
:- use_module(compatibility).   % load XYZ prolog compatibility
:- use_module(                  % load generic parts
        [ error                 % errors and warnings
        , goodies               % general goodies (library extensions)
        , debug                 % application specific debugging
        , virtual_machine       % virtual machine of application
        , ...                   % more generic stuff
        ]).
:- ensure_loaded(
        [ ...                   % the application itself
        ]).
The `use_module' declarations will import the public predicates from 
the generic modules into the user module. The 
`ensure_loaded' directive loads the modules that constitute the actual 
application. It is assumed these modules import predicates from each 
other using
use_module/[1,2] 
as far as necessary.
In combination with the object-oriented schema described below it is possible to define a neat modular architecture. The generic code defines general utilities and the message passing predicates (invoke/3 in the example below). The application modules define classes that communicate using the message passing predicates.
Another typical way to use the module system is for defining classes within an object oriented paradigm. The class structure and the methods of a class can be defined in a module and the explicit module-boundary overruling describes in section 5.7.2 can by used by the message passing code to invoke the behaviour. An outline of this mechanism is given below.
%       Define class point
:- module(point, []).           % class point, no exports
%        name           type,           default access
%                                       value
variable(x,             integer,        0,      both).
variable(y,             integer,        0,      both).
%         method name   predicate name  arguments
behaviour(mirror,       mirror,         []).
mirror(P) :-
        fetch(P, x, X),
        fetch(P, y, Y),
        store(P, y, X),
        store(P, x, Y).
The predicates fetch/3 and store/3 are predicates that change instance variables of instances. The figure below indicates how message passing can easily be implemented:
%       invoke(+Instance, +Selector, ?ArgumentList)
%       send a message to an instance
invoke(I, S, Args) :-
        class_of_instance(I, Class),
        Class:behaviour(S, P, ArgCheck), !,
        convert_arguments(ArgCheck, Args, ConvArgs),
        Goal =.. [P|ConvArgs],
        Class:Goal.
The construct <Module>:<Goal> explicitly calls Goal in module Module. It is discussed in more detail in section 5.7.