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