home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / plbin.zip / pl / man / module.doc (.txt) < prev    next >
LaTeX Document  |  1992-07-17  |  21KB  |  421 lines

  1. \chapter{Using Modules}            \label{sec:modules}
  2. \section{Why Using Modules?}
  3. In traditional Prolog systems the predicate space was flat.  This
  4. approach is not very suitable for the development of large
  5. applications, certainly not if these applications are developed by
  6. more than one programmer.  In many cases, the definition of a Prolog
  7. predicate requires sub-predicates that are intented only to complete
  8. the definition of the main predicate.  With a flat and global
  9. predicate space these support predicates will be visible from the
  10. entire program.
  11. For this reason, it is desirable that each source module has it's own
  12. predicate space.  A module consists of a declaration for it's name,
  13. it's {\em public} predicates and the predicates themselves.  This
  14. approach allow the programmer to use short (local) names for support
  15. predicates without worrying about name conflicts with the support
  16. predicates of other modules.  The module declaration also makes
  17. explicit which predicates are meant for public usage and which for
  18. private purposes.  Finally, using the module information, cross
  19. reference programs can indicate possible problems much better.
  20. \section{Name-based versus Predicate-based Modules}
  21. Two approaches to realise a module system are commonly used in Prolog
  22. and other languages.  The first one is the {\em name based} module
  23. system.  In these systems, each atom read is tagged (normally
  24. prefixed) with the module name, with the exception of those atoms that
  25. are defined {\em public}.  In the second approach, each module
  26. actually implements its own predicate space.
  27. A critical problem with using modules in Prolog is introduced by the
  28. meta-predicates that transform between Prolog data and Prolog
  29. predicates.  Consider the case where we write:
  30. \begin{boxed}\begin{code}
  31. :- module(extend, [add_extension/3]).
  32. add_extension(Extension, Plain, Extended) :-
  33.     maplist(extend_atom(Extension), Plain, Extended).
  34. extend_atom(Extension, Plain, Extended) :-
  35.     concat(Plain, Extension, Extended).
  36. \end{code}\end{boxed}
  37. In this case we would like maplist to call extend_atom/3 in the module
  38. {\tt extend}.  A name based module system will do this correctly. It
  39. will tag the atom {\tt extend_atom} with the module and maplist will
  40. use this to construct the tagged term extend_atom/3.  A name based
  41. module however, will not only tag the atoms that will eventually be
  42. used to refer to a predicate, but {\em all} atoms that are not declared
  43. public.  So, with a name based module system also data is local to the
  44. module.  This introduces another serious problem:
  45. \begin{boxed}\begin{code}
  46. :- module(action, [action/3]).
  47. action(Object, sleep, Arg) :- ....
  48. action(Object, awake, Arg) :- ....
  49. :- module(process, [awake_process/2]).
  50. awake_process(Process, Arg) :-
  51.     action(Process, awake, Arg).
  52. \end{code}\end{boxed}
  53. This code uses a simple object-oriented implementation technique
  54. were atoms are used as method selectors.  Using a name based module
  55. system, this code will not work, unless we declare the selectors
  56. puclic atoms in all modules that use them.  Predicate based module
  57. systems do not require particular precautions for handling this case.
  58. It appears we have to choose either to have local data, or to have
  59. trouble with meta-predicates.  Probably it is best to choose for
  60. the predicate based approach as novice users will not often write
  61. generic meta-predicates that have to be used across multiple modules,
  62. but are likely to write programs that pass data around across
  63. modules.  Experienced Prolog programmers should be able to deal with 
  64. the complexities of meta-predicates in a predicate based module
  65. system.
  66. \section{Defining a Module}
  67. Modules normally are created by loading a {\em module file}.  A module
  68. file is a file holding a module/2 directive as its first term.  The
  69. module/2 directive declares the name and the public (i.e.\
  70. externally visible) predicates of the module.  The rest of the file
  71. is loaded into the module.  Below is an example of a module file,
  72. defining reverse/2. 
  73. \begin{boxed}\begin{code}
  74. :- module(reverse, [reverse/2]).
  75. reverse(List1, List2) :-
  76.     rev(List1, [], List2).
  77. rev([], List, List).
  78. rev([Head|List1], List2, List3) :-
  79.     rev(List1, [Head|List2], List3).
  80. \end{code}\end{boxed}
  81. \section{Importing Predicates into a Module}
  82. As explained before, in the predicate based approach ad<apted by
  83. SWI-Prolog, each module has it's own predicate space.  In SWI-Prolog,
  84. a module initially is completely empty.  Predicates can be added
  85. to a module by loading a module file as demonstrated in the previous
  86. section, using assert or by {\em importing} them from another module.
  87. Two mechanisms for importing predicates explicitely from another module
  88. exist.  The use_module/[1,2] predicates load a module file and import
  89. (part of the) public predicates of the file.  The import/1 predicate
  90. imports any predicate from any module.
  91. .C use_module 1 +File
  92. Load the file(s) specified with {\em File} just like ensure_loaded/1.
  93. The files should all be module files.  All exported predicates from the
  94. loaded files are imported into the context module.  The difference
  95. between this predicate and ensure_loaded/1 becomes apparent if the file
  96. is already loaded into another module.  In this case ensure_loaded/1
  97. does nothing; use_module will import all public predicates of the module
  98. into the current context module.
  99. .C use_module 2 +File, +ImportList
  100. Load the file specified with {\em File} (only one file is accepted).
  101. {\em File} should be a module file. {\em ImportList} is a list of
  102. name/arity pairs specifying the predicates that should be imported from
  103. the loaded module.  If a predicate is specified that is not exported from
  104. the loaded module a warning will be printed.  The predicate will
  105. nevertheless be imported to simplify debugging.
  106. .C import 1 +Head
  107. Import predicate {\em Head} into the current context module. {\em Head}
  108. should specify the source module using the {\em $<$module$>$:$<$term$>$}
  109. construct. Note that predicates are normally imported using one of the
  110. directives use_module/[1,2]. import/1 is meant for handling imports
  111. into dynamically created modules.
  112. It would be rather inconvient to have to import each predicate
  113. refered to by the module, including the system predicates.  For this
  114. reason each module is assigned a {\em default} module.  All predicates
  115. in the default module are available without extra declarations.  Their
  116. definition however can be overruled in the local module.  This schedule
  117. is implemented by the exception handling mechanism of SWI-Prolog:  if
  118. an undefined predicate exception is raised for a predicate in some
  119. module, the exception handler first tries to import the predicate from
  120. the module's default module.  On success, normal execution is resumed.
  121. \subsection{Reserved Modules}
  122. SWI-Prolog contains two special modules.  The first one is the module
  123. {\tt system}.  This module contains all built-in predicates described
  124. in this manual.  Module {\tt system} has no default module assigned to
  125. it.  The second special module is the module {\tt user}.  This module
  126. forms the initial working space of the user.  Initially it is empty.
  127. The default module of module {\tt user} is {\tt system}, making all
  128. built-in predicate definitions available as defaults.  Built-in
  129. predicates thus can be overruled by defining them in module {\tt user}
  130. before they are used.
  131. All other modules default to module {\tt user}.  This implies they can
  132. use all predicates imported into {\tt user} without explicitely
  133. importing them.
  134. \section{Using the Module System}
  135. The current structure of the module system has been designed with some
  136. specific organisations for large programs in mind.  Many large
  137. programs define a basic library layer on top of which the actual
  138. program itself is defined.  The module {\em user}, acting as the
  139. default module for all other modules of the program can be used to
  140. distribute these definitions over all program module without
  141. introducing the need to import this common layer each time
  142. explicitely.  It can also be used to redefine built-in predicates
  143. if this is required to maintain compatibility to some other Prolog
  144. implementation.  Typically, the loadfile of a large application
  145. looks like this:
  146. \begin{boxed}\begin{code}
  147. :- use_module(compatibility).    % load XYZ prolog compatibility
  148. :- use_module(            % load generic parts
  149.     [ error            % errors and warnings
  150.     , goodies        % general goodies (library extensions)
  151.     , debug            % application specific debugging
  152.     , virtual_machine    % virtual machine of application
  153.     , ...            % more generic stuff
  154. :- ensure_loaded(
  155.     [ ...            % the application itself
  156. \end{code}\end{boxed}
  157. The `use_module' declarations will import the public predicates from
  158. the generic modules into the {\tt user} module.  The `ensure_loaded'
  159. directive loads the modules that constitute the actual application.
  160. It is assumed these modules import predicates from each other using
  161. use_module/[1,2] as far as necessary.
  162. In combination with the object-oriented schema described below it is
  163. possible to define a neat modular architecture.  The generic code
  164. defines general utilities and the message passing predicates (invoke/3
  165. in the example below).  The application modules define classes that
  166. communicate using the message passint predicates.
  167. \subsection{Object Oriented Programming}
  168. Another typical way to use the module system is for defining classes
  169. within an object oriented paradigm.  The class structure and the
  170. methods of a class can be defined in a module and the explicit
  171. module-boundary  overruling describes in section~\ref{sec:overrule}
  172. can by used by the message passing code to invoke the behaviour.  An
  173. outline of this mechanism is given below.
  174. \begin{boxed}\begin{code}
  175. %    Define class point
  176. :- module(point, []).        % class point, no exports
  177. %     name        type,        default    access
  178. %                    value
  179. variable(x,        integer,    0,    both).
  180. variable(y,        integer,    0,    both).
  181. %      method name    predicate name    arguments
  182. behaviour(mirror,    mirror,        []).
  183. mirror(P) :-
  184.     fetch(P, x, X),
  185.     fetch(P, y, Y),
  186.     store(P, y, X),
  187.     store(P, x, Y).
  188. \end{code}\end{boxed}
  189. The predicates fetch/3 and store/3 are predicates that change instance
  190. variables of instances.  The figure below indicates how message
  191. passing can easily be implemented:
  192. \begin{boxed}\begin{code}
  193. %    invoke(+Instance, +Selector, ?ArgumentList)
  194. %    send a message to an instance
  195. invoke(I, S, Args) :-
  196.     class_of_instance(I, Class),
  197.     Class:behaviour(S, P, ArgCheck), !,
  198.     convert_arguments(ArgCheck, Args, ConvArgs),
  199.     Goal =.. [P|ConvArgs],
  200.     Class:Goal.
  201. \end{code}\end{boxed}
  202. The construct {\em `Module:Goal'} explicitely calls {\em Goal} in
  203. module {\em Module}.  It is discussed in more detail in
  204. section~\ref{sec:metacall}.
  205. \section{Meta-Predicates in Modules}
  206. As indicated in the introduction, the problem with a predicate based
  207. module system lies in the difficulty to find the correct predicate
  208. from a Prolog term.  The predicate `solution(Solution)' can exist in
  209. more than one module, but `assert(solution(4))' in some module is
  210. supposed to refer to the correct version of solution/1.
  211. Various approaches are possible to solve this problem.  One is to add
  212. an extra argument to all predicates (e.g.\ `assert(Module, Term)').
  213. Another is to tag the term somehow to indicate which module is desired
  214. (e.g.\ `assert(Module:Term)').  Both approaches are not very
  215. attractive as they make the user responsible for chosing the correct
  216. module, inviting unclear programming by asserting in other modules.
  217. The predicate assert/1 is supposed to assert in the module it is
  218. called from and should do so without being told explicitely.  For
  219. this reason, the notion {\em context module} has been introduced.
  220. \subsection{Definition and Context Module}
  221. Each predicate of the program is assigned a module, called it's {\em
  222. definition module}.  The definition module of a predicate is always the
  223. module in which the predicate was originally defined.  Each active goal
  224. in the Prolog system has a {\em context module} assigned to it.
  225. The context module is used to find predicates from a Prolog term.  By
  226. default, this module is the definition module of the predicate running
  227. the goal.  For meta-predicates however, this is the context module of
  228. the goal that invoked them.  We call this {\em module_transparent} in
  229. SWI-Prolog.  In the `using maplist' example above, the predicate
  230. maplist/3 is declared module_transparent. This implies the context
  231. module remains {\tt extend}, the context module of add_extension/3.
  232. This way maplist/3 can decide to call extend_atom in module {\tt
  233. extend} rather than in it's own definition module.
  234. All built-in predicates that refer to predicates via a Prolog term are
  235. declared module_transparent.  Below is the code defining maplist.
  236. \begin{boxed}\begin{code}
  237. :- module(maplist, maplist/3).
  238. :- module_transparent maplist/3.
  239. %    maplist(+Goal, +List1, ?List2)
  240. %    True if Goal can succesfully be applied to all succesive pairs
  241. %    of elements of List1 and List2.
  242. maplist(_, [], []).
  243. maplist(Goal, [Elem1|Tail1], [Elem2|Tail2]) :-
  244.     apply(Goal, [Elem1, Elem2]), 
  245.     maplist(Goal, Tail1, Tail2).
  246. \end{code}\end{boxed}
  247. \subsection{Overruling Module Boundaries}
  248. The mechanism above is sufficient to create an acceptable module
  249. system.  There are however cases in which we would like to be able to
  250. overrule this schema and explicitely call a predicate in some module
  251. or assert explicitly in some module.  The first is useful to invoke
  252. goals in some module from the user's toplevel or to implement a
  253. object-oriented system (see above).  The latter is useful to create
  254. and modify {\em dynamic} modules (see section~\ref{sec:dynamic-modules}). 
  255. For this purpose, the reserved term \verb$:/2$ has been introduced.
  256. All built-in predicates that transform a term into a predicate
  257. reference will check whether this term is of the form
  258. \mbox{`$<$Module$>$:$<$Term$>$'}.  If so, the predicate is searched
  259. for in {\em Module} instead of the goal's context module.  The
  260. \verb$:/2$ operator may be nested, in which case the inner-most module
  261. is used.
  262. The special calling construct \mbox{$<$Module$>$:$<$Goal$>$} pretends
  263. {\em Goal} is called from {\em Module} instead of the context module.
  264. Examples:
  265. \begin{code}
  266. ?- assert(world:done).    % asserts done/0 into module world
  267. ?- world:assert(done).    % the same
  268. ?- world:done.        % calls done/0 in module world
  269. \end{code}
  270. \section{Dynamic Modules}        \label{sec:dynamic-modules}
  271. Sofar, we discussed modules that were created by loading a
  272. module-file.  These modules have been introduced on facilitate the
  273. development of large applications.  The modules are fully defined at
  274. load-time of the application and normally will not change during 
  275. execution.  Having the notion of a set of predicates as a
  276. self-contained world can be attractive for other purposes as well.
  277. For example, assume an application that can reason about multiple
  278. worlds.  It is attractive to store the data of a particular world in a
  279. module, so we extract information from a world simply by invoking
  280. goals in this world.
  281. Dynamic modules can easily be created.  Any built-in predicate that
  282. tries to locate a predicate in a specific module will create this
  283. module as a side-effect if it did not yet exist.  Example:
  284. \begin{code}
  285. ?- assert(world_1, consistent),
  286.    world_1:unkown(_, fail).
  287. \end{code}
  288. These calls create a module called {\tt world_1} and make the call
  289. `world_1:consistent' succeed.  Undefined predicates will not start the
  290. tracer or autoloader for this module (see unknown/2).
  291. Import and export from dynamically created world is arranged via the
  292. predicates import/1 and export/1:
  293. \begin{code}
  294. ?- world_5:export(solve(_,_)).        % exports solve/2 from world_5
  295. ?- world_3:import(world_5:solve(_,_)).    % and import it to world_3
  296. \end{code}
  297. \section{Module Handling Predicates}
  298. This section gives the predicate definitions for the remaining
  299. built-in predicates that handle modules.
  300. .D module 2 +Module, +PublicList
  301. This directive can only be used as the first term of a source file. It
  302. declares the file to be a {\em module file}, defining {\em Module} and
  303. exporting the predicates of {\em PublicList}. {\em PublicList} is a
  304. list of name/arity pairs.
  305. .P module_transparent +Name/+Arity, ...
  306. {\em Preds} is a comma separated list of name/arity pairs (like
  307. dynamic/1).  Each goal associated with a transparent declared predicate
  308. will inherit the {\em context module} from its parent goal.
  309. .C context_module 1 -Module
  310. Unify {\em Module} with the context module of the current goal.
  311. context_module/1 itself is transparent.
  312. .C export 1 +Head
  313. Add a predicate to the public list of the context module.  This implies
  314. the predicate will be imported into another module if this module is
  315. imported with use_module/[1,2].  Note that predicates are normally
  316. exported using the directive module/2. export/1 is meant to handle
  317. export from dynamically created modules.
  318. .C export_list 2 +Module, -Exports
  319. Unifies {\em Exports} with a list of terms.  Each term has the name and
  320. arity of a public predicate of {\em Module}.  The order of the terms in
  321. {\em Exports} is not defined.  See also predicate_property/2.
  322. .S Compatibility of the Module System
  323. The principles behind the module system of SWI-Prolog differ in a
  324. number of aspects from the Quintus Prolog module system.
  325. \begin{itemize}
  326.     \item
  327. The SWI-Prolog module system allows the user to redefine system
  328. predicates.
  329.     \item
  330. All predicates that are available in the {\em system} and {\em user}
  331. modules are visible in all other modules as well.
  332.     \item
  333. Quintus has the `meta_predicate/1' declaration were SWI-Prolog has the
  334. module_transparent/1 declaration.
  335. \end{itemize}
  336. The meta_predicate/1 declaration causes the compiler to tag arguments
  337. that pass module sensitive information with the module using the
  338. \verb$:/2$ operator.  This approach has some disadvantages:
  339. \begin{itemize}
  340.     \item
  341. Changing a meta_predicate declaration implies all predicates {\em
  342. calling} the predicate need to be reloaded. This can cause serious
  343. consistency problems.
  344.     \item
  345. It does not help for dynamically defined predicates calling module
  346. sensitive predicates.
  347.     \item
  348. It slows down the compiler (at least in the SWI-Prolog architecture).
  349.     \item
  350. At least within the SWI-Prolog architecture the run-time overhead is
  351. larger than the overhead introduced by the transparent mechanism.
  352. \end{itemize}
  353. Unfortunately the transparent predicate approach also has some
  354. disadvantages. If a predicate {\em A} passes module sensitive information
  355. to a predicate {\em B}, passing the same information to a module
  356. sensitive system predicate both {\em A} and {\em B} should be declared
  357. transparent. Using the Quintus approach only {\em A} needs to be
  358. treated special (i.e. declared with meta_predicate/1)%
  359.     \footnote{Although this would make it impossible to call {\it B}
  360.           directly.}.
  361. A second problem arises if the body of a transparent predicate uses
  362. module sensitive predicates for which it wants to refer to its own
  363. module. Suppose we want to define findall/3 using assert/1 and
  364. retract/1%
  365.     \footnote{The system version uses recordz/2 and recorded/3.}.
  366. The example in figure~\ref{fig:findall} gives the solution.
  367. \begin{figure}
  368. \begin{boxed}
  369. \begin{code}
  370. :- module(findall, [findall/3]).
  371. :- dynamic
  372.     solution/1.
  373. :- module_transparent
  374.     findall/3, 
  375.     store/2.
  376. findall(Var, Goal, Bag) :-
  377.     assert(findall:solution('$mark')), 
  378.     store(Var, Goal), 
  379.     collect(Bag).
  380. store(Var, Goal) :-
  381.     Goal,             % refers to context module of
  382.                 % caller of findall/3
  383.     assert(findall:solution(Var)), 
  384.     fail.
  385. store(_, _).
  386. collect(Bag) :-
  387.     ..., 
  388. \end{code}
  389. \end{boxed}
  390.     \caption{Findall using modules}
  391.     \label{fig:findall}
  392. \end{figure}
  393. The Quintus meta_predicate/1 directive can in many cases be replaced by
  394. the transparent declaration.  Figure~\ref{fig:meta} gives a definition
  395. of meta_predicate/1 as available from the `quintus' library package.
  396. \begin{figure}
  397. \begin{boxed}
  398. \begin{code}
  399. :- op(1150, fx, (meta_predicate)).
  400. meta_predicate((Head, More)) :- !, 
  401.     meta_predicate1(Head), 
  402.     meta_predicate(More).
  403. meta_predicate(Head) :-
  404.     meta_predicate1(Head).
  405. meta_predicate1(Head) :-
  406.     Head =.. [Name|Arguments], 
  407.     member(Arg, Arguments), 
  408.     module_expansion_argument(Arg), !, 
  409.     functor(Head, Name, Arity), 
  410.     module_transparent(Name/Arity).
  411. meta_predicate1(_).        % just a mode declaration
  412. module_expansion_argument(:).
  413. module_expansion_argument(N) :- integer(N).
  414. \end{code}
  415. \end{boxed}
  416.     \caption{Definition of meta_predicate/1}
  417.     \label{fig:meta}
  418. \end{figure}
  419. The discussion above about the problems with the transparent mechanism
  420. show the two cases in which this simple transformation does not work.
  421.