1540 lines
45 KiB
Prolog
1540 lines
45 KiB
Prolog
/*************************************************************************
|
||
* *
|
||
* YAP Prolog *
|
||
* *
|
||
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
||
* *
|
||
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
||
* *
|
||
**************************************************************************
|
||
* *
|
||
* File: consult.yap *
|
||
* Last rev: 8/2/88 *
|
||
* mods: *
|
||
* comments: Consulting Files in YAP *
|
||
* *
|
||
*************************************************************************/
|
||
:- system_module( '$_consult', [compile/1,
|
||
consult/1,
|
||
db_files/1,-
|
||
ensure_loaded/1,
|
||
exists_source/1,
|
||
exo_files/1,
|
||
(initialization)/2,
|
||
load_files/2,
|
||
make/0,
|
||
make_library_index/1,
|
||
module/2,
|
||
prolog_load_context/2,
|
||
reconsult/1,
|
||
source_file/1,
|
||
source_file/2,
|
||
source_file_property/2,
|
||
use_module/3],
|
||
['$add_multifile'/3,
|
||
'$csult'/2,
|
||
'$do_startup_reconsult'/1,
|
||
'$elif'/2,
|
||
'$else'/1,
|
||
'$endif'/1,
|
||
'$if'/2,
|
||
'$include'/2,
|
||
'$initialization'/1,
|
||
'$initialization'/2,
|
||
'$lf_opt'/3,
|
||
'$load_files'/3,
|
||
'$require'/2,
|
||
'$set_encoding'/1,
|
||
'$use_module'/3]).
|
||
|
||
:- use_system_module( '$_absf', ['$full_filename'/3]).
|
||
|
||
:- use_system_module( '$_boot', ['$clear_reconsulting'/0,
|
||
'$init_system'/0,
|
||
'$init_win_graphics'/0,
|
||
'$loop'/2,
|
||
'$system_catch'/4]).
|
||
|
||
:- use_system_module( '$_errors', ['$do_error'/2]).
|
||
|
||
:- use_system_module( '$_load_foreign', ['$import_foreign'/3]).
|
||
|
||
:- use_system_module( '$_modules', ['$add_to_imports'/3,
|
||
'$convert_for_export'/7,
|
||
'$extend_exports'/3]).
|
||
|
||
:- use_system_module( '$_preds', ['$current_predicate_no_modules'/3]).
|
||
|
||
/**
|
||
|
||
\defgroup YAPConsulting Loading files into YAP
|
||
@ingroup YAPLoading
|
||
|
||
We present the main predicates and directives available to load
|
||
files and to set-up the Prolog environment. We discuss
|
||
|
||
+ @ref YAPReadFiles
|
||
|
||
+ @ref YAPCompilerSettings
|
||
|
||
|
||
@defgroup YAPReadFiles The Predicates that Read Source Files
|
||
@ingroup YAPConsulting
|
||
|
||
@{
|
||
|
||
*/
|
||
|
||
|
||
/**
|
||
|
||
@pred load_files(+ _Files_, + _Options_)
|
||
|
||
General implementation of the consult/1 family. Execution is controlled by the
|
||
following flags:
|
||
|
||
+ consult(+ _Mode_)
|
||
|
||
This extension controls the type of file to load. If _Mode_ is:
|
||
|
||
`consult`, clauses are added to the data-base, unless from the same file;
|
||
`reconsult`, clauses are recompiled,
|
||
`db`, these are facts that need to be added to the data-base,
|
||
`exo`, these are facts with atoms and integers that can be stored in a compact representation (see load_exo/1).
|
||
|
||
+ silent(+ _Bool_)
|
||
|
||
If true, load the file without printing a message. The specified
|
||
value is the default for all files loaded as a result of loading
|
||
the specified files.
|
||
|
||
+ stream(+ _Input_)
|
||
|
||
This SWI-Prolog extension compiles the data from the stream
|
||
_Input_. If this option is used, _Files_ must be a single atom
|
||
which is used to identify the source-location of the loaded
|
||
clauses as well as remove all clauses if the data is re-consulted.
|
||
|
||
This option is added to allow compiling from non-file locations
|
||
such as databases, the web, the user (see consult/1) or other
|
||
servers.
|
||
|
||
+ compilation_mode(+ _Mode_)
|
||
|
||
This extension controls how procedures are compiled. If _Mode_ is
|
||
`compact` clauses are compiled and no source code is stored; if it
|
||
is `source` clauses are compiled and source code is stored; if it
|
||
is `assert_all` clauses are asserted into the data-base.
|
||
|
||
+ encoding(+ _Encoding_)
|
||
|
||
Character encoding used in consulting files. Please (see
|
||
[Encoding](@ref Encoding)) for supported encodings.
|
||
|
||
+ expand(+ _Bool_)
|
||
|
||
If `true`, run the filenames through expand_file_name/2 and load
|
||
the returned files. Default is false, except for consult/1 which
|
||
is intended for interactive use.
|
||
|
||
+ if(+ _Condition_)
|
||
|
||
Load the file only if the specified _Condition_ is satisfied. The
|
||
value `true` the file unconditionally, `changed` loads the file if
|
||
it was not loaded before, or has been modified since it was loaded
|
||
the last time, `not_loaded` loads the file if it was not loaded
|
||
before.
|
||
|
||
+ imports(+ _ListOrAll_)
|
||
|
||
If `all` and the file is a module file, import all public
|
||
predicates. Otherwise import only the named predicates. Each
|
||
predicate is referred to as `\<name\>/\<arity\>`. This option has
|
||
no effect if the file is not a module file.
|
||
|
||
+ must_be_module(+ _Bool_)
|
||
|
||
If true, raise an error if the file is not a module file. Used by
|
||
` use_module/1 and use_module/2.
|
||
|
||
+ autoload(+ _Autoload_)
|
||
|
||
SWI-compatible option where if _Autoload_ is `true` undefined
|
||
predicates are loaded on first call.
|
||
|
||
+ derived_from(+ _File_)
|
||
|
||
SWI-compatible option to control make/0. Currently not supported.
|
||
|
||
*/
|
||
%
|
||
% SWI options
|
||
% autoload(true,false)
|
||
% derived_from(File) -> make
|
||
% encoding(Encoding) => implemented
|
||
% expand(true,false)
|
||
% if(changed,true,not_loaded) => implemented
|
||
% imports(all,List) => implemented
|
||
% qcompile(true,false)
|
||
% silent(true,false) => implemented
|
||
% stream(Stream) => implemented
|
||
% consult(consult,reconsult,exo,db) => implemented
|
||
% compilation_mode(compact,source,assert_all) => implemented
|
||
% register(true, false) => implemented
|
||
%
|
||
load_files(Files,Opts) :-
|
||
'$load_files'(Files,Opts,load_files(Files,Opts)).
|
||
|
||
'$lf_option'(autoload, 1, _).
|
||
'$lf_option'(derived_from, 2, false).
|
||
'$lf_option'(encoding, 3, default).
|
||
'$lf_option'(expand, 4, false).
|
||
'$lf_option'(if, 5, true).
|
||
'$lf_option'(imports, 6, all).
|
||
'$lf_option'(qcompile, 7, never).
|
||
'$lf_option'(silent, 8, _).
|
||
'$lf_option'(skip_unix_header, 9, false).
|
||
'$lf_option'(compilation_mode, 10, source).
|
||
'$lf_option'(consult, 11, reconsult).
|
||
'$lf_option'(stream, 12, _).
|
||
'$lf_option'(register, 13, true).
|
||
'$lf_option'('$files', 14, _).
|
||
'$lf_option'('$call', 15, _).
|
||
'$lf_option'('$use_module', 16, _).
|
||
'$lf_option'('$consulted_at', 17, _).
|
||
'$lf_option'('$options', 18, _).
|
||
'$lf_option'('$location', 19, _).
|
||
'$lf_option'(dialect, 20, yap).
|
||
'$lf_option'(format, 21, source).
|
||
'$lf_option'(redefine_module, 22, false).
|
||
'$lf_option'(reexport, 23, false).
|
||
'$lf_option'(sandboxed, 24, false).
|
||
'$lf_option'(scope_settings, 25, false).
|
||
'$lf_option'(modified, 26, _).
|
||
'$lf_option'('$context_module', 27, _).
|
||
'$lf_option'('$parent_topts', 28, _).
|
||
'$lf_option'(must_be_module, 29, false).
|
||
|
||
'$lf_option'(last_opt, 29).
|
||
|
||
'$lf_opt'( Op, TOpts, Val) :-
|
||
'$lf_option'(Op, Id, _),
|
||
arg( Id, TOpts, Val ).
|
||
|
||
'$load_files'(Files, Opts, Call) :-
|
||
( '$nb_getval'('$lf_status', OldTOpts, fail), nonvar(OldTOpts) ->
|
||
'$lf_opt'(silent, OldTOpts, OldVerbosity),
|
||
'$lf_opt'(autoload, OldTOpts, OldAutoload)
|
||
;
|
||
true ),
|
||
'$check_files'(Files,load_files(Files,Opts)),
|
||
'$lf_option'(last_opt, LastOpt),
|
||
functor( TOpts, opt, LastOpt ),
|
||
( source_location(ParentF, Line) -> true ; ParentF = user_input, Line = -1 ),
|
||
'$lf_opt'('$location', TOpts, ParentF:Line),
|
||
'$lf_opt'('$files', TOpts, Files),
|
||
'$lf_opt'('$call', TOpts, Call),
|
||
'$lf_opt'('$options', TOpts, Opts),
|
||
'$lf_opt'('$parent_topts', TOpts, OldTOpts),
|
||
'$process_lf_opts'(Opts,TOpts,Files,Call),
|
||
'$lf_default_opts'(1, LastOpt, TOpts),
|
||
'$check_use_module'(Call,UseModule),
|
||
'$lf_opt'('$use_module', TOpts, UseModule),
|
||
'$current_module'(M0),
|
||
( '$lf_opt'(silent, TOpts, Verbosity),
|
||
var(Verbosity) ->
|
||
Verbosity = OldVerbosity
|
||
;
|
||
true
|
||
),
|
||
( '$lf_opt'(autoload, TOpts, Autoload),
|
||
var(Autoload) ->
|
||
Autoload = OldAutoload
|
||
;
|
||
true
|
||
),
|
||
% make sure we can run consult
|
||
'$init_system',
|
||
'$lf'(Files, M0, Call, TOpts).
|
||
|
||
'$check_files'(Files, Call) :-
|
||
var(Files), !,
|
||
'$do_error'(instantiation_error, Call).
|
||
'$check_files'(M:Files, Call) :- !,
|
||
(var(M)
|
||
->
|
||
'$do_error'(instantiation_error, Call)
|
||
;
|
||
atom(M)
|
||
->
|
||
'$check_files'(Files,Call)
|
||
;
|
||
'$do_error'(type_error(atom,M), Call)
|
||
).
|
||
'$check_files'(Files, Call) :-
|
||
( ground(Files)
|
||
->
|
||
true
|
||
;
|
||
'$do_error'(instantiation_error, Call)
|
||
).
|
||
|
||
'$process_lf_opts'(V, _, _, Call) :-
|
||
var(V), !,
|
||
'$do_error'(instantiation_error,Call).
|
||
'$process_lf_opts'([], _, _, _).
|
||
'$process_lf_opts'([Opt|Opts],TOpt,Files,Call) :-
|
||
Opt =.. [Op, Val],
|
||
ground(Val),
|
||
'$lf_opt'(Op, TOpt, Val),
|
||
'$process_lf_opt'(Op, Val,Call), !,
|
||
'$process_lf_opts'(Opts, TOpt, Files, Call).
|
||
'$process_lf_opts'([Opt|_],_,_,Call) :-
|
||
'$do_error'(domain_error(unimplemented_option,Opt),Call).
|
||
|
||
'$process_lf_opt'(autoload, Val, Call) :-
|
||
( Val == false -> true ;
|
||
Val == true -> true ;
|
||
'$do_error'(domain_error(unimplemented_option,autoload(Val)),Call) ).
|
||
'$process_lf_opt'(derived_from, File, Call) :-
|
||
( atom(File) -> true ; '$do_error'(type_error(atom,File),Call) ).
|
||
'$process_lf_opt'(encoding, Encoding, _Call) :-
|
||
atom(Encoding).
|
||
'$process_lf_opt'(expand, Val, Call) :-
|
||
( Val == true -> '$do_error'(domain_error(unimplemented_option,expand),Call) ;
|
||
Val == false -> true ;
|
||
'$do_error'(domain_error(unimplemented_option,expand(Val)),Call) ).
|
||
'$process_lf_opt'(if, If, Call) :-
|
||
( If == changed -> true ;
|
||
If == true -> true ;
|
||
If == not_loaded -> true ;
|
||
'$do_error'(domain_error(unimplemented_option,if),Call) ).
|
||
'$process_lf_opt'(imports, Val, Call) :-
|
||
( Val == all -> true ;
|
||
var(Val) -> Val = all ;
|
||
is_list(Val) -> ( ground(Val) -> true ; '$do_error'(instantiation_error,Call) ) ;
|
||
'$do_error'(domain_error(unimplemented_option,imports(Val)),Call) ).
|
||
'$process_lf_opt'(qcompile, Val,Call) :-
|
||
( Val == true -> '$do_error'(domain_error(unimplemented_option,expand),Call) ;
|
||
Val == false -> true ;
|
||
'$do_error'(domain_error(unimplemented_option,expand(Val)),Call) ).
|
||
'$process_lf_opt'(silent, Val, Call) :-
|
||
( Val == false -> true ;
|
||
Val == true -> true ;
|
||
'$do_error'(domain_error(unimplemented_option,silent(Val)),Call) ).
|
||
'$process_lf_opt'(skip_unix_header, Val, Call) :-
|
||
( Val == false -> true ;
|
||
Val == true -> true ;
|
||
'$do_error'(domain_error(unimplemented_option,skip_unix_header(Val)),Call) ).
|
||
'$process_lf_opt'(compilation_mode, Val, Call) :-
|
||
( Val == source -> true ;
|
||
Val == compact -> true ;
|
||
Val == assert_all -> true ;
|
||
'$do_error'(domain_error(unimplemented_option,compilation_mode(Val)),Call) ).
|
||
'$process_lf_opt'(consult, Val , Call) :-
|
||
( Val == reconsult -> true ;
|
||
Val == consult -> true ;
|
||
Val == exo -> true ;
|
||
Val == db -> true ;
|
||
'$do_error'(domain_error(unimplemented_option,consult(Val)),Call) ).
|
||
'$process_lf_opt'(reexport, Val , Call) :-
|
||
( Val == true -> true ;
|
||
Val == false -> true ;
|
||
'$do_error'(domain_error(unimplemented_option,reexport(Val)),Call) ).
|
||
'$process_lf_opt'(must_be_module, Val , Call) :-
|
||
( Val == true -> true ;
|
||
Val == false -> true ;
|
||
'$do_error'(domain_error(unimplemented_option,must_be_module(Val)),Call) ).
|
||
'$process_lf_opt'(stream, Val, Call) :-
|
||
( current_stream(_,_,Val) -> true ;
|
||
'$do_error'(type_error(stream,Val),Call) ).
|
||
'$process_lf_opt'(register, Val, Call) :-
|
||
( Val == false -> true ;
|
||
Val == true -> true ;
|
||
'$do_error'(domain_error(unimplemented_option,register(Val)),Call) ).
|
||
'$process_lf_opt'('$context_module', Val, Call) :-
|
||
( atom(File) -> true ; '$do_error'(type_error(atom,File),Call) ).
|
||
|
||
|
||
'$lf_default_opts'(I, LastOpt, _TOpts) :- I > LastOpt, !.
|
||
'$lf_default_opts'(I, LastOpt, TOpts) :-
|
||
I1 is I+1,
|
||
arg(I, TOpts, A),
|
||
( nonvar(A) -> true ;
|
||
'$lf_option'(_Name, I, A)
|
||
),
|
||
'$lf_default_opts'(I1, LastOpt, TOpts).
|
||
|
||
|
||
|
||
'$check_use_module'(use_module(_), use_module(_)) :- !.
|
||
'$check_use_module'(use_module(_,_), use_module(_)) :- !.
|
||
'$check_use_module'(use_module(M,_,_), use_module(M)) :- !.
|
||
'$check_use_module'(_, load_files) :- !.
|
||
|
||
'$lf'(V,_,Call, _ ) :- var(V), !,
|
||
'$do_error'(instantiation_error,Call).
|
||
'$lf'([], _, _, _) :- !.
|
||
'$lf'(M:X, _, Call, TOpts) :- !,
|
||
(
|
||
atom(M)
|
||
->
|
||
'$lf'(X, M, Call, TOpts)
|
||
;
|
||
'$do_error'(type_error(atom,M),Call)
|
||
).
|
||
'$lf'([F|Fs], Mod, Call, TOpts) :- !,
|
||
% clean up after each consult
|
||
( '$lf'(F,Mod,Call, TOpts), fail ;
|
||
'$lf'(Fs, Mod, Call, TOpts), fail;
|
||
true
|
||
).
|
||
'$lf'(user, Mod, _, TOpts) :- !,
|
||
b_setval('$source_file', user_input),
|
||
'$do_lf'(Mod, user_input, user_input, TOpts).
|
||
'$lf'(user_input, Mod, _, TOpts) :- !,
|
||
b_setval('$source_file', user_input),
|
||
'$do_lf'(Mod, user_input, user_input, TOpts).
|
||
'$lf'(File, Mod, Call, TOpts) :-
|
||
'$lf_opt'(stream, TOpts, Stream),
|
||
b_setval('$source_file', File),
|
||
( var(Stream) ->
|
||
/* need_to_open_file */
|
||
'$full_filename'(File, Y, Call),
|
||
open(Y, read, Stream)
|
||
;
|
||
true
|
||
), !,
|
||
'$lf_opt'(reexport, TOpts, Reexport),
|
||
'$lf_opt'(if, TOpts, If),
|
||
( var(If) -> If = true ; true ),
|
||
'$lf_opt'(imports, TOpts, Imports),
|
||
'$start_lf'(If, Mod, Stream, TOpts, File, Reexport, Imports),
|
||
close(Stream).
|
||
'$lf'(X, _, Call, _) :-
|
||
'$do_error'(permission_error(input,stream,X),Call).
|
||
|
||
'$start_lf'(not_loaded, Mod, Stream, TOpts, UserFile, Reexport,Imports) :-
|
||
'$file_loaded'(Stream, Mod, Imports, TOpts), !,
|
||
'$lf_opt'('$options', TOpts, Opts),
|
||
'$lf_opt'('$location', TOpts, ParentF:Line),
|
||
'$loaded'(Stream, UserFile, Mod, ParentF, Line, not_loaded, _File, _Dir, Opts),
|
||
'$reexport'( TOpts, ParentF, Reexport, Imports, _File ).
|
||
'$start_lf'(changed, Mod, Stream, TOpts, UserFile, Reexport, Imports) :-
|
||
'$file_unchanged'(Stream, Mod, Imports, TOpts), !,
|
||
'$lf_opt'('$options', TOpts, Opts),
|
||
'$lf_opt'('$location', TOpts, ParentF:Line),
|
||
'$loaded'(Stream, UserFile, Mod, ParentF, Line, changed, _File, _Dir, Opts),
|
||
'$reexport'( TOpts, ParentF, Reexport, Imports, _File ).
|
||
'$start_lf'(_, Mod, Stream, TOpts, File, Reexport, Imports) :-
|
||
'$do_lf'(Mod, Stream, File, TOpts).
|
||
|
||
|
||
/**
|
||
|
||
@pred ensure_loaded(+ _F_) is iso
|
||
|
||
When the files specified by _F_ are module files,
|
||
ensure_loaded/1 loads them if they have note been previously
|
||
loaded, otherwise advertises the user about the existing name clashes
|
||
and prompts about importing or not those predicates. Predicates which
|
||
are not public remain invisible.
|
||
|
||
When the files are not module files, ensure_loaded/1 loads them
|
||
if they have not been loaded before, and naes nothing otherwise.
|
||
|
||
_F_ must be a list containing the names of the files to load.
|
||
*/
|
||
ensure_loaded(Fs) :-
|
||
'$load_files'(Fs, [if(not_loaded)],ensure_loaded(Fs)).
|
||
|
||
compile(Fs) :-
|
||
'$load_files'(Fs, [], compile(Fs)).
|
||
|
||
/**
|
||
@pred [ _F_ ]
|
||
@pred consult(+ _F_)
|
||
|
||
|
||
Adds the clauses written in file _F_ or in the list of files _F_
|
||
to the program.
|
||
|
||
In YAP consult/1 does not remove previous clauses for
|
||
the procedures defined in other files than _F_, but since YAP-6.4.3 it will redefine all procedures defined in _F_.
|
||
|
||
All code in YAP is compiled, and the compileer generates static
|
||
procedures by default. In case you need to manipulate the original
|
||
code, the expanded version of the original source code is available by
|
||
calling source/0 or by enabling the source flag.
|
||
|
||
*/
|
||
% consult(Fs) :-
|
||
% '$has_yap_or',
|
||
% '$do_error'(context_error(consult(Fs),clause),query).
|
||
consult(V) :-
|
||
var(V), !,
|
||
'$do_error'(instantiation_error,consult(V)).
|
||
consult(M0:Fs) :- !,
|
||
'$consult'(Fs, M0).
|
||
consult(Fs) :-
|
||
'$current_module'(M0),
|
||
'$consult'(Fs, M0).
|
||
|
||
'$consult'(Fs,Module) :-
|
||
'$access_yap_flags'(8, 2), % SICStus Prolog compatibility
|
||
!,
|
||
'$load_files'(Module:Fs,[],consult(Fs)).
|
||
'$consult'(Fs, Module) :-
|
||
'$load_files'(Module:Fs,[consult(consult)],consult(Fs)).
|
||
|
||
|
||
/**
|
||
|
||
@pred [ - _F_ ]
|
||
@pred reconsult(+ _F_ )
|
||
@pred compile(+ _F_ )
|
||
|
||
Updates the program by replacing the
|
||
previous definitions for the predicates defined in _F_. It differs from consult/1
|
||
in that it only multifile/1 predicates are not reset in a reconsult. Instead, consult/1
|
||
sees all predicates as multifile.
|
||
|
||
YAP also offers no difference between consult/1 and compile/1. The two
|
||
are implemented by the same exact code.
|
||
|
||
Example:
|
||
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
?- [file1, -file2, -file3, file4].
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
will consult `file1` `file4` and reconsult `file2` and
|
||
`file3`. That is, it could be written as:
|
||
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
?- consult(file1),
|
||
reconsult( [file2, file3],
|
||
consult( [file4] ).
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
*/
|
||
reconsult(Fs) :-
|
||
'$load_files'(Fs, [], reconsult(Fs)).
|
||
|
||
|
||
/* exo_files(+ _Files_)
|
||
|
||
Load compactly a database of facts with equal structure, see @cite
|
||
x. Useful when wanting to read in a very compact way database tables,
|
||
it saves space by storing data, not a compiled program. The idea was
|
||
introduced in @cite y, but never implemented because often indexing
|
||
just takes more room. It was redefined recebtly by exploiting
|
||
different forms of indexing, as shown in @cite x.
|
||
|
||
@note implementation
|
||
|
||
The function Yap_ExoLookup() is the mai interface betwwen the WAM
|
||
and exo components. The algorithms are straightforward, that is,
|
||
mostly hash-tables but have close to linear performance..
|
||
*/
|
||
|
||
exo_files(Fs) :-
|
||
'$load_files'(Fs, [consult(exo), if(not_loaded)], exo_files(Fs)).
|
||
|
||
/**
|
||
|
||
@pred load_db(+ _Files_)
|
||
|
||
|
||
Load a database of ground facts. All facts must take up the same amount of storage, so that
|
||
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.
|
||
|
||
See \cite for a motivation for this technique. YAP implements this
|
||
optimization by default whenever it loads a large number of facts (see
|
||
Yap_BuildMegaClause(PredEntry *ap) ) for the details. On the other
|
||
hand, loading the data-base will cause fragmentation because
|
||
individual facts facts need extra headers ands tails, and because
|
||
often new atoms will be stored in the Symbol Table, see
|
||
LookupAtom(const char *atom). The main advantage of load_db/1 is
|
||
that it allocates the necessary memory only once. Just doing this
|
||
may halve total memory usage in large in-memory database-oriented applications.
|
||
|
||
@note Implementation
|
||
|
||
YAP implements load_db/1 as a two-step non-optimised process. First,
|
||
it counts the nmuber of facts and checks their size. Second, it
|
||
allocates and fills the memory. The first step of the algorithm is
|
||
implemented by dbload_get_space(), and the second by
|
||
dbload_add_facts().
|
||
|
||
db_files/1 itself is just a call to load_files/2.
|
||
*/
|
||
db_files(Fs) :-
|
||
'$load_files'(Fs, [consult(db), if(not_loaded)], exo_files(Fs)).
|
||
|
||
|
||
'$csult'(Fs, M) :-
|
||
'$extract_minus'(Fs, MFs), !,
|
||
'$load_files'(M:MFs,[],[M:Fs]).
|
||
'$csult'(Fs, M) :-
|
||
'$load_files'(M:Fs,[consult(consult)],[M:Fs]).
|
||
|
||
'$extract_minus'([], []).
|
||
'$extract_minus'([-F|Fs], [F|MFs]) :-
|
||
'$extract_minus'(Fs, MFs).
|
||
|
||
|
||
'$do_lf'(ContextModule, Stream, UserFile, TOpts) :-
|
||
'$lf_opt'('$context_module', TOpts, ContextModule),
|
||
'$lf_opt'(reexport, TOpts, Reexport),
|
||
'$msg_level'( TOpts, Verbosity),
|
||
% format( 'I=~w~n', [Verbosity=UserFile] ),
|
||
'$lf_opt'(encoding, TOpts, Encoding),
|
||
'$set_encoding'(Stream, Encoding),
|
||
% export to process
|
||
b_setval('$lf_status', TOpts),
|
||
'$reset_if'(OldIfLevel),
|
||
% take care with [a:f], a is the ContextModule
|
||
'$current_module'(SourceModule, ContextModule),
|
||
'$lf_opt'(consult, TOpts, Reconsult0),
|
||
'$lf_opt'('$options', TOpts, Opts),
|
||
'$lf_opt'('$location', TOpts, ParentF:Line),
|
||
'$loaded'(Stream, UserFile, SourceModule, ParentF, Line, Reconsult, File, Dir, Opts),
|
||
working_directory(OldD, Dir),
|
||
H0 is heapused, '$cputime'(T0,_),
|
||
'$set_current_loop_stream'(OldStream, Stream),
|
||
'$swi_current_prolog_flag'(generate_debug_info, GenerateDebug),
|
||
'$lf_opt'(compilation_mode, TOpts, CompMode),
|
||
'$comp_mode'(OldCompMode, CompMode),
|
||
recorda('$initialisation','$',_),
|
||
( Reconsult \== consult ->
|
||
'$start_reconsulting'(File),
|
||
'$start_consult'(Reconsult,File,LC),
|
||
'$remove_multifile_clauses'(File),
|
||
StartMsg = reconsulting,
|
||
EndMsg = reconsulted
|
||
;
|
||
'$start_consult'(Reconsult,File,LC),
|
||
( File \= user_input, File \= [] -> '$remove_multifile_clauses'(File) ; true ),
|
||
StartMsg = consulting,
|
||
EndMsg = consulted
|
||
),
|
||
print_message(Verbosity, loading(StartMsg, File)),
|
||
'$lf_opt'(skip_unix_header , TOpts, SkipUnixHeader),
|
||
( SkipUnixHeader == true->
|
||
'$skip_unix_header'(Stream)
|
||
;
|
||
true
|
||
),
|
||
'$loop'(Stream,Reconsult),
|
||
H is heapused-H0, '$cputime'(TF,_), T is TF-T0,
|
||
'$current_module'(Mod, SourceModule),
|
||
print_message(Verbosity, loaded(EndMsg, File, Mod, T, H)),
|
||
'$end_consult',
|
||
(
|
||
Reconsult = reconsult ->
|
||
'$clear_reconsulting'
|
||
;
|
||
true
|
||
),
|
||
'$set_current_loop_stream'(Stream, OldStream),
|
||
'$swi_set_prolog_flag'(generate_debug_info, GenerateDebug),
|
||
'$comp_mode'(_CompMode, OldCompMode),
|
||
working_directory(_,OldD),
|
||
% surely, we were in run mode or we would not have included the file!
|
||
nb_setval('$if_skip_mode',run),
|
||
% back to include mode!
|
||
nb_setval('$if_level',OldIfLevel),
|
||
'$lf_opt'('$use_module', TOpts, UseModule),
|
||
'$bind_module'(Mod, UseModule),
|
||
'$lf_opt'(imports, TOpts, Imports),
|
||
'$import_to_current_module'(File, ContextModule, Imports, _, TOpts),
|
||
'$reexport'( TOpts, ParentF, Reexport, Imports, File ),
|
||
( LC == 0 -> prompt(_,' |: ') ; true),
|
||
'$exec_initialisation_goals',
|
||
% format( 'O=~w~n', [Mod=UserFile] ),
|
||
!.
|
||
|
||
% are we in autoload and autoload_flag is false?
|
||
'$msg_level'( TOpts, Verbosity) :-
|
||
'$lf_opt'(autoload, TOpts, AutoLoad),
|
||
AutoLoad == true,
|
||
'$swi_current_prolog_flag'(verbose_autoload, false), !,
|
||
Verbosity = silent.
|
||
'$msg_level'( _TOpts, Verbosity) :-
|
||
'$swi_current_prolog_flag'(verbose_load, false), !,
|
||
Verbosity = silent.
|
||
'$msg_level'( _TOpts, Verbosity) :-
|
||
'$swi_current_prolog_flag'(verbose, silent), !,
|
||
Verbosity = silent.
|
||
'$msg_level'( TOpts, Verbosity) :-
|
||
'$lf_opt'(silent, TOpts, Silent),
|
||
Silent == true, !,
|
||
Verbosity = silent.
|
||
'$msg_level'( _TOpts, informational).
|
||
|
||
'$reset_if'(OldIfLevel) :-
|
||
'$nb_getval'('$if_level', OldIfLevel, fail), !,
|
||
nb_setval('$if_level',0).
|
||
'$reset_if'(0) :-
|
||
nb_setval('$if_level',0).
|
||
|
||
'$get_if'(Level0) :-
|
||
'$nb_getval'('$if_level', Level, fail), !,
|
||
Level0 = Level.
|
||
'$get_if'(0).
|
||
|
||
'$bind_module'(_, load_files).
|
||
'$bind_module'(Mod, use_module(Mod)).
|
||
|
||
'$import_to_current_module'(File, ContextModule, Imports, RemainingImports, TOpts) :-
|
||
\+ recorded('$module','$module'(File, _Module, _, |