1% BEGIN LICENSE BLOCK 2% Version: CMPL 1.1 3% 4% The contents of this file are subject to the Cisco-style Mozilla Public 5% License Version 1.1 (the "License"); you may not use this file except 6% in compliance with the License. You may obtain a copy of the License 7% at www.eclipse-clp.org/license. 8% 9% Software distributed under the License is distributed on an "AS IS" 10% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11% the License for the specific language governing rights and limitations 12% under the License. 13% 14% The Original Code is The ECLiPSe Constraint Logic Programming System. 15% The Initial Developer of the Original Code is Cisco Systems, Inc. 16% Portions created by the Initial Developer are 17% Copyright (C) 2006 Cisco Systems, Inc. All Rights Reserved. 18% 19% Contributor(s): 20% 21% END LICENSE BLOCK 22 23:- comment(alias, "Control"). 24:- comment(summary, "Built-ins and language constructs to control execution"). 25:- comment(categories, ["Built-In Predicates"]). 26 27:- tool((~) / 1). 28:- tool((^) / 2). 29:- tool((',') / 2). 30:- tool((*->) / 2). 31:- tool((->) / 2). 32:- tool((:) / 2). 33:- tool((;) / 2). 34:- tool((@) / 2). 35:- tool((\+) / 1). 36:- tool(block / 3). 37:- tool(call / 1). 38:- tool(catch / 3). 39:- tool((do) / 2). 40:- tool(fail_if / 1). 41:- tool((not) / 1). 42:- tool((once) / 1). 43:- tool(mutex / 2). 44:- tool(mutex_init / 1). 45:- tool(phrase / 2). 46:- tool(phrase / 3). 47 48:- comment(phrase / 2, [ 49 summary:"Succeeds if List unifies with a list from the specified grammar Grammar. 50 51", 52 amode:(phrase(+,++) is semidet), 53 amode:(phrase(+,-) is nondet), 54 desc:html(" phrase/2 can be use as a recognizer or as a generator of grammars. As a 55 recognizer, it succeeds or fails if term belongs or not to the specified 56 grammar Grammar. As a generator, it generates on backtracking all the 57 elements of the grammar. 58 59<P> 60 A grammar is specified by setting the flag macro_expansion to on and by 61 compiling clauses using the DCG operator -->. 62 63<P> 64"), 65 args:["Grammar" : "Compound term or Atom.", "List" : "List of grammar terminals (prolog terms)."], 66 resat:"Depends on the particular grammar", 67 fail_if:"List does not belong to Grammar", 68 exceptions:[4 : "Grammar is not instantiated.", 5 : "Grammar is a number or a string (i.e. not a valid DCG head)."], 69 eg:" 70 [eclipse]: sh('cat gram.pl'). 71 sentence --> noun_phrase, verb_phrase. 72 noun_phrase --> article, noun. 73 verb_phrase --> verb | verb, noun_phrase. 74 article --> [the]. 75 noun --> [compiler]. 76 noun --> [program]. 77 verb --> [compiles]. 78 yes. 79 [eclipse]: [gram]. 80 /home/user/gram.pl compiled 732 bytes in 0.37 seconds 81 yes. 82 [eclipse]: phrase(sentence,[the,compiler,compiles]). 83 yes. 84 [eclipse]: phrase(sentence,[the,compiler,compiles,the,program]). 85 yes. 86 [eclipse]: phrase(sentence, X). 87 88 X = [the, compiler, compiles] More? (;) 89 90 X = [the, compiler, compiles, the, compiler] More? (;) 91 92 X = [the, compiler, compiles, the, program] More? (;) 93 94 X = [the, program, compiles] More? (;) 95 96 X = [the, program, compiles, the, compiler] More? (;) 97 98 X = [the, program, compiles, the, program] 99 yes. 100 [eclipse]: 101 102Fail: 103 phrase(sentence, [not, a, sentence]). 104 105Error: 106 phrase(X, [what, time, is, it]). (Error 4). 107 phrase(\"sentence\", X). (Error 5). 108 phrase(123, X). (Error 5). 109 110 111 112", 113 see_also:[phrase/3, current_macro / 4, macro / 3, erase_macro / 2]]). 114 115:- comment(phrase / 3, [ 116 summary:"Succeeds if Tokens can be parsed as part of the grammar defined in Grammar 117and Remainder contains any remaining terms in Tokens. 118 119", 120 amode:(phrase(+,-,-) is nondet), 121 amode:(phrase(+,+,-) is nondet), 122 amode:(phrase(+,+,+) is semidet), 123 desc:html(" phrase/3 is used to parse grammars (DCGs) defined using the grammar rule 124 operator -->. The flag macro_expansion must be set on when compiling 125 grammar rules. 126 127<P> 128 Giving a list of terms in Tokens, phrase/3 parses it according to the 129 grammar defined in Grammar. As the terms in Tokens are parsed in order, 130 any remaining terms are returned in Remainder. Further acceptable 131 solutions are returned on backtracking. 132"), 133 args:["Grammar" : "Compound Term or Atom.", "Tokens" : "List of Prolog terms.", "Remainder" : "List of Prolog terms."], 134 resat:"Depends on the grammar", 135 fail_if:"The initial terms in Tokens do not belong to Grammar", 136 exceptions:[4 : "Grammar is not instantiated.", 5 : "Grammar is a number or a string."], 137 eg:" 138 [eclipse]: [user]. 139 a --> []. 140 a --> [z],a. 141 user compiled 212 bytes in 0.03 seconds 142 yes. 143 [eclipse]: phrase(a,[z,z],[]). 144 145 yes. 146 [eclipse]: phrase(a,[z,z,z,y],[z,y]). 147 148 yes. 149 [eclipse]: phrase(a,[z,z,y],R). 150 151 R = [z, z, y] More? (;) 152 153 R = [z, y] More? (;) 154 155 R = [y] More? (;) 156 157 no (more) solution. 158 [eclipse]: phrase(a,X,[y]). 159 160 X = [y] More? (;) 161 162 X = [z, y] More? (;) 163 164 X = [z, z, y] More? (;) 165 166 X = [z, z, z, y] More? (;) 167 168 X = [z, z, z, z, y] More? (;) 169 yes. 170 [eclipse]: 171 172Fail: 173 phrase(a, [z, z, y], []). 174 175Error: 176 phrase(X, [what, time, is, it], [is, it],R). (Error 4). 177 phrase(\"a\", X,R). (Error 5). 178 phrase(456, X,R). (Error 5). 179 180 181 182", 183 see_also:[phrase/2, current_macro / 4, macro / 3, erase_macro / 2]]). 184 185:- comment(abort / 0, [ 186 summary:"The current computation is aborted and control is returned to the top 187level. 188 189", 190 amode:(abort is erroneous), 191 desc:html(" Used to abort the current computation and return control to the top 192 level. This predicate is also executed when Ctrl-C is typed (unless the 193 interrupt handler for this event has been redefined). 194 195<P> 196 abort/0 is implemented using throw(abort), which is caught by the top level 197 loop. If there is an active catch/3 (or block/3) call whose tag matches 198 the atom abort, the control does not return to the top level loop but is 199 caught by this catch-block. If there is neither a top level loop (eg the -e 200 option has been used) nor any block to catch the abort, then ECLiPSe will 201 either return to the host program (in case of an embedded ECLiPSe) or 202 the ECLiPSe process will exit (in case of a standalone ECLiPSe). 203 204<P> 205"), 206 args:[], 207 eg:" 208 [eclipse]: abort. 209 Aborting execution.... 210 [eclipse]: 211 212 213 214", 215 see_also:[kill / 2, catch / 3, throw / 1]]). 216 217:- comment(call / 1, [ 218 summary:"Succeeds if Goal succeeds. 219 220", 221 amode:call(+), 222 desc:html(" Calls the goal Goal. This predicate is used to call goals whose 223 functors are known only at the time they are called. 224 225<P> 226 Note that: 227 228<P> 229 call(Goal) is logically the same as Goal and !/0 does not cut through 230 call/1. 231 232<P> 233"), 234 args:["Goal" : "Atom or compound term."], 235 resat:"Resatisfiable if Goal is resatisfiable", 236 fail_if:"Fails if Goal fails", 237 exceptions:[4 : "Goal is not instantiated.", 5 : "Goal is not an atom or a compound term."], 238 eg:" 239Success: 240 [eclipse]: [user]. 241 or(A -> B, C) :- call(A), !, call(B). 242 or(_ -> _, C) :- call(C). 243 user compiled 412 bytes in 0.02 seconds 244 [eclipse]: or(write(a)->fail, write(k)). 245 a 246 no. 247 [eclipse]: or(fail->write(here),true). 248 yes. 249 250Fail: 251 [eclipse]: call(fail),write(here). 252 no. 253Error: 254 call(G). (Error 4). 255 call(\"write(a)\"). (Error 5). 256 257 258 259", 260 see_also:[subcall / 2, (@) / 2, (:) / 2, call/(2.._)]]). 261 262:- comment((',') / 2, [ 263 summary:"Comma (AND) operator - succeeds if the goals Goal1 and Goal2 both succeed 264 265", 266 template:"+Goal1 , +Goal2", 267 desc:html(" Succeeds if both Goal1 and Goal2 can be satisfied. 268 269<P> 270 Note that !/0 cuts through ,/2. 271 272<P> 273"), 274 args:["Goal1" : "Atom or compound term.", "Goal2" : "Atom or compound term."], 275 resat:"Resatisfiable if either Goal1 or Goal2 are resatisfiable", 276 fail_if:"Fails if either Goal1 or Goal2 fails", 277 eg:" 278Success: 279 [eclipse]: (F=\"file1\", writeln(F)). 280 file1 281 F = \"file1\" 282 yes. 283 284 [eclipse]: call((write(a), write(b))). 285 ab 286 yes. 287 288 289 290", 291 see_also:[(;) / 2]]). 292 293:- comment(! / 0, [ 294 index:["Cut"], 295 summary:"Cut - succeeds and removes all choice points between cut and parent goal. 296 297", 298 amode:(! is det), 299 desc:html(" The cut operation succeeds immediately when first encountered as a goal. 300 The cut commits all the choices made since the parent goal was invoked, 301 and causes any other alternatives to be discarded. 302 303<P> 304 Note that: 305 306<P> 307 !/0 cuts through ,/2, ;/2 and the right hand side of ->/2, i.e. cuts that 308 occur in these positions affect the whole clause and subsequent alternatives. 309 It does NOT cut through call/1, not/1, once/1, the left hand side of ->/2 310 (the condition), or other meta-calling constructs - such cuts only have a 311 local effect. 312 313<P> 314"), 315 args:[], 316 eg:" 317Success: 318 [eclipse]: [user]. 319 or(A -> B, C) :- call(A), !, call(B). 320 or(_ -> _, C) :- call(C). 321 user compiled 412 bytes in 0.02 seconds 322 [eclipse]: or(write(a)->fail, write(k)). 323 a 324 no. 325 [eclipse]: or(fail->fail,write(k)). 326 k 327 yes. 328 329 [eclipse]: [user]. 330 echo :- repeat, read(X), echo(X), !. 331 echo(end_of_file). 332 echo(X) :- writeln(X), fail. 333 user compiled 404 bytes in 0.02 seconds 334 yes. % if the cut is left out, backtracking occurs. 335 [eclipse]: echo. 336 f(1,2). 337 f(1,2) 338 end_of_file. 339 yes. 340 341 342 343", 344 see_also:[fail / 0, (once) / 1, repeat / 0, (;) / 2]]). 345 346:- comment(fail / 0, [ 347 summary:"Does not succeed. A synonym of false/0. 348 349", 350 amode:(fail is failure), 351 desc:html(" Does not succeed. 352 353<P> 354"), 355 args:[], 356 fail_if:"Always fails", 357 eg:" 358Success: 359 [eclipse]: [user]. 360 not1(Goal) :- call(Goal),!,fail. 361 not1(_). 362 user compiled 208 bytes in 0.02 seconds 363 [eclipse]: not1(true). 364 no. 365 [eclipse]: not1(fail). 366 yes. 367 368Fail: 369 fail. 370 371 372 373", 374 see_also:[true / 0, false / 0]]). 375 376:- comment(false / 0, [ 377 summary:"Does not succeed (synonym of fail/0). 378 379", 380 amode:(false is failure), 381 desc:html(" Does not succeed. 382 383<P> 384"), 385 args:[], 386 fail_if:"Always fails", 387 eg:" 388Success: 389 [eclipse]: [user]. 390 not1(Goal) :- call(Goal), !, false. 391 not1(_). 392 user compiled 208 bytes in 0.02 seconds 393 [eclipse]: not1(true). 394 no. 395 [eclipse]: not1(fail). 396 yes. 397 [eclipse]: not1(false). 398 yes. 399 400Fail: 401 false. 402 403 404 405", 406 see_also:[fail / 0]]). 407 408:- comment((not) / 1, [ 409 index:["Negation"], 410 summary:"Succeeds if Goal cannot be satisfied (uses negation as failure). 411 412", 413 template:"not +Goal", 414 amode:(not(+) is semidet), 415 desc:html(" Used to fail if Goal succeeds. Uses the standard Prolog form of 416 negation as failure. 417 418<P> 419 To check whether a call Goal succeeds without binding variables, the 420 call not not Goal can be used. Note that !/0 does not cut through 421 not/1. 422 423<P> 424"), 425 args:["Goal" : "Atom or compound term."], 426 fail_if:"Fails if Goal succeeds", 427 eg:" 428Success: 429 not fail . 430 not 1 == 2 . 431 not X==1 . 432 not not X = 1. 433 % does not bind X 434Fail: 435 not(X=1). 436 not(true). 437 not(3 == 3). 438 439 440 441", 442 see_also:[(\+) / 1, (~) / 1, (->)/2]]). 443 444:- comment((\+) / 1, [ 445 index:["Negation"], 446 summary:"Succeeds if Goal cannot be satisfied. Uses negation as failure (synonym of not/1). 447 448", 449 template:"\\+ +Goal", 450 amode:(\+(+) is semidet), 451 desc:html(" Used to fail if the goal Goal can be satisfied. Uses the standard 452 Prolog form of negation as failure. 453 454<P> 455 May be used to check whether a call Goal succeeds without binding 456 variables, the call \\+ \\+ Goal can be used. 457 458<P> 459 Note that: 460 461<P> 462 !/0 does not cut through \\+/1. 463 464<P> 465"), 466 args:["Goal" : "Goal."], 467 fail_if:"Fails if Goal succeeds", 468 eg:" 469Success: 470 \\+ fail. 471 \\+ 1 == 2. 472 \\+ X == 1. 473 \\+ \\+ X = 1. 474 % does not bind X 475Fail: 476 \\+ X = 1. 477 \\+ true. 478 \\+ 3 == 3. 479 480 481 482", 483 see_also:[(->)/2, (not) / 1, (~) / 1]]). 484 485:- comment((once) / 1, [ 486 summary:"Succeeds if Goal succeeds, and removes all its alternatives --- equivalent 487to call((Goal, !)) 488 489", 490 template:"once +Goal", 491 amode:(once(+) is det), 492 desc:html(" Used to find a single solution for Goal, alternative solutions are 493 ignored (cut). 494 495<P> 496 Note that !/0 does not cut through once/1. 497 498<P> 499"), 500 args:["Goal" : "Goal."], 501 fail_if:"Fails if Goal fails", 502 exceptions:[4 : "Goal is not instantiated.", 5 : "Goal is neither an atom nor a compound term."], 503 eg:" 504Success: 505 [eclipse]: once member(X, [1,2,3]). 506 X = 1 % only first solution is bound. 507 yes. 508 509Fail: 510 [eclipse]: once 1=2. 511 no. 512 513Error: 514 once Goal. (Error 4). 515 once \"ls\". (Error 5). 516 once 1.0. (Error 5). 517 518 519 520", 521 see_also:[call / 1, (->) / 2]]). 522 523:- comment((;) / 2, [ 524 index:["Disjunction","Or"], 525 summary:"Semicolon (OR) operator - Succeeds if the goal Goal1 succeeds or if the 526goal Goal2 succeeds. 527 528", 529 template:"+Goal1 ; +Goal2", 530 amode:(';'(+,+) is nondet), 531 desc:html("\ 532 Succeeds if either of Goal1 and Goal2 succeeds. 533<P> 534 If Goal1 has the special form A -> B (or A *-> B) then the disjunction 535 turns into an if-then-else construct. See those predicates for details. 536<P> 537 !/0 cuts through ;/2. 538"), 539 args:["Goal1" : "Atom or compound term.", "Goal2" : "Atom or compound term."], 540 resat:"Resatisfiable if Goal1 does not contain a literal cut", 541 fail_if:"Fails if both Goal1 and Goal2 fail", 542 eg:" 543Success: 544 1 == 2; 2 == 2. 545 546 [eclipse]: (write(a), fail) ; (write(b); write(c)). 547 ab 548 yes. 549 550 [eclipse]: (write(a); write(b)), write(c). 551 ac 552 yes. 553 554Fail: 555 1 == 2; 3 == 2. 556 557 558 559", 560 see_also:[! / 0, (->) / 2, (*->)/2]]). 561 562:- comment((~) / 1, [ 563 index:["Negation"], 564 summary:"The sound negation operator. If Goal is not ground, the predicate delays. 565 566", 567 template:"~ +Goal", 568 amode:(~(+) is semidet), % delay 569 desc:html(" 570 This is the sound negation operator. It can be used instead of 571 not/1, or \\+/1 (the negation as failure operators). It is known 572 that negation as failure may yield non-logical results if the Goal 573 contains free variables. To avoid this, ~/1 delays if Goal is not 574 ground. If the free variables are bound later in the execution, 575 the delayed predicate is woken and executed and may yield success 576 or failure. While ~/1 always behaves logically, in some cases it 577 delays where negation as failure or constructive negation would 578 have immediately (and correctly) failed. 579 580<P> 581"), 582 args:["Goal" : "Callable term or a variable."], 583 fail_if:"Fails if Goal can be satisfied", 584 eg:" 585Success: 586 ~ 3 = 4. 587 ~ 3 = X, (delays ... 588 X = 4. ... and succeeds with X = 4) 589Fail: 590 ~ 3 = 3. 591 ~ 3 = X, (delays ... 592 X = 3. ... and fails) 593 ~ X = X, (delays ... 594 X = 3. ... and fails) 595 596 597 598", 599 see_also:[(not) / 1, (\+) / 1, suspend/3]]). 600 601:- comment((@) / 2, [ 602 summary:"Goal is executed in the calling context of ContextModule. 603 604", 605 template:"Goal @ ContextModule", 606 amode:(@(+,+)), 607 desc:html(" The calling context of a goal is normally the module where the goal is 608 called. @/2 allows to specify this context module explicitly. This is 609 needed when writing meta-predicates (i.e. predicates which have goals or 610 predicates as their arguments) or predicates which depend otherwise on 611 the module system's visibility rules. 612<P> 613 @/2 changes only the context module, not the lookup module. I.e. the 614 way the definition of Goal is found is not affected at all. To specify 615 the lookup module, use :/2. The following table summarises: 616<PRE> 617 Call within module(m) lookup module caller module 618 619 ..., twice(X), ... m m 620 ..., lm : twice(X), ... lm m 621 ..., twice(X) @ cm, ... m cm 622 ..., lm : twice(X) @ cm, ... lm cm 623 ..., call(twice(X)) @ cm, ... cm cm 624</PRE> 625 If Goal is not a tool-predicate, then Goal@ContextModule is completely 626 equivalent to Goal. 627"), 628 args:["Goal" : "Callable term (atom or compound).", "ContextModule" : "Atom."], 629 resat:"Resatisfiable if Goal is resatisfiable", 630 fail_if:"Fails if Goal fails", 631 exceptions:[4 : "Goal is not instantiated.", 5 : "Goal is neither an atom nor a compound term.", 68 : "Goal is an undefined procedure in the caller module."], 632 eg:" 633 [eclipse 1]: [user]. 634 :- tool(where/0, where/1). 635 where(Module) :- 636 printf(\"where/0 was called from module %w\\n\", 637 [Module]). 638 ^D 639 [eclipse 2]: where. 640 where/0 was called from module eclipse 641 yes. 642 [eclipse 3]: where @ m. 643 where/0 was called from module m 644 yes. 645 [eclipse 4]: call(where) @ m. 646 calling an undefined procedure where in module m 647 [eclipse 1]: [user]. 648 :- tool(print_local_preds/0, print_local_preds/1). 649 print_local_preds(Module) :- 650 current_predicate(P) @ Module, 651 get_flag(P, visibility, local) @ Module, 652 writeln(P), 653 fail. 654 ^D 655 [eclipse 2]: print_local_preds. 656 print_local_preds / 0 657 print_local_preds / 1 658 659 660 661", 662 see_also:[(:) / 2, call / 1, tool / 2]]). 663 664 665:- comment((:) / 2, [ 666 summary:"Call the procedure visible in LookupModule rather than the caller module", 667 template:"+LookupModule : +Goal", 668 amode:(:(+,+)), 669 desc:html("\ 670 This predicate provides a means to invoke a procedure which is not visible. 671 Normally, when a procedure is called, the system looks for a visible 672 definition (local or imported) in the caller module. This primitive 673 on the other hand allows to specify a different lookup module. 674<P> 675 Two conditions must be satisfied for the lookup to succeed: 676<UL> 677 <LI>the definition wanted must be visible in the lookup module 678 <LI>the definition wanted must be exported from its home module 679</UL> 680 The purpose of this is to allow calling procedures whose definition is 681 not visible in the caller module. The two main uses of this facility are: 682<OL> 683 <LI>If there are several definitions of a procedure with the same name 684 in different modules, :/2 can be used to specify which one to call. 685 <LI>If a module wants to define a procedure, but needs to call 686 another procedure of the same name (but from a different module), 687 :/2 can be used to call that one instead of the locally defined one. 688</OL> 689 Note that :/2 does not affect the caller (context) module. 690 The following table summarises the different idioms: 691<PRE> 692 Call within module(m) lookup module caller module 693 694 ..., twice(X), ... m m 695 ..., lm : twice(X), ... lm m 696 ..., twice(X) @ cm, ... m cm 697 ..., lm : twice(X) @ cm, ... lm cm 698 ..., call(twice(X)) @ cm, ... cm cm 699</PRE> 700<P> 701 Note: In earlier versions of Eclipse the left hand side argument of 702 :/2 was required to be the module where the procedure was defined, 703 rather than just visible. 704"), 705 args:["Goal" : "Callable term (atom or compound).", "LookupModule" : "Atom."], 706 resat:"Resatisfiable if Goal is resatisfiable", 707 fail_if:"Fails if Goal fails", 708 exceptions:[4 : "Goal is not instantiated.", 709 4 : "Module is not instantiated.", 710 5 : "Goal is neither an atom nor a compound term.", 711 5 : "Module is not an atom.", 712 68 : "Goal is an undefined procedure in Module."], 713 eg:" 714% two definitions are visible: 715 716 :- lib(ria). % exports #>= / 2 717 :- lib(eplex). % exports #>= / 2 718 719 ..., ria:(X #>= Y), ... 720 ..., eplex:(X #>= Y), ... 721 722 723% the library predicate is hidden by the local definition: 724 725 :- lib(lists). % exports print_list/1 726 727 print_list(List) :- 728 writeln(\"This is the list:\"), 729 lists:print_list(List). 730 731", 732 see_also:[call / 1, (@) / 2, (export) / 1]]). 733 734 735:- comment((do) / 2, [ 736 index:["foreach","fromto","foreacharg","foreachelem","foreachindex","for","multifor","count","Iteration","Loops"], 737 summary:"Execute Goals iteratively according to IterationSpecs. 738 739", 740 template:"+IterationSpecs do +Goals", 741 amode:(do(+,+)), 742 desc:html(" 743 The do-loop is a control structure (or meta-predicate) for writing 744 simple iterations without the need for an auxiliary recursive predicate. 745<P> 746 A do-loop corresponds to a call to an auxiliary recursive predicate 747 of the form 748<PRE> do__n(...) :- !. 749 do__n(...) :- Goals, do__n(...).</PRE> 750 IterationSpecs specifies the termination condition, and what is being 751 iterated over. It can be one (or a combination) of the following: 752 <DL> 753 <DT><STRONG>fromto(First,In,Out,Last)</STRONG><DD> 754 iterate Goals starting with In=First until Out=Last. 755 In and Out are local loop variables. For all but the first 756 iteration, the value of In is the same as the value of Out in 757 the previous iteration. 758 759 <DT><STRONG>foreach(X,List)</STRONG><DD> 760 iterate Goals with X ranging over all elements of List. 761 X is a local loop variable. 762 Can also be used for constructing a list. 763 764 <DT><STRONG>foreacharg(X,StructOrArray)</STRONG><DD> 765 iterate Goals with X ranging over all arguments of StructOrArray. 766 X is a local loop variable. 767 Cannot be used for constructing a term. 768 769 <DT><STRONG>foreacharg(X,StructOrArray,Idx)</STRONG><DD> 770 same as before, but Idx is set to the argument position of X in 771 StructOrArray, i.e. arg(Idx, StructOrArray, X) is true. 772 X and Idx are local loop variables. 773 774 <DT><STRONG>foreachelem(X,Array)</STRONG><DD> 775 like foreacharg/2, but iterates over all elements of an array 776 of arbitrary dimension. The order is the natural order, i.e. 777 if Array = []([](a, b, c), [](d, e, f)), then for successive 778 iterations X is bound in turn to a, b, c, d, e and f. 779 Ragged arrays (where sub-arrays are of non-uniform length) 780 are allowed and handled correctly. Array may be the empty 781 array [] which leads to zero iterations. Opposed to that, 782 occurrences of [] within the multidimensional array 783 are treated as ordinary array elements. 784 X is a local loop variable. 785 Cannot be used for constructing an array! 786 787 <DT><STRONG>foreachelem(X,Array,Idx)</STRONG><DD> 788 same as before, but Idx is set to the index position of X in 789 Array, i.e. subscript(Array, Idx, X) is true. 790 X and Idx are local loop variables. 791 792 <DT><STRONG>foreachindex(Idx,Array)</STRONG><DD> 793 like foreachelem/3, but returns just the index position and 794 not the element. Idx is a local loop variable. 795 796 <DT><STRONG>for(I,MinExpr,MaxExpr)</STRONG><DD> 797 iterate Goals with I ranging over integers from MinExpr to 798 MaxExpr. I is a local loop variable. MinExpr and MaxExpr 799 can be arithmetic expressions. Can be used only for 800 controlling iteration, i.e. MaxExpr cannot be uninstantiated. 801 802 <DT><STRONG>for(I,MinExpr,MaxExpr,Increment) </STRONG><DD> 803 same as before, but an integer or integer expression Increment 804 can be specified (it defaults to 1). 805 806 <DT><STRONG>multifor(List,MinList,MaxList)</STRONG><DD> 807 like for/3, but allows iteration over multiple indices (saves 808 writing nested loops). Each element of List takes a value 809 between the corresponding elements in MinList and MaxList. 810 Successive iterations go through the possible combinations of 811 values for List in lexicographic order. List is a local 812 loop variable. MinList and MaxList must be either lists of 813 arithmetic expressions evaluating to integers, or arithmetic 814 expressions evaluating to integers (in the latter case 815 they are treated as lists containing the (evaluated) integer 816 repeated an appropriate number of times). If none of List, 817 MinList and MaxList is a list of fixed length at compile time then 818 either MinList or MaxList must be a list of fixed length at call 819 time (so that it is known how many indices are to be iterated). 820 All lists must be the same length and must not be empty. 821 822 <DT><STRONG>multifor(List,MinList,MaxList,IncrementList)</STRONG><DD> 823 same as before, but IncrementList can be specified (i.e. how 824 much to increment each element of List by). IncrementList must 825 be either a list of arithmetic expressions evaluating to non-zero 826 integers, or an arithmetic expression evaluating to a non-zero 827 integer (in which case all elements are incremented by this amount). 828 IncrementList defaults to 1. 829 830 <DT><STRONG>count(I,Min,Max)</STRONG><DD> 831 iterate Goals with I ranging over integers from Min up to Max. 832 I is a local loop variable. 833 Can be used for controlling iteration as well as counting, 834 i.e. Max can be a uninstantiated. 835 836 <DT><STRONG>param(Var1,Var2,...)</STRONG><DD> 837 for declaring variables in Goals as global, i.e. as shared with 838 the loop context and shared among all iterations of the loop. 839 CAUTION: By default, variables in Goals have local scope, which means 840 that in every iteration these variables are new (even if a variable 841 of the same name occurs outside the do-construct). 842 843 <DT><STRONG>loop_name(Name)</STRONG><DD> 844 This specifier does not affect the semantics of the loop. It allows 845 to give the loop a name, mainly for debugging purposes. Name must be 846 an atom, and is used as the name of the auxiliary predicate into which 847 the loop may be compiled. The name should therefore not clash with 848 other predicate names in the same module. 849 </DL> 850 Note that fromto/4 is the most general specifier, while foreach/2, 851 foreacharg/2,3, foreachelem/2,3, foreachindex/2, count/3, for/3,4, 852 multifor/3,4 and param/N are convenient shorthands. 853 <P> 854 There are three ways to combine the above specifiers in a single do loop: 855 <DL> 856 <DT><STRONG>IterSpec1, IterSpec2</STRONG> (\"synchronous iteration\")<DD> 857 This is the normal way to combine iteration specifiers: simply 858 provide a comma-separated sequence of them. The specifiers are 859 iterated synchronously; that is, they all take their first \"value\" 860 for the first execution of Goals, their second \"value\" for the 861 second execution of Goals, etc. The order in which they are written 862 does not matter, and the set of local loop variables is the 863 union of those of IterSpec1 and IterSpec2. 864 865 When multiple iteration specifiers are given in this way, typically 866 not all of them will impose a termination condition on the loop 867 (e.g. <STRONG>foreach</STRONG> with an uninstantiated list and 868 <STRONG>count</STRONG> with an uninstantiated maximum do not impose 869 a termination condition), but at least one of them should do so. If 870 several specifiers impose termination conditions, then these 871 conditions must coincide, i.e. specify the same number of 872 iterations. 873 874 <DT><STRONG>IterSpec1 * IterSpec2</STRONG> (\"cross product\")<DD> 875 This iterates over the cross product of IterSpec1 and IterSpec2. 876 The sequence of iteration is to iterate IterSpec2 completely for a 877 given \"value\" of IterSpec1 before doing the same with the next 878 \"value\" of IterSpec1, and so on. The set of local loop variables 879 is the union of those of IterSpec1 and IterSpec2. 880 881 <DT><STRONG>IterSpec1 >> IterSpec2</STRONG> (\"nested iteration\")<DD> 882 Like ( IterSpec1 do ( IterSpec2 do Goals ) ), including with respect 883 to scoping. The local loop variables are those of IterSpec2; in 884 particular, those of IterSpec1 are not available unless IterSpec2 885 passes them through, e.g. using a <STRONG>param</STRONG>. 886 Similarly, the only \"external\" variables available as inputs to 887 IterSpec2 are the locals of IterSpec1; variables from outside the 888 loop are not available unless passed through by IterSpec1, e.g. 889 using a <STRONG>param</STRONG>. 890 </DL> 891 <P> 892 Syntax: The do-operator binds like the semicolon, i.e. less than comma. 893 That means that the whole do-construct should always be parenthesised. 894 <P> 895 Do-loops can be used as a control structure in grammar rules as well: 896 A do-loop in a grammar rule context will generate (or parse) the 897 concatenation of the lists of symbols generated (or parsed) by each 898 loop iteration (the grammar rule transformation effectively adds a 899 hidden fromto-iterator to a do-loop). 900 <P> 901 Cuts in the loop body only have a local effect, i.e. they do not cut 902 through the loop. 903 <P> 904 Unless you use :-pragma(noexpand) or the compiler's expand_goals:off 905 option, the do-construct is compiled into an efficient auxiliary 906 predicate. By default, the name of this predicate is do__nnn 907 (where nnn is a unique integer), unless you have explicitly specified 908 a name using the loop_name(Name) specifier. 909"), 910 args:[ 911 "IterationSpecs" : "a comma-separated sequence of iteration specifiers", 912 "Goal" : "a goal (atom or compound term)"], 913 resat:"Resatisfiable if Goal is resatisfiable", 914 fail_if:"Fails if Goal fails, or if two IterationSpecs specify a different number of iterations", 915 exceptions:[4 : "IterationSpecs insufficiently instantiated", 123 : "Ill-formed IterationSpecs"], 916 eg:" 917% iterate over list 918?- (foreach(X,[1,2,3]) do writeln(X)). 919 920% maplist (construct a new list from an existing list) 921?- (foreach(X,[1,2,3]), foreach(Y,List) do Y is X+3). 922 923% sumlist 924?- (foreach(X,[1,2,3]), fromto(0,In,Out,Sum) do Out is In+X). 925 926% reverse list 927?- (foreach(X,[1,2,3]), fromto([],In,Out,Rev) do Out=[X|In]). 928 929% reverse list (even shorter) 930?- (foreach(X,[1,2,3]), fromto([],In,[X|In],Rev) do true). 931 932% iterate over integers from 1 up to 5 933?- (for(I,1,5) do writeln(I)). 934 935% iterate over integers from 1 up to 5 936?- (count(I,1,5) do writeln(I)). 937 938% iterate over integers from 5 down to 1 939?- (for(I,5,1,-1) do writeln(I)). 940 941% make list of integers [1,2,3,4,5] 942?- (for(I,1,5), foreach(I,List) do true). 943 944% make a list of length 3 945?- (foreach(_,List), for(_,1,3) do true). 946 947% get the length of a list 948?- (foreach(_,[a,b,c]), count(_,1,N) do true). 949 950% actually, the length/2 builtin is (almost) 951length(List, N) :- (foreach(_,List), count(_,1,N) do true). 952 953% iterate [I,J] over [1,1], [1,2], [1,3], [2,1], ..., [3,3]: 954?- (multifor([I,J],1,3) do writeln([I,J])). 955 956% similar, but have different start/stop values for I and J: 957?- (multifor([I,J], [2,1], [4,5]) do writeln([I,J])). 958 959% similar, but only do odd values for the second variable: 960?- (multifor(List, [2,1], [4,5], [1,2]) do writeln(List)). 961 962% filter list elements 963?- (foreach(X,[5,3,8,1,4,6]), fromto(List,Out,In,[]) do 964 X>3 -> Out=[X|In] ; Out=In). 965 966% iterate over structure arguments 967?- (foreacharg(X,s(a,b,c,d,e)) do writeln(X)). 968 969% collect arguments in a list 970% (bad example, use =.. if you really want to do that!) 971?- (foreacharg(X,s(a,b,c,d,e)), foreach(X,List) do true). 972 973% collect arguments reverse 974?- (foreacharg(X,s(a,b,c,d,e)), fromto([],In,[X|In],List) do true). 975 976% or like this: 977?- S = s(a,b,c,d,e), functor(S, _, N), 978 (for(I,N,1,-1), foreach(A,List), param(S) do arg(I,S,A)). 979 980% rotate arguments in a struct 981?- S0 = s(a,b,c,d,e), functor(S0, F, N), functor(S1, F, N), 982 ( foreacharg(X,S0,I), param(S1, N) do 983 I1 is (I mod N)+1, arg(I1,S1,X) 984 ). 985 986% flatten an array into a list 987?- (foreachelem(X,[]([](5,1,2),[](3,3,2))), foreach(X,List) do true). 988 989% transpose a 2D array 990?- A = []([](5,1,2),[](3,3,2)), 991 dim(A, [R,C]), dim(T, [C,R]), 992 ( foreachelem(X,A,[I,J]), param(T) do 993 subscript(T, [J,I], X) 994 ). 995 996% same, using foreachindex 997?- A = []([](5,1,2),[](3,3,2)), 998 dim(A, [R,C]), dim(T, [C,R]), 999 ( foreachindex([I,J],A), param(A, T) do 1000 subscript(A, [I,J], X), 1001 subscript(T, [J,I], X) 1002 ). 1003 1004% The following two are equivalent 1005?- (foreach(X,[1,2,3]) do writeln(X)). 1006?- (fromto([1,2,3],In,Out,[]) do In=[X|Out], writeln(X)). 1007 1008% The following two are equivalent 1009?- (count(I,1,5) do writeln(I)). 1010?- (fromto(0,I0,I,5) do I is I0+1, writeln(I)). 1011 1012 1013% Some examples for nested loops. Print all pairs of list elements: 1014?- Xs = [1,2,3,4], 1015 ( foreach(X, Xs), param(Xs) do 1016 ( foreach(Y,Xs), param(X) do 1017 writeln(X-Y) 1018 ) 1019 ). 1020 1021% or using the product combinator: 1022?- Xs = [1,2,3,4], 1023 ( foreach(X, Xs) * foreach(Y, Xs) do 1024 writeln(X-Y) 1025 ). 1026 1027% and the same without symmetries: 1028?- Xs = [1,2,3,4], 1029 ( fromto(Xs, [X|Xs1], Xs1, []) do 1030 ( foreach(Y,Xs1), param(X) do 1031 writeln(X-Y) 1032 ) 1033 ). 1034 1035% or using the nesting combinator: 1036?- Xs = [1,2,3,4], 1037 ( fromto(Xs, [X|Xs1], Xs1, []) >> ( foreach(Y,Xs1), param(X) ) do 1038 writeln(X-Y) 1039 ). 1040 1041% Find all pairs of list elements and collect them in a result list: 1042pairs(Xs, Ys, Zs) :- 1043 ( 1044 foreach(X,Xs), 1045 fromto(Zs, Zs4, Zs1, []), 1046 param(Ys) 1047 do 1048 ( 1049 foreach(Y,Ys), 1050 fromto(Zs4, Zs3, Zs2, Zs1), 1051 param(X) 1052 do 1053 Zs3 = [X-Y|Zs2] 1054 ) 1055 ). 1056 1057% or 1058pairs(Xs, Ys, Zs) :- 1059 ( 1060 foreach(X, Xs) * foreach(Y, Ys), 1061 foreach(Z, Zs) 1062 do 1063 Z = X-Y 1064 ). 1065 1066 1067% Flatten a 2-dimensional matrix into a list: 1068flatten_matrix(Mat, Xs) :- 1069 dim(Mat, [M,N]), 1070 ( 1071 for(I,1,M), 1072 fromto(Xs, Xs4, Xs1, []), 1073 param(Mat,N) 1074 do 1075 ( 1076 for(J,1,N), 1077 fromto(Xs4, [X|Xs2], Xs2, Xs1), 1078 param(Mat,I) 1079 do 1080 subscript(Mat, [I,J], X) 1081 ) 1082 ). 1083 1084% Same using * to avoid nesting: 1085flatten_matrix(Mat, Xs) :- 1086 dim(Mat, [M,N]), 1087 ( 1088 for(I, 1, M) * for(J, 1, N), 1089 foreach(X, Xs), 1090 param(Mat) 1091 do 1092 subscript(Mat, [I,J], X) 1093 ). 1094 1095% Same using multifor to avoid nesting: 1096flatten_matrix(Mat, Xs) :- 1097 dim(Mat, [M,N]), 1098 ( 1099 multifor([I,J], 1, [M,N]), 1100 foreach(X, Xs), 1101 param(Mat) 1102 do 1103 subscript(Mat, [I,J], X) 1104 ). 1105 1106% Same for an array of arbitrary dimension: 1107flatten_array(Array, Xs) :- 1108 dim(Array, Dims), 1109 ( 1110 multifor(Idx, 1, Dims), 1111 foreach(X, Xs), 1112 param(Array) 1113 do 1114 subscript(Array, Idx, X) 1115 ). 1116 1117% Same but returns the elements in the reverse order: 1118flatten_array(Array, Xs) :- 1119 dim(Array, Dims), 1120 ( 1121 multifor(Idx, Dims, 1, -1), 1122 foreach(X, Xs), 1123 param(Array) 1124 do 1125 subscript(Array, Idx, X) 1126 ). 1127 1128% Flatten nested lists one level (cf. flatten/2 which flattens completely): 1129?- List = [[a,b],[[c,d,e],[f]],[g]], 1130 (foreach(Xs,List) >> foreach(X,Xs), foreach(X,Ys) do true). 1131 1132% Iterate over all ordered pairs of integers 1..4 1133% (param(I) required to make I available in body of loop): 1134?- (for(I,1,4) >> (for(J,I+1,4), param(I)) do writeln(I-J)). 1135 1136% Same for general 1..N (param(N) required to make N available to second for): 1137?- N=4, 1138 ((for(I,1,N), param(N)) >> (for(J,I+1,N), param(I)) do writeln(I-J)). 1139 1140 1141% Do-loop inside a Grammar Rule 1142% This rule will accept/generate a list of integers from 1 to N 1143intlist(N) --> ( for(I,1,N) do [I] ). 1144", 1145 see_also:[pragma / 1]]). 1146 1147:- comment(fork / 2, [ 1148 summary:"Succeeds for all integers I between 1 and Max. The solutions are generated 1149in parallel. 1150 1151", 1152 amode:(fork(+,-) is nondet), 1153 desc:html(" Generates in parallel the integers between 1 and a given maximum Max. 1154 The order of solutions is unspecified. For every value of Max, this 1155 predicate behaves as if defined by 1156 1157<P> 1158<PRE> 1159 :- parallel fork/2. 1160 fork(Max, Max). 1161 ... 1162 fork(Max, 2). 1163 fork(Max, 1). 1164</PRE> 1165 Operationally, the advantage of fork/2 compared to a recursive 1166 definition like 1167 1168<P> 1169<PRE> 1170 :- parallel bfork/2. 1171 bfork(Max, Max). 1172 bfork(Max, I) :- Max>1, Max1 is Max-1, bfork(Max1, I). 1173</PRE> 1174 is that fork/2 creates only a single wide choice point instead of Max 1175 binary ones. This improves efficiency, especially for parallel 1176 execution. 1177 1178<P> 1179"), 1180 args:[ 1181 "Max":"Integer", 1182 "I":"Variable or Integer" 1183 ], 1184 fail_if:"Fails if Max is less than 1", 1185 exceptions:[4 : "Max is not instantiated.", 5 : "Max is not an integer."], 1186 eg:" 1187% peclipse -w 3 1188[eclipse 1]: fork(5,X), get_flag(worker, W). 1189X = 5 1190W = 1 More? (;) 1191X = 3 1192W = 3 More? (;) 1193X = 4 1194W = 2 More? (;) 1195X = 2 1196W = 1 More? (;) 1197X = 1 1198W = 3 More? (;) 1199no (more) solution. 1200 1201 1202 1203", 1204 see_also:[between / 4, (parallel) / 1, repeat / 0, get_flag / 2]]). 1205 1206:- comment((-?->) / 1, [ 1207 index:["Matching"], 1208 summary:"The matching operator. The head of the clause which contains it will not 1209be unified with the caller, one-way matching will be used instead. 1210 1211", 1212 template:"-?-> ?Body", 1213 desc:html(" This operator is used to produce matching clauses, i.e. clauses whose 1214 head is unified with the caller only in one direction, namely without 1215 binding any variables in the caller. Therefore, only those clause will 1216 be selected, which are more general than the call, i.e. the call must 1217 be an instance of the head. If the clause head is unifiable with the 1218 call, but this unification would bind any of the variables in the call, 1219 the unification fails. 1220 1221<P> 1222 -?-> must occur at the beginning of the clause body, directly behind the 1223 :- symbol, and it must be followed by a non-empty body. Matching 1224 clauses with no body must use true/0 after the matching operator. 1225 1226<P> 1227 The matching operator can be also used to decompose attributed 1228 variables. When an attributed variable occurs in the head of a matching 1229 clause, it is not unified with the call argument (which would trigger 1230 the unification handlers) but instead, the call argument is decomposed 1231 into the variable and its attribute(s): 1232 1233<P> 1234<PRE> 1235 get_attr(X{A}, Attr) :- 1236 -?-> 1237 A = Attr. 1238</PRE> 1239 This predicate can be used to return the attribute of its argument if it 1240 is an attributed variable and to fail if it is not. 1241 1242<P> 1243 Clause matching is not supported by dynamic predicates. A run-time exception 1244 will be raised when executing a matching clause head that is dynamic. 1245 1246<P> 1247"), 1248 args:["Body" : "Callable term or a variable."] 1249 ]). 1250 1251:- comment(mutex_init / 1, [ 1252 summary:"Initialise the mutual exclusion lock MutexId", 1253 amode:(mutex_init(+) is det), 1254 desc:html("\ 1255 This built-in is used in parallel programs in connection with mutex/2 1256 to implement mutual exclusion between parallel workers. 1257 "), 1258 args:["MutexId" : "Atom."], 1259 exceptions:[4 : "MutexId is not instantiated", 1260 5 : "MutexId is not an atom"], 1261 see_also:[mutex/ 2]]). 1262 1263 1264:- comment(mutex / 2, [ 1265 summary:"Equivalent to once(Goal) but with mutual exclusion among parallel workers. 1266 1267", 1268 amode:(mutex(+,+) is det), 1269 desc:html(" This built-in can be used in parallel programs to implement mutual 1270 exclusion between parallel workers. A Goal that is called via mutex/2 1271 can be sure that no parallel worker is executing at the same time any 1272 goal that is protected by a mutex/2 with the same MutexId. 1273 1274<P> 1275 Note that in a side effect free program there is no need ever to worry 1276 about mutual exclusion. Only when side effects are involved (e.g. 1277 read/1,2 and write/1,2, assert/1, setval/2, record/2 etc.) it may be 1278 necessary to acquire exclusive access to the common resource by using 1279 mutex/2. 1280 1281<P> 1282"), 1283 args:["MutexId" : "Atom.", "Goal" : "Atom or compound term."], 1284 fail_if:"Fails if Goal fails", 1285 exceptions:[4 : "Goal is not instantiated.", 5 : "Goal is not an atom or a compound term."], 1286 eg:" 1287 :- mutex_init(my_lock). 1288 1289 atomic_write_list(List) :- 1290 % make sure the list is printed in one chunk 1291 mutex(my_lock, write_list(List)). 1292 1293 write_list([]) :- nl. 1294 write_list([X|Xs]) :- writeln(X), write_list(Xs). 1295 1296 [eclipse]: generate_lists_in_parallel(L), 1297 atomic_write_list(L), fail. 1298 1299 1300 1301", 1302 see_also:[mutex_init / 1, (once) / 1]]). 1303 1304:- comment(block / 3, [ 1305 summary:"Equivalent to call(Goal) if Goal succeeds or fails. 1306If Goal throws an exception that unifies with Catcher, Recovery is executed", 1307 args:["Goal" : "A callable term.", 1308 "Catcher" : "Any term.", 1309 "Recovery" : "A callable term."], 1310 desc:"This is a deprecated alias for catch/3 - see there.", 1311 resat:"Resatisfiable if Goal is resatisfiable, or Goal exits and Recovery is resatisfiable", 1312 fail_if:"Fail if Goal fails, or if Goal exits and Recovery fails", 1313 see_also:[catch/3, throw/1, exit_block/1]]). 1314 1315 1316:- comment(catch / 3, [ 1317 summary:"Equivalent to call(Goal) if Goal succeeds or fails. 1318If Goal throws an exception that unifies with Catcher, Recovery is executed", 1319 desc:html("\ 1320 First, Goal is called from the current module, and if this succeeds then 1321 catch/3 succeeds. If Goal fails, then so does the call of catch/3. In 1322 other words, unless exceptions are involved, catch(Goal, ..., ...) 1323 operates like call(Goal), and Catcher and Recovery are ignored. 1324<P> 1325 If, however, an exception is thrown during the execution of Goal 1326 (either by an error condition in a built-in predicate, or by an invocation 1327 of throw/1), and the exception term unifies with Catcher, then the 1328 execution of Goal is undone, and Recovery is called instead. In this 1329 case, catch(Goal,Catcher,Recovery) is equivalent to call(Recovery). 1330 Note that exceptions within Recovery are NOT caught by this catch! 1331<P> 1332 If Goal terminates with an exception, and the exception term does NOT 1333 unify with Catcher, then the exception is passed on, allowing an ancestor 1334 catch/3 to catch it. The innermost invocation of catch/3 whose Catcher 1335 argument matches the exception will catch it. 1336<P> 1337 NOTE: block/3 is a deprecated alias for catch/3, and behaves identically. 1338 exit_block/1 is a deprecated alias for throw/1, and behaves identically. 1339<P> 1340"), 1341 amode:catch(+,+,+), 1342 amode:catch(+,-,+), 1343 args:["Goal" : "A callable term.", 1344 "Catcher" : "Any term.", 1345 "Recovery" : "A callable term."], 1346 resat:"Resatisfiable if Goal is resatisfiable, or Goal exits and Recovery is resatisfiable", 1347 fail_if:"Fail if Goal fails, or if Goal exits and Recovery fails", 1348 eg:" 1349 % success, failure and backtracking are not affected by the catch: 1350 ?- catch(X is 3+4, T, writeln(recover(T))). 1351 X = 7 1352 T = T 1353 Yes (0.00s cpu) 1354 1355 ?- catch(8 is 3+4, T, writeln(recover(T))). 1356 No (0.00s cpu) 1357 1358 ?- catch(member(X,[1,2]), T, writeln(recover(T))). 1359 X = 1 1360 T = T 1361 Yes (0.00s cpu, solution 1, maybe more) ? ; 1362 X = 2 1363 T = T 1364 Yes (0.00s cpu, solution 2) 1365 1366 1367 % A variable Catcher catches all throws 1368 ?- catch(throw(hello), T, writeln(recover(T))). 1369 recover(hello) 1370 T = hello 1371 Yes (0.00s cpu) 1372 1373 1374 % An instantiated Catcher catches only matching throws 1375 ?- catch(throw(hello), hello, writeln(recovered)). 1376 recovered 1377 Yes (0.00s cpu) 1378 1379 ?- catch(throw(hello), world, writeln(recovered)). 1380 uncaught exception in throw(hello) 1381 Abort 1382 1383 1384 % A partially instantiated Catcher catches only matching throws 1385 ?- catch(throw(hello(world)), hello(Who), writeln(recovered(Who))). 1386 recovered(world) 1387 Yes (0.00s cpu) 1388 1389 ?- catch(throw(hi(world)), hello(Who), writeln(recovered(Who))). 1390 uncaught exception in throw(hi(world)) 1391 Yes (0.00s cpu) 1392 1393 1394 % ECLiPSe's error handlers usually execute throw(abort) 1395 % and therefore can be caught with a catch: 1396 ?- catch(X is 1//0, T, writeln(recover(T))). 1397 arithmetic exception in //(1, 0, X) 1398 recover(abort) 1399 X = X 1400 T = abort 1401 Yes (0.01s cpu) 1402 1403 1404 % Executing a recovery action AND passing the exception on: 1405 ?- catch(throw(hello), T, (writeln(caught(T)), throw(T))). 1406 caught(hello) 1407 uncaught exception in throw(hello) 1408 Abort 1409", 1410 see_also:[throw / 1, abort/0]]). 1411 1412 1413:- comment((^) / 2, [ 1414 index:["Existential quantification"], 1415 summary:"Succeeds if Goal succeeds. 1416 1417", 1418 template:"+Vars ^ +Goal", 1419 desc:html(" Calls the goal Goal. This predicate is equivalent to call(Goal) unless 1420 used inside bagof/3, setof/3 or coverof/3. In this case it is to be 1421 read as \"there exist instantiations for the variables in Vars such that 1422 Goal is true\". 1423 1424<P> 1425"), 1426 args:["Vars" : "Any term, but usually a variable.", "Goal" : "Atom or compound term."], 1427 resat:"Resatisfiable if Goal is resatisfiable", 1428 fail_if:"Fails if Goal fails", 1429 exceptions:[4 : "Goal is not instantiated.", 5 : "Goal is not an atom or a compound term."], 1430 eg:" 1431refer to bagof/3 for examples. 1432 1433 1434 1435", 1436 see_also:[call / 1, bagof / 3, setof / 3, coverof / 3]]). 1437 1438 1439:- comment(exit_block / 1, [ 1440 summary:"Throw an exception described by Ball. Continue execution 1441at the recovery procedure of a matching ancestestor catch/3 or block/3", 1442 desc:"This is a deprecated alias for throw/1 - see there.", 1443 amode:(exit_block(+) is erroneous), 1444 args:["Ball" : "Any term, but no variable"], 1445 exceptions:[ 1446 4 : "Ball is uninstantiated.", 1447 230 : "Ball does not unify with a Catcher of any uncompleted call of catch/3 or block/3."], 1448 see_also:[throw/1, catch/3, block/3]]). 1449 1450:- comment(throw / 1, [ 1451 summary:"Throw an exception described by Ball. Continue execution 1452at the recovery procedure of a matching ancestestor catch/3", 1453 desc:html("\ 1454 This predicate neither succeeds nor fails, but raises (or \"throws\") 1455 an exception identified by the term Ball. Execution will then continue 1456 with the Recovery goal of the innermost catch/3 ancestor that catches this 1457 exception (i.e., whose second argument, the Catcher, unifies with Ball). 1458<P> 1459 If the exception is not caught by any catch/3 in the user program, then 1460 <UL> 1461 <LI>in a development system with a toplevel, the exception will be caught 1462 by the toplevel, reporting an 'uncaught exception' (230) error. 1463 <LI>in a standalone ECLiPSe without toplevel (e.g. using the -e command 1464 line option), the process will exit with exit code 2. 1465 <LI>in an embeddded system, control will return to the host program 1466 with a corresponding return code (PTHROW, EC_throw, etc). 1467 </UL> 1468<P> 1469 The term that is unified with the ancestor's Catcher is a copy of the 1470 Ball, i.e. if it contains variables, these are not identical to the 1471 original ones in Ball. 1472<P> 1473 NOTE: block/3 is a deprecated alias for catch/3, and behaves identically. 1474 exit_block/1 is a deprecated alias for throw/1, and behaves identically. 1475<P> 1476"), 1477 amode:(throw(+) is erroneous), 1478 args:["Ball" : "Any term, but no variable"], 1479 exceptions:[ 1480 4 : "Ball is uninstantiated.", 1481 230 : "Ball does not unify with a Catcher of any uncompleted call of catch/3."], 1482 eg:" 1483 % A variable Catcher catches all throws 1484 ?- catch(throw(hello), T, writeln(recover(T))). 1485 recover(hello) 1486 T = hello 1487 Yes (0.00s cpu) 1488 1489 1490 % An instantiated Catcher catches only matching throws 1491 ?- catch(throw(hello), hello, writeln(recovered)). 1492 recovered 1493 Yes (0.00s cpu) 1494 1495 ?- catch(throw(hello), world, writeln(recovered)). 1496 uncaught exception in throw(hello) 1497 Abort 1498 1499 1500 % A partially instantiated Catcher catches only matching throws 1501 ?- catch(throw(hello(world)), hello(Who), writeln(recovered(Who))). 1502 recovered(world) 1503 Yes (0.00s cpu) 1504 1505 ?- catch(throw(hi(world)), hello(Who), writeln(recovered(Who))). 1506 uncaught exception in throw(hi(world)) 1507 Yes (0.00s cpu) 1508 1509 1510 % The caught term is a copy of the thrown term (fresh variables) 1511 ?- T1=f(X), catch(throw(T1), T2, true), variant(T1, T2), T1\\==T2. 1512 T1 = f(X_88) 1513 T2 = f(X_510) 1514 Yes (0.00s cpu) 1515 1516Error: 1517 throw(_). (Error 4). 1518 throw(never_caught). (Error 230). 1519", 1520 see_also:[catch/3]]). 1521 1522 1523:- comment((->) / 2, [ 1524 index:["Conditional"], 1525 summary:"Conditional construct - succeeds if Then succeeds for the first solution of Condition, 1526or if Condition fails and Else succeeds.", 1527 template:"+Condition -> +Then ; +Else", 1528 desc:html(" 1529 The conditional (if-then-else) construct. First Condition is called 1530 and if this succeeds any further solutions of Condition are cut and 1531 Then is called. Else is never executed in this case regardless of the 1532 outcome of Then. 1533<P> 1534 If Condition fails, Else is called. In this case, Then is never executed. 1535<P> 1536 It is allowed, but not recommended to use ->/2 without ;/2 as 1537 <PRE> 1538 ( Condition -> Then ) 1539 </PRE> 1540 because this is equivalent to 1541 <PRE> 1542 ( Condition -> Then ; fail ) 1543 </PRE> 1544 which is sometimes considered unintuitive. If this behaviour is really 1545 wanted, it can be expressed more clearly by 1546 <PRE> 1547 once Condition , Then 1548 </PRE> 1549<P> 1550 The more common idiom, where nothing is to be done in the else-case, 1551 must be written like this, using true/0: 1552 <PRE> 1553 ( Condition -> Then ; true ) 1554 </PRE> 1555<P> 1556 Also note that a !/0 inside Condition only has a local effect in Condition. 1557 If a !/0 appears in Then or Else, it cuts through the whole construct. 1558 1559<P> 1560 Since ->/2 and ;/2 have a lower precedence than ,/2, the whole construct 1561 should always be enclosed in parentheses: 1562 <PRE> 1563 ( Condition -> 1564 Then 1565 ; 1566 Else 1567 ) 1568 </PRE> 1569"), 1570 args:["Condition" : "Atom or compound term.", "Then" : "Atom or compound term.", "Else" : "Atom or compound term."], 1571 resat:"Resatisfiable if Condition succeeds and Then is resatisfiable, or Condition fails and Else is resatisfiable", 1572 fail_if:"Fails if Condition succeeds and Then fails, or if Condition and Else fail", 1573 exceptions:[4 : "One of the arguments is not instantiated.", 5 : "One of the arguments is neither an atom nor a compound term."], 1574 eg:" 1575Success: 1576 % Then-branch executed 1577 ?- X = 1, ( X == 1 -> write(a) ; write(b) ). 1578 a 1579 X = 1 1580 Yes (0.00s cpu) 1581 1582 % Else-branch executed 1583 ?- X = 2, ( X == 1 -> write(a) ; write(b) ). 1584 b 1585 No (0.00s cpu) 1586 1587 % the Condition is cut, the Then-branch isn't 1588 ?- ( member(X,[1,2]) -> member(Y,[a,b]) ; member(Y,[c,d]) ). 1589 X = 1 1590 Y = a 1591 Yes (0.00s cpu, solution 1, maybe more) 1592 X = 1 1593 Y = b 1594 Yes (0.03s cpu, solution 2) 1595", 1596 see_also:[(;) / 2, ! / 0, (*->)/2]]). 1597 1598 1599:- comment((*->) / 2, [ 1600 index:["Soft cut", "Conditional"], 1601 summary:"Soft-cut-conditional construct - succeeds if Then succeeds for 1602some solution of Condition, or if Condition fails and Else succeeds", 1603 template:"+Condition *-> +Then ; +Else", 1604 desc:html("<P>\ 1605 This construct is similar to the standard conditional construct 1606 <PRE> 1607 Condition -> Then ; Else 1608 </PRE> 1609 except that it does not discard alternative solutions to Condition. 1610 This means that, on backtracking, alternative solutions to Condition 1611 are found, and the Then branch will be executed for each solution 1612 of the Condition (rather than just the first one). 1613 </P><P> 1614 This functionality is sometimes referred to as 'soft cut'. A soft cut 1615 is a cut that discards an alternative which is not the chronologically 1616 most recent one (the Else-alternative is older than the alternatives 1617 within Condition). 1618 </P><P> 1619 The operational semantics is as follows: if Condition succeeds, Then is executed, 1620 and on backtracking subsequent solutions of Condition and Then are returned, but 1621 Else is never executed. Only if Condition has no solutions at all, Else is executed. 1622<P> 1623 Although it is allowed to use *->/2 without ;/2, this is of little 1624 use since (Condition *-> Then) is the same as the simple conjunction (Condition , Then). 1625<P> 1626 Also note that a !/0 inside Condition only has a local effect in Condition. 1627 If a !/0 appears in Then or Else, it cuts through the whole construct. 1628<P> 1629 Since *->/2 and ;/2 have a lower precedence than ,/2, the whole construct 1630 should always be enclosed in parentheses: 1631 <PRE> 1632 ( Condition *-> 1633 Then 1634 ; 1635 Else 1636 ) 1637 </PRE> 1638"), 1639 args:["Condition" : "Atom or compound term.", "Then" : "Atom or compound term.", "Else" : "Atom or compound term."], 1640 resat:"Resatisfiable if Condition or Then are resatisfiable, or Condition is not satisfiable and Else is resatisfiable", 1641 fail_if:"Fails if Then fails for all solutions of Condition, or if Condition and Else both fail", 1642 exceptions:[4 : "One of the arguments is not instantiated.", 5 : "One of the arguments is neither an atom nor a compound term."], 1643 eg:" 1644 ?- ( member(X,[1,2,3]) *-> writeln(then(X)) ; writeln(else(X)) ). 1645 then(1) 1646 X = 1 1647 Yes (0.00s cpu, solution 1, maybe more) ? ; 1648 then(2) 1649 X = 2 1650 Yes (0.00s cpu, solution 2, maybe more) ? ; 1651 then(3) 1652 X = 3 1653 Yes (0.00s cpu, solution 3) 1654 1655 1656 ?- X=4, ( member(X,[1,2,3]) *-> writeln(then(X)) ; writeln(else(X)) ). 1657 else(4) 1658 Yes (0.00s cpu) 1659 1660 ?- ( member(X,[1,2]) *-> member(Y,[a,b]) ; member(Y,[c,d]) ). 1661 X = 1 1662 Y = a 1663 Yes (0.00s cpu, solution 1, maybe more) 1664 X = 1 1665 Y = b 1666 Yes (0.02s cpu, solution 2, maybe more) 1667 X = 2 1668 Y = a 1669 Yes (0.02s cpu, solution 3, maybe more) 1670 X = 2 1671 Y = b 1672 Yes (0.03s cpu, solution 4) 1673", 1674 see_also:[(->)/2, (;) / 2, ! / 0]]). 1675 1676 1677:- comment(repeat / 0, [ 1678 summary:"Succeeds as often as tried.", 1679 amode:(repeat is multi), 1680 desc:html(" Used to succeed as often as tried. 1681 1682<P> 1683 This predicate could be defined as 1684 1685<P> 1686<PRE> 1687 repeat. 1688 repeat :- repeat. 1689</PRE> 1690 repeat/0 succeeds when reached on backtracking. 1691 1692<P> 1693 !/0 may be added to exit from a clause containing repeat/0, as it 1694 removes all choice points above it in the clause. 1695 1696<P> 1697"), 1698 args:[], 1699 eg:" 1700Success: 1701 [eclipse]: [p]. 1702 /home/user/p compiled 408 bytes in 0.03 seconds 1703 yes. 1704 [eclipse]: print_file(p). 1705 print_file(File) :- 1706 open(File, read, S), 1707 repeat, 1708 get(S,Char), 1709 put(Char), 1710 at_eof(S), 1711 !, 1712 close(S), 1713 flush(output). 1714 yes. 1715 1716 1717 1718 1719", 1720 see_also:[! / 0]]). 1721 1722:- comment(true / 0, [ 1723 summary:"Succeeds always. 1724 1725", 1726 amode:(true is det), 1727 desc:html(" Succeeds. For example, can be used as a default, to join the `then' 1728 path in ->/2 to the `if' path, or as a void event handler. 1729 1730<P> 1731"), 1732 args:[], 1733 eg:" 1734Success: 1735 (F \\== \"d.error\" -> 1736 writeln(error, \"Incorrect file \"), 1737 writeln( error,F) 1738 ; 1739 true 1740 ), 1741 (L < 0 -> 1742 writeln(error, \"Error in line number\") 1743 ; 1744 true 1745 ). 1746 1747 1748 1749", 1750 see_also:[fail / 0, false / 0]]). 1751 1752 1753:- comment( 1754 call / (2..255), [ 1755 template:[ 1756 "call(+GoalPrefix, ?Arg, ?...)" 1757 ], 1758 args:["GoalPrefix":" A callable term", 1759 "Arg":"An additional argument for Goal", 1760 "...":"Optional further additional arguments for Goal" 1761 ], 1762 summary:"Call with any number of additional arguments", 1763 desc:html("<P>\ 1764 Call the goal formed by appending the additional argument Arg 1765 (and any further arguments given) to GoalPrefix. For example, 1766 the following calls are all equivalent and invoke p/2: 1767 <PRE> 1768 call(p, 1, 2) 1769 call(p(1), 2) 1770 call(p(1,2) ) 1771 </PRE> 1772 The maximum arity for call/N is the one indicated by 1773 get_flag(max_predicate_arity,N), and is at least 255. 1774 </P><P> 1775 These predicates are sensitive to their calling context module 1776 in the same way as call/1. 1777 </P><P> 1778 Implementation note: These predicates are materialised lazily the 1779 first time they are being invoked. They may therefore not show up 1780 with current_built_in/1, get_flag/3 or other similar access methods. 1781 </P>"), 1782 resat:"Resatisfiable if the called goal is resatisfiable", 1783 fail_if:"Fails if the called goal fails", 1784 exceptions:[ 1785 4 : "GoalPrefix is not instantiated.", 1786 5 : "GoalPrefix is not an atom or a compound term.", 1787 68 : "Constructed goal refers to an undefined predicate." 1788 ], 1789 eg:" 1790 ?- call(p, 1, 2, 3). 1791 calling an undefined procedure p(1, 2, 3) in module eclipse 1792 Abort 1793 1794 ?- call(append(L, R), [1]). 1795 L = [] 1796 R = [1] 1797 Yes (0.00s cpu, solution 1, maybe more) 1798 L = [1] 1799 R = [] 1800 Yes (0.00s cpu, solution 2) 1801 1802 ?- call(+(3), 4, X). 1803 X = 7 1804 Yes (0.00s cpu) 1805 1806 1807 % A typical use case 1808 filter(_, [], []). 1809 filter(Pred, [X|Xs], Ys) :- 1810 ( call(Pred, X) -> 1811 Ys = [X|Ys1], 1812 filter(Pred, Xs, Ys1) 1813 ; 1814 filter(Pred, Xs, Ys) 1815 ). 1816 1817 ?- filter(atom, [1, a, 2, b, c], As). 1818 As = [a, b, c] 1819 Yes (0.03s cpu) 1820 ?- filter(integer, [1, a, 2, b, c], As). 1821 As = [1, 2] 1822 Yes (0.06s cpu) 1823 ?- filter(<(2), [5, 1, 4, 2, 3], Is). 1824 Is = [5, 4, 3] 1825 Yes (0.00s cpu) 1826", 1827 see_also:[call/1, (@)/2, (:)/2]]). 1828 1829