325 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			325 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | 
 | ||
|  | % SWI emulation. | ||
|  | % written in an on-demand basis. | ||
|  | 
 | ||
|  | %% @defgroup swi Compatibility with SWI-Prolog and Other Prolog systems | ||
|  | 
 | ||
|  | /**  | ||
|  | 
 | ||
|  | @defgroup System SWI Dialect Support | ||
|  | 
 | ||
|  |    | ||
|  | This library provides a number of SWI-Prolog builtins that are not by | ||
|  | default in YAP. This support is loaded with the | ||
|  | ~~~~~ | ||
|  | expects_dialect(swi) | ||
|  | ~~~~~ | ||
|  | 
 | ||
|  |  command. | ||
|  | 
 | ||
|  | @{ | ||
|  | 
 | ||
|  | */ | ||
|  | 
 | ||
|  | /** @pred  time_file(+ _File_,- _Time_)  | ||
|  | 
 | ||
|  | 
 | ||
|  | Unify the last modification time of  _File_ with | ||
|  |  _Time_.  _Time_ is a floating point number expressing the seconds | ||
|  | elapsed since Jan 1, 1970. | ||
|  | 
 | ||
|  |   | ||
|  | */ | ||
|  | /** @pred concat_atom(+ _List_,- _Atom_)  | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  |  _List_ is a list of atoms, integers or floating point numbers. Succeeds | ||
|  | if  _Atom_ can be unified with the concatenated elements of  _List_. If | ||
|  |  _List_ has exactly 2 elements it is equivalent to `atom_concat/3`, | ||
|  | allowing for variables in the list. | ||
|  | 
 | ||
|  |   | ||
|  | */ | ||
|  | 
 | ||
|  | :- module(system, [concat_atom/2, | ||
|  | 		   concat_atom/3, | ||
|  | 		   read_clause/1, | ||
|  | 		   chdir/1, | ||
|  | 		   compile_aux_clauses/1, | ||
|  | 		   convert_time/2, | ||
|  | 		   convert_time/8, | ||
|  | 		   '$declare_module'/5, | ||
|  | 		   '$set_predicate_attribute'/3, | ||
|  | 		   stamp_date_time/3, | ||
|  | 		   date_time_stamp/2, | ||
|  | 		   time_file/2, | ||
|  | 		   flag/3, | ||
|  | 		   require/1, | ||
|  | 		   normalize_space/2, | ||
|  | 		   current_flag/1 | ||
|  | 		]). | ||
|  | 
 | ||
|  | :- reexport(library(charsio),[ | ||
|  | 			      write_to_chars/2, | ||
|  | 			      read_from_chars/2 | ||
|  | 			     ]). | ||
|  | 
 | ||
|  | :- reexport(library(lists),[append/2, | ||
|  | 			    append/3, | ||
|  | 			    delete/3, | ||
|  | 			    member/2, | ||
|  | 			    flatten/2, | ||
|  | 			    intersection/3, | ||
|  | 			    last/2, | ||
|  | 			    memberchk/2, | ||
|  | 			    max_list/2, | ||
|  | 			    min_list/2, | ||
|  | 			    nextto/3, | ||
|  | 			    permutation/2, | ||
|  | 			    reverse/2, | ||
|  | 			    select/3, | ||
|  | 			    selectchk/3, | ||
|  | 			    sublist/2, | ||
|  | 			    sumlist/2, | ||
|  | 			    nth1/4, | ||
|  | 			    nth0/4, | ||
|  | 			    nth1/3, | ||
|  | 			    nth0/3]). | ||
|  | 
 | ||
|  | :- reexport(library(apply),[maplist/2, | ||
|  | 			    maplist/3, | ||
|  | 			    maplist/4, | ||
|  | 			    maplist/5, | ||
|  | 			    include/3, | ||
|  | 			    exclude/3, | ||
|  | 			    partition/4, | ||
|  | 			    partition/5 | ||
|  | 			   ]). | ||
|  | 
 | ||
|  | :- reexport(library(system), | ||
|  | 	      [datime/1, | ||
|  | 	       mktime/2, | ||
|  | 	       file_property/2, | ||
|  | 	       delete_file/1]). | ||
|  | 
 | ||
|  | :- reexport(library(arg), | ||
|  | 	      [genarg/3]). | ||
|  | 
 | ||
|  | :- reexport(library(apply_macros), | ||
|  | 	      []). | ||
|  | 
 | ||
|  | :- reexport(library(terms), | ||
|  | 	      [subsumes/2, | ||
|  | 	       subsumes_chk/2, | ||
|  | 	       term_hash/2, | ||
|  | 	       unifiable/3, | ||
|  | 	       cyclic_term/1, | ||
|  | 	       variant/2]). | ||
|  | 
 | ||
|  | :- use_module(library(error),[must_be/2]). | ||
|  | 
 | ||
|  | 
 | ||
|  | :- source. | ||
|  | 
 | ||
|  | :- style_check(all). | ||
|  | 
 | ||
|  | :- yap_flag(unknown,error). | ||
|  | 
 | ||
|  | :- yap_flag(open_expands_filename,false). | ||
|  | 
 | ||
|  | :- yap_flag(autoload,true). | ||
|  | 
 | ||
|  | :- set_prolog_flag(user_flags,silent). | ||
|  | 
 | ||
|  | 
 | ||
|  | % Time is given as a float in SWI-Prolog. | ||
|  | swi_get_time(FSecs) :- datime(Datime),  mktime(Datime, Secs), FSecs is Secs*1.0. | ||
|  | 
 | ||
|  | goal_expansion(atom_concat(A,B),atomic_concat(A,B)). | ||
|  | /** @pred  atom_concat(? _A1_,? _A2_,? _A12_) is iso | ||
|  | 
 | ||
|  | The predicate holds when the third argument unifies with an atom, and | ||
|  | the first and second unify with atoms such that their representations | ||
|  | concatenated are the representation for  _A12_. | ||
|  | 
 | ||
|  | If  _A1_ and  _A2_ are unbound, the built-in will find all the atoms | ||
|  | that concatenated give  _A12_. | ||
|  | 
 | ||
|  |   | ||
|  | */ | ||
|  | 
 | ||
|  | goal_expansion(atom_concat(A,B,C),atomic_concat(A,B,C)). | ||
|  | %goal_expansion(arg(A,_,_),_) :- nonvar(A), !, fail. | ||
|  | goal_expansion(arg(A,B,C),genarg(A,B,C)). | ||
|  | 
 | ||
|  | % make sure we also use  | ||
|  | :- user:library_directory(X), | ||
|  | 	atom(X), | ||
|  | 	atom_concat([X,'/dialect/swi'],SwiDir), | ||
|  | 	\+ user:library_directory(SwiDir), | ||
|  | 	asserta(user:library_directory(SwiDir)), | ||
|  | 	fail | ||
|  | 	; | ||
|  | 	true. | ||
|  | 
 | ||
|  | :- multifile | ||
|  |    user:file_search_path/2. | ||
|  | 
 | ||
|  | :- dynamic | ||
|  |    user:file_search_path/2. | ||
|  | 
 | ||
|  | /** @pred concat_atom(? _List_,+ _Separator_,? _Atom_) | ||
|  | 
 | ||
|  | 
 | ||
|  | Creates an atom just like concat_atom/2, but inserts  _Separator_ | ||
|  | between each pair of atoms.  For example: | ||
|  | 
 | ||
|  | ~~~~~ | ||
|  | ?- concat_atom([gnu, gnat], ', ', A). | ||
|  | 
 | ||
|  | A = 'gnu, gnat' | ||
|  | ~~~~~ | ||
|  | 
 | ||
|  | (Unimplemented) This predicate can also be used to split atoms by | ||
|  | instantiating  _Separator_ and  _Atom_: | ||
|  | 
 | ||
|  | ~~~~~ | ||
|  | ?- concat_atom(L, -, 'gnu-gnat'). | ||
|  | 
 | ||
|  | L = [gnu, gnat] | ||
|  | ~~~~~ | ||
|  | 
 | ||
|  |   | ||
|  | */ | ||
|  | concat_atom([A|List], Separator, New) :- var(List), !, | ||
|  | 	atom_codes(Separator,[C]), | ||
|  | 	atom_codes(New, NewChars), | ||
|  | 	split_atom_by_chars(NewChars,C,L,L,A,List). | ||
|  | concat_atom(List, Separator, New) :- | ||
|  | 	add_separator_to_list(List, Separator, NewList), | ||
|  | 	atomic_concat(NewList, New). | ||
|  | 
 | ||
|  | 
 | ||
|  | split_atom_by_chars([],_,[],L,A,[]):- | ||
|  | 	atom_codes(A,L). | ||
|  | split_atom_by_chars([C|NewChars],C,[],L,A,[NA|Atoms]) :- !, | ||
|  | 	atom_codes(A,L), | ||
|  | 	split_atom_by_chars(NewChars,C,NL,NL,NA,Atoms). | ||
|  | split_atom_by_chars([C1|NewChars],C,[C1|LF],LAtom,Atom,Atoms) :- | ||
|  | 	split_atom_by_chars(NewChars,C,LF,LAtom,Atom,Atoms). | ||
|  | 
 | ||
|  | add_separator_to_list([], _, []). | ||
|  | add_separator_to_list([T], _, [T]) :- !. | ||
|  | add_separator_to_list([H|T], Separator, [H,Separator|NT]) :- | ||
|  | 	add_separator_to_list(T, Separator, NT). | ||
|  | 
 | ||
|  | concat_atom(List, New) :- | ||
|  | 	atomic_concat(List, New). | ||
|  | 
 | ||
|  | 
 | ||
|  | bindings_message(V) --> | ||
|  |        { cvt_bindings(V, Bindings) }, | ||
|  |        prolog:message(query(_YesNo,Bindings)), !. | ||
|  | 
 | ||
|  | cvt_bindings([],[]). | ||
|  | cvt_bindings([[Name|Value]|L],[AName=Value|Bindings]) :- | ||
|  | 	atom_codes(AName, Name), | ||
|  | 	cvt_bindings(L,Bindings). | ||
|  | 
 | ||
|  | /** @pred chdir(+ _Dir_)  | ||
|  | 
 | ||
|  | Compatibility predicate.  New code should use working_directory/2. | ||
|  | */ | ||
|  | chdir(X) :- cd(X). | ||
|  | 
 | ||
|  | %%	convert_time(+Stamp, -String) | ||
|  | % | ||
|  | %	Convert  a time-stamp as  obtained though get_time/1 into a  textual | ||
|  | %	representation  using the C-library function ctime().  The  value is | ||
|  | %	returned  as a  SWI-Prolog string object  (see section  4.23).   See | ||
|  | %	also convert_time/8. | ||
|  | % | ||
|  | %	@deprecated Use format_time/3. | ||
|  | 
 | ||
|  | 
 | ||
|  | convert_time(Stamp, String) :- | ||
|  | 	format_time(string(String), '%+', Stamp). | ||
|  | 
 | ||
|  | %%	convert_time(+Stamp, -Y, -Mon, -Day, -Hour, -Min, -Sec, -MilliSec) | ||
|  | % | ||
|  | %	Convert   a  time  stamp,   provided  by   get_time/1,   time_file/2, | ||
|  | %	etc.   Year is  unified with the year,  Month with the month  number | ||
|  | %	(January  is 1), Day  with the day of  the month (starting with  1), | ||
|  | %	Hour  with  the hour  of the  day (0--23),  Minute  with the  minute | ||
|  | %	(0--59).   Second with the  second (0--59) and MilliSecond with  the | ||
|  | %	milliseconds  (0--999).  Note that the latter might not  be accurate | ||
|  | %	or  might always be 0, depending  on the timing capabilities of  the | ||
|  | %	system.  See also convert_time/2. | ||
|  | % | ||
|  | %	@deprecated Use stamp_date_time/3. | ||
|  | 
 | ||
|  | convert_time(Stamp, Y, Mon, Day, Hour, Min, Sec, MilliSec) :- | ||
|  | 	stamp_date_time(Stamp, | ||
|  | 			date(Y, Mon, Day, | ||
|  | 			     Hour, Min, FSec, | ||
|  | 			     _, _, _), | ||
|  | 			local), | ||
|  | 	Sec is integer(float_integer_part(FSec)), | ||
|  | 	MilliSec is integer(float_fractional_part(FSec)*1000). | ||
|  | 
 | ||
|  | 
 | ||
|  | compile_aux_clauses([]). | ||
|  | compile_aux_clauses([(:- G)|Cls]) :- !, | ||
|  | 	prolog_load_context(module, M), | ||
|  | 	once(M:G), | ||
|  | 	compile_aux_clauses(Cls). | ||
|  | compile_aux_clauses([Cl|Cls]) :- | ||
|  | 	prolog_load_context(module, M), | ||
|  | 	assert_static(M:Cl), | ||
|  | 	compile_aux_clauses(Cls). | ||
|  | 
 | ||
|  | 
 | ||
|  | flag(Key, Old, New) :- | ||
|  | 	recorded(Key, Old, R), !, | ||
|  | 	( | ||
|  | 	 Old \== New | ||
|  | 	-> | ||
|  | 	 erase(R), | ||
|  | 	 recorda(Key, New, _) | ||
|  | 	; | ||
|  | 	 true | ||
|  | 	). | ||
|  | flag(Key, 0, New) :- | ||
|  | 	functor(Key, N, Ar), | ||
|  | 	functor(K, N, Ar), | ||
|  | 	assert(flag(K)), | ||
|  | 	recorda(K, New, _). | ||
|  | 
 | ||
|  | current_flag(Key) :- | ||
|  | 	swi:flag(Key). | ||
|  | 
 | ||
|  | require(F) :- | ||
|  | 	must_be(list, F), | ||
|  | 	% notice that this must be used as a declaration. | ||
|  | 	prolog_load_context(module, Mod), | ||
|  | 	required_predicates(F, Mod). | ||
|  | 
 | ||
|  | required_predicates([], _). | ||
|  | required_predicates([F|Fs], M) :- | ||
|  | 	required_predicate(F, M), | ||
|  | 	required_predicates(Fs, M). | ||
|  | 
 | ||
|  | required_predicate(Na/Ar, M) :- | ||
|  | 	functor(G, Na, Ar), | ||
|  | 	( | ||
|  | 	 predicate_property(M:G, _) -> | ||
|  | 	 true | ||
|  | 	; | ||
|  |          autoloader:find_predicate(G, _) | ||
|  | 	). | ||
|  | 
 | ||
|  | /** | ||
|  | @} | ||
|  | */ |