YAP 7.1.0
consult.yap
Go to the documentation of this file.
1/*************************************************************************
2* *
3 * YAP Prolog *
4* *
5 * Yap Prolog was developed at NCCUP - Universidade do Porto *
6* *
7* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
8* *
9**************************************************************************
10* *
11* File: consult.yap *
12* Last rev: 8/2/88 *
13* mods: *
14* comments: Consulting Files in YAP *
15* *
16*************************************************************************/
17/**
18 * @file consult.yap
19 * @author VITOR SANTOS COSTA <vsc@VITORs-MBP.lan>
20 * @date Wed Nov 18 14:01:10 2015
21 *
22 * @brief loading programs into YAP
23 *
24 *
25*/
26:- system_module( '$_consult', [compile/1,
28 db_files/1,
30 exists_source/1,
31 exo_files/1,
32 (initialization)/2,
34 make/0,
35 make_library_index/1,
39 source_file/1,
40 source_file/2,
41 source_file_property/2,
43 ['$add_multifile'/3,
44 '$csult'/2,
45 '$do_startup_reconsult'/1,
46 '$elif'/2,
47 '$else'/1,
48 '$endif'/1,
49 '$if'/2,
50 '$include'/2,
51 '$initialization'/1,
52 '$initialization'/2,
53 '$lf_opt'/3,
54 '$load_files'/3,
55 '$require'/2,
56 '$set_encoding'/1,
57 '$use_module'/3]).
58
59:- '$full_filename'/2use_system_module( '$_absf', []).
60
61:- '$clear_reconsulting'/0'$init_system'/0'$init_win_graphics'/0'$loop'/2'$system_catch'/4use_system_module( '$_boot', [,
62 ,
63 ,
64 ,
65 ]).
66
67:- '$do_error'/2use_system_module( '$_errors', []).
68
69:- '$import_foreign'/3use_system_module( '$_load_foreign', []).
70
71:- '$add_to_imports'/3'$convert_for_export'/6'$extend_exports'/3use_system_module( '$_modules', [,
72 ,
73 ]).
74
75:- '$current_predicate'/4use_system_module( '$_preds', []).
76
77/**
78
79 @defgroup YAPConsulting Loading files into YAP
80 @ingroup load_files
81
82 @{
83
84 We present the main predicates and directives available to load
85files and to set-up the Prolog environment. We discuss
86
87 + @ref YAPReadFiles
88
89 + @ref YAPCompilerSettings
90
91 @}
92 */
93
94/**
95@defgroup YAPReadFiles The Predicates that Read Source Files
96 @ingroup YAPConsulting
97
98@{
99 */
100
101/**
102
103 @pred load_files(+_Files_, +_Options_)
104
105Implementation of the consult/1 family. Execution is controlled by the
106following flags:
107
108+ consult(+ _Mode_)
109
110 This extension controls the type of file to load. If _Mode_ is:
111
112 `consult`, clauses are added to the data-base, unless from the same file;
113 `reconsult`, clauses are recompiled,
114 `db`, these are facts that need to be added to the data-base,
115 `exo`, these are facts with atoms and integers that can be stored in a compact representation (see load_exo/1).
116
117+ silent(+ _Bool_)
118
119 If true, load the file without printing a message. The specified
120 value is the default for all files loaded as a result of loading
121 the specified files.
122
123+ stream(+ _Input_)
124
125 This SWI-Prolog extension compiles the data from the stream
126 _Input_. If this option is used, _Files_ must be a single atom
127 which is used to identify the source-location of the loaded
128 clauses as well as remove all clauses if the data is re-consulted.
129
130 This option is added to allow compiling from non-file locations
131 such as databases, the web, the user (see consult/1) or other
132 servers.
133
134+ compilation_mode(+ _Mode_)
135
136 This extension controls how procedures are compiled. If _Mode_ is
137 `compact` clauses are compiled and no source code is stored; if it
138 is `source` clauses are compiled and source code is stored; if it
139 is `assert_all` clauses are asserted into the data-base.
140
141+ encoding(+ _Encoding_)
142
143 Character encoding used in consulting files. Please (see
144 [Encoding](@ref Encoding)) for supported encodings.
145
146+ expand(+ _Bool_)
147
148 If `true`, run the filenames through expand_file_name/2 and load
149 the returned files. Default is false, except for consult/1 which
150 is intended for interactive use.
151
152+ if(+ _Condition_)
153
154 Load the file only if the specified _Condition_ is satisfied. The
155 value `true` the file unconditionally, `changed` loads the file if
156 it was not loaded before, or has been modified since it was loaded
157 the last time, `not_loaded` loads the file if it was not loaded
158 before.
159
160+ imports(+ _ListOrAll_)
161
162 If `all` and the file is a module file, import all public
163 predicates. Otherwise import only the named predicates. Each
164 predicate is referred to as `<name>/<arity>`. This option has
165 no effect if the file is not a module file.
166
167+ must_be_module(+ _Bool_)
168
169 If true, raise an error if the file is not a module file. Used by
170 use_module/1 and use_module/2.
171
172+ qcompile(+ _Value_)
173
174 SWI-Prolog flag that controls whether loaded files should be also
175 compiled into `qly` files. The default value is obtained from the flag
176 `qcompile`:
177
178 `never`, no `qly` file is generated unless the user calls
179 qsave_file/1 and friends, or sets the qcompile option in
180 load_files/2;
181
182 `auto`, all files are qcompiled.
183
184 `large`, files above 100KB are qcompiled.
185
186 `part`, not supported in YAP.
187
188+ autoload(+ _Autoload_)
189
190SWI-compatible option where if _Autoload_ is `true` undefined
191 predicates are loaded on first call.
192
193+ derived_from(+ _File_)
194
195 SWI-compatible option to control make/0. Currently not supported.
196
197*/
198
199load_files(Files0,Opts) :-
200 '$yap_strip_module'(Files0,M,Files),
201 '$load_files'(Files,M,Opts,M:load_files(Files,Opts)).
202
203
204
205
206/**
207
208 @pred ensure_loaded(+ _F_) is iso
209
210When the files specified by _F_ are module files,
211ensure_loaded/1 loads them if they have note been previously
212loaded, otherwise advertises the user about the existing name clashes
213 and prompts about importing or not those predicates. Predicates which
214are not public remain invisible.
215
216When the files are not module files, ensure_loaded/1 loads them
217 eh if they have not been loaded before, and does nothing otherwise.
218
219 _F_ must be a list containing the names of the files to load.
220*/
221ensure_loaded(Fs) :-
222 load_files(Fs, [if(not_loaded)]).
223
224compile(Fs) :-
225 load_files(Fs, []).
226
227/**
228 @pred [ _F_ ]
229 @pred consult(+ _F_)
230
231
232Adds the clauses written in file _F_ or in the list of files _F_
233to the program.
234
235In YAP consult/1 does not remove previous clauses for
236the procedures defined in other files than _F_, but since YAP-6.4.3 it will redefine all procedures defined in _F_.
237
238All code in YAP is compiled, and the compiler generates static
239procedures by default. In case you need to manipulate the original
240code, the expanded version of the original source code is available by
241calling source/0 or by enabling the source flag.
242
243*/
244% consult(Fs) :-
245% '$has_yap_or'
246% '$do_error'(context_error(consult(Fs),cla ,query).
247consult(V) :-
248 var(V), var,
249 '$do_error'(instantiation_error,consult(V)).
250consult(M0:Fs) :- consult,
251 '$consult'(Fs, M0).
252consult(Fs) :-
253 current_source_module(M0,M0),
254 '$consult'(Fs, M0).
255
256'$consult'(Fs,Module) :-
257 current_prolog_flag(language_mode, iso), % SICStus Prolog compatibility
258 current_prolog_flag,
259 load_files(Module:Fs,[]).
260'$consult'(Fs, Module) :-
261 load_files(Module:Fs,[consult(consult)]).
262
263
264/**
265
266@pred [ - _F_ ]
267@pred reconsult(+ _F_ )
268 @pred compile(+ _F_ )
269
270Updates the program by replacing the
271previous definitions for the predicates defined in _F_. It differs from consult/1
272in that it only multifile/1 predicates are not reset in a reconsult. Instead, consult/1
273sees all predicates as multifile.
274
275YAP also offers no difference between consult/1 and compile/1. The two
276are implemented by the same exact code.
277
278Example:
279
280```
281?- [file1, -file2, -file3, file4].
282```
283 will consult `file1` `file4` and reconsult `file2` and
284`file3`. That is, it could be written as:
285
286```
287?- consult(file1),
288 reconsult( [file2, file3],
289 consult( [file4] ).
290```
291
292*/
293reconsult(Fs) :-
294 load_files(Fs, []).
295
296
297/* exo_files(+ _Files_)
298
299Load compactly a database of facts with equal structure, see @cite
300x. Useful when wanting to read in a very compact way database tables,
301it saves space by storing data, not a compiled program. The idea was
302introduced in @cite y, but never implemented because often indexing
303just takes more room. It was redefined recebtly by exploiting
304different forms of indexing, as shown in @cite x.
305
306@note implementation
307
308 The function Yap_ExoLookup() is the mai interface betwwen the WAM
309 and exo components. The algorithms are straightforward, that is,
310 mostly hash-tables but have close to linear performance..
311*/
312
313exo_files(Fs) :-
314 load_files(Fs, [consult(exo), if(not_loaded)]).
315
316/**
317
318 @pred load_db(+ _Files_)
319
320
321Load a database of ground facts. All facts must take up the same amount of storage, so that
322 a fact $I$ can be accessed at position _P[I-1]_. This representation thus stores the facts as a huge continuous array, the so-called mega clause.
323
324See \cite for a motivation for this technique. YAP implements this
325optimization by default whenever it loads a large number of facts (see
326Yap_BuildMegaClause(PredEntry *ap) ) for the details. On the other
327hand, loading the data-base will cause fragmentation because
328individual facts facts need extra headers ands tails, and because
329often new atoms will be stored in the Symbol Table, see
330LookupAtom(const char *atom). The main advantage of load_db/1 is
331that it allocates the necessary memory only once. Just doing this
332 may halve total memory usage in large in-memory database-oriented applications.
333
334@note Implementation
335
336YAP implements load_db/1 as a two-step non-optimised process. First,
337 it counts the nmuber of facts and checks their size. Second, it
338 allocates and fills the memory. The first step of the algorithm is
339 implemented by dbload_get_space(), and the second by
340 dbload_add_facts().
341
342 db_files/1 itself is just a call to load_files/2.
343*/
344db_files(Fs) :-
345 load_files(Fs, [consult(db), if(not_loaded)]).
346
347
348'$csult'(Fs, _M) :-
349 '$skip_list'(_, Fs ,L),
350 L \== [],
351 ,
352 :dot_qualified_goal(Fs).
353'$csult'(Fs, M) :-
354 '$extract_minus'(Fs, MFs), '$extract_minus',
355 load_files(M:MFs,[]).
356'$csult'(Fs, M) :-
357 load_files(M:Fs,[consult(consult)]).
358
359'$csult_in_mod'(M, -F ) :- load_files(M:F,[]).
360'$csult_in_mod'(M, F ) :- load_files(M:F,[consult(consult)]).
361
362'$extract_minus'([], []).
363'$extract_minus'([-F|Fs], [F|MFs]) :-
364 '$extract_minus'(Fs, MFs).
365
366
367/** @defgroup YAPCompilerSettings Directing and Configuring the Compiler
368 @ingroup YAPProgramming
369
370@{
371
372 The YAP system also includes a number of primitives designed to set
373 compiler parameters and to track the state of the compiler. One
374 important example is the number of directivees that allow setting up
375 properties of predicates. It is also possible to enable or disable
376 waraanings about possible issues with the code in the program, sich
377 as the occurrence .
378
379This section presents a set of built-ins predicates designed to set the
380environment for the compiler.
381
382*/
383
384
385/** @pred prolog_to_os_filename(+ _PrologPath_,- _OsPath_)
386
387This is an SWI-Prolog built-in. Converts between the internal Prolog
388pathname conventions and the operating-system pathname conventions. The
389internal conventions are Unix and this predicates is equivalent to =/2
390(unify) on Unix systems. On DOS systems it will change the
391directory-separator, limit the filename length map dots, except for the
392last one, onto underscores.
393
394*/
395
396
397% retract old multifile clauses for current file.
398'$remove_multifile_clauses'(FileName) :-
399 recorded('$multifile_defs','$defined'(FileName,_,_,_),R1),
400 erase(R1),
401 erase.
402'$remove_multifile_clauses'(FileName) :-
403 recorded('$mf','$mf_clause'(FileName,_,_,Module,Ref),R),
404 '$erase_clause'(Ref, Module),
405 erase(R),
406 erase.
407'$remove_multifile_clauses'(_).
408
409/** @pred initialization(+ _G_) is iso
410
411The compiler will execute goals _G_ after consulting the current
412file.
413
414Notice that the goal will execute in the calling context, not within the file context,
415In other words, the source module and execution directory will be the ones of the parent
416environment. Use initialization/2 for more flexible behavior.
417
418*/
419'$initialization'(G) :-
420 '$initialization'( G, after_load ).
421
422
423
424/** @pred initialization(+ _Goal_,+ _When_)
425
426Similar to initialization/1, but allows specifying when
427 _Goal_ is executed while loading the program-text:
428
429
430 + now
431 Execute _Goal_ immediately.
432
433 + after_load
434 Execute _Goal_ after loading program-text. This is the same as initialization/1.
435
436 + restore
437 Do not execute _Goal_ while loading the program, but only when restoring a state (not implemented yet).
438
439*/
440initialization(G,OPT) :-
441 '$initialization'(G, OPT),
442 '$initialization'.
443initialization(_G,_OPT).
444
445'$initialization'(G0,OPT) :-
446 must_be_callable( G0),
447 expand_goal(G0, G),
448 % must_be_of_type(oneof([after_load, now, restore]),
449 % OPT),
450
451 (
452 OPT == now
453 ->
454 ( catch(call(G),
455 Error,
456 '$LoopError'( Error, consult )
457 ) ->
458 catch ;
459 format(user_error,':- ~w failed.~n',[G])
460 )
461 ;
462 OPT == after_load
463 ->
464 '$show_consult_level'(L),
465 strip_module(G,M,GF),
466 recordz('$initialization_queue',q(L,M:GF),_)
467 ;
468 OPT == recordz
469 ->
470 recordz('$call_at_restore', G, _ )
471 ).
472
473/**
474
475@}
476*/
477
478
479'$exec_initialization_goals' :-
480 set_prolog_flag(optimise, true),
481 set_prolog_flag(verbose_load, false),
482 recorded('$blocking_code',_,R),
483 erase(R),
484 erase.
485% system goals must be performed first
486'$exec_initialization_goals' :-
487 recorded('$system_initialization',G,R),
488 erase(R),
489 G \= '$',
490 ( catch(G, Error, user:'$LoopError'(Error, top))
491 ->
492 catch
493 ;
494 format(user_error,':- ~w failed.~n',[G])
495 ),
496 fail.
497'$exec_initialization_goals' :-
498 '$show_consult_level'(L),
499 recorded('$initialization_queue',q(L,G),R),
500 erase(R),
501 (catch(
502 (G),
503 E,
504 '$LoopError'(E,top)
505 )
506 ->
507 catch %format(user_error,':- ~w ok.~n',[G]),
508 ;
509 format(user_error,':- ~q failed.~n',[G]),
510 format
511 ).
512'$exec_initialization_goals'.
513
514%
515% reconsult at startup...
516%
517'$do_startup_reconsult'(_X) :-
518 '$init_win_graphics',
519 '$do_startup_reconsult'.
520'$do_startup_reconsult'(X) :-
521 catch(load_files(user:X, [silent(true)]), Error, '$LoopError'(Error, consult)),
522 catch,
523 ( current_prolog_flag(halt_after_consult, false) -> current_prolog_flag ; halt(0)).
524'$do_startup_reconsult'(_) .
525
526'$skip_unix_header'(Stream) :-
527 /** @pred prolog_load_context(? _Key_, ? _Value_)
528
529 Obtain information on what is going on in the compilation process. The
530 following keys are available:
531
532 + directory (prolog_load_context/2 option)
533
534 Full name for the directory where YAP is currently consulting the
535 file.
536
537 + file (prolog_load_context/2 option)
538
539 Full name for the file currently being consulted. Notice that included
540 filed are ignored.
541
542 + module (prolog_load_context/2 option)
543
544 Current source module.
545
546 + `source` (prolog_load_context/2 option)
547
548 Full name for the file currently being read in, which may be consulted,
549 reconsulted, or included.
550
551 + `stream` (prolog_load_context/2 option)
552
553 Stream currently being read in.
554
555 + `term_position` (prolog_load_context/2 option)
556
557 Stream position at the stream currently being read in. For SWI
558 compatibility, it is a term of the form
559 '$stream_position'(0,Line,0,0).
560
561 + `source_location(? _File Name_, ? _Line_)` (prolog_load_context/2 option)
562
563 SWI-compatible predicate. If the last term has been read from a physical file (i.e., not from the file user or a string), unify File with an absolute path to the file and Line with the line-number in the file. Please use prolog_load_context/2.
564
565 + `source_file(? _File_)` (prolog_load_context/2 option)
566
567 SWI-compatible predicate. True if _File_ is a loaded Prolog source file.
568
569 + `source_file(? _ModuleAndPred_ ,? _File_)` (prolog_load_context/2 option)
570
571 SWI-compatible predicate. True if the predicate specified by _ModuleAndPred_ was loaded from file _File_, where _File_ is an absolute path name (see `absolute_file_name/2`).
572
573*/
574prolog_load_context(directory, DirName) :-
575 ( source_location(F, _)
576 -> file_directory_name(F, DirName) ;
577 working_directory( DirName, DirName )
578 ).
579prolog_load_context(file, FileName) :-
580 ( source_location(FileName, _)
581 ->
582 source_location
583 ;
584 FileName = source_location
585 ).
586prolog_load_context(module, X) :-
587 '__NB_getval__'('$consulting_file', _, fail),
588 current_source_module(Y,Y),
589 Y = X.
590prolog_load_context(source, F0) :-
591 ( source_location(F0, _) /*,
592 '$input_context'(Context),
593 '$top_file'(Context, F0, F) */
594 ->
595 source_location
596 ;
597 F0 = source_location
598 ).
599prolog_load_context(stream, Stream) :-
600 stream_property(Stream, alias(loop_stream) ).
601
602
603% if the file exports a module, then we can
604% be imported from any module.
605'$file_loaded'(F0, M) :-
606 %format( 'L=~w~n', [(F0)] ),
607 (
608 atom_concat(Prefix, '.qly', F0 );
609 Prefix=F0
610 ),
611 (
612 absolute_file_name(Prefix,F,[access(read),file_type(qly),file_errors(fail),solutions(first),expand(true)])
613 ;
614 F0 = F
615 ),
616 '$ensure_file_loaded'(F, M).
617
618'$ensure_file_loaded'(F, NM) :-
619 % loaded from the same module, but does not define a module.
620 recorded('$source_file','$source_file'(F, _Age, NM), _R),
621 % make sure: it either defines a new module or it was loaded in the same context
622 (recorded('$module','$module'(F,NM,_ASource,_P,_),_) ->
623 recorded
624 ;
625 current_source_module(M,M), M == NM
626).
627
628 % if the file exports a module, then we can
629% be imported from any module.
630'$file_unchanged'(F, NM) :-
631 % loaded from the same module, but does not define a module.
632 recorded('$source_file','$source_file'(F, Age, NM), R),
633 % make sure: it either defines a new module or it was loaded in the same context
634 '$file_is_unchanged'(F, R, Age),
635 '$file_is_unchanged',
636% ( F = '/usr/local/share/Yap/rbtrees.yap' ->start_low_level_trace ; true),
637 (recorded('$module','$module'(F,NM,_ASource,_P,_),_) ->
638 recorded
639 ;
640 current_source_module(M,M), M == NM
641 ).
642
643'$file_is_unchanged'(F, R, Age) :-
644 time_file64(F,CurrentAge),
645 ( (Age == CurrentAge ; Age = -1) -> true; erase(R), erase).
646
647 % inform the file has been loaded and is now available.
648'$loaded'(F, UserFile, M, OldF, Line, Reconsult0, Reconsult, Dir, TOpts, Opts) :-
649 ( '$lf_opt'('$from_stream',TOpts,true) -> working_directory(Dir,Dir) ; file_directory_name(F, Dir) ),
650 nb_setval('$consulting_file', F ),
651 (
652 % if we are reconsulting, always start from scratch
653 Reconsult0 \== consult,
654 Reconsult0 \== not_loaded,
655 Reconsult0 \== changed,
656 recorded('$source_file','$source_file'(F, _,_),R),
657 erase(R),
658 erase
659 ;
660 var(Reconsult0)
661 ->
662 Reconsult = var
663 ;
664 Reconsult = Reconsult0
665 ),
666 (
667 Reconsult \== ,
668 recorded('$lf_loaded','$lf_loaded'(F, _, _, _, _, _, _),R),
669 erase(R),
670 erase
671 ;
672 var(Reconsult)
673 ->
674 Reconsult = var
675 ;
676 Reconsult = Reconsult0
677 ),
678 ( '$lf_opt'('$from_stream',TOpts,true) -> Age = 0 ; time_file64(F, Age) ),
679 % modules are logically loaded only once
680
681 ( recorded('$module','$module'(F,_DonorM,_SourceF, _AllExports, _Line),_) -> recorded ;
682 recordaifnot('$source_file','$source_file'( F, Age, M), _) -> recordaifnot ;
683 recordaifnot ),
684 recorda('$lf_loaded','$lf_loaded'( F, M, Reconsult, UserFile, OldF, Line, Opts), _).
685
686/** @pred make
687
688SWI-Prolog originally included this built-in as a Prolog version of the Unix `make`
689utility program. In this case the idea is to reconsult all source files that have been changed since they were originally compiled into Prolog. YAP has a limited implementation of make/0 that
690just goes through every loaded file and verifies whether reloading is needed.
691
692*/
693
694recorda :-
695 recorded('$lf_loaded','$lf_loaded'(F1,_M,reconsult,_,_,_,_),_),
696 load_files(F1, [if(changed)]),
697 load_files.
698load_files.
699
700make_library_index(_Directory).
701
702'$fetch_stream_alias'(OldStream,Alias) :-
703 stream_property(OldStream, alias(Alias)), stream_property.
704
705'$require'(_Ps, _M).
706
707'$store_clause'('$source_location'(File, _Line):Clause, File) :-
708 assert_static(Clause).
709% reload_file(File) :-
710% ' $source_base_name'(File, Compile),
711% findall(M-Opts,
712% source_file_property(File, load_context(M, _, Opts)),
713% Modules),
714% ( Modules = [First-OptsFirst|Rest]
715% -> Extra = [ silent(false),
716% register(false)
717% ],
718% merge_options([if(true)|Extra], OptsFirst, OFirst),
719% % debug(make, 'Make: First load ~q', [load_files(First:Compile, OFirst)]),
720% load_files(First:Compile, OFirst),
721% forall(member(Context-Opts, Rest),
722% ( merge_options([if(not_loaded)|Extra], Opts, O),
723% % debug(make, 'Make: re-import: ~q',
724% % [load_files(Context:Compile, O)]),
725% load_files(Context:Compile, O)
726% ))
727% ; load_files(user:Compile)
728% ).
729
730% ' $source_base_name'(File, Compile) :-
731% file_name_extension(Compile, Ext, File),
732% user:prolog_file_type(Ext, prolog), !.
733% ' $source_base_name'(File, File).
734
735source_file_property( File0, Prop) :-
736 ( nonvar(File0) -> absolute_file_name(File0,File) ; File = File0 ),
737 '$source_file_property'( File, Prop).
738
739'$source_file_property'( OldF, includes(F, Age)) :-
740 recorded('$lf_loaded','$lf_loaded'( F, _M, include, _File, OldF, _Line, _), _),
741 recorded('$source_file','$source_file'( F, Age, _), _).
742'$source_file_property'( F, included_in(OldF, Line)) :-
743 recorded('$lf_loaded','$lf_loaded'( F, _M, include, _File, OldF, Line, _), _).
744'$source_file_property'( F, load_context(OldF, Line, Options)) :-
745 recorded('$lf_loaded','$lf_loaded'( F, _M, V, _File, OldF, Line, Options), _), V \== recorded.
746'$source_file_property'( F, modified(Age)) :-
747 recorded('$source_file','$source_file'( F, Age, _), _).
748'$source_file_property'( F, module(M)) :-
749 recorded('$module','$module'(F,M,_,_,_),_).
750
751unload_file( F0 ) :-
752 absolute_file_name( F0, F1, [expand(true),file_type(prolog)] ),
753 '$unload_file'( F1, F0 ).
754
755% eliminate multi-files;
756% get rid of file-only predicataes.
757'$unload_file'( FileName, _F0 ) :-
758 current_module(Mod),
759 '$current_predicate'(_A,Mod,P,all),
760 '$owner_file'(P,Mod,FileName),
761 \+ '$is_multifile'(P,Mod),
762 functor( P, Na, Ar),
763 abolish(Mod:Na/Ar),
764 abolish.
765%next multi-file.
766'$unload_file'( FileName, _F0 ) :-
767 recorded('$source_file','$source_file'( FileName, _Age, _), R),
768 erase(R),
769 erase.
770'$unload_file'( FileName, _F0 ) :-
771 recorded('$mf','$mf_clause'(FileName,_Name,_Arity, Module,ClauseRef), R),
772 erase(R),
773 '$erase_clause'(ClauseRef, Module),
774 '$erase_clause'.
775'$unload_file'( FileName, _F0 ) :-
776 recorded('$multifile_dynamic'(_,_,_), '$mf'(_Na,_A,_M,FileName,R), R1),
777 erase(R1),
778 erase(R),
779 erase.
780'$unload_file'( FileName, _F0 ) :-
781 recorded('$multifile_defs','$defined'(FileName,_Name,_Arity,_Mod), R),
782 erase(R),
783 erase.
784'$unload_file'( FileName, _F0 ) :-
785 recorded('$module','$module'( FileName, Mod, _SourceF, _, _), R),
786 erase( R ),
787 unload_module(Mod),
788 unload_module.
789'$unload_file'( FileName, _F0 ) :-
790 recorded('$directive','$d'( FileName, _M:_G, _Mode, _VL, _Pos ), R),
791 erase(R),
792 erase.
793
794
795
796/**
797
798@defgroup Conditional_Compilation Conditional Compilation
799
800@ingroup YAPCompilerSettings
801
802@{
803 Conditional compilation builds on the same principle as
804term_expansion/2, goal_expansion/2 and the expansion of
805grammar rules to compile sections of the source-code
806conditionally. One of the reasons for introducing conditional
807compilation is to simplify writing portable code.
808
809
810Note that these directives can only be appear as separate terms in the
811 input. Typical usage scenarios include:
812
813
814 Load different libraries on different dialects
815
816 Define a predicate if it is missing as a system predicate
817
818 Realise totally different implementations for a particular
819part of the code due to different capabilities.
820
821 Realise different configuration options for your software.
822
823```
824:- if(test1).
825section_1.
826:- elif(test2).
827section_2.
828:- elif(test3).
829section_3.
830:- else.
831section_else.
832 :- endif.
833```
834
835*/
836
837/** @pred if( : _Goal_)
838
839 Compile subsequent code only if _Goal_ succeeds. For enhanced
840portability, _Goal_ is processed by `expand_goal/2` before execution.
841If an error occurs, the error is printed and processing proceeds as if
842 _Goal_ has failed.
843
844*/
845%
846% This is complicated because of embedded ifs.
847%
848'$if'(_,top) :- '$if', '$if'.
849'$if'(_Goal,_) :-
850 '__NB_getval__'('$if_level',Level0,Level=0),
851 Level is Level0 + 1,
852 nb_setval('$if_level',Level),
853 ( '__NB_getval__'('$endif', OldEndif, fail) -> '__NB_getval__' ; OldEndif='__NB_getval__'),
854 ( '__NB_getval__'('$if_skip_mode', Mode, fail) -> '__NB_getval__' ; Mode = '__NB_getval__' ),
855 nb_setval('$endif',elif(Level,OldEndif,Mode)),
856 nb_setval.
857% we are in skip mode, ignore....
858'$if'(_Goal,_) :-
859 '__NB_getval__'('$endif',elif(Level, OldEndif, skip), fail), '__NB_getval__',
860 nb_setval('$endif',endif(Level, OldEndif, skip)).
861% we are in non skip mode, check....
862'$if'(Goal,_) :-
863 (
864 '$if_call'(Goal)
865 ->
866 % we will execute this branch, and later enter skip
867 '__NB_getval__'('$endif', elif(Level,OldEndif,Mode), fail),
868 nb_setval('$endif',endif(Level,OldEndif,Mode))
869 ;
870 % we are now in skip, but can start an elif.
871 nb_setval('$if_skip_mode',skip)
872 ).
873
874/**
875@pred else
876Start `else' branch.
877
878*/
879'$else'(top) :- '$else', '$else'.
880'$else'(_) :-
881 '__NB_getval__'('$if_level',0,true),
882 '__NB_getval__',
883 '$do_error'(context_error(no_if),(:- else)).
884% we have done an if, so just skip
885'$else'(_) :-
886 nb_getval('$endif',endif(_Level,_,_)), nb_getval,
887 nb_setval('$if_skip_mode',skip).
888% we can try the elif
889'$else'(_) :-
890 '__NB_getval__'('$if_level',Level,Level=0),
891 nb_getval('$endif',elif(Level,OldEndif,Mode)),
892 nb_setval('$endif',endif(Level,OldEndif,Mode)),
893 nb_setval('$if_skip_mode',run).
894
895/** @pred elif(+ _Goal_)
896
897
898Equivalent to `:- else. :-if(Goal) ... :- endif.` In a sequence
899as below, the section below the first matching elif is processed, If
900no test succeeds the else branch is processed.
901*/
902'$elif'(_,top) :- '$elif', '$elif'.
903'$elif'(Goal,_) :-
904 '__NB_getval__'('$if_level',0,true),
905 '__NB_getval__',
906 '$do_error'(context_error(no_if),(:- elif(Goal))).
907% we have done an if, so just skip
908 nb_getval('$endif',endif(_,_,_)), nb_getval,
909 nb_setval('$if_skip_mode',skip).
910% we can try the elif
911'$elif'(Goal,_) :-
912 '__NB_getval__'('$if_level',Level,fail),
913 '__NB_getval__'('$endif',elif(Level,OldEndif,Mode),fail),
914 ('$if_call'(Goal)
915 ->
916% we will not skip, and we will not run any more branches.
917 nb_setval('$endif',endif(Level,OldEndif,Mode)),
918 nb_setval('$if_skip_mode',run)
919 ;
920% we will (keep) on skipping
921 nb_setval('$if_skip_mode',skip)
922 ).
923'$elif'(_,_).
924
925/** @pred endif
926End of conditional compilation.
927
928*/
929'$endif'(top) :- '$endif', '$endif'.
930'$endif'(_) :-
931% unmmatched endif.
932 '__NB_getval__'('$if_level',0,true),
933 '__NB_getval__',
934 '$do_error'(context_error(no_if),(:- endif)).
935'$endif'(_) :-
936% back to where you belong.
937 '__NB_getval__'('$if_level',Level,Level=0),
938 nb_getval('$endif',Endif),
939 Level0 is Level-1,
940 nb_setval('$if_level',Level0),
941 arg(2,Endif,OldEndif),
942 arg(3,Endif,OldMode),
943 nb_setval('$endif',OldEndif),
944 nb_setval('$if_skip_mode',OldMode).
945
946
947'$if_call'(G) :-
948 catch('$eval_if'(G), E, (print_message(error, E), fail)).
949
950'$eval_if'(Goal) :-
951 '$expand_term'(Goal,TrueGoal),
952 once(TrueGoal).
953
954'$if_directive'((:- if(_))).
955'$if_directive'((:- else)).
956'$if_directive'((:- elif(_))).
957'$if_directive'((:- endif)).
958
959
960'$comp_mode'( OldCompMode, CompMode) :-
961 var(CompMode), var,
962 '$fetch_comp_status'( OldCompMode ).
963'$comp_mode'(OldCompMode, assert_all) :-
964'$comp_mode',
965 '$fetch_comp_status'(OldCompMode),
966 nb_setval('$assert_all',on).
967'$comp_mode'(OldCompMode, source) :-
968 '$comp_mode',
969 '$fetch_comp_status'(OldCompMode),
970 set_prolog_flag(source, true).
971'$comp_mode'(OldCompMode, compact) :-
972 '$fetch_comp_status'(OldCompMode),
973 set_prolog_flag(source, false).
974
975'$fetch_comp_status'(assert_all) :-
976 '__NB_getval__'('$assert_all',on, fail), '__NB_getval__'.
977'$fetch_comp_status'(source) :-
978 current_prolog_flag(source, true), current_prolog_flag.
979'$fetch_comp_status'(compact).
980
981/** consult_depth(-int:_LV_)
982 *
983 * Unify _LV_ with the number of files being consulted.
984 */
985consult_depth(LV) :- '$show_consult_level'(LV).
986
987prolog_library(File) :-
988 yap_flag(verbose_load,Old,false),
989 ensure_loaded(library(File)),
990 yap_flag(verbose_load,_,Old).
991
992'$full_filename'(File0,File) :-
993 absolute_file_name(File0,[access(read),file_type(prolog),file_errors(fail),solutions(first),expand(true)],File).
994
995:- '$add_multifile'(dot_qualified_goal,1,user).
996
997
998/**
999
1000 @}
1001*/
1002
abolish(+ PredSpec)
absolute_file_name(+Name:atom,+Path:atom)
absolute_file_name( -File:atom, +Path:atom, +Options:list)
assert_static(: C)
catch( : Goal,+ Exception,+ Action)
module(+ M:atom,+ L:list )
must_be_callable( ?_Goal_ )
recordaifnot(+ K, T,- R)
stream_property( Stream, Prop )
Definition: top.yap:2
working_directory( ?_CurDir_,? NextDir)
nb_setval(+ Name,+ Value)
erase(+ R)
recordz(+ K, T,- R)
current_module( ? Mod:atom)
use_module(? M,? F,+ L)
halt(+ I)
nb_getval(+ Name, - Value)
once( 0:G)
current_prolog_flag(? Flag,- Value)
set_prolog_flag(+ Flag,+ Value)
compile(+ F )
consult(+ F)
ensure_loaded(+ F)
load_files(+_Files_, +_Options_)
prolog_load_context(? Key, ? Value)
Definition: consult.yap:479
reconsult(+ F )
arg(+ N,+ T, A)
functor( T, F, N)
nonvar( T)
var( T)