1/* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: J.Wielemaker@vu.nl 5 WWW: http://www.swi-prolog.org 6 Copyright (c) 2019, VU University Amsterdam 7 CWI, Amsterdam 8 All rights reserved. 9 10 Redistribution and use in source and binary forms, with or without 11 modification, are permitted provided that the following conditions 12 are met: 13 14 1. Redistributions of source code must retain the above copyright 15 notice, this list of conditions and the following disclaimer. 16 17 2. Redistributions in binary form must reproduce the above copyright 18 notice, this list of conditions and the following disclaimer in 19 the documentation and/or other materials provided with the 20 distribution. 21 22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 POSSIBILITY OF SUCH DAMAGE. 34*/ 35 36:- module(xsb, 37 [ add_lib_dir/1, % +Directories 38 add_lib_dir/2, % +Root, +Directories 39 40 compile/2, % +File, +Options 41 load_dyn/1, % +File 42 load_dyn/2, % +File, +Direction 43 load_dync/1, % +File 44 load_dync/2, % +File, +Direction 45 46 set_global_compiler_options/1, % +Options 47 compiler_options/1, % +Options 48 49 xsb_import/2, % +Preds, From 50 xsb_set_prolog_flag/2, % +Flag, +Value 51 52 fail_if/1, % :Goal 53 54 sk_not/1, % :Goal 55 gc_tables/1, % -Remaining 56 57 cputime/1, % -Seconds 58 walltime/1, % -Seconds 59 60 (thread_shared)/1, % :Spec 61 62 debug_ctl/2, % +Option, +Value 63 64 fmt_write/2, % +Fmt, +Term 65 fmt_write/3, % +Stream, +Fmt, +Term 66 67 path_sysop/2, % +Op, ?Value 68 path_sysop/3, % +Op, ?Value1, ?Value2 69 70 abort/1, % +Message 71 72 op(1050, fy, import), 73 op(1050, fx, export), 74 op(1040, xfx, from), 75 op(1100, fy, index), % ignored 76 op(1100, fy, ti), % transformational indexing? 77 op(1100, fx, mode), % ignored 78 op(1045, xfx, as), 79 op(900, fy, tnot), 80 op(900, fy, not), % defined as op in XSB 81 op(1100, fx, thread_shared) 82 ]). 83:- use_module(library(error)). 84:- use_module(library(debug)). 85:- use_module(library(dialect/xsb/source)). 86:- use_module(library(tables)). 87:- use_module(library(aggregate)). 88:- use_module(library(option)). 89:- use_module(library(apply)). 90:- if(exists_source(library(dialect/xsb/timed_call))). 91:- use_module(library(dialect/xsb/timed_call)). 92:- export(timed_call/2). 93:- endif.
101:- meta_predicate 102 xsb_import( , ), % Module interaction 103 104 compile( , ), % Loading files 105 load_dyn( ), 106 load_dyn( , ), 107 load_dync( ), 108 load_dync( , ), 109 110 thread_shared( ), 111 112 fail_if( ), % Meta predicates 113 sk_not( ). 114 115 116 117 /******************************* 118 * LIBRARY SETUP * 119 *******************************/
126push_xsb_library :- 127 ( absolute_file_name(library(dialect/xsb), Dir, 128 [ file_type(directory), 129 access(read), 130 solutions(all), 131 file_errors(fail) 132 ]), 133 asserta((user:file_search_path(library, Dir) :- 134 prolog_load_context(dialect, xsb))), 135 fail 136 ; true 137 ). 138 139:- push_xsb_library.
145:- public setup_dialect/0. 146 147setup_dialect :- 148 style_check(-discontiguous). 149 150:- multifile 151 user:term_expansion/2, 152 user:goal_expansion/2. 153 154:- dynamic 155 moved_directive/2. 156 157% Register XSB specific term-expansion to rename conflicting directives. 158 159userterm_expansion(In, Out) :- 160 prolog_load_context(dialect, xsb), 161 xsb_term_expansion(In, Out). 162 163xsb_term_expansion((:- Directive), []) :- 164 prolog_load_context(file, File), 165 retract(moved_directive(File, Directive)), 166 debug(xsb(header), 'Moved to head: ~p', [Directive]), 167 !. 168xsb_term_expansion((:- import Preds from From), 169 (:- xsb_import(Preds, From))). 170xsb_term_expansion((:- index(_PI, _, _)), []). % what is tbis? 171xsb_term_expansion((:- index(_PI, _How)), []). 172xsb_term_expansion((:- index(_PI)), []). 173xsb_term_expansion((:- ti(_PI)), []). 174xsb_term_expansion((:- mode(_Modes)), []). 175 176usergoal_expansion(In, Out) :- 177 prolog_load_context(dialect, xsb), 178 ( xsb_mapped_predicate(In, Out) 179 -> true 180 ; xsb_inlined_goal(In, Out) 181 ). 182 183xsb_mapped_predicate(expand_file_name(File, Expanded), 184 xsb_expand_file_name(File, Expanded)). 185xsb_mapped_predicate(set_prolog_flag(Flag, Value), 186 xsb_set_prolog_flag(Flag, Value)). 187xsb_mapped_predicate(abolish_module_tables(UserMod), 188 abolish_module_tables(user)) :- 189 UserMod == usermod. 190 191xsb_inlined_goal(fail_if(P), \+(P)).
198:- dynamic 199 mapped__module/2. % XSB name -> Our name 200 201xsb_import(Into:Preds, From) :- 202 mapped__module(From, Mapped), 203 !, 204 xsb_import(Preds, Into, Mapped). 205xsb_import(Into:Preds, From) :- 206 xsb_import(Preds, Into, From). 207 208xsb_import(Var, _Into, _From) :- 209 var(Var), 210 !, 211 instantiation_error(Var). 212xsb_import((A,B), Into, From) :- 213 !, 214 xsb_import(A, Into, From), 215 xsb_import(B, Into, From). 216xsb_import(Name/Arity, Into, From) :- 217 functor(Head, Name, Arity), 218 xsb_mapped_predicate(Head, NewHead), 219 functor(NewHead, NewName, Arity), 220 !, 221 xsb_import(NewName/Arity, Into, From). 222xsb_import(PI, Into, usermod) :- 223 !, 224 export(user:PI), 225 @(import(user:PI), Into). 226xsb_import(Name/Arity, Into, _From) :- 227 functor(Head, Name, Arity), 228 predicate_property(Into:Head, iso), 229 !, 230 debug(xsb(import), '~p: already visible (ISO)', [Into:Name/Arity]). 231xsb_import(PI, Into, From) :- 232 import_from_module(clean, PI, Into, From), 233 !. 234xsb_import(PI, Into, From) :- 235 prolog_load_context(file, Here), 236 absolute_file_name(From, Path, 237 [ extensions(['P', pl, prolog]), 238 access(read), 239 relative_to(Here), 240 file_errors(fail) 241 ]), 242 !, 243 debug(xsb(import), '~p: importing from ~p', [Into:PI, Path]), 244 load_module(Into:Path, PI). 245xsb_import(PI, Into, From) :- 246 absolute_file_name(library(From), Path, 247 [ extensions(['P', pl, prolog]), 248 access(read), 249 file_errors(fail) 250 ]), 251 !, 252 debug(xsb(import), '~p: importing from ~p', [Into:PI, Path]), 253 load_module(Into:Path, PI). 254xsb_import(Name/Arity, Into, _From) :- 255 functor(Head, Name, Arity), 256 predicate_property(Into:Head, visible), 257 !, 258 debug(xsb(import), '~p: already visible', [Into:Name/Arity]). 259xsb_import(PI, Into, From) :- 260 import_from_module(dirty, PI, Into, From), 261 !. 262xsb_import(_Name/_Arity, _Into, From) :- 263 existence_error(xsb_module, From).
271import_from_module(clean, PI, Into, From) :- 272 module_property(From, exports(List)), 273 memberchk(PI, List), 274 !, 275 debug(xsb(import), '~p: importing from module ~p', [Into:PI, From]), 276 @(import(From:PI), Into). 277import_from_module(dirty, PI, Into, From) :- 278 current_predicate(From:PI), 279 !, 280 debug(xsb(import), '~p: importing from module ~p', [Into:PI, From]), 281 ( check_exported(From, PI) 282 -> @(import(From:PI), Into) 283 ; true 284 ). 285import_from_module(dirty, PI, _Into, From) :- 286 module_property(From, file(File)), 287 !, 288 print_message(error, xsb(not_in_module(File, From, PI))). 289 290check_exported(Module, PI) :- 291 module_property(Module, exports(List)), 292 memberchk(PI, List), 293 !. 294check_exported(Module, PI) :- 295 module_property(Module, file(File)), 296 print_message(error, xsb(not_in_module(File, Module, PI))). 297 298load_module(Into:Path, PI) :- 299 use_module(Into:Path, []), 300 ( module_property(Module, file(Path)) 301 -> file_base_name(Path, File), 302 file_name_extension(Base, _, File), 303 ( Base == Module 304 -> true 305 ; atom_concat(xsb_, Base, Module) 306 -> map_module(Base, Module) 307 ; print_message(warning, 308 xsb(file_loaded_into_mismatched_module(Path, Module))), 309 map_module(Base, Module) 310 ) 311 ; print_message(warning, xsb(loaded_unknown_module(Path))) 312 ), 313 import_from_module(_, PI, Into, Module). 314 315map_module(XSB, Module) :- 316 mapped__module(XSB, Module), 317 !. 318map_module(XSB, Module) :- 319 assertz(mapped__module(XSB, Module)).
326xsb_set_prolog_flag(unify_with_occurs_check, XSBVal) :- 327 !, 328 map_bool(XSBVal, Val), 329 set_prolog_flag(occurs_check, Val). 330xsb_set_prolog_flag(Flag, Value) :- 331 set_prolog_flag(Flag, Value). 332 333map_bool(on, true). 334map_bool(off, false). 335 336 337 /******************************* 338 * BUILT-IN PREDICATES * 339 *******************************/
348add_lib_dir(Directories) :- 349 add_lib_dir('.', Directories). 350 351add_lib_dir(_, Var) :- 352 var(Var), 353 !, 354 instantiation_error(Var). 355add_lib_dir(Root, (A,B)) :- 356 !, 357 add_lib_dir(Root, A), 358 add_lib_dir(Root, B). 359add_lib_dir(Root, a(Dir)) :- 360 !, 361 add_to_library_directory(Root, Dir, asserta). 362add_lib_dir(Root, Dir) :- 363 add_to_library_directory(Root, Dir, assertz). 364 365add_to_library_directory(Root, Dir, How) :- 366 ( expand_file_name(Dir, [Dir1]) 367 -> true 368 ; Dir1 = Dir 369 ), 370 relative_file_name(TheDir, Root, Dir1), 371 exists_directory(TheDir), 372 !, 373 ( user:library_directory(TheDir) 374 -> true 375 ; call(How, user:library_directory(TheDir)) 376 ). 377add_to_library_directory(_, _, _).
384compile(File, _Options) :-
385 qcompile(File).
all_dynamic
option.
SWI-Prolog never had that as clause/2 is allowed on static code,
which is the main reason to want this.
The dync versions demand source in canonical format. In SWI-Prolog there is little reason to demand this.
399load_dyn(File) :- 400 '$style_check'(Style, Style), 401 setup_call_cleanup( 402 style_check(-singleton), 403 load_files(File), 404 '$style_check'(_, Style)). 405 406load_dyn(File, Dir) :- must_be(oneof([z]), Dir), load_dyn(File). 407load_dync(File) :- load_dyn(File). 408load_dync(File, Dir) :- load_dyn(File, Dir).
414:- multifile xsb_compiler_option/1. 415:- dynamic xsb_compiler_option/1. 416 417set_global_compiler_options(List) :- 418 must_be(list, List), 419 maplist(set_global_compiler_option, List). 420 421set_global_compiler_option(+Option) :- 422 !, 423 valid_compiler_option(Option), 424 ( xsb_compiler_option(Option) 425 -> true 426 ; assertz(xsb_compiler_option(Option)) 427 ). 428set_global_compiler_option(-Option) :- 429 !, 430 valid_compiler_option(Option), 431 retractall(xsb_compiler_option(Option)). 432set_global_compiler_option(-Option) :- 433 valid_compiler_option(Option), 434 ( xsb_compiler_option(Option) 435 -> true 436 ; assertz(xsb_compiler_option(Option)) 437 ). 438 439valid_compiler_option(Option) :- 440 must_be(oneof([ singleton_warnings_off, 441 optimize, 442 allow_redefinition, 443 xpp_on, 444 spec_off 445 ]), Option).
451compiler_options(Options) :- 452 must_be(list, Options), 453 maplist(compiler_option, Options). 454 455compiler_option(+Option) :- 456 !, 457 valid_compiler_option(Option), 458 set_compiler_option(Option). 459compiler_option(-Option) :- 460 !, 461 valid_compiler_option(Option), 462 clear_compiler_option(Option). 463compiler_option(Option) :- 464 valid_compiler_option(Option), 465 set_compiler_option(Option). 466 467set_compiler_option(singleton_warnings_off) :- 468 style_check(-singleton). 469set_compiler_option(optimize) :- 470 set_prolog_flag(optimise, true). 471set_compiler_option(allow_redefinition). 472set_compiler_option(xpp_on). 473set_compiler_option(spec_off). 474 475clear_compiler_option(singleton_warnings_off) :- 476 style_check(+singleton). 477clear_compiler_option(optimize) :- 478 set_prolog_flag(optimise, false). 479clear_compiler_option(allow_redefinition). 480clear_compiler_option(xpp_on). 481 482 /******************************* 483 * BUILT-INS * 484 *******************************/
491fail_if(P) :- 492 \+ . 493 494 /******************************* 495 * TABLING BUILT-INS * 496 *******************************/
504sk_not(P) :-
505 not_exists(P).
517gc_tables(Remaining) :- 518 garbage_collect_atoms, 519 aggregate_all(count, remaining_table(_), Remaining). 520 521remaining_table(Trie) :- 522 current_blob(Trie, trie), 523 '$is_answer_trie'(Trie, _Type), 524 '$atom_references'(Trie, 0).
530cputime(Seconds) :-
531 statistics(cputime, Seconds).
537walltime(Seconds) :-
538 get_time(Now),
539 statistics(epoch, Epoch),
540 Seconds is Now - Epoch.
547debug_ctl(prompt, off) :- 548 !, 549 leash(-all). 550debug_ctl(prompt, on) :- 551 !, 552 leash(+full). 553debug_ctl(hide, Preds) :- 554 !, 555 '$hide'(Preds). 556debug_ctl(Option, Value) :- 557 debug(xsb(compat), 'XSB: not implemented: ~p', 558 [ debug_ctl(Option, Value) ]).
565thread_shared(Spec) :-
566 dynamic(Spec).
578fmt_write(Fmt, Term) :- 579 fmt_write(current_output, Fmt, Term). 580 581fmt_write(Stream, Fmt, Term) :- 582 ( compound(Term) 583 -> Term =.. [_|Args] 584 ; Args = [Term] 585 ), 586 fmt_write_format(Fmt, Format), 587 format(Stream, Format, Args). 588 589:- dynamic 590 fmt_write_cache/2. 591 592fmt_write_format(Fmt, Format) :- 593 fmt_write_cache(Fmt, Format), 594 !. 595fmt_write_format(Fmt, Format) :- 596 string_codes(Fmt, FmtCodes), 597 phrase(format_fmt(Codes, []), FmtCodes), 598 atom_codes(Format, Codes), 599 asserta(fmt_write_cache(Fmt, Format)). 600 601format_fmt(Format, Tail) --> 602 "%", 603 ( format_esc(Format, Tail0) 604 -> ! 605 ; here(Rest), 606 { print_message(warning, xsb(fmt_write(ignored(Rest)))), 607 fail 608 } 609 ), 610 format_fmt(Tail0, Tail). 611format_fmt([0'~,0'~|T0], T) --> 612 "~", 613 !, 614 format_fmt(T0, T). 615format_fmt([H|T0], T) --> 616 [H], 617 !, 618 format_fmt(T0, T). 619format_fmt(T, T) --> []. 620 621format_esc(Fmt, Tail) --> 622 format_esc(Fmt0), 623 !, 624 { append(Fmt0, Tail, Fmt) 625 }. 626 627format_esc(`~16r`) --> "x". 628format_esc(`~d`) --> "d". 629format_esc(`~f`) --> "f". 630format_esc(`~s`) --> "s". 631format_esc(`%`) --> "%". 632 633here(Rest, Rest, Rest).
645path_sysop(isplain, File) :- 646 exists_file(File). 647path_sysop(isdir, Dir) :- 648 exists_directory(Dir). 649path_sysop(rm, File) :- 650 delete_file(File). 651path_sysop(rmdir, Dir) :- 652 delete_directory(Dir). 653path_sysop(rmdir_rec, Dir) :- 654 delete_directory_and_contents(Dir). 655path_sysop(cwd, CWD) :- 656 working_directory(CWD, CWD). 657path_sysop(chdir, CWD) :- 658 working_directory(_, CWD). 659path_sysop(mkdir, Dir) :- 660 make_directory(Dir). 661path_sysop(exists, Entry) :- 662 access_file(Entry, exist). 663path_sysop(readable, Entry) :- 664 access_file(Entry, read). 665path_sysop(writable, Entry) :- 666 access_file(Entry, write). 667path_sysop(executable, Entry) :- 668 access_file(Entry, execute). 669path_sysop(tmpfilename, Name) :- 670 tmp_file(swi, Name). 671path_sysop(isabsolute, Name) :- 672 is_absolute_file_name(Name). 673 674 675path_sysop(rename, Old, New) :- 676 rename_file(Old, New). 677path_sysop(copy, From, To) :- 678 copy_file(From, To). 679path_sysop(link, From, To) :- 680 link_file(From, To, symbolic). 681path_sysop(modtime, Path, Time) :- 682 time_file(Path, Time). 683path_sysop(newerthan, Path1, Path2) :- 684 time_file(Path1, Time1), 685 ( catch(time_file(Path2, Time2), error(existence_error(_,_),_), fail) 686 -> Time1 > Time2 687 ; true 688 ). 689path_sysop(size, Path, Size) :- 690 size_file(Path, Size). 691path_sysop(extension, Path, Ext) :- 692 file_name_extension(_, Ext, Path). 693path_sysop(basename, Path, Base) :- 694 file_base_name(Path, File), 695 file_name_extension(Base, _, File). 696path_sysop(dirname, Path, Dir) :- 697 file_directory_name(Path, Dir0), 698 ( sub_atom(Dir0, _, _, 0, /) 699 -> Dir = Dir0 700 ; atom_concat(Dir0, /, Dir) 701 ). 702path_sysop(expand, Name, Path) :- 703 absolute_file_name(Name, Path).
709abort(Message) :- 710 print_message(error, aborted(Message)), 711 abort. 712 713 /******************************* 714 * MESSAGES * 715 *******************************/ 716 717:- multifile 718 prolog:message//1. 719 720prologmessage(xsb(not_in_module(File, Module, PI))) --> 721 [ 'XSB: ~p, implementing ~p does not export ~p'-[File, Module, PI] ]. 722prologmessage(xsb(file_loaded_into_mismatched_module(File, Module))) --> 723 [ 'XSB: File ~p defines module ~p'-[File, Module] ]. 724prologmessage(xsb(ignored(debug_ctl(Option, Value)))) --> 725 [ 'XSB: debug_ctl(~p,~p) is not implemented'-[Option,Value] ]
XSB Prolog compatibility layer
This module provides partial compatibility with the XSB Prolog system */