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, "Recorded Database"). 24:- comment(summary, "The record-family of built-ins to store data across failures"). 25:- comment(categories, ["Built-In Predicates","Data Structures"]). 26 27:- tool(erase / 2). 28:- tool(erase_all / 1). 29%:- tool(erase_all / 2). 30:- tool(is_record / 1). 31:- tool(record / 2). 32:- tool(recorda / 2). 33:- tool(recorda / 3). 34:- tool(recorded / 2). 35:- tool(recorded / 3). 36:- tool(recorded_list / 2). 37%:- tool(recorded_refs / 2). 38:- tool(recordz / 2). 39:- tool(recordz / 3). 40:- tool(rerecord / 2). 41:- tool(current_record / 1). 42 43:- comment(desc, html("\ 44 ECLiPSe provides several facilities to store information across 45 backtracking. The following table gives an overview. If at all 46 possible, the handle-based facilities (bags, records, shelves, 47 stores) should be preferred because they lead to cleaner, reentrant 48 code (without global state) and reduce the risk of memory leaks. 49<PRE> 50 Facility Type Reference See 51 ================================================================ 52 bags unordered bag by handle bag_create/1 53 ---------------------------------------------------------------- 54 anon.records ordered list by handle record_create/1 55 ---------------------------------------------------------------- 56 shelves array by handle shelf_create/2,3 57 ---------------------------------------------------------------- 58 stores hash table by handle store_create/1 59 ---------------------------------------------------------------- 60 named shelves array by name shelf/2 61 ---------------------------------------------------------------- 62 named stores hash table by name store/1 63 ---------------------------------------------------------------- 64 non-logical single cell by name variable/1,2 65 variables 66 ---------------------------------------------------------------- 67 non-logical array by name array/1,2 68 arrays 69 ---------------------------------------------------------------- 70 named records ordered list by name record/1,2 71 ---------------------------------------------------------------- 72 dynamic ordered list by name dynamic/1,assert/1 73 predicates 74 ---------------------------------------------------------------- 75</PRE> 76 ")). 77 78:- comment(current_record / 1, [ 79 summary:"Succeeds if Key is the key of a recorded item. 80 81", 82 amode:(current_record(+) is semidet), 83 amode:(current_record(-) is nondet), 84 desc:html(" Used to backtrack over the keys currently recorded in the indexed 85 database. Key must be either a variable, an atom or a compound term. 86 In the case of compound terms, all keys of the same name and arity are 87 treated as equal. 88 89<P> 90"), 91 args:["Key" : "Variable, atom, compound term, or handle."], 92 fail_if:"Fails if Key is not a current key", 93 exceptions:[5 : "Key is neither a variable, an atom nor a compound term."], 94 eg:" 95 Success: 96 [eclipse]: record(whiskey,jameson), 97 > record(whiskey,bushmills), 98 > record(beer,lowenbrau), 99 > record(car(bmw), 735). 100 yes. 101 [eclipse]: current_record(Key). 102 Key = beer More? (;) 103 Key = whiskey More? (;) 104 Key = car(_g62) More? (;) 105 no (more) solution. 106 Fail: 107 record(whiskey,bushmills),current_record(bushmills). 108 Error: 109 current_record(1). (Error 5) 110 current_record(\"whiskey\"). (Error 5) 111 112 113 114", 115 see_also:[is_record / 1]]). 116 117:- comment(record_create / 1, [ 118 summary:"Create an anonymous record handle", 119 amode:(record_create(-) is det), 120 desc:html(" 121 This creates an anonymous 'record' object which can store an 122 ordered list of terms, and whose contents are unaffected by 123 backtracking. 124<P> 125 Records can be referred to either by handle or by name. Whenever 126 possible, handles should be used, because this naturally leads to 127 robust, reentrant code, and avoids the danger of memory leaks. 128 An anonymous record disappears when the system backtracks over 129 its creation, when the record handle gets garbage collected, 130 or when it is explicitly destroyed. 131<P> 132 When named records are used, the visibility of the record name is 133 local to the module where it was created. A named record never 134 disappears, therefore, in order to free the associated memory, 135 its contents should be erased when no longer needed. 136 "), 137 args:["Handle" : "Variable, will be bound to a handle."], 138 eg:" 139 ?- record_create(R), record(R,a), record(R,b), recorded_list(R,L). 140 L = [a,b] 141 142 ?- record_create(R), 143 ( member(X,[a,b,c]), record(R,X), fail 144 ; recorded_list(R,L) 145 ). 146 L = [a,b,c] 147", 148 see_also:[is_record / 1, record/1, record/2, recorded/2]]). 149 150:- comment(erase / 2, [ 151 summary:"Succeeds if the term Value associated with key Key is removed as an entry 152in the indexed database. 153 154", 155 amode:(erase(+,+) is semidet), 156 amode:(erase(+,-) is semidet), 157 desc:html(" Finds the first term associated with Key that can be unified with Value 158 and removes its entry from the indexed database. It fails if such an 159 entry cannot be found. If Value is uninstantiated, the first value 160 under the key Key is removed. In the case of compound terms, all keys 161 of the same name and arity are treated as equal. Backtracking through 162 calls of erase/2 does not undo an erasure. 163 164<P> 165"), 166 args:["Key" : "Atom, compound term, or handle.", "Value" : "Any Prolog term."], 167 fail_if:"Fails if Value does not unify with any term recorded under the key Key", 168 exceptions:[4 : "Key is not instantiated.", 5 : "Key is neither an atom nor a compound term."], 169 eg:" 170 Success: 171 [eclipse]: record(whiskey,jameson), 172 > record(whiskey,bushmills), 173 > record(whiskey,glenfiddich), 174 > record(whiskey,dimple). 175 yes. 176 [eclipse]: erase(whiskey,dimple),erase(whiskey,Value). 177 Value = jameson 178 yes. 179 [eclipse]: recorded(whiskey,L). 180 L = bushmills More? (;) 181 L = glenfiddich More? (;) 182 no (more) solution. 183 Fail: 184 erase(whiskey,jameson). 185 Error: 186 erase(Key,anything). (Error 4) 187 erase(\"whiskey\",anything). (Error 5) 188 189 190 191", 192 see_also:[erase_all / 1]]). 193 194:- comment(erase_all / 1, [ 195 summary:"All the the values associated with key Key are removed from the indexed 196database. 197 198", 199 amode:(erase_all(+) is det), 200 desc:html(" Used to remove all entries from the indexed database with the associated 201 key Key. In the case of compound terms, all keys of the same name and 202 arity are treated as equal. 203 204<P> 205"), 206 args:["Key" : "An atom, compound term or handle."], 207 exceptions:[4 : "Key is uninstantiated.", 5 : "Key is neither an atom nor a compound term."], 208 eg:" 209 Success: 210 [eclipse]: record(whiskey,jameson), 211 > record(whiskey,bushmills), 212 > record(whiskey,glenfiddich), 213 > record(whiskey,dimple). 214 yes. 215 [eclipse]: erase_all(whiskey). 216 yes. 217 [eclipse]: recorded(whiskey,L). 218 no (more) solution. 219 Error: 220 erase_all(Key). (Error 4) 221 erase_all(\"key\"). (Error 5) 222 erase_all(1). (Error 5) 223 224 225 226", 227 see_also:[erase / 2]]). 228 229:- comment(is_record / 1, [ 230 summary:"Succeeds if Key is a key of a recorded item. 231 232", 233 amode:(is_record(+) is semidet), 234 desc:html(" Used to test whether Key is a key of a recorded item. Fails if Key is 235 not a key for a recorded item. In the case of compound terms, all keys 236 of the same name and arity are treated as equal. 237 238<P> 239"), 240 args:["Key" : "An atom, compound term or handle."], 241 fail_if:"Fails if Key is not a key for a recorded item", 242 exceptions:[4 : "Key is uninstantiated.", 5 : "Key is neither an atom nor a compound term."], 243 eg:" 244 Success: 245 [eclipse]: record(whiskey,jameson), 246 > record(whiskey,bushmills), 247 > record(beer,lowenbrau). 248 yes. 249 [eclipse]: is_record(whiskey). 250 yes. 251 [eclipse]: is_record(beer). 252 yes. 253 Fail: 254 [eclipse]: is_record(wine). 255 no. 256 Error: 257 is_record(Key). (Error 4) 258 is_record(\"whiskey\"). (Error 5) 259 260 261 262", 263 see_also:[current_record / 1, record / 1]]). 264 265:- comment(record / 2, [ 266 summary:"Records the term Value at the end of key Key in the indexed database. 267 268", 269 amode:(record(+,?) is det), 270 desc:html(" Used to record any prolog term Value at the end of the indexed database 271 entry associated with the key Key. A synonym for recordz/2. In the 272 case of compound terms, all keys of the same name and arity are treated 273 as equal. 274 275<P> 276 If backtracking occurs through the call of record/2 the associated Value 277 is not removed from the indexed database. Recording the same Value 278 twice results in two identical entries in the indexed database. All 279 variables are recorded according to their internal representations. 280 281<P> 282"), 283 args:["Key" : "An atom, compound term, or handle.", "Value" : "Any prolog term."], 284 exceptions:[4 : "Key is not instantiated.", 5 : "Key is neither an atom nor a compound term."], 285 eg:" 286 Success: 287 record(a(compound,term),value1). 288 record([a,different,term],value2). 289 290 [eclipse]: record(whiskey,jameson), 291 > record(whiskey,glenlivet), 292 > record(whiskey,bushmills). 293 yes. 294 [eclipse]: recorded(whiskey,Value). 295 Value = jameson More (;) 296 Value = glenlivet More (;) 297 Value = bushmills More (;) 298 no (more) solution. 299Error: 300 record(Key, anything). (Error 4) 301 record(\"key\",anything). (Error 5) 302 303 304 305", 306 see_also:[recorda / 2, recordz / 2]]). 307 308:- comment(recorda / 2, [ 309 summary:"Records the term Value at the beginning of key Key in the indexed database. 310 311", 312 amode:(recorda(+,?) is det), 313 desc:html(" Used to record any prolog term Value at the beginning of the indexed 314 database entry associated with the key Key. In the case of compound 315 terms, all keys of the same name and arity are treated as equal. 316 317<P> 318 If backtracking occurs through the call of recorda/2 the associated 319 Value is not removed from the indexed database. 320 321<P> 322"), 323 args:["Key" : "An atom, compound term, or handle.", "Value" : "Any prolog term."], 324 exceptions:[4 : "Key is not instantiated.", 5 : "Key is neither an atom nor a compound term."], 325 eg:" 326 Success: 327 recorda(a(compound,term),value1). 328 recorda([a,compound,term],value2). 329 330 [eclipse]: recorda(whiskey,jameson), 331 > recorda(whiskey,bushmills), 332 > recorda(whiskey,glenlivet). 333 yes. 334 [eclipse]: recorded(whiskey,Value). 335 Value = glenlivet More (;) 336 Value = bushmills More (;) 337 Value = jameson More (;) 338 no (more) solution. 339Error: 340 recorda(Key, anything). (Error 4) 341 recorda(\"key\",anything). (Error 5) 342 343 344 345", 346 see_also:[record / 2, recordz / 2]]). 347 348:- comment(recorded / 2, [ 349 summary:"Succeeds if the term Value has been recorded in the indexed database under 350the key Key. 351 352", 353 amode:(recorded(+,-) is nondet), 354 amode:(recorded(+,+) is nondet), 355 desc:html(" Used to find all values associated with a key. Unifies Value with the 356 first term that has been associated with Key. In the case of compound 357 terms, all keys of the same name and arity are treated as equal. If 358 Value is instantiated, the instantiated term is used as a filter to reduce 359 the number of terms returned by the recorded database and unified with Value, 360 thus improving the speed of retrieving the term. 361 362<P> 363 Backtracking will unify Value with successive values associated with Key 364 in the order in which they were recorded. 365 366<P> 367"), 368 args:["Key" : "An atom or a compound term.", "Value" : "Any Prolog term."], 369 fail_if:"Fails if nothing is recorded under the key Key", 370 exceptions:[4 : "Key is not instantiated.", 5 : "Key is neither an atom nor a compound term."], 371 eg:" 372 Success: 373 [eclipse]: record(beer,paulaner), 374 > record(beer,lowenbrau), 375 > record(beer,spaten), 376 > recorded(beer,Value). 377 Value = paulaner More? (;) 378 Value = lowenbrau More? (;) 379 Value = spaten More? (;) 380 no (more) solution. 381 Fail: 382 erase_all(beer),recorded(beer,guiness). 383 Error: 384 recorded(Beer,Value). (Error 4) 385 recorded(\"beer\",Value). (Error 5) 386 recorded(1,Value). (Error 5) 387 388 389 390", 391 see_also:[record / 2]]). 392 393:- comment(recordz / 2, [ 394 summary:"Records the term Value at the end of key Key in the indexed database. 395 396", 397 amode:(recordz(+,?) is det), 398 desc:html(" Used to record any prolog term Value at the end of the indexed database 399 entry associated with the key Key. A synonym for record/2. In the case 400 of compound terms, all keys of the same name and arity are treated as 401 equal. 402 403<P> 404 If backtracking occurs through the call of recordz/2 the associated 405 Value is not removed from the indexed database. 406 407<P> 408"), 409 args:["Key" : "An atom, compound term, or handle.", "Value" : "Any prolog term."], 410 exceptions:[4 : "Key is not instantiated.", 5 : "Key is neither an atom nor a compound term."], 411 eg:" 412 Success: 413 [eclipse]: recordz(whiskey,jameson), 414 > recordz(whiskey,[scotch,irish,canadian,american]), 415 > recordz(whiskey,bushmills). 416 yes. 417 [eclipse]: recorded(whiskey,Value). 418 Value = jameson More (;) 419 Value = [scotch,irish,canadian,american] More (;) 420 Value = bushmills More (;) 421 no (more) solution. 422 423 recordz(a(compound,term),value1). 424 recordz([a,compound,term],value2). 425Error: 426 recordz(Key, anything). (Error 4) 427 recordz(\"key\",anything). (Error 5) 428 recordz(1,anything). (Error 5) 429 430 431 432", 433 see_also:[record / 2, recorda / 2]]). 434 435:- comment(rerecord / 2, [ 436 summary:"Erases all entries recorded under the key Key and replaces them with the 437given value Value. 438 439", 440 amode:(rerecord(+,?) is det), 441 desc:html(" Used to erase all values associated with Key and then record the term 442 Value under the key Key. If Key does not exist previously, it will 443 record Value under Key in the indexed database. In the case of compound 444 terms, all keys of the same name and arity are treated as equal. 445 446<P> 447 Backtracking through a call of rerecord/2 does not undo erasure of the 448 erased values and the value Value is not removed. 449 450<P> 451"), 452 args:["Key" : "An atom or a compound term.", "Value" : "Any prolog term."], 453 exceptions:[4 : "Key is not instantiated.", 5 : "Key is neither an atom nor a compound term."], 454 eg:" 455 Success: 456 [eclipse]: record(beer,lowenbrau), 457 > record(beer,paulaner), 458 > record(beer,spaten), 459 > rerecord(beer,guinness). 460 yes. 461 [eclipse]: recorded(beer,Value). 462 Value = guinness More? (;) 463 no (more) solution. 464 [eclipse]: erase_all(beer),rerecord(beer,guinness). 465 yes. 466 [eclipse]: recorded(beer,guinness). 467 yes. 468 Error: 469 rerecord(Beer,anything). (Error 4) 470 rerecord(1,anything). (Error 5) 471 rerecord(1.0,anything). (Error 5) 472 rerecord(\"str\",anything). (Error 5) 473 474 475 476", 477 see_also:[erase_all / 1]]). 478 479:- comment(erase / 1, [ 480 summary:"Succeeds if the database reference DBRef designates a term recorded in the 481indexed database and this term is successfully erased. 482 483", 484 amode:(erase(+) is semidet), 485 desc:html(" The database reference DBRef must refer to a term that has been recorded 486 in the indexed database. Database references can be obtained from the 487 predicates recorda/3, recordz/3 and recorded/3. If the referenced term 488 has already been erased, erase/1 fails. Backtracking through calls of 489 erase/1 does not undo an erasure. Note that an erased term can still 490 be retrieved via the database reference, but it can no longer be found 491 by lookup under the recording-key. 492 493<P> 494"), 495 args:["DBRef" : "A database reference."], 496 fail_if:"Fails if DBRef refers to an already erased record", 497 exceptions:[4 : "DBRef is not instantiated.", 5 : "DBRef is not a database reference."], 498 eg:" 499 Success: 500 [eclipse]: recordz(whiskey, jameson, _), 501 recordz(whiskey, glenfiddich, Ref), 502 recordz(whiskey, dimple, _), 503 erase(Ref). 504 Ref = 'DBREF'(16'50470d28) 505 yes. 506 [eclipse]: recorded(whiskey, L, _). 507 L = jameson More? (;) 508 L = dimple More? (;) 509 no (more) solution. 510 Fail: 511 [eclipse]: recorded(whiskey,_,R), !, erase(R), erase(R). 512 no (more) solution. 513 Error: 514 erase(Var). (Error 4) 515 erase(123). (Error 5) 516 517 518 519", 520 see_also:[erase_all / 1, is_handle/1, recorda / 3, recordz / 3, recorded / 3, referenced_record / 2]]). 521 522:- comment(recorded_list / 2, [ 523 summary:"Succeeds if the List is the list of all terms that are currently recorded 524in the indexed database under the key Key. 525 526", 527 amode:(recorded_list(+,-) is det), 528 desc:html(" Unifies List with a list of all the terms that are currently recorded 529 under the key Key. While recorded/2 returns the terms one by one on 530 backtracking, recorded_list/2 gives them all at once. The order of the 531 list corresponds to the order in which the terms would be delivered by 532 recorded/2. recorded_list/2 could be defined as 533 534<P> 535<PRE> 536 recorded_list(Key, List) :- 537 findall(Term, recorded(Key, Term), List). 538</PRE> 539 In the case of compound terms, all keys of the same name and arity are 540 treated as equal. 541 542<P> 543"), 544 args:["Key" : "An atom or a compound term.", "List" : "A (possibly empty) list of Prolog terms."], 545 exceptions:[4 : "Key is not instantiated.", 5 : "Key is neither an atom nor a compound term.", 5 : "List is neither an variable nor a list."], 546 eg:" 547 Success: 548 [eclipse]: erase_all(beer), recorded_list(beer,List). 549 List = [] 550 yes. 551 [eclipse]: record(beer,paulaner), record(beer,lowenbrau), 552 recorda(beer,spaten), recorded_list(beer,List). 553 List = [spaten, paulaner, lowenbrau] 554 yes. 555 Fail: 556 erase_all(beer), recorded_list(beer,[paulaner]). 557 Error: 558 recorded_list(Beer,Value). (Error 4) 559 recorded_list(1,Value). (Error 5) 560 recorded_list(beer,lowenbrau). (Error 5) 561 562 563 564", 565 see_also:[record / 2, recorded / 2]]). 566 567:- comment(recorda / 3, [ 568 summary:"Records the term Value at the beginning of key Key in the indexed database. 569 570", 571 amode:(recorda(+,?,-) is det), 572 desc:html(" Used to record any prolog term Value at the beginning of the indexed 573 database entry associated with the key Key. Unlike recorda/2, this 574 predicate delivers a so-called database reference in DBRef which is a 575 unique handle for the indexed database entry that is created. 576 In the case of compound terms, all keys of the same name and arity are 577 treated as equal. 578 579<P> 580 If backtracking occurs through the call of recorda/3 the associated 581 Value is not removed from the indexed database. 582 583<P> 584"), 585 args:["Key" : "An atom, compound term, or handle.", "Value" : "Any prolog term.", "DBRef" : "A variable."], 586 exceptions:[4 : "Key is not instantiated.", 5 : "Key is neither an atom nor a compound term.", 5 : "DBRef neither a variable nor a database reference."], 587 eg:" 588 Success: 589 [eclipse]: recorda(whiskey,jameson,Ref1), 590 recorda(whiskey,bushmills,Ref2). 591 Ref1 = 'DBREF'(16'50470dc8) 592 Ref2 = 'DBREF'(16'50470de0) 593 yes. 594Error: 595 recorda(Key, anything, Ref). (Error 4) 596 recorda(\"key\",anything, Ref). (Error 5) 597 recorda(key,anything, 99). (Error 5) 598 599 600 601", 602 see_also:[recordz / 3, recorded / 3, is_handle/1, erase / 1, referenced_record / 2]]). 603 604:- comment(recorded / 3, [ 605 summary:"Succeeds if the term Value has been recorded in the indexed database under 606the key Key and DBRef is its unique reference. 607 608", 609 amode:(recorded(+,-,-) is nondet), 610 amode:(recorded(+,+,-) is nondet), 611 desc:html(" Used to find all values associated with a key. Value is unified with 612 the first term that is associated with Key. DBRef is unified with the 613 unique database reference of this database entry. In the case of 614 compound terms, all keys of the same name and arity are treated as 615 equal. If Value is instantiated, the instantiated term is used as a 616 filter to reduce the number of terms returned by the recorded database 617 and unified with Value, thus improving the speed of retrieving the term. 618 619 620<P> 621 Backtracking will unify Value and DBRef with the value resp. the 622 database reference of successive values associated with Key in the order 623 in which they were recorded. 624 625<P> 626"), 627 args:["Key" : "An atom or a compound term.", "Value" : "Any Prolog term.", "DBRef" : "A variable."], 628 fail_if:"Fails if nothing is recorded under the key Key", 629 exceptions:[4 : "Key is not instantiated.", 5 : "Key is neither an atom nor a compound term.", 5 : "DBRef is neither a variable nor a database reference."], 630 eg:" 631 Success: 632 [eclipse]: recordz(beer, paulaner, _), 633 recordz(beer, lowenbrau, _), 634 recorded(beer, Value, Ref). 635 Value = paulaner 636 Ref = 'DBREF'(16'50470e90) More? (;) 637 Value = lowenbrau 638 Ref = 'DBREF'(16'50470ea8) More? (;) 639 no (more) solution. 640 Fail: 641 erase_all(beer),recorded(beer,guiness, Ref). 642 Error: 643 recorded(Beer,Value,Ref). (Error 4) 644 recorded(\"beer\",Value,Ref). (Error 5) 645 recorded(1,Value,Ref). (Error 5) 646 647 648", 649 see_also:[recorda / 3, recordz / 3, erase / 1, is_handle/1, referenced_record / 2]]). 650 651:- comment(recordz / 3, [ 652 summary:"Records the term Value at the end of key Key in the indexed database. 653 654", 655 amode:(recordz(+,?,-) is det), 656 desc:html(" Used to record any prolog term Value at the end of the indexed database 657 entry associated with the key Key. Unlike recordz/2, this predicate 658 delivers a so-called database reference in DBRef which is a unique handle 659 for the indexed database entry that is created. In the case of 660 compound terms, all keys of the same name and arity are treated as equal. 661 662<P> 663 If backtracking occurs through the call of recordz/3 the associated 664 Value is not removed from the indexed database. 665 666<P> 667"), 668 args:["Key" : "An atom, compound term, or handle.", "Value" : "Any prolog term.", "DBRef" : "A variable."], 669 exceptions:[4 : "Key is not instantiated.", 5 : "Key is neither an atom nor a compound term.", 5 : "DBRef neither a variable nor a database reference."], 670 eg:" 671 Success: 672 [eclipse]: recordz(whiskey,jameson,Ref1), 673 recordz(whiskey,bushmills,Ref2). 674 Ref1 = 'DBREF'(16'50470f10) 675 Ref2 = 'DBREF'(16'50470f28) 676 yes. 677Error: 678 recordz(Key, anything, Ref). (Error 4) 679 recordz(\"key\",anything, Ref). (Error 5) 680 recordz(key,anything, 99). (Error 5) 681 682 683 684", 685 see_also:[recorda / 3, recorded / 3, erase / 1, is_handle/1, referenced_record / 2]]). 686 687:- comment(referenced_record / 2, [ 688 summary:"Succeeds if Value is the Term recorded under the database reference DBRef.", 689 amode:(referenced_record(+,-) is det), 690 desc:html("\ 691 The database reference DBRef must refer to a term that has previously 692 been recorded in the indexed database. Database references can be 693 obtained from the predicates recorda/3, recordz/3 and recorded/3. 694 Value is unified with a copy of the recorded term. Note that this 695 is the case even if the original database entry has been removed since 696 the database reference was obtained (logical update semantics). 697"), 698 args:["DBRef" : "A database reference.", "Value" : "Any Prolog term."], 699 exceptions:[4 : "DBRef is not instantiated.", 5 : "DBRef is neither a variable nor a database reference."], 700 eg:" 701 [eclipse]: recordz(beer, paulaner, Ref), referenced_record(Ref, X). 702 Ref = 'DBREF'(16'50470d00) 703 X = paulaner 704 yes. 705 706 [eclipse]: recorded(beer, _, Ref), referenced_record(Ref, X). 707 Ref = 'DBREF'(16'50470d00) 708 X = paulaner More? (;) 709 yes. 710 711 [eclipse]: recorded(beer, _, Ref), erase(Ref), referenced_record(Ref, X). 712 Ref = 'DBREF'(16'50470d00) 713 X = paulaner More? (;) 714 yes. 715 716Error: 717 referenced_record(_, Value). (Error 4) 718 referenced_record(123, Value). (Error 5) 719 720 721 722", 723 see_also:[recorda / 3, recordz / 3, recorded / 3, erase / 1, referenced_record / 2]]). 724