1/* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: jan@swi-prolog.org 5 WWW: https://www.swi-prolog.org 6 Copyright (c) 1985-2026, University of Amsterdam 7 VU University Amsterdam 8 SWI-Prolog Solutions b.v. 9 All rights reserved. 10 11 Redistribution and use in source and binary forms, with or without 12 modification, are permitted provided that the following conditions 13 are met: 14 15 1. Redistributions of source code must retain the above copyright 16 notice, this list of conditions and the following disclaimer. 17 18 2. Redistributions in binary form must reproduce the above copyright 19 notice, this list of conditions and the following disclaimer in 20 the documentation and/or other materials provided with the 21 distribution. 22 23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 POSSIBILITY OF SUCH DAMAGE. 35*/ 36 37:- module(backward_compatibility, 38 [ '$arch'/2, 39 '$version'/1, 40 '$home'/1, 41 '$argv'/1, 42 '$set_prompt'/1, 43 '$strip_module'/3, 44 '$declare_module'/3, 45 '$module'/2, 46 at_initialization/1, % :Goal 47 displayq/1, 48 displayq/2, 49 sformat/2, % -String, +Fmt 50 sformat/3, % -String, +Fmt, +Args 51 concat/3, 52 concat_atom/2, % +List, -Atom 53 concat_atom/3, % +List, +Sep, -Atom 54 '$apropos_match'/2, % +Needle, +Hashstack 55 read_clause/1, % -Term 56 read_clause/2, % +Stream, -Term 57 read_variables/2, % -Term, -VariableNames 58 read_variables/3, % +Stream, -Term, -VariableNames 59 read_pending_input/3, % +Stream, -List, ?Tail 60 feature/2, 61 set_feature/2, 62 substring/4, 63 string_to_list/2, % ?String, ?Codes 64 string_to_atom/2, % ?String, ?Atom 65 flush/0, 66 write_ln/1, % +Term 67 write_length/3, % +Term, -Length, +Options 68 proper_list/1, % @Term 69 free_variables/2, % +Term, -Variables 70 hash_term/2, % +Term, -Hash 71 checklist/2, % :Goal, +List 72 sublist/3, % :Goal, +List, -Sublist 73 sumlist/2, % +List, -Sum 74 convert_time/2, % +Stamp, -String 75 convert_time/8, % +String, -YMDmhs.ms 76 'C'/3, % +List, -Head, -Tail 77 current_thread/2, % ?Thread, ?Status 78 current_mutex/3, % ?Mutex, ?Owner, ?Count 79 message_queue_size/2, % +Queue, -TermsWaiting 80 lock_predicate/2, % +Name, +Arity 81 unlock_predicate/2, % +Name, +Arity 82 current_module/2, % ?Module, ?File 83 export_list/2, % +Module, -Exports 84 call_cleanup/3, % :Goal, ?Catcher, :Cleanup 85 setup_and_call_cleanup/3, % :Setup, :Goal, :Cleanup 86 setup_and_call_cleanup/4, % :Setup, :Goal, ?Catcher, :Cleanup 87 merge/3, % +List1, +List2, -Union 88 merge_set/3, % +Set1, +Set2, -Union 89 (index)/1, % :Head 90 hash/1, % :PI 91 set_base_module/1, % :Base 92 eval_license/0, 93 trie_insert_new/3, % +Trie, +Term, -Node 94 thread_at_exit/1, % :Goal 95 read_history/6, % +Show, +Help, +Special, +Prompt, 96 % -Term, -Bindings 97 '$sig_atomic'/1 % :Goal 98 ]). 99:- autoload(library(apply),[maplist/3,maplist/2]). 100:- autoload(library(lists),[sum_list/2]). 101:- autoload(library(system),[lock_predicate/1,unlock_predicate/1]). 102 103 104:- meta_predicate 105 at_initialization(), 106 call_cleanup(,,), 107 setup_and_call_cleanup(,,), 108 setup_and_call_cleanup(,,,), 109 checklist(, ), 110 sublist(, , ), 111 index(), 112 hash(), 113 set_base_module(), 114 thread_at_exit(), 115 '$sig_atomic'(). 116 117/** <module> Backward compatibility 118 119This library defines predicates that used to exist in older version of 120SWI-Prolog, but are considered obsolete as there functionality is neatly 121covered by new features. Most often, these constructs are superseded by 122ISO-standard compliant predicates. 123 124Please also note the existence of quintus.pl and edinburgh.pl for more 125compatibility predicates. 126 127@see gxref/0 can be used to find files that import from 128 library(backcomp) and thus reply on deprecated features. 129*/ 130 131%! '$arch'(-Architecture, -Version) is det. 132% 133% @deprecated use current_prolog_flag(arch, Architecture) 134 135'$arch'(Arch, unknown) :- 136 current_prolog_flag(arch, Arch). 137 138%! '$version'(Version:integer) is det. 139% 140% @deprecated use current_prolog_flag(version, Version) 141 142'$version'(Version) :- 143 current_prolog_flag(version, Version). 144 145%! '$home'(-SWIPrologDir) is det. 146% 147% @deprecated use current_prolog_flag(home, SWIPrologDir) 148% @see file_search_path/2, absolute_file_name/3, The Prolog home 149% directory is available through the alias =swi=. 150 151'$home'(Home) :- 152 current_prolog_flag(home, Home). 153 154%! '$argv'(-Argv:list) is det. 155% 156% @deprecated use current_prolog_flag(os_argv, Argv) or 157% current_prolog_flag(argv, Argv) 158 159'$argv'(Argv) :- 160 current_prolog_flag(os_argv, Argv). 161 162%! '$set_prompt'(+Prompt) is det. 163% 164% Set the prompt for the toplevel 165% 166% @deprecated use set_prolog_flag(toplevel_prompt, Prompt). 167 168'$set_prompt'(Prompt) :- 169 ( is_list(Prompt) 170 -> Prompt0 = Prompt 171 ; atom_codes(Prompt, Prompt0) 172 ), 173 maplist(percent_to_tilde, Prompt0, Prompt1), 174 atom_codes(Atom, Prompt1), 175 set_prolog_flag(toplevel_prompt, Atom). 176 177percent_to_tilde(0'%, 0'~) :- !. 178percent_to_tilde(X, X). 179 180 181%! displayq(@Term) is det. 182%! displayq(+Stream, @Term) is det. 183% 184% Write term ignoring operators and quote atoms. 185% 186% @deprecated Use write_term/3 or write_canonical/2. 187 188displayq(Term) :- 189 write_term(Term, [ignore_ops(true),quoted(true)]). 190displayq(Stream, Term) :- 191 write_term(Stream, Term, [ignore_ops(true),quoted(true)]). 192 193 194%! sformat(-String, +Format, +Args) is det. 195%! sformat(-String, +Format) is det. 196% 197% @deprecated Use format/3 as =|format(string(String), ...)|= 198 199:- module_transparent sformat/2, sformat/3. 200 201sformat(String, Format) :- 202 format(string(String), Format, []). 203sformat(String, Format, Arguments) :- 204 format(string(String), Format, Arguments). 205 206%! concat(+Atom1, +Atom2, -Atom) is det. 207% 208% @deprecated Use ISO atom_concat/3 209 210concat(A, B, C) :- 211 atom_concat(A, B, C). 212 213%! concat_atom(+List, -Atom) is det. 214% 215% Concatenate a list of atomic values to an atom. 216% 217% @deprecated Use atomic_list_concat/2 as proposed by the prolog 218% commons initiative. 219 220concat_atom([A, B], C) :- 221 !, 222 atom_concat(A, B, C). 223concat_atom(L, Atom) :- 224 atomic_list_concat(L, Atom). 225 226 227%! concat_atom(+List, +Separator, -Atom) is det. 228% 229% Concatenate a list of atomic values to an atom, inserting Separator 230% between each consecutive elements. 231% 232% @deprecated Use atomic_list_concat/3 as proposed by the prolog 233% commons initiative. 234 235concat_atom(L, Sep, Atom) :- 236 atomic_list_concat(L, Sep, Atom). 237 238%! '$apropos_match'(+Needle, +Haystack) is semidet. 239% 240% True if Needle is a sub atom of Haystack. Ignores the case 241% of Haystack. 242 243'$apropos_match'(Needle, Haystack) :- 244 sub_atom_icasechk(Haystack, _, Needle). 245 246%! read_clause(-Term) is det. 247% 248% @deprecated Use read_clause/3 or read_term/3. 249 250read_clause(Term) :- 251 read_clause(current_input, Term). 252 253%! read_clause(+Stream, -Term) is det. 254% 255% @deprecated Use read_clause/3 or read_term/3. 256 257read_clause(Stream, Term) :- 258 read_clause(Stream, Term, [process_comment(false)]). 259 260%! read_variables(-Term, -Bindings) is det. 261%! read_variables(+In:stream, -Term, -Bindings) is det. 262% 263% @deprecated Use ISO read_term/2 or read_term/3. 264 265read_variables(Term, Vars) :- 266 read_term(Term, [variable_names(Vars)]). 267 268read_variables(Stream, Term, Vars) :- 269 read_term(Stream, Term, [variable_names(Vars)]). 270 271%! read_pending_input(+Stream, -Codes, ?Tail) is det. 272% 273% @deprecated Use read_pending_codes/3. 274 275read_pending_input(Stream, Codes, Tail) :- 276 read_pending_codes(Stream, Codes, Tail). 277 278%! feature(?Key, ?Value) is nondet. 279%! set_feature(+Key, @Term) is det. 280% 281% Control Prolog flags. 282% 283% @deprecated Use ISO current_prolog_flag/2 and set_prolog_flag/2. 284 285feature(Key, Value) :- 286 current_prolog_flag(Key, Value). 287 288set_feature(Key, Value) :- 289 set_prolog_flag(Key, Value). 290 291%! substring(+String, +Offset, +Length, -Sub) 292% 293% Predecessor of sub_string using 1-based Offset. 294% 295% @deprecated Use sub_string/5. 296 297substring(String, Offset, Length, Sub) :- 298 Offset0 is Offset - 1, 299 sub_string(String, Offset0, Length, _After, Sub). 300 301%! string_to_list(?String, ?Codes) is det. 302% 303% Bi-directional conversion between a string and a list of 304% character codes. 305% 306% @deprecated Use string_codes/2. 307 308string_to_list(String, Codes) :- 309 string_codes(String, Codes). 310 311%! string_to_atom(?String, ?Atom) is det. 312% 313% Bi-directional conversion between string and atom. 314% 315% @deprecated Use atom_string/2. Note that the order of the 316% arguments is reversed. 317 318string_to_atom(Atom, String) :- 319 atom_string(String, Atom). 320 321%! flush is det. 322% 323% @deprecated use ISO flush_output/0. 324 325flush :- 326 flush_output. 327 328%! write_ln(@Term) is det 329% 330% @deprecated Use writeln/1. 331 332write_ln(X) :- 333 writeln(X). 334 335%! write_length(@Term, -Length, +Options) 336% 337% @deprecated use write_size/4 338 339write_length(Term, Length, Options) :- 340 '$option'(max_length(ML), Options), 341 !, 342 write_size(Term, Length, _, [max_width(ML)]). 343write_length(Term, Length, _Options) :- 344 write_size(Term, Length, _, []). 345 346%! proper_list(+List) 347% 348% Old SWI-Prolog predicate to check for a list that really ends 349% in a []. There is not much use for the quick is_list, as in 350% most cases you want to process the list element-by-element anyway. 351% 352% @deprecated Use ISO is_list/1. 353 354proper_list(List) :- 355 is_list(List). 356 357%! free_variables(+Term, -Variables) 358% 359% Return a list of unbound variables in Term. The name 360% term_variables/2 is more widely used. 361% 362% @deprecated Use term_variables/2. 363 364free_variables(Term, Variables) :- 365 term_variables(Term, Variables). 366 367%! hash_term(+Term, -Hash) is det. 368% 369% If Term is ground, Hash is unified to an integer representing 370% a hash for Term. Otherwise Hash is left unbound. 371% 372% @deprecated Use term_hash/2. 373 374hash_term(Term, Hash) :- 375 term_hash(Term, Hash). 376 377%! checklist(:Goal, +List) 378% 379% @deprecated Use maplist/2 380 381 382checklist(Goal, List) :- 383 maplist(Goal, List). 384 385%! sublist(:Goal, +List1, ?List2) 386% 387% Succeeds if List2 unifies with a list holding those terms for which 388% call(Goal, Elem) succeeds. 389% 390% @deprecated Use include/3 from library(apply) 391% @compat DEC10 library 392 393sublist(_, [], []) :- !. 394sublist(Goal, [H|T], Sub) :- 395 call(Goal, H), 396 !, 397 Sub = [H|R], 398 sublist(Goal, T, R). 399sublist(Goal, [_|T], R) :- 400 sublist(Goal, T, R). 401 402%! sumlist(+List, -Sum) is det. 403% 404% True when Sum is the list of all numbers in List. 405% 406% @deprecated Use sum_list/2 407 408sumlist(List, Sum) :- 409 sum_list(List, Sum). 410 411%! '$strip_module'(+Term, -Module, -Plain) 412% 413% This used to be an internal predicate. It was added to the XPCE 414% compatibility library without $ and since then used at many 415% places. From 5.4.1 onwards strip_module/3 is built-in and the $ 416% variation is added here for compatibility. 417% 418% @deprecated Use strip_module/3. 419 420:- module_transparent 421 '$strip_module'/3. 422 423'$strip_module'(Term, Module, Plain) :- 424 strip_module(Term, Module, Plain). 425 426%! '$module'(-OldTypeIn, +NewTypeIn) 427 428'$module'(OldTypeIn, NewTypeIn) :- 429 '$current_typein_module'(OldTypeIn), 430 '$set_typein_module'(NewTypeIn). 431 432%! '$declare_module'(Module, File, Line) 433% 434% Used in triple20 particle library. Should use a public interface 435 436'$declare_module'(Module, File, Line) :- 437 '$declare_module'(Module, user, user, File, Line, false). 438 439 440%! at_initialization(:Goal) is det. 441% 442% Register goal only to be run if a saved state is restored. 443% 444% @deprecated Use initialization(Goal, restore) 445 446at_initialization(Goal) :- 447 initialization(Goal, restore). 448 449%! convert_time(+Stamp, -String) 450% 451% Convert a time-stamp as obtained though get_time/1 into a textual 452% representation using the C-library function ctime(). The value is 453% returned as a SWI-Prolog string object (see section 4.23). See 454% also convert_time/8. 455% 456% @deprecated Use format_time/3. 457 458 459convert_time(Stamp, String) :- 460 format_time(string(String), '%+', Stamp). 461 462%! convert_time(+Stamp, -Y, -Mon, -Day, -Hour, -Min, -Sec, -MilliSec) 463% 464% Convert a time stamp, provided by get_time/1, time_file/2, 465% etc. Year is unified with the year, Month with the month number 466% (January is 1), Day with the day of the month (starting with 1), 467% Hour with the hour of the day (0--23), Minute with the minute 468% (0--59). Second with the second (0--59) and MilliSecond with the 469% milliseconds (0--999). Note that the latter might not be accurate 470% or might always be 0, depending on the timing capabilities of the 471% system. See also convert_time/2. 472% 473% @deprecated Use stamp_date_time/3. 474 475convert_time(Stamp, Y, Mon, Day, Hour, Min, Sec, MilliSec) :- 476 stamp_date_time(Stamp, 477 date(Y, Mon, Day, 478 Hour, Min, FSec, 479 _, _, _), 480 local), 481 Sec is integer(float_integer_part(FSec)), 482 MilliSec is integer(float_fractional_part(FSec)*1000). 483 484%! 'C'(?List, ?Head, ?Tail) is det. 485% 486% Used to be generated by DCG. Some people appear to be using in 487% in normal code too. 488% 489% @deprecated Do not use in normal code; DCG no longer generates it. 490 491'C'([H|T], H, T). 492 493 494%! current_thread(?Thread, ?Status) is nondet. 495% 496% @deprecated Replaced by thread_property/2 497 498current_thread(Thread, Status) :- 499 nonvar(Thread), 500 !, 501 catch(thread_property(Thread, status(Status)), 502 error(existence_error(thread, _), _), 503 fail). 504current_thread(Thread, Status) :- 505 thread_property(Thread, status(Status)). 506 507%! current_mutex(?Mutex, ?Owner, ?Count) is nondet. 508% 509% @deprecated Replaced by mutex_property/2 510 511current_mutex(Mutex, Owner, Count) :- 512 nonvar(Mutex), 513 !, 514 catch(mutex_property(Mutex, status(Status)), 515 error(existence_error(mutex, _), _), 516 fail), 517 map_mutex_status(Status, Owner, Count). 518current_mutex(Mutex, Owner, Count) :- 519 mutex_property(Mutex, status(Status)), 520 map_mutex_status(Status, Owner, Count). 521 522map_mutex_status(unlocked, [], 0). 523map_mutex_status(locked(Owner, Count), Owner, Count). 524 525 526%! message_queue_size(+Queue, -Size) is det. 527% 528% True if Queue holds Size terms. 529% 530% @deprecated Please use message_queue_property(Queue, Size) 531 532message_queue_size(Queue, Size) :- 533 message_queue_property(Queue, size(Size)). 534 535%! lock_predicate(+Name, +Arity) is det. 536%! unlock_predicate(+Name, +Arity) is det. 537% 538% @deprecated see lock_predicate/1 and unlock_predicate/1. 539 540:- module_transparent 541 lock_predicate/2, 542 unlock_predicate/2. 543 544lock_predicate(Name, Arity) :- 545 lock_predicate(Name/Arity). 546 547unlock_predicate(Name, Arity) :- 548 unlock_predicate(Name/Arity). 549 550%! current_module(?Module, ?File) is nondet. 551% 552% True if Module is a module loaded from File. 553% 554% @deprecated Use module_property(Module, file(File)) 555 556current_module(Module, File) :- 557 module_property(Module, file(File)). 558 559%! export_list(+Module, -List) is det. 560% 561% Module exports the predicates of List. 562% 563% @deprecated Use module_property(Module, exports(List)) 564 565export_list(Module, List) :- 566 module_property(Module, exports(List)). 567 568%! call_cleanup(:Goal, +Catcher, :Cleanup) 569% 570% Call Cleanup with an indication of the reason unified to Catcher. 571% 572% @deprecated Use setup_call_catcher_cleanup/4. 573 574call_cleanup(Goal, Catcher, Cleanup) :- 575 setup_call_catcher_cleanup(true, Goal, Catcher, Cleanup). 576 577%! setup_and_call_cleanup(:Setup, :Goal, :Cleanup). 578% 579% Call Cleanup once after Goal is finished. 580% 581% @deprecated Use setup_call_cleanup/3. 582 583setup_and_call_cleanup(Setup, Goal, Cleanup) :- 584 setup_call_cleanup(Setup, Goal, Cleanup). 585 586%! setup_and_call_cleanup(:Setup, :Goal, Catcher, :Cleanup). 587% 588% Call Cleanup once after Goal is finished, with Catcher 589% unified to the reason 590% 591% @deprecated Use setup_call_cleanup/3. 592 593setup_and_call_cleanup(Setup, Goal, Catcher, Cleanup) :- 594 setup_call_catcher_cleanup(Setup, Goal, Catcher,Cleanup). 595 596%! merge_set(+Set1, +Set2, -Set3) 597% 598% Merge the ordered sets Set1 and Set2 into a new ordered set 599% without duplicates. 600% 601% @deprecated New code should use ord_union/3 from 602% library(ordsets) 603 604merge_set([], L, L) :- !. 605merge_set(L, [], L) :- !. 606merge_set([H1|T1], [H2|T2], [H1|R]) :- H1 @< H2, !, merge_set(T1, [H2|T2], R). 607merge_set([H1|T1], [H2|T2], [H2|R]) :- H1 @> H2, !, merge_set([H1|T1], T2, R). 608merge_set([H1|T1], [H2|T2], [H1|R]) :- H1 == H2, merge_set(T1, T2, R). 609 610 611%! merge(+List1, +List2, -List3) 612% 613% Merge the ordered sets List1 and List2 into a new ordered list. 614% Duplicates are not removed and their order is maintained. 615% 616% @deprecated The name of this predicate is far too general for 617% a rather specific function. 618 619merge([], L, L) :- !. 620merge(L, [], L) :- !. 621merge([H1|T1], [H2|T2], [H|R]) :- 622 ( H1 @=< H2 623 -> H = H1, 624 merge(T1, [H2|T2], R) 625 ; H = H2, 626 merge([H1|T1], T2, R) 627 ). 628 629%! index(:Head) is det. 630% 631% Prepare the predicate indicated by Head for multi-argument 632% indexing. 633% 634% @deprecated As of version 5.11.29, SWI-Prolog performs 635% just-in-time indexing on all arguments. 636 637index(Head) :- 638 print_message(warning, decl_no_effect(index(Head))). 639 640%! hash(:PredInd) is det. 641% 642% Demands PredInd to be indexed using a hash-table. This is 643% handled dynamically. 644 645hash(PI) :- 646 print_message(warning, decl_no_effect(hash(PI))). 647 648%! set_base_module(:Base) is det. 649% 650% Set the default module from which we inherit. 651% 652% @deprecated Equivalent to set_module(base(Base)). 653 654set_base_module(M:Base) :- 655 set_module(M:base(Base)). 656 657%! eval_license is det. 658% 659% @deprecated Equivalent to license/0 660 661eval_license :- 662 license. 663 664%! trie_insert_new(+Trie, +Term, -Handle) is semidet. 665% 666% @deprecated use trie_insert/4. 667 668trie_insert_new(Trie, Term, Handle) :- 669 trie_insert(Trie, Term, [], Handle). 670 671%! thread_at_exit(:Goal) is det. 672% 673% Register Goal to be called when the calling thread exits. 674% @deprecated use prolog_listen(this_thread_exit, Goal) 675 676thread_at_exit(Goal) :- 677 prolog_listen(this_thread_exit, Goal). 678 679%! read_history(+Show, +Help, +Special, +Prompt, -Term, -Bindings) 680% 681% @deprecated use read_term_with_history/2. 682 683read_history(Show, Help, Special, Prompt, Term, Bindings) :- 684 read_term_with_history( 685 Term, 686 [ show(Show), 687 help(Help), 688 no_save(Special), 689 prompt(Prompt), 690 variable_names(Bindings) 691 ]). 692 693%! '$sig_atomic'(:Goal) 694% 695% Execute Goal without processing signals. 696% 697% @deprecated use sig_atomic/1. 698 699'$sig_atomic'(Goal) :- 700 sig_atomic(Goal)