535 lines
16 KiB
Prolog
Executable File
535 lines
16 KiB
Prolog
Executable File
|
|
/*************************************************************************
|
|
* *
|
|
* YAP Prolog *
|
|
* *
|
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
|
* *
|
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-2011 *
|
|
* *
|
|
**************************************************************************
|
|
* *
|
|
* File: qly.yap *
|
|
* Last rev: *
|
|
* mods: *
|
|
* comments: fast save/restore *
|
|
* *
|
|
*************************************************************************/
|
|
:- system_module( '$_qly', [qload_module/1,
|
|
qsave_file/1,
|
|
qsave_module/1,
|
|
qsave_program/1,
|
|
qsave_program/2,
|
|
restore/1,
|
|
save_program/1,
|
|
save_program/2], ['$init_state'/0]).
|
|
|
|
:- use_system_module( '$_absf', ['$system_library_directories'/2]).
|
|
|
|
:- use_system_module( '$_boot', ['$system_catch'/4]).
|
|
|
|
:- use_system_module( '$_consult', ['$do_startup_reconsult'/1]).
|
|
|
|
:- use_system_module( '$_control', ['$run_atom_goal'/1]).
|
|
|
|
:- use_system_module( '$_errors', ['$do_error'/2]).
|
|
|
|
:- use_system_module( '$_preds', ['$init_preds'/0]).
|
|
|
|
:- use_system_module( '$_protect', ['$protect'/0]).
|
|
|
|
:- use_system_module( '$_threads', ['$reinit_thread0'/0]).
|
|
|
|
:- use_system_module( '$_yio', ['$extend_file_search_path'/1]).
|
|
|
|
/**
|
|
|
|
@defgroup YAPSaving Saving and Loading Prolog States
|
|
@ingroup YAPLoading
|
|
|
|
YAP can save and read images of its current state to files, known as
|
|
saved states. It is possible to save the entire state or just a module
|
|
or a file. Notice that saved states in YAP depend on the architecture
|
|
where they were made, and may also depend on the version of YAP being
|
|
saved.
|
|
|
|
YAP always tries to find saved states from the current directory
|
|
first. If it cannot it will use the environment variable [YAPLIBDIR](@ref YAPLIBDIR), if
|
|
defined, or search the default library directory.
|
|
*/
|
|
|
|
/** @pred save_program(+ _F_)
|
|
Saves the current state of the data-base in file _F_ .
|
|
|
|
The result is a resource archive containing a saved state that
|
|
expresses all Prolog data from the running program and all
|
|
user-defined resources. Depending on the stand_alone option, the
|
|
resource is headed by the emulator, a Unix shell script or nothing.
|
|
|
|
**/
|
|
save_program(File) :-
|
|
qsave_program(File).
|
|
|
|
/** @pred save_program(+ _F_, : _G_)
|
|
|
|
Saves an image of the current state of the YAP database in file
|
|
_F_, and guarantee that execution of the restored code will start by
|
|
trying goal _G_.
|
|
**/
|
|
qsave_program(File) :-
|
|
'$save_program_status'([], qsave_program(File)),
|
|
open(File, write, S, [type(binary)]),
|
|
'$qsave_program'(S),
|
|
close(S).
|
|
|
|
/** @pred qsave_program(+ _F_, Opts)
|
|
|
|
Saves an image of the current state of the YAP database in file
|
|
_F_, currently the options in _Opts_ are ignored:
|
|
|
|
+ stack(+ _KBytes_)
|
|
Limit for the local and global stack.
|
|
|
|
+ trail(+ _KBytes_)
|
|
Limit for the trail stack.
|
|
|
|
+ goal(: _Callable_)
|
|
Initialization goal for the new executable (see -g).
|
|
|
|
+ init_file(+ _Atom_)
|
|
Default initialization file for the new executable. See -f.
|
|
|
|
**/
|
|
qsave_program(File, Opts) :-
|
|
'$save_program_status'(Opts, qsave_program(File,Opts)),
|
|
open(File, write, S, [type(binary)]),
|
|
'$qsave_program'(S),
|
|
% make sure we're not going to bootstrap from this file.
|
|
close(S).
|
|
|
|
/** @pred save_program(+ _F_, : _G_)
|
|
|
|
Saves an image of the current state of the YAP database in file
|
|
_F_, and guarantee that execution of the restored code will start by
|
|
trying goal _G_.
|
|
**/
|
|
save_program(File, Goal) :-
|
|
recorda('$restore_goal', Goal ,_R),
|
|
fail.
|
|
save_program(File, _Goal) :-
|
|
qsave_program(File).
|
|
|
|
'$save_program_status'(Flags, G) :-
|
|
findall(F:V,'$x_yap_flag'(F,V),L),
|
|
recordz('$program_state',L,_),
|
|
'$cvt_qsave_flags'(Flags, G),
|
|
fail.
|
|
'$save_program_status'(_Flags, _G).
|
|
|
|
'$cvt_qsave_flags'(Flags, G) :-
|
|
nonvar(Flags),
|
|
strip_module(Flags, M, LFlags),
|
|
'$skip_list'(_Len, LFlags, []),
|
|
'$cvt_qsave_lflags'(LFlags, G, M).
|
|
'$cvt_qsave_flags'(Flags, G,_OFlags) :-
|
|
var(Flags),
|
|
'$do_error'(instantiation_error,G).
|
|
'$cvt_qsave_flags'(Flags, G,_OFlags) :-
|
|
'$do_error'(type_error(list,Flags),G).
|
|
|
|
'$cvt_qsave_lflags'([], _, _).
|
|
'$cvt_qsave_lflags'([Flag|Flags], G, M) :-
|
|
'$cvt_qsave_flag'(Flag, G, M),
|
|
'$cvt_qsave_lflags'(Flags, G, M).
|
|
|
|
'$cvt_qsave_flag'(Flag, G, _) :-
|
|
var(Flag), !,
|
|
'$do_error'(instantiation_error,G).
|
|
'$cvt_qsave_flag'(local(B), G, _) :- !,
|
|
( number(B) ->
|
|
(
|
|
B > 0 -> recordz('$restore_flag',local(B),_) ;
|
|
B =:= 0 -> true ;
|
|
'$do_error'(domain_error(not_less_than_zero,B),G))
|
|
;
|
|
'$do_error'(type_error(integer,B),G)
|
|
).
|
|
'$cvt_qsave_flag'(global(B), G, _) :- !,
|
|
( number(B) ->
|
|
(
|
|
B > 0 -> recordz('$restore_flag',global(B),_) ;
|
|
B =:= 0 -> true ;
|
|
'$do_error'(domain_error(not_less_than_zero,B),G))
|
|
;
|
|
'$do_error'(type_error(integer,B),G)
|
|
).
|
|
'$cvt_qsave_flag'(stack(B), G, _) :- !,
|
|
( number(B) ->
|
|
(
|
|
B > 0 -> recordz('$restore_flag',stack(B),_) ;
|
|
B =:= 0 -> true ;
|
|
'$do_error'(domain_error(not_less_than_zero,B),G))
|
|
;
|
|
'$do_error'(type_error(integer,B),G)
|
|
).
|
|
'$cvt_qsave_flag'(trail(B), G, _) :- !,
|
|
( number(B) ->
|
|
(
|
|
B > 0 -> recordz('$restore_flag',trail(B),_) ;
|
|
B =:= 0 -> true ;
|
|
'$do_error'(domain_error(not_less_than_zero,B),G))
|
|
;
|
|
'$do_error'(type_error(integer,B),G)
|
|
).
|
|
'$cvt_qsave_flag'(goal(B), G, M) :- !,
|
|
( callable(B) ->
|
|
strip_module(M:B, M1, G1),
|
|
recordz('$restore_flag',goal(M1:G1),_)
|
|
;
|
|
'$do_error'(type_error(callable,B),G)
|
|
).
|
|
'$cvt_qsave_flag'(toplevel(B), G, M) :- !,
|
|
( callable(B) ->
|
|
strip_module(M:B, M1, G1),
|
|
recordz('$restore_flag',toplevel(M1:G1),_)
|
|
;
|
|
'$do_error'(type_error(callable,B),G)
|
|
).
|
|
'$cvt_qsave_flag'(init_file(B), G, M) :- !,
|
|
( atom(B) ->
|
|
recordz('$restore_flag', init_file(M:B), _)
|
|
;
|
|
'$do_error'(type_error(atom,B),G)
|
|
).
|
|
%% '$cvt_qsave_flag'(autoload(_B), G, autoload(_B)).
|
|
%% '$cvt_qsave_flag'(op(_B), G, op(_B)).
|
|
%% '$cvt_qsave_flag'(stand_alone(_B), G, stand_alone(_B)).
|
|
%% '$cvt_qsave_flag'(emulator(_B), G, emulator(_B)).
|
|
%% '$cvt_qsave_flag'(foreign(_B), G, foreign(_B)).
|
|
'$cvt_qsave_flag'(Opt, G, _M) :-
|
|
'$do_error'(domain_error(qsave_program,Opt), G).
|
|
|
|
% there is some ordering between flags.
|
|
'$x_yap_flag'(goal, Goal).
|
|
'$x_yap_flag'(language, V).
|
|
'$x_yap_flag'(M:unknown, V) :-
|
|
current_module(M),
|
|
yap_flag(M:unknown, V).
|
|
'$x_yap_flag'(X, V) :-
|
|
yap_flag(X, V),
|
|
X \= language,
|
|
X \= readline,
|
|
X \= timezone,
|
|
X \= tty_control,
|
|
X \= undefined,
|
|
X \= user_input,
|
|
X \= user_output,
|
|
X \= user_error,
|
|
X \= version,
|
|
X \= version_data.
|
|
|
|
'$init_state' :-
|
|
recorded('$program_state', _, _), !,
|
|
'$do_init_state'.
|
|
'$init_state'.
|
|
|
|
'$do_init_state' :-
|
|
compile_expressions,
|
|
'$init_preds',
|
|
fail.
|
|
'$do_init_state' :-
|
|
recorded('$program_state',L,R),
|
|
erase(R),
|
|
lists:member(F:V,L),
|
|
catch(yap_flag(F,V),_,fail),
|
|
fail.
|
|
'$do_init_state' :-
|
|
'$reinit_thread0',
|
|
fail.
|
|
'$do_init_state' :-
|
|
set_value('$user_module',user),
|
|
'$protect',
|
|
fail.
|
|
'$do_init_state' :-
|
|
'$current_module'(prolog),
|
|
module(user),
|
|
fail.
|
|
'$do_init_state' :-
|
|
'$init_from_saved_state_and_args',
|
|
fail.
|
|
'$do_init_state'.
|
|
|
|
%
|
|
% first, recover what we need from the saved state...
|
|
%
|
|
'$init_from_saved_state_and_args' :-
|
|
'$init_path_extensions',
|
|
fail.
|
|
% use if we come from a save_program and we have SWI's shlib
|
|
'$init_from_saved_state_and_args' :-
|
|
current_prolog_flag(hwnd, _HWND),
|
|
load_files(library(win_menu), [silent(true)]),
|
|
fail.
|
|
'$init_from_saved_state_and_args' :-
|
|
recorded('$reload_foreign_libraries',G,R),
|
|
erase(R),
|
|
shlib:reload_foreign_libraries,
|
|
fail.
|
|
% this should be done before -l kicks in.
|
|
'$init_from_saved_state_and_args' :-
|
|
'$access_yap_flags'(16,0),
|
|
( exists('~/.yaprc') -> load_files('~/.yaprc', []) ; true ),
|
|
( exists('~/.prologrc') -> load_files('~/.prologrc', []) ; true ),
|
|
( exists('~/prolog.ini') -> load_files('~/prolog.ini', []) ; true ),
|
|
fail.
|
|
% use if we come from a save_program and we have a goal to execute
|
|
'$init_from_saved_state_and_args' :-
|
|
get_value('$consult_on_boot',X), X \= [],
|
|
set_value('$consult_on_boot',[]),
|
|
'$do_startup_reconsult'(X),
|
|
fail.
|
|
'$init_from_saved_state_and_args' :-
|
|
recorded('$restore_flag', init_file(M:B), R),
|
|
erase(R),
|
|
'$do_startup_reconsult'(M:B),
|
|
fail.
|
|
'$init_from_saved_state_and_args' :-
|
|
recorded('$restore_flag', unknown(M:B), R),
|
|
erase(R),
|
|
yap_flag(M:unknown,B),
|
|
fail.
|
|
'$init_from_saved_state_and_args' :-
|
|
'$startup_goals',
|
|
fail.
|
|
'$init_from_saved_state_and_args' :-
|
|
recorded('$restore_goal',G,R),
|
|
erase(R),
|
|
prompt(_,'| '),
|
|
'$system_catch'('$do_yes_no'((G->true),user),user,Error,user:'$Error'(Error)),
|
|
fail.
|
|
'$init_from_saved_state_and_args'.
|
|
|
|
'$init_path_extensions' :-
|
|
get_value('$extend_file_search_path',P), !,
|
|
P \= [],
|
|
set_value('$extend_file_search_path',[]),
|
|
'$extend_file_search_path'(P).
|
|
'$init_path_extensions' :-
|
|
retractall(user:library_directory(_)),
|
|
% make sure library_directory is open.
|
|
\+ clause(user:library_directory(_),_),
|
|
'$system_library_directories'(library,D),
|
|
assert(user:library_directory(D)),
|
|
fail.
|
|
'$init_path_extensions' :-
|
|
retractall(user:library_directory(_)),
|
|
% make sure library_directory is open.
|
|
\+ clause(user:library_directory(_),_),
|
|
'$system_library_directories'(commons,D),
|
|
assert(user:commons_directory(D)),
|
|
fail.
|
|
'$init_path_extensions'.
|
|
|
|
% then we can execute the programs.
|
|
'$startup_goals' :-
|
|
recorded('$startup_goal',G,_),
|
|
'$current_module'(Module),
|
|
'$system_catch'('$query'(once(G), []),Module,Error,user:'$Error'(Error)),
|
|
fail.
|
|
'$startup_goals' :-
|
|
get_value('$init_goal',GA),
|
|
GA \= [],
|
|
set_value('$init_goal',[]),
|
|
'$run_atom_goal'(GA),
|
|
fail.
|
|
'$startup_goals' :-
|
|
recorded('$restore_flag', goal(Module:GA), R),
|
|
erase(R),
|
|
'$system_catch'('$query'(once(GA), []),Module,Error,user:'$Error'(Error)),
|
|
fail.
|
|
'$startup_goals' :-
|
|
get_value('$myddas_goal',GA), GA \= [],
|
|
set_value('$myddas_goal',[]),
|
|
get_value('$myddas_user',User), User \= [],
|
|
set_value('$myddas_user',[]),
|
|
get_value('$myddas_db',Db), Db \= [],
|
|
set_value('$myddas_db',[]),
|
|
get_value('$myddas_host',HostT),
|
|
( HostT \= [] ->
|
|
Host = HostT,
|
|
set_value('$myddas_host',[])
|
|
;
|
|
Host = localhost
|
|
),
|
|
get_value('$myddas_pass',PassT),
|
|
( PassT \= [] ->
|
|
Pass = PassT,
|
|
set_value('$myddas_pass',[])
|
|
;
|
|
Pass = ''
|
|
),
|
|
use_module(library(myddas)),
|
|
call(db_open(mysql,myddas,Host/Db,User,Pass)),
|
|
'$myddas_import_all',
|
|
fail.
|
|
'$startup_goals'.
|
|
|
|
%
|
|
% MYDDAS: Import all the tables from one database
|
|
%
|
|
|
|
'$myddas_import_all':-
|
|
call(db_my_show_tables(myddas,table(Table))),
|
|
call(db_import(myddas,Table,Table)),
|
|
fail.
|
|
'$myddas_import_all'.
|
|
|
|
/** @pred qsave_file(+ _File_, +_State_)
|
|
|
|
Saves an image of all the information compiled by the systemm from file _F_ to _State_.
|
|
This includes modules and predicatees eventually including multi-predicates.
|
|
**/
|
|
|
|
qsave_file(File, State) :-
|
|
recorded('$module', '$module'(File,Mod,Exps,Line), _),
|
|
'$fetch_parents_module'(Mod, Parents),
|
|
'$fetch_imports_module'(Mod, Imps),
|
|
'$fetch_multi_files_module'(Mod, MFs),
|
|
'$fetch_meta_predicates_module'(Mod, Metas),
|
|
'$fetch_module_transparents_module'(Mod, ModTransps),
|
|
asserta(Mod:'@mod_info'(F, Exps, Line, Parents, Imps, Metas, ModTransps)),
|
|
atom_concat(Mod,'.qly',OF),
|
|
open(State, write, S, [type(binary)]),
|
|
'$qsave_module_preds'(S, Mod),
|
|
close(S),
|
|
abolish(Mod:'@mod_info'/7),
|
|
fail.
|
|
qsave_file(_).
|
|
|
|
/** @pred qsave_module(+ _Module_, +_State_)
|
|
Saves an image of all the information compiled by the systemm on module _F_ to _State_.
|
|
**/
|
|
|
|
qsave_module(Mod, OF) :-
|
|
recorded('$module', '$module'(F,Mod,Exps,L), _),
|
|
'$fetch_parents_module'(Mod, Parents),
|
|
'$fetch_imports_module'(Mod, Imps),
|
|
'$fetch_multi_files_module'(Mod, MFs),
|
|
'$fetch_meta_predicates_module'(Mod, Metas),
|
|
'$fetch_module_transparents_module'(Mod, ModTransps),
|
|
asserta(Mod:'@mod_info'(F, Exps, L, Parents, Imps, Metas, ModTransps)),
|
|
atom_concat(Mod,'.qly',OF),
|
|
open(OF, write, S, [type(binary)]),
|
|
'$qsave_module_preds'(S, Mod),
|
|
close(S),
|
|
abolish(Mod:'@mod_info'/7),
|
|
fail.
|
|
qsave_module(_).
|
|
|
|
/**
|
|
@pred restore(+ _F_)
|
|
Restores a previously saved state of YAP from file _F_.
|
|
|
|
*/
|
|
restore(File) :-
|
|
open(File, read, S, [type(binary)]),
|
|
'$qload_program'(S),
|
|
close(S).
|
|
|
|
/**
|
|
@pred qload_module(+ _F_)
|
|
Restores a previously saved state of YAP with from file _F_.
|
|
|
|
*/
|
|
qload_module(Mod) :-
|
|
atom_concat(Mod,'.qly',IF),
|
|
open(IF, read, S, [type(binary)]),
|
|
'$qload_module_preds'(S),
|
|
close(S),
|
|
fail.
|
|
qload_module(Mod) :-
|
|
'$complete_read'(Mod).
|
|
|
|
'$complete_read'(Mod) :-
|
|
retract(Mod:'@mod_info'(F, Exps, Line,Parents, Imps, Metas, ModTransps)),
|
|
abolish(Mod:'$mod_info'/7),
|
|
recorda('$module', '$module'(F,Mod,Exps,Line), _),
|
|
'$install_parents_module'(Mod, Parents),
|
|
'$install_imports_module'(Mod, Imps),
|
|
'$install_multi_files_module'(Mod, MFs),
|
|
'$install_meta_predicates_module'(Mod, Metas),
|
|
'$install_module_transparents_module'(Mod, ModTransps).
|
|
|
|
'$fetch_imports_module'(Mod, Imports) :-
|
|
findall(Info, '$fetch_import_module'(Mod, Info), Imports).
|
|
|
|
% detect an importerator that is local to the module.
|
|
'$fetch_import_module'(Mod, '$import'(Mod0,Mod,G0,G,N,K)) :-
|
|
recorded('$import', '$import'(Mod0,Mod,G0,G,N,K), _).
|
|
|
|
'$fetch_parents_module'(Mod, Parents) :-
|
|
findall(Parent, prolog:'$parent_module'(Mod,Parent), Parents).
|
|
|
|
'$fetch_module_transparents_module'(Mod, Module_Transparents) :-
|
|
findall(Info, '$fetch_module_transparent_module'(Mod, Info), Module_Transparents).
|
|
|
|
% detect an module_transparenterator that is local to the module.
|
|
'$fetch_module_transparent_module'(Mod, '$module_transparent'(F,Mod,N,P)) :-
|
|
prolog:'$module_transparent'(F,Mod0,N,P), Mod0 == Mod.
|
|
|
|
'$fetch_meta_predicates_module'(Mod, Meta_Predicates) :-
|
|
findall(Info, '$fetch_meta_predicate_module'(Mod, Info), Meta_Predicates).
|
|
|
|
% detect an meta_predicateerator that is local to the module.
|
|
'$fetch_meta_predicate_module'(Mod, '$meta_predicate'(F,Mod,N,P)) :-
|
|
prolog:'$meta_predicate'(F,Mod0,N,P), Mod0 == Mod.
|
|
|
|
'$fetch_multi_files_module'(Mod, Multi_Files) :-
|
|
findall(Info, '$fetch_multi_file_module'(Mod, Info), Multi_Files).
|
|
|
|
% detect an multi_fileerator that is local to the module.
|
|
'$fetch_multi_file_module'(Mod, '$defined'(FileName,Name,Arity,Mod)) :-
|
|
recorded('$multifile_defs','$defined'(FileName,Name,Arity,Mod), _).
|
|
|
|
'$fetch_term_expansions_module'(Mod, Term_Expansions) :-
|
|
findall(Info, '$fetch_term_expansion_module'(Mod, Info), Term_Expansions).
|
|
|
|
% detect an term_expansionerator that is local to the module.
|
|
'$fetch_term_expansion_module'(Mod,'$defined'(FileName,Name,Arity,Mod)) :-
|
|
recorded('$multifile_defs','$defined'(FileName,Name,Arity,Mod), _).
|
|
|
|
|
|
|
|
'$install_ops_module'(_, []).
|
|
'$install_ops_module'(Mod, op(X,Y,Op).Ops) :-
|
|
op(X, Y, Mod:Op),
|
|
'$install_ops_module'(Mod, Ops).
|
|
|
|
'$install_imports_module'(_, []).
|
|
'$install_imports_module'(Mod, Import.Imports) :-
|
|
recordz('$import', Import, _),
|
|
'$install_imports_module'(Mod, Imports).
|
|
|
|
'$install_parents_module'(_, []).
|
|
'$install_parents_module'(Mod, Parent.Parents) :-
|
|
assert(prolog:Parent),
|
|
'$install_parents_module'(Mod, Parents).
|
|
|
|
'$install_module_transparents_module'(_, []).
|
|
'$install_module_transparents_module'(Mod, Module_Transparent.Module_Transparents) :-
|
|
assert(prolog:Module_Transparent),
|
|
'$install_module_transparents_module'(Mod, Module_Transparents).
|
|
|
|
'$install_meta_predicates_module'(_, []).
|
|
'$install_meta_predicates_module'(Mod, Meta_Predicate.Meta_Predicates) :-
|
|
assert(prolog:Meta_Predicate),
|
|
'$install_meta_predicates_module'(Mod, Meta_Predicates).
|
|
|
|
'$install_multi_files_module'(_, []).
|
|
'$install_multi_files_module'(Mod, Multi_File.Multi_Files) :-
|
|
recordz('$multifile_defs',Multi_File, _).
|
|
'$install_multi_files_module'(Mod, Multi_Files).
|
|
|
|
|
|
|