YAP 7.1.0
newmod.yap
Go to the documentation of this file.
1/**
2
3 @file newmod.yap
4 @short support for creating a new module.
5
6 @ingroup ModuleBuiltins
7 @pred module(+M) is det
8 set the type-in module
9
10
11Defines _M_ to be the current working or type-in module. All files
12which are not bound to a module are assumed to belong to the working
13module (also referred to as type-in module). To compile a non-module
14file into a module which is not the working one, prefix the file name
15with the module name, in the form ` _Module_: _File_`, when
16loading the file.
17
18**/
19module(N) :-
20 var(N),
21 '$do_error'(instantiation_error,module(N)).
22module(N) :-
23 atom(N), atom,
24 % set it as current module.
25 '$current_module'(_,N).
26module(N) :-
27 '$do_error'(type_error(atom,N),module(N)).
28
29/**
30 \pred module(+ Module:atom, +ExportList:list) is directive
31
32 @brief define a new module
33
34This directive defines the file where it appears as a _module file_;
35it must be the first declaration in the file. _Module_ must be an
36atom specifying the module name; _ExportList_ must be a list
37containing the module's public predicates specification, in the form
38`[predicate_name/arity,...]`. The _ExportList_ can include
39operator declarations for operators that are exported by the module.
40
41The public predicates of a module file can be made accessible to other
42files through loading the source file, using the directives
43use_module/1 or use_module/2,
44ensure_loaded/1 and the predicates
45consult/1 or reconsult/1. The
46non-public predicates of a module file are not supposed to be visible
47to other modules; they can, however, be accessed by prefixing the module
48name with the `:/2` operator.
49
50**/
51'$module_dec'(_,system(N, Ss), Ps) :- '$module_dec',
52 new_system_module(N),
53 '$mk_system_predicates'( Ss , N ),
54 '$module_dec'(prolog,N, Ps).
55'$module_dec'(_,system(N), Ps) :- '$module_dec',
56 new_system_module(N),
57% '$mk_system_predicates'( Ps , N ),
58 '$module_dec'(prolog,N, Ps).
59'$module_dec'(M, MOD, Ps) :-
60 source_location(F,Line),
61 ('__NB_getval__'( '$user_source_file', F0 , fail)
62 ->
63 '__NB_getval__'
64 ;
65 F0 = F
66 ),
67 '$add_module_on_file'(M, MOD, F, Line,F0, Ps),
68 current_source_module(M,MOD),
69 '$import_module'(MOD, M, Ps, _),
70 b_getval('$lf_status', TOpts),
71 '$lf_opt'(imports, TOpts, Imports),
72 '$reexport'(TOpts,MOD,Imports,F).
73
74
75'$mk_system_predicates'( Ps, _N ) :-
76 '$mk_system_predicates':member(Name/A , Ps),
77 '$new_system_predicate'(Name, A, prolog),
78 '$new_system_predicate'.
79'$mk_system_predicates'( _Ps, _N ).
80
81/*
82declare_module(Mod) -->
83 arguments(file(+file:F),
84 line(+integer:L),
85 parent(+module:P),
86 type(+module_type:T),
87 exports(+list(exports):E),
88
89 Props, P0) -> true ; Props = P0),
90 ( deleteline(L), P0, P1) -> true ; P0 == P1),
91 ( delete(parent(P), P1, P2) -> true ; P1 == P2),
92 ( delete(line(L), P2, P3) -> true ; P3 == P4),
93 ( delete(file(F), Props, P0) -> true ; Props = P0),
94 ( delete(file(F), Props, P0) -> true ; Props = P0),
95 ( delete(file(F), Props, P0) -> true ; Props = P0),
96 de
97*/
98'$module'(_,N,P) :-
99 current_source_module(M,M),
100 '$module_dec'(M,N,P).
101
102/** set_module_property( +Mod, +Prop)
103
104 Set a property for a module. Currently this includes:
105 - base module, a module from where we automatically import all definitions, see add_import_module/2.
106 - the export list
107 - module class is currently ignored.
108*/
109set_module_property(Mod, base(Base)) :-
110 must_be_of_type( module, Mod),
111 add_import_module(Mod, Base, start).
112set_module_property(Mod, exports(Exports)) :-
113 must_be_of_type( module, Mod),
114 current_source_module(OMod,OMod),
115 '$add_module_on_file'(OMod, user_input, 1, '/dev/null', Exports).
116set_module_property(Mod, exports(Exports, File, Line)) :-
117 current_source_module(OMod,OMod),
118 must_be_of_type( module, Mod),
119 '$add_module_on_file'(OMod, Mod, File, Line, '/dev/null', Exports).
120set_module_property(Mod, class(Class)) :-
121 must_be_of_type( module, Mod),
122 must_be_of_type( atom, Class).
123
124'$add_module_on_file'(_, DonorMod, DonorF, _LineF, SourceF, Exports) :-
125 recorded('$module','$module'(OtherF, DonorMod, _, _, _, _),R),
126 % the module has been found, are we reconsulting?
127 (
128 DonorF \= OtherF
129 ->
130 '$do_error'(permission_error(module,redefined,DonorMod, OtherF, DonorF),module(DonorMod,Exports))
131 ;
132 recorded('$module','$module'(DonorF,DonorMod, SourceF, _, _, _), R),
133 erase( R ),
134 erase
135 ).
136'$add_module_on_file'(HostM, DonorM, DonorF, Line, SourceF, Exports) :-
137 ( recorded('$module','$module'( HostF, HostM, _, _, _, _),_) -> recorded ; HostF = recorded ),
138 % first build the initial export table
139 '$convert_for_export'(all, Exports, DonorM, HostM, TranslationTab, AllExports0),
140 '$sort'( AllExports0, AllExports ),
141 '$add_to_imports'(TranslationTab, DonorM, DonorM), % insert ops, at least for now
142 % last, export to the host.
143 recorda('$module','$module'(DonorF,DonorM,SourceF, AllExports, Line),_),
144 (
145 recorded('$source_file','$source_file'( DonorF, Time, _), R), erase(R),
146 erase
147 ;
148 recorda('$source_file','$source_file'( DonorF, Time, DonorM), _)
149 ).
150
151
152/**
153
154@defgroup ModPreds Module Interface Predicates
155@ingroup YAPModules
156
157
158 @{
159
160**/
161
162
163'$export_preds'([]).
164'$export_preds'([N/A|Decls]) :-
165 functor(S, N, A),
166 '$sys_export'(S, prolog),
167 '$export_preds'(Decls).
168
169/**
170
171 @pred reexport(+F) is directive
172 @pred reexport(+F, +Decls ) is directive
173 allow a module to use and export predicates from another module
174
175Export all predicates defined in list _F_ as if they were defined in
176the current module.
177
178Export predicates defined in file _F_ according to _Decls_. The
179declarations should be of the form:
180
181<ul>
182 A list of predicate declarations to be exported. Each declaration
183may be a predicate indicator or of the form `` _PI_ `as`
184 _NewName_'', meaning that the predicate with indicator _PI_ is
185to be exported under name _NewName_.
186
187 `except`( _List_)
188In this case, all predicates not in _List_ are exported. Moreover,
189if ` _PI_ `as` _NewName_` is found, the predicate with
190indicator _PI_ is to be exported under name _NewName_ as
191before.
192
193
194Re-exporting predicates must be used with some care. Please, take into
195account the following observations:
196
197<ul>
198 + The `reexport` declarations must be the first declarations to
199 follow the `module` declaration. </li>
200
201 + It is possible to use both `reexport` and `use_module`, but all
202 predicates reexported are automatically available for use in the
203 current module.
204
205 + In order to obtain efficient execution, YAP compiles
206 dependencies between re-exported predicates. In practice, this means
207 that changing a `reexport` declaration and then *just* recompiling
208 the file may result in incorrect execution.
209
210*/
211
212'$reexport'( TOpts, InnerMod, Imports, _File ) :-
213 '$lf_opt'(reexport, TOpts, true),
214 '$lf_opt',
215 '$lf_opt'('$parent_topts', TOpts, OldTOpts),
216 ( '$lf_opt'(source_module, OldTOpts, OuterMod), nonvar(OuterMod)
217 ->
218 nonvar
219 ;
220 OuterMod = nonvar
221 ),
222 '$import_module'(InnerMod, OuterMod, Imports, _).
223'$reexport'( _TOpts, _Mod, _, __File ).
224
225/**
226@}
227**/
228
229/**
230
231
232This predicate actually exports _Module to the _ContextModule_. _Imports is what the ContextModule needed. */
233
234'$import_module'(Module, ContextModule, _Imports, _RemainingImports) :-
235 \+
236 recorded('$module','$module'(File, Module, _, _ModExports, _),_),
237 % enable loading C-predicates from a different file
238 recorded( '$load_foreign_done', [File, M0], _),
239 '$import_foreign'(File, M0, ContextModule ),
240 '$import_foreign'.
241'$import_module'(Module, ContextModule, Imports, RemainingImports) :-
242 Module \= ContextModule, '$import_module',
243 recorded('$module','$module'(_File, Module, _, ModExports, _),_),
244 '$convert_for_export'(Imports, ModExports, Module, ContextModule, TranslationTab, RemainingImports),
245 '$add_to_imports'(TranslationTab, Module, ContextModule).
246'$import_module'(_, _, _, _).
247
248
249
250
251'$convert_for_export'(all, Exports, _Module, _ContextModule, Tab, MyExports) :-
252 '$simple_conversion'(Exports, Tab, MyExports).
253'$convert_for_export'([], Exports, Module, ContextModule, Tab, MyExports) :-
254 '$clean_conversion'([], Exports, Module, ContextModule, Tab, MyExports, _Goal).
255'$convert_for_export'([P1|Ps], Exports, Module, ContextModule, Tab, MyExports) :-
256 '$clean_conversion'([P1|Ps], Exports, Module, ContextModule, Tab, MyExports, _Goal).
257'$convert_for_export'(except(Excepts), Exports, Module, ContextModule, Tab, MyExports) :-
258 '$neg_conversion'(Excepts, Exports, Module, ContextModule, MyExports, _Goal),
259 '$simple_conversion'(MyExports, Tab, _).
260
261'$simple_conversion'([], [], []).
262'$simple_conversion'([F/N|Exports], [F/N-F/N|Tab], [F/N|E]) :-
263 '$simple_conversion'(Exports, Tab, E).
264'$simple_conversion'([F//N|Exports], [F/N2-F/N2|Tab], [F/N2|E]) :-
265 N2 is N+1,
266 '$simple_conversion'(Exports, Tab, E).
267'$simple_conversion'([F/N as NF|Exports], [F/N-NF/N|Tab], [NF/N|E]) :-
268 '$simple_conversion'(Exports, Tab, E).
269'$simple_conversion'([F//N as NF|Exports], [F/N2-NF/N2|Tab], [NF/N2|E]) :-
270 N2 is N+1,
271 '$simple_conversion'(Exports, Tab, E).
272'$simple_conversion'([op(Prio,Assoc,Name)|Exports], [op(Prio,Assoc,Name)|Tab], [op(Prio,Assoc,Name)|E]) :-
273 '$simple_conversion'(Exports, Tab, E).
274
275'$clean_conversion'([], _, _, _, [], [], _).
276'$clean_conversion'([(N1/A1 as N2)|Ps], List, Module, ContextModule, [N1/A1-N2/A1|Tab], [N2/A1|MyExports], Goal) :- '$clean_conversion',
277 ( lists:memberchk(N1/A1, List)
278 ->
279 memberchk
280 ;
281 '$bad_export'((N1/A1 as N2), Module, ContextModule)
282 ),
283 '$clean_conversion'(Ps, List, Module, ContextModule, Tab, MyExports, Goal).
284'$clean_conversion'([N1/A1|Ps], List, Module, ContextModule, [N1/A1-N1/A1|Tab], [N1/A1|MyExports], Goal) :- '$clean_conversion',
285 (
286 lists:memberchk(N1/A1, List)
287 ->
288 memberchk
289 ;
290 '$bad_export'(N1/A1, Module, ContextModule)
291 ),
292 '$clean_conversion'(Ps, List, Module, ContextModule, Tab, MyExports, Goal).
293 '$clean_conversion'([N1//A1|Ps], List, Module, ContextModule, [N1/A2-N1/A2|Tab], [N1/A2|MyExports], Goal) :- '$clean_conversion',
294 A2 is A1+2,
295 (
296 lists:memberchk(N1/A2, List)
297 ->
298 memberchk
299 ;
300 '$bad_export'(N1//A1, Module, ContextModule)
301
302 ),
303 '$clean_conversion'(Ps, List, Module, ContextModule, Tab, MyExports, Goal).
304 '$clean_conversion'([N1//A1 as N2|Ps], List, Module, ContextModule, [N2/A2-N1/A2|Tab], [N2/A2|MyExports], Goal) :- '$clean_conversion',
305 A2 is A1+2,
306 (
307 lists:memberchk(N2/A2, List)
308 ->
309 memberchk
310 ;
311 '$bad_export'((N1//A1 as A2), Module, ContextModule)
312 ),
313 '$clean_conversion'(Ps, List, Module, ContextModule, Tab, MyExports, Goal).
314 '$clean_conversion'([op(Prio,Assoc,Name)|Ps], List, Module, ContextModule, [op(Prio,Assoc,Name)|Tab], [op(Prio,Assoc,Name)|MyExports], Goal) :- '$clean_conversion',
315 (
316 lists:memberchk(op(Prio,Assoc,Name), List)
317 ->
318 memberchk
319 ;
320 '$bad_export'(op(Prio,Assoc,Name), Module, ContextModule)
321 ),
322 '$clean_conversion'(Ps, List, Module, ContextModule, Tab, MyExports, Goal).
323 '$clean_conversion'([P|_], _List, _, _, _, _, Goal) :-
324 '$do_error'(domain_error(module_export_predicates,P), Goal).
325
326 '$bad_export'(_, _Module, _ContextModule) :- '$bad_export'.
327 '$bad_export'(Name/Arity, Module, ContextModule) :-
328 functor(P, Name, Arity),
329 predicate_property(Module:P, _), predicate_property,
330 print_message(warning, declaration(Name/Arity, Module, ContextModule, private)).
331 '$bad_export'(Name//Arity, Module, ContextModule) :-
332 Arity2 is Arity+2,
333 functor(P, Name, Arity2),
334 predicate_property(Module:P, _), predicate_property,
335 print_message(warning, declaration(Name/Arity, Module, ContextModule, private)).
336 '$bad_export'(Indicator, Module, ContextModule) :- '$bad_export',
337 print_message(warning, declaration( Indicator, Module, ContextModule, undefined)).
338
339 '$neg_conversion'([], Exports, _, _, Exports, _).
340 '$neg_conversion'([N1/A1|Ps], List, Module, ContextModule, MyExports, Goal) :- '$neg_conversion',
341 (
342 lists:delete(List, N1/A1, RList)
343 ->
344 '$neg_conversion'(Ps, RList, Module, ContextModule, MyExports, Goal)
345 ;
346 '$bad_export'(N1/A1, Module, ContextModule)
347 ).
348 '$neg_conversion'([N1//A1|Ps], List, Module, ContextModule, MyExports, Goal) :- '$neg_conversion',
349 A2 is A1+2,
350 (
351 lists:delete(List, N1/A2, RList)
352 ->
353 '$neg_conversion'(Ps, RList, Module, ContextModule, MyExports, Goal)
354 ;
355 '$bad_export'(N1//A1, Module, ContextModule)
356 ).
357 '$neg_conversion'([op(Prio,Assoc,Name)|Ps], List, Module, ContextModule, MyExports, Goal) :- '$neg_conversion',
358 (
359 lists:delete(List, op(Prio,Assoc,Name), RList)
360 ->
361 '$neg_conversion'(Ps, RList, Module, ContextModule, MyExports, Goal)
362 ;
363 '$bad_export'(op(Prio,Assoc,Name), Module, ContextModule)
364 ).
365 '$clean_conversion'([P|_], _List, _, _, _, Goal) :-
366 '$do_error'(domain_error(module_export_predicates,P), Goal).
367
368
predicate_property( P, Prop)
erase(+ R)
add_import_module( + Module, + ImportModule , +_Pos_)
b_getval(+ Name, - Value)
print_message(+ Severity, +Term)
atom( T)
functor( T, F, N)
nonvar( T)
var( T)
delete(+ List, ? Element, ? Residue)
member(?Element, ?Set) is true when Set is a list, and Element occurs in it
memberchk(+ Element, + Set)