| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /*************************************************************************
 | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | *	 YAP Prolog 							 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | *	Yap Prolog was developed at NCCUP - Universidade do Porto	 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997	 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | ************************************************************************** | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | * File:		dbase.c							 * | 
					
						
							|  |  |  | * Last rev:	8/2/88							 * | 
					
						
							|  |  |  | * mods:									 * | 
					
						
							|  |  |  | * comments:	YAP's internal data base				 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | *************************************************************************/ | 
					
						
							|  |  |  | #ifdef SCCS
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static char SccsId[] = "%W% %G%"; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /** @defgroup Internal_Database Internal Data Base
 | 
					
						
							| 
									
										
										
										
											2015-01-04 23:58:23 +00:00
										 |  |  | @ingroup builtins | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | @{ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | Some programs need global information for, e.g. counting or collecting | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | data obtained by backtracking. As a rule, to keep this information, the | 
					
						
							|  |  |  | internal data base should be used instead of asserting and retracting | 
					
						
							|  |  |  | clauses (as most novice programmers  do), . | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | In YAP (as in some other Prolog systems) the internal data base (i.d.b. | 
					
						
							|  |  |  | for short) is faster, needs less space and provides a better insulation of | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | program and data than using asserted/retracted clauses. | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | The i.d.b. is implemented as a set of terms, accessed by keys that | 
					
						
							|  |  |  | unlikely what happens in (non-Prolog) data bases are not part of the | 
					
						
							|  |  |  | term. Under each key a list of terms is kept. References are provided so that | 
					
						
							|  |  |  | terms can be identified: each term in the i.d.b. has a unique reference | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | (references are also available for clauses of dynamic predicates). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | There is a strong analogy between the i.d.b. and the way dynamic | 
					
						
							|  |  |  | predicates are stored. In fact, the main i.d.b. predicates might be | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | implemented using dynamic predicates: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ~~~~~ | 
					
						
							|  |  |  | recorda(X,T,R) :- asserta(idb(X,T),R). | 
					
						
							|  |  |  | recordz(X,T,R) :- assertz(idb(X,T),R). | 
					
						
							|  |  |  | recorded(X,T,R) :- clause(idb(X,T),R). | 
					
						
							|  |  |  | ~~~~~ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | We can take advantage of this, the other way around, as it is quite | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | easy to write a simple Prolog interpreter, using the i.d.b.: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ~~~~~ | 
					
						
							|  |  |  | asserta(G) :- recorda(interpreter,G,_). | 
					
						
							|  |  |  | assertz(G) :- recordz(interpreter,G,_). | 
					
						
							|  |  |  | retract(G) :- recorded(interpreter,G,R), !, erase(R). | 
					
						
							|  |  |  | call(V) :- var(V), !, fail. | 
					
						
							|  |  |  | call((H :- B)) :- !, recorded(interpreter,(H :- B),_), call(B). | 
					
						
							|  |  |  | call(G) :- recorded(interpreter,G,_). | 
					
						
							|  |  |  | ~~~~~ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | In YAP, much attention has been given to the implementation of the | 
					
						
							|  |  |  | i.d.b., especially to the problem of accelerating the access to terms kept in | 
					
						
							|  |  |  | a large list under the same key. Besides using the key, YAP uses an internal | 
					
						
							|  |  |  | lookup function, transparent to the user, to find only the terms that might | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | unify. For instance, in a data base containing the terms | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ~~~~~ | 
					
						
							|  |  |  | b | 
					
						
							|  |  |  | b(a) | 
					
						
							|  |  |  | c(d) | 
					
						
							|  |  |  | e(g) | 
					
						
							|  |  |  | b(X) | 
					
						
							|  |  |  | e(h) | 
					
						
							|  |  |  | ~~~~~ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | stored under the key k/1, when executing the query | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | ~~~~~ | 
					
						
							|  |  |  | :- recorded(k(_),c(_),R). | 
					
						
							|  |  |  | ~~~~~ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | `recorded` would proceed directly to the third term, spending almost the | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | time as if `a(X)` or `b(X)` was being searched. | 
					
						
							|  |  |  | The lookup function uses the functor of the term, and its first three | 
					
						
							|  |  |  | arguments (when they exist). So, `recorded(k(_),e(h),_)` would go | 
					
						
							|  |  |  | directly to the last term, while `recorded(k(_),e(_),_)` would find | 
					
						
							|  |  |  | first the fourth term, and then, after backtracking, the last one. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | This mechanism may be useful to implement a sort of hierarchy, where | 
					
						
							|  |  |  | the functors of the terms (and eventually the first arguments) work as | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | secondary keys. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | In the YAP's i.d.b. an optimized representation is used for | 
					
						
							|  |  |  | terms without free variables. This results in a faster retrieval of terms | 
					
						
							|  |  |  | and better space usage. Whenever possible, avoid variables in terms in terms | 
					
						
							|  |  |  | stored in the  i.d.b. | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #include "Yap.h"
 | 
					
						
							|  |  |  | #include "clause.h"
 | 
					
						
							|  |  |  | #include "yapio.h"
 | 
					
						
							| 
									
										
										
										
											2004-09-17 19:34:53 +00:00
										 |  |  | #include "attvar.h"
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | #include "heapgc.h"
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #if HAVE_STRING_H
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  | #if HAVE_STRING_H
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* There are two options to implement traditional immediate update semantics.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    - In the first option, we only remove an element of the chain when | 
					
						
							| 
									
										
										
										
											2010-10-26 10:05:49 +01:00
										 |  |  |    it is physically disposed of. This simplifies things, because | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |    pointers are always valid, but it complicates some stuff a bit: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |    o You may have go through long lines of deleted db entries before you | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |    actually reach the one you want. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    o Deleted clauses are also not removed of the chain. The solution | 
					
						
							|  |  |  |    was to place a fail in every clause, but you still have to | 
					
						
							|  |  |  |    backtrack through failed clauses. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    An alternative solution is to remove clauses from the chain, even | 
					
						
							|  |  |  |    if they are still phisically present. Unfortunately this creates | 
					
						
							|  |  |  |    problems because immediate update semantics means you have to | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |    backtrack clauses or see the db entries stored later. | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    There are several solutions. One of the simplest is to use an age | 
					
						
							|  |  |  |    counter. When you backtrack to a removed clause or to a deleted db | 
					
						
							|  |  |  |    entry you use the age to find newly entered clauses in the DB. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This still causes a problem when you backtrack to a deleted | 
					
						
							|  |  |  |    clause, because clauses are supposed to point to the next | 
					
						
							|  |  |  |    alternative, and having been removed from the chain you cannot | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |    point there directly. One solution is to have a predicate in C that | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |    recovers the place where to go to and then gets rid of the clause. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define DISCONNECT_OLD_ENTRIES 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef MACYAPBUG
 | 
					
						
							|  |  |  | #define Register
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #define Register register
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Flags for recorda or recordz				 */ | 
					
						
							|  |  |  | /* MkCode should be the same as CodeDBProperty */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #define MkFirst 1
 | 
					
						
							|  |  |  | #define MkCode CodeDBBit
 | 
					
						
							|  |  |  | #define MkLast 4
 | 
					
						
							|  |  |  | #define WithRef 8
 | 
					
						
							|  |  |  | #define MkIfNot 16
 | 
					
						
							|  |  |  | #define InQueue 32
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define FrstDBRef(V) ((V)->First)
 | 
					
						
							|  |  |  | #define NextDBRef(V) ((V)->Next)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define DBLength(V) (sizeof(DBStruct) + (Int)(V) + CellSize)
 | 
					
						
							|  |  |  | #define AllocDBSpace(V) ((DBRef)Yap_AllocCodeSpace(V))
 | 
					
						
							|  |  |  | #define FreeDBSpace(V) Yap_FreeCodeSpace(V)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if SIZEOF_INT_P == 4
 | 
					
						
							|  |  |  | #define ToSmall(V) ((link_entry)(Unsigned(V) >> 2))
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #define ToSmall(V) ((link_entry)(Unsigned(V) >> 3))
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SFUNC
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #define MaxSFs 256
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Term SName;    /* The culprit */ | 
					
						
							|  |  |  |   CELL *SFather; /* and his father's position */ | 
					
						
							|  |  |  | } SFKeep; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #define HashFieldMask ((CELL)0xffL)
 | 
					
						
							|  |  |  | #define DualHashFieldMask ((CELL)0xffffL)
 | 
					
						
							|  |  |  | #define TripleHashFieldMask ((CELL)0xffffffL)
 | 
					
						
							|  |  |  | #define FourHashFieldMask ((CELL)0xffffffffL)
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #define ONE_FIELD_SHIFT 8
 | 
					
						
							|  |  |  | #define TWO_FIELDS_SHIFT 16
 | 
					
						
							|  |  |  | #define THREE_FIELDS_SHIFT 24
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #define AtomHash(t) (Unsigned(t) >> 4)
 | 
					
						
							|  |  |  | #define FunctorHash(t) (Unsigned(t) >> 4)
 | 
					
						
							|  |  |  | #define NumberHash(t) (Unsigned(IntOfTerm(t)))
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-29 20:29:52 +00:00
										 |  |  | #define LARGE_IDB_LINK_TABLE 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* traditionally, YAP used a link table to recover IDB terms*/ | 
					
						
							|  |  |  | #if LARGE_IDB_LINK_TABLE
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | typedef BITS32 link_entry; | 
					
						
							| 
									
										
										
										
											2001-12-18 16:17:26 +00:00
										 |  |  | #define SIZEOF_LINK_ENTRY 4
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | typedef BITS16 link_entry; | 
					
						
							| 
									
										
										
										
											2001-12-18 16:17:26 +00:00
										 |  |  | #define SIZEOF_LINK_ENTRY 2
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* These global variables are necessary to build the data base
 | 
					
						
							|  |  |  |    structure */ | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  | typedef struct db_globs { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   link_entry *lr, *LinkAr; | 
					
						
							|  |  |  |   /* we cannot call Error directly from within recorded(). These flags are used
 | 
					
						
							|  |  |  |      to delay for a while | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  |   DBRef *tofref; /* place the refs also up	 */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef SFUNC
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   CELL *FathersPlace;   /* Where the father was going when the term
 | 
					
						
							|  |  |  |                          * was reached */ | 
					
						
							|  |  |  |   SFKeep *SFAr, *TopSF; /* Where are we putting our SFunctors */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   DBRef found_one; /* Place where we started recording */ | 
					
						
							|  |  |  |   UInt sz;         /* total size */ | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  | } dbglobs; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef SUPPORT_HASH_TABLES
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   CELL key; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   DBRef entry; | 
					
						
							|  |  |  | } hash_db_entry; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef table { | 
					
						
							|  |  |  |   Int NOfEntries; | 
					
						
							|  |  |  |   Int HashArg; | 
					
						
							|  |  |  |   hash_db_entry *table; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | } | 
					
						
							|  |  |  | hash_db_table; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static CELL *cpcells(CELL *, CELL *, Int); | 
					
						
							|  |  |  | static void linkblk(link_entry *, CELL *, CELL); | 
					
						
							|  |  |  | static Int cmpclls(CELL *, CELL *, Int); | 
					
						
							| 
									
										
										
										
											2013-04-25 17:15:04 -05:00
										 |  |  | static Prop FindDBProp(AtomEntry *, int, unsigned int, Term); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static CELL CalcKey(Term); | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static CELL *MkDBTerm(CELL *, CELL *, CELL *, CELL *, CELL *, CELL *, int *, | 
					
						
							|  |  |  |                       struct db_globs *); | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static CELL *MkDBTerm(CELL *, CELL *, CELL *, CELL *, CELL *, int *, | 
					
						
							|  |  |  |                       struct db_globs *); | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBRef CreateDBStruct(Term, DBProp, int, int *, UInt, struct db_globs *); | 
					
						
							|  |  |  | static DBRef record(int, Term, Term, Term CACHE_TYPE); | 
					
						
							|  |  |  | static DBRef check_if_cons(DBRef, Term); | 
					
						
							|  |  |  | static DBRef check_if_var(DBRef); | 
					
						
							|  |  |  | static DBRef check_if_wvars(DBRef, unsigned int, CELL *); | 
					
						
							|  |  |  | static int scheckcells(int, CELL *, CELL *, link_entry *, CELL); | 
					
						
							|  |  |  | static DBRef check_if_nvars(DBRef, unsigned int, CELL *, struct db_globs *); | 
					
						
							|  |  |  | static Int p_rcda(USES_REGS1); | 
					
						
							|  |  |  | static Int p_rcdap(USES_REGS1); | 
					
						
							|  |  |  | static Int p_rcdz(USES_REGS1); | 
					
						
							|  |  |  | static Int p_rcdzp(USES_REGS1); | 
					
						
							|  |  |  | static Int p_drcdap(USES_REGS1); | 
					
						
							|  |  |  | static Int p_drcdzp(USES_REGS1); | 
					
						
							|  |  |  | static Term GetDBTerm(DBTerm *, int src CACHE_TYPE); | 
					
						
							|  |  |  | static DBProp FetchDBPropFromKey(Term, int, int, char *); | 
					
						
							|  |  |  | static Int i_recorded(DBProp, Term CACHE_TYPE); | 
					
						
							|  |  |  | static Int c_recorded(int CACHE_TYPE); | 
					
						
							|  |  |  | static Int co_rded(USES_REGS1); | 
					
						
							|  |  |  | static Int in_rdedp(USES_REGS1); | 
					
						
							|  |  |  | static Int co_rdedp(USES_REGS1); | 
					
						
							|  |  |  | static Int p_first_instance(USES_REGS1); | 
					
						
							|  |  |  | static void ErasePendingRefs(DBTerm *CACHE_TYPE); | 
					
						
							|  |  |  | static void RemoveDBEntry(DBRef CACHE_TYPE); | 
					
						
							|  |  |  | static void EraseLogUpdCl(LogUpdClause *); | 
					
						
							|  |  |  | static void MyEraseClause(DynamicClause *CACHE_TYPE); | 
					
						
							|  |  |  | static void PrepareToEraseClause(DynamicClause *, DBRef); | 
					
						
							|  |  |  | static void EraseEntry(DBRef); | 
					
						
							|  |  |  | static Int p_erase(USES_REGS1); | 
					
						
							|  |  |  | static Int p_eraseall(USES_REGS1); | 
					
						
							|  |  |  | static Int p_erased(USES_REGS1); | 
					
						
							|  |  |  | static Int p_instance(USES_REGS1); | 
					
						
							|  |  |  | static int NotActiveDB(DBRef); | 
					
						
							|  |  |  | static DBEntry *NextDBProp(PropEntry *); | 
					
						
							|  |  |  | static Int init_current_key(USES_REGS1); | 
					
						
							|  |  |  | static Int cont_current_key(USES_REGS1); | 
					
						
							|  |  |  | static Int cont_current_key_integer(USES_REGS1); | 
					
						
							|  |  |  | static Int p_rcdstatp(USES_REGS1); | 
					
						
							|  |  |  | static Int p_somercdedp(USES_REGS1); | 
					
						
							|  |  |  | static yamop *find_next_clause(DBRef USES_REGS); | 
					
						
							|  |  |  | static Int p_jump_to_next_dynamic_clause(USES_REGS1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef SFUNC
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void SFVarIn(Term); | 
					
						
							|  |  |  | static void sf_include(SFKeep *); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_init_queue(USES_REGS1); | 
					
						
							|  |  |  | static Int p_enqueue(USES_REGS1); | 
					
						
							|  |  |  | static void keepdbrefs(DBTerm *CACHE_TYPE); | 
					
						
							|  |  |  | static Int p_dequeue(USES_REGS1); | 
					
						
							| 
									
										
										
										
											2013-04-25 17:15:04 -05:00
										 |  |  | static void ErDBE(DBRef CACHE_TYPE); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void ReleaseTermFromDB(DBTerm *CACHE_TYPE); | 
					
						
							| 
									
										
										
										
											2013-04-25 17:15:04 -05:00
										 |  |  | static PredEntry *new_lu_entry(Term); | 
					
						
							|  |  |  | static PredEntry *new_lu_int_key(Int); | 
					
						
							|  |  |  | static PredEntry *find_lu_entry(Term); | 
					
						
							|  |  |  | static DBProp find_int_key(Int); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #define db_check_trail(x)                                                      \
 | 
					
						
							|  |  |  |   {                                                                            \ | 
					
						
							|  |  |  |     if (Unsigned(dbg->tofref) == Unsigned(x)) {                                \ | 
					
						
							|  |  |  |       goto error_tr_overflow;                                                  \ | 
					
						
							|  |  |  |     }                                                                          \ | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static UInt new_trail_size(void) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   UInt sz = (LOCAL_TrailTop - (ADDR)TR) / 2; | 
					
						
							| 
									
										
										
										
											2010-05-11 12:25:49 +01:00
										 |  |  |   if (sz < K64) | 
					
						
							|  |  |  |     return K64; | 
					
						
							|  |  |  |   if (sz > M1) | 
					
						
							|  |  |  |     return M1; | 
					
						
							| 
									
										
										
										
											2005-10-28 17:38:50 +00:00
										 |  |  |   return sz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static int recover_from_record_error(int nargs) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   switch (LOCAL_Error_TYPE) { | 
					
						
							|  |  |  |   case RESOURCE_ERROR_STACK: | 
					
						
							|  |  |  |     if (!Yap_gcl(LOCAL_Error_Size, nargs, ENV, gc_P(P, CP))) { | 
					
						
							|  |  |  |       Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     goto recover_record; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   case RESOURCE_ERROR_TRAIL: | 
					
						
							| 
									
										
										
										
											2005-10-28 17:38:50 +00:00
										 |  |  |     if (!Yap_growtrail(new_trail_size(), FALSE)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       Yap_Error(RESOURCE_ERROR_TRAIL, TermNil, | 
					
						
							|  |  |  |                 "YAP could not grow trail in recorda/3"); | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     goto recover_record; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   case RESOURCE_ERROR_HEAP: | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if (!Yap_growheap(FALSE, LOCAL_Error_Size, NULL)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       Yap_Error(RESOURCE_ERROR_HEAP, LOCAL_Error_Term, LOCAL_ErrorMessage); | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     goto recover_record; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   case RESOURCE_ERROR_AUXILIARY_STACK: | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if (!Yap_ExpandPreAllocCodeSpace(LOCAL_Error_Size, NULL, TRUE)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       Yap_Error(RESOURCE_ERROR_AUXILIARY_STACK, LOCAL_Error_Term, | 
					
						
							|  |  |  |                 LOCAL_ErrorMessage); | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     goto recover_record; | 
					
						
							|  |  |  |   default: | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     Yap_Error(LOCAL_Error_TYPE, LOCAL_Error_Term, LOCAL_ErrorMessage); | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | recover_record: | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							|  |  |  |   LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef SUPPORT_HASH_TABLES
 | 
					
						
							|  |  |  | /* related property and hint on number of entries */ | 
					
						
							|  |  |  | static void create_hash_table(DBProp p, Int hint) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   int off = sizeof(CELL) * 4, out; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Int size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (hint < p->NOfEntries) | 
					
						
							|  |  |  |     hint = p->NOfEntries; | 
					
						
							|  |  |  |   while (off) { | 
					
						
							| 
									
										
										
										
											2010-05-11 00:18:12 +01:00
										 |  |  |     Int limit = ((CELL)1) << (off); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (inp >= limit) { | 
					
						
							|  |  |  |       out += off; | 
					
						
							|  |  |  |       inp >>= off; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     off >>= 1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-05-11 00:18:12 +01:00
										 |  |  |   if ((size = ((CELL)1) << out) < hint) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     hint <<= 1; | 
					
						
							|  |  |  |   /* clean up the table */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   pt = tbl = (hash_db_entry *)AllocDBSpace(hint * sizeof(hash_db_entry)); | 
					
						
							|  |  |  |   Yap_LUClauseSpace += hint * sizeof(hash_db_entry); | 
					
						
							|  |  |  |   for (i = 0; i < hint; i++) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     pt->key = NULL; | 
					
						
							|  |  |  |     pt++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* next insert the entries */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void insert_in_table() {} | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void remove_from_table() {} | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | inline static CELL *cpcells(CELL *to, CELL *from, Int n) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #if HAVE_MEMMOVE
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   memmove((void *)to, (void *)from, (size_t)(n * sizeof(CELL))); | 
					
						
							|  |  |  |   return (to + n); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  |   while (n-- >= 0) { | 
					
						
							|  |  |  |     *to++ = *from++; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return (to); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void linkblk(link_entry *r, CELL *c, CELL offs) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   CELL p; | 
					
						
							|  |  |  |   while ((p = (CELL)*r) != 0) { | 
					
						
							|  |  |  |     Term t = c[p]; | 
					
						
							|  |  |  |     r++; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     c[p] = AdjustIDBPtr(t, offs); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int cmpclls(CELL *a, CELL *b, Int n) { | 
					
						
							| 
									
										
										
										
											2002-01-30 00:26:43 +00:00
										 |  |  |   while (n-- > 0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (*a++ != *b++) | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2002-01-30 00:26:43 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  | #if !THREADS
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | int Yap_DBTrailOverflow() { | 
					
						
							|  |  |  |   return ((CELL *)LOCAL_s_dbg->lr > (CELL *)LOCAL_s_dbg->tofref - 2048); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* get DB entry for ap/arity; */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Prop FindDBPropHavingLock(AtomEntry *ae, int CodeDB, unsigned int arity, | 
					
						
							|  |  |  |                                  Term dbmod) { | 
					
						
							|  |  |  |   Prop p0; | 
					
						
							|  |  |  |   DBProp p; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-30 16:42:05 +00:00
										 |  |  |   p = RepDBProp(p0 = ae->PropsOfAE); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   while (p0 && | 
					
						
							|  |  |  |          (((p->KindOfPE & ~0x1) != (CodeDB | DBProperty)) || | 
					
						
							|  |  |  |           (p->ArityOfDB != arity) || | 
					
						
							|  |  |  |           ((CodeDB & MkCode) && p->ModuleOfDB && p->ModuleOfDB != dbmod))) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     p = RepDBProp(p0 = p->NextOfPE); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return p0; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* get DB entry for ap/arity; */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Prop FindDBProp(AtomEntry *ae, int CodeDB, unsigned int arity, | 
					
						
							|  |  |  |                        Term dbmod) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Prop out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   READ_LOCK(ae->ARWLock); | 
					
						
							| 
									
										
										
										
											2001-11-15 00:01:43 +00:00
										 |  |  |   out = FindDBPropHavingLock(ae, CodeDB, arity, dbmod); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   READ_UNLOCK(ae->ARWLock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return (out); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* These two functions allow us a fast lookup method in the data base */ | 
					
						
							|  |  |  | /* PutMasks builds the mask and hash for a single argument	 */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | inline static CELL CalcKey(Term tw) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   /* The first argument is known to be instantiated */ | 
					
						
							|  |  |  |   if (IsApplTerm(tw)) { | 
					
						
							|  |  |  |     Functor f = FunctorOfTerm(tw); | 
					
						
							|  |  |  |     if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  |       if (f == FunctorDBRef) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         return (FunctorHash(tw)); /* Ref */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } /* if (f == FunctorLongInt || f == FunctorDouble) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       return (NumberHash(RepAppl(tw)[1])); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return (FunctorHash(f)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else if (IsAtomOrIntTerm(tw)) { | 
					
						
							|  |  |  |     if (IsAtomTerm(tw)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       return (AtomHash(tw)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return (NumberHash(tw)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return (FunctorHash(FunctorList)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* EvalMasks builds the mask and hash for up to three arguments of a term */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static CELL EvalMasks(register Term tm, CELL *keyp) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  |   if (IsVarTerm(tm)) { | 
					
						
							|  |  |  |     *keyp = 0L; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return (0L); | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  |   } else if (IsApplTerm(tm)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Functor fun = FunctorOfTerm(tm); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (IsExtensionFunctor(fun)) { | 
					
						
							|  |  |  |       if (fun == FunctorDBRef) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         *keyp = FunctorHash(tm); /* Ref */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } else /* if (f == FunctorLongInt || f == FunctorDouble) */ { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         *keyp = NumberHash(RepAppl(tm)[1]); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       return (FourHashFieldMask); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       unsigned int arity; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       arity = ArityOfFunctor(fun); | 
					
						
							|  |  |  | #ifdef SFUNC
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (arity == SFArity) { /* do not even try to calculate masks */ | 
					
						
							|  |  |  |         *keyp = key; | 
					
						
							|  |  |  |         return (FourHashFieldMask); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |       switch (arity) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       case 1: { | 
					
						
							|  |  |  |         Term tw = ArgOfTerm(1, tm); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (IsNonVarTerm(tw)) { | 
					
						
							|  |  |  |           *keyp = (FunctorHash(fun) & DualHashFieldMask) | | 
					
						
							|  |  |  |                   (CalcKey(tw) << TWO_FIELDS_SHIFT); | 
					
						
							|  |  |  |           return (FourHashFieldMask); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           *keyp = (FunctorHash(fun) & DualHashFieldMask); | 
					
						
							|  |  |  |           return (DualHashFieldMask); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       case 2: { | 
					
						
							|  |  |  |         Term tw1, tw2; | 
					
						
							|  |  |  |         CELL key, mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         key = FunctorHash(fun) & DualHashFieldMask; | 
					
						
							|  |  |  |         mask = DualHashFieldMask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         tw1 = ArgOfTerm(1, tm); | 
					
						
							|  |  |  |         if (IsNonVarTerm(tw1)) { | 
					
						
							|  |  |  |           key |= ((CalcKey(tw1) & HashFieldMask) << TWO_FIELDS_SHIFT); | 
					
						
							|  |  |  |           mask |= (HashFieldMask << TWO_FIELDS_SHIFT); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         tw2 = ArgOfTerm(2, tm); | 
					
						
							|  |  |  |         if (IsNonVarTerm(tw2)) { | 
					
						
							|  |  |  |           *keyp = key | (CalcKey(tw2) << THREE_FIELDS_SHIFT); | 
					
						
							|  |  |  |           return (mask | (HashFieldMask << THREE_FIELDS_SHIFT)); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           *keyp = key; | 
					
						
							|  |  |  |           return (mask); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       default: { | 
					
						
							|  |  |  |         Term tw1, tw2, tw3; | 
					
						
							|  |  |  |         CELL key, mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         key = FunctorHash(fun) & HashFieldMask; | 
					
						
							|  |  |  |         mask = HashFieldMask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         tw1 = ArgOfTerm(1, tm); | 
					
						
							|  |  |  |         if (IsNonVarTerm(tw1)) { | 
					
						
							|  |  |  |           key |= (CalcKey(tw1) & HashFieldMask) << ONE_FIELD_SHIFT; | 
					
						
							|  |  |  |           mask |= HashFieldMask << ONE_FIELD_SHIFT; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         tw2 = ArgOfTerm(2, tm); | 
					
						
							|  |  |  |         if (IsNonVarTerm(tw2)) { | 
					
						
							|  |  |  |           key |= (CalcKey(tw2) & HashFieldMask) << TWO_FIELDS_SHIFT; | 
					
						
							|  |  |  |           mask |= HashFieldMask << TWO_FIELDS_SHIFT; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         tw3 = ArgOfTerm(3, tm); | 
					
						
							|  |  |  |         if (IsNonVarTerm(tw3)) { | 
					
						
							|  |  |  |           *keyp = key | (CalcKey(tw3) << THREE_FIELDS_SHIFT); | 
					
						
							|  |  |  |           return (mask | (HashFieldMask << THREE_FIELDS_SHIFT)); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           *keyp = key; | 
					
						
							|  |  |  |           return (mask); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     CELL key = (FunctorHash(FunctorList) & DualHashFieldMask); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     CELL mask = DualHashFieldMask; | 
					
						
							|  |  |  |     Term th = HeadOfTerm(tm), tt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (IsNonVarTerm(th)) { | 
					
						
							|  |  |  |       mask |= (HashFieldMask << TWO_FIELDS_SHIFT); | 
					
						
							|  |  |  |       key |= (CalcKey(th) << TWO_FIELDS_SHIFT); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     tt = TailOfTerm(tm); | 
					
						
							|  |  |  |     if (IsNonVarTerm(tt)) { | 
					
						
							|  |  |  |       *keyp = key | (CalcKey(tt) << THREE_FIELDS_SHIFT); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       return (mask | (HashFieldMask << THREE_FIELDS_SHIFT)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     *keyp = key; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return (mask); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | CELL Yap_EvalMasks(register Term tm, CELL *keyp) { return EvalMasks(tm, keyp); } | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* Called to inform that a new pointer to a data base entry has been added */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #define MarkThisRef(Ref) ((Ref)->NOfRefsTo++)
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* From a term, builds its representation in the data base */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* otherwise, we just need to restore variables*/ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | typedef struct { CELL *addr; } visitel; | 
					
						
							|  |  |  | #define DB_UNWIND_CUNIF()                                                      \
 | 
					
						
							|  |  |  |   while (visited < (visitel *)AuxSp) {                                         \ | 
					
						
							|  |  |  |     RESET_VARIABLE(visited->addr);                                             \ | 
					
						
							|  |  |  |     visited++;                                                                 \ | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* no checking for overflow while building DB terms yet */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #define CheckDBOverflow(X)                                                     \
 | 
					
						
							|  |  |  |   if (CodeMax + X >= (CELL *)visited - 1024) {                                 \ | 
					
						
							|  |  |  |     goto error;                                                                \ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* no checking for overflow while building DB terms yet */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #define CheckVisitOverflow()                                                   \
 | 
					
						
							|  |  |  |   if ((CELL *)to_visit + 1024 >= ASP) {                                        \ | 
					
						
							|  |  |  |     goto error2;                                                               \ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static CELL *copy_long_int(CELL *st, CELL *pt) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   /* first thing, store a link to the list before we move on */ | 
					
						
							|  |  |  |   st[0] = (CELL)FunctorLongInt; | 
					
						
							|  |  |  |   st[1] = pt[1]; | 
					
						
							| 
									
										
										
										
											2006-08-22 16:12:46 +00:00
										 |  |  |   st[2] = EndSpecials; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   /* now reserve space */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return st + 3; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static CELL *copy_double(CELL *st, CELL *pt) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   /* first thing, store a link to the list before we move on */ | 
					
						
							|  |  |  |   st[0] = (CELL)FunctorDouble; | 
					
						
							|  |  |  |   st[1] = pt[1]; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   st[2] = pt[2]; | 
					
						
							| 
									
										
										
										
											2006-08-22 16:12:46 +00:00
										 |  |  |   st[3] = EndSpecials; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2006-08-22 16:12:46 +00:00
										 |  |  |   st[2] = EndSpecials; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   /* now reserve space */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return st + (2 + SIZEOF_DOUBLE / SIZEOF_INT_P); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static CELL *copy_string(CELL *st, CELL *pt) { | 
					
						
							|  |  |  |   UInt sz = pt[1] + 3; | 
					
						
							| 
									
										
										
										
											2013-12-02 14:49:41 +00:00
										 |  |  |   /* first thing, store a link to the list before we move on */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   memcpy(st, pt, sizeof(CELL) * sz); | 
					
						
							| 
									
										
										
										
											2013-12-02 14:49:41 +00:00
										 |  |  |   /* now reserve space */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return st + sz; | 
					
						
							| 
									
										
										
										
											2013-12-02 14:49:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static CELL *copy_big_int(CELL *st, CELL *pt) { | 
					
						
							|  |  |  |   Int sz = | 
					
						
							|  |  |  |       sizeof(MP_INT) + (((MP_INT *)(pt + 2))->_mp_alloc * sizeof(mp_limb_t)); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* first functor */ | 
					
						
							|  |  |  |   st[0] = (CELL)FunctorBigInt; | 
					
						
							| 
									
										
										
										
											2008-11-28 15:54:46 +00:00
										 |  |  |   st[1] = pt[1]; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   /* then the actual number */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   memcpy((void *)(st + 2), (void *)(pt + 2), sz); | 
					
						
							|  |  |  |   st = st + 2 + sz / CellSize; | 
					
						
							|  |  |  |   /* then the tail for gc */ | 
					
						
							| 
									
										
										
										
											2006-08-22 16:12:46 +00:00
										 |  |  |   st[0] = EndSpecials; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return st + 1; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | #endif /* BIG_INT */
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-10-31 12:09:49 +00:00
										 |  |  | #define DB_MARKED(d0) ((CELL *)(d0) < CodeMax && (CELL *)(d0) >= tbase)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* This routine creates a complex term in the heap. */ | 
					
						
							|  |  |  | static CELL *MkDBTerm(register CELL *pt0, register CELL *pt0_end, | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |                       register CELL *StoPoint, CELL *CodeMax, CELL *tbase, | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |                       CELL *attachmentsp, | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |                       int *vars_foundp, struct db_globs *dbg) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | #if THREADS
 | 
					
						
							|  |  |  | #undef Yap_REGS
 | 
					
						
							|  |  |  |   register REGSTORE *regp = Yap_regp; | 
					
						
							|  |  |  | #define Yap_REGS (*regp)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   register visitel *visited = (visitel *)AuxSp; | 
					
						
							|  |  |  |   /* store this in H */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   register CELL **to_visit = (CELL **)HR; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   CELL **to_visit_base = to_visit; | 
					
						
							|  |  |  |   /* where we are going to add a new pair */ | 
					
						
							|  |  |  |   int vars_found = 0; | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							|  |  |  |   Term ConstraintsTerm = TermNil; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   CELL *origH = HR; | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-04-22 20:07:07 +00:00
										 |  |  |   CELL *CodeMaxBase = CodeMax; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | loop: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   while (pt0 <= pt0_end) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     CELL *ptd0 = pt0; | 
					
						
							|  |  |  |     CELL d0 = *ptd0; | 
					
						
							|  |  |  |   restart: | 
					
						
							|  |  |  |     if (IsVarTerm(d0)) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       goto deref_var; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (IsApplTerm(d0)) { | 
					
						
							|  |  |  |       register Functor f; | 
					
						
							|  |  |  |       register CELL *ap2; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* we will need to link afterwards */ | 
					
						
							|  |  |  |       ap2 = RepAppl(d0); | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							| 
									
										
										
										
											2012-01-11 13:27:25 +00:00
										 |  |  |       if (ap2 >= tbase && ap2 <= StoPoint) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         db_check_trail(dbg->lr + 1); | 
					
						
							|  |  |  |         *dbg->lr++ = ToSmall((CELL)(StoPoint) - (CELL)(tbase)); | 
					
						
							|  |  |  |         *StoPoint++ = d0; | 
					
						
							|  |  |  |         ++pt0; | 
					
						
							|  |  |  |         continue; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       db_check_trail(dbg->lr + 1); | 
					
						
							|  |  |  |       *dbg->lr++ = ToSmall((CELL)(StoPoint) - (CELL)(tbase)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       f = (Functor)(*ap2); | 
					
						
							|  |  |  |       if (IsExtensionFunctor(f)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         switch ((CELL)f) { | 
					
						
							|  |  |  |         case (CELL) FunctorDBRef: { | 
					
						
							|  |  |  |           DBRef dbentry; | 
					
						
							|  |  |  |           /* store now the correct entry */ | 
					
						
							|  |  |  |           dbentry = DBRefOfTerm(d0); | 
					
						
							|  |  |  |           *StoPoint++ = d0; | 
					
						
							|  |  |  |           dbg->lr--; | 
					
						
							|  |  |  |           if (dbentry->Flags & LogUpdMask) { | 
					
						
							|  |  |  |             LogUpdClause *cl = (LogUpdClause *)dbentry; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cl->ClRefCount++; | 
					
						
							|  |  |  |           } else { | 
					
						
							|  |  |  |             dbentry->NOfRefsTo++; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           *--dbg->tofref = dbentry; | 
					
						
							|  |  |  |           db_check_trail(dbg->lr); | 
					
						
							|  |  |  |           /* just continue the loop */ | 
					
						
							|  |  |  |           ++pt0; | 
					
						
							|  |  |  |           continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         case (CELL) FunctorLongInt: | 
					
						
							|  |  |  |           CheckDBOverflow(3); | 
					
						
							|  |  |  |           *StoPoint++ = AbsAppl(CodeMax); | 
					
						
							|  |  |  |           CodeMax = copy_long_int(CodeMax, ap2); | 
					
						
							|  |  |  |           ++pt0; | 
					
						
							|  |  |  |           continue; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         case (CELL) FunctorBigInt: | 
					
						
							|  |  |  |           CheckDBOverflow(3 + Yap_SizeOfBigInt(d0)); | 
					
						
							|  |  |  |           /* first thing, store a link to the list before we move on */ | 
					
						
							|  |  |  |           *StoPoint++ = AbsAppl(CodeMax); | 
					
						
							|  |  |  |           CodeMax = copy_big_int(CodeMax, ap2); | 
					
						
							|  |  |  |           ++pt0; | 
					
						
							|  |  |  |           continue; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         case (CELL) FunctorString: { | 
					
						
							|  |  |  |           CELL *st = CodeMax; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           CheckDBOverflow(3 + ap2[1]); | 
					
						
							|  |  |  |           /* first thing, store a link to the list before we move on */ | 
					
						
							|  |  |  |           *StoPoint++ = AbsAppl(st); | 
					
						
							|  |  |  |           CodeMax = copy_string(CodeMax, ap2); | 
					
						
							|  |  |  |           ++pt0; | 
					
						
							|  |  |  |           continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         case (CELL) FunctorDouble: { | 
					
						
							|  |  |  |           CELL *st = CodeMax; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           CheckDBOverflow(4); | 
					
						
							|  |  |  |           /* first thing, store a link to the list before we move on */ | 
					
						
							|  |  |  |           *StoPoint++ = AbsAppl(st); | 
					
						
							|  |  |  |           CodeMax = copy_double(CodeMax, ap2); | 
					
						
							|  |  |  |           ++pt0; | 
					
						
							|  |  |  |           continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       /* first thing, store a link to the list before we move on */ | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       *StoPoint++ = AbsAppl(CodeMax); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* next, postpone analysis to the rest of the current list */ | 
					
						
							| 
									
										
										
										
											2013-07-22 10:42:50 -05:00
										 |  |  |       CheckVisitOverflow(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       to_visit[0] = pt0 + 1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       to_visit[1] = pt0_end; | 
					
						
							|  |  |  |       to_visit[2] = StoPoint; | 
					
						
							|  |  |  |       to_visit[3] = (CELL *)*pt0; | 
					
						
							|  |  |  |       to_visit += 4; | 
					
						
							|  |  |  |       *pt0 = StoPoint[-1]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |       if (pt0 < pt0_end) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         to_visit[0] = pt0 + 1; | 
					
						
							|  |  |  |         to_visit[1] = pt0_end; | 
					
						
							|  |  |  |         to_visit[2] = StoPoint; | 
					
						
							|  |  |  |         to_visit += 3; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |       d0 = ArityOfFunctor(f); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       pt0 = ap2 + 1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       pt0_end = ap2 + d0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       CheckDBOverflow(d0 + 1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* prepare for our new compound term */ | 
					
						
							|  |  |  |       /* first the functor */ | 
					
						
							|  |  |  |       *CodeMax++ = (CELL)f; | 
					
						
							|  |  |  |       /* we'll be working here */ | 
					
						
							|  |  |  |       StoPoint = CodeMax; | 
					
						
							|  |  |  |       /* now reserve space */ | 
					
						
							|  |  |  |       CodeMax += d0; | 
					
						
							|  |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     } else if (IsPairTerm(d0)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* we will need to link afterwards */ | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       CELL *ap2 = RepPair(d0); | 
					
						
							| 
									
										
										
										
											2012-01-11 13:27:25 +00:00
										 |  |  |       if (ap2 >= tbase && ap2 <= StoPoint) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         db_check_trail(dbg->lr + 1); | 
					
						
							|  |  |  |         *dbg->lr++ = ToSmall((CELL)(StoPoint) - (CELL)(tbase)); | 
					
						
							|  |  |  |         *StoPoint++ = d0; | 
					
						
							|  |  |  |         ++pt0; | 
					
						
							|  |  |  |         continue; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (IsAtomOrIntTerm(Deref(ap2[0])) && IsPairTerm(Deref(ap2[1]))) { | 
					
						
							|  |  |  |         /* shortcut for [1,2,3,4,5] */ | 
					
						
							|  |  |  |         Term tt = Deref(ap2[1]); | 
					
						
							|  |  |  |         Term th = Deref(ap2[0]); | 
					
						
							|  |  |  |         Int direction = RepPair(tt) - ap2; | 
					
						
							|  |  |  |         CELL *OldStoPoint; | 
					
						
							|  |  |  |         CELL *lp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (direction < 0) | 
					
						
							|  |  |  |           direction = -1; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           direction = 1; | 
					
						
							|  |  |  |         db_check_trail(dbg->lr + 1); | 
					
						
							|  |  |  |         *dbg->lr++ = ToSmall((CELL)(StoPoint) - (CELL)(tbase)); | 
					
						
							|  |  |  |         *StoPoint++ = AbsPair(CodeMax); | 
					
						
							|  |  |  |         OldStoPoint = StoPoint; | 
					
						
							|  |  |  |         do { | 
					
						
							|  |  |  |           lp = RepPair(tt); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (lp >= tbase && lp <= StoPoint) { | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           CheckDBOverflow(2); | 
					
						
							|  |  |  |           CodeMax[0] = th; | 
					
						
							|  |  |  |           db_check_trail(dbg->lr + 1); | 
					
						
							|  |  |  |           *dbg->lr++ = ToSmall((CELL)(CodeMax + 1) - (CELL)(tbase)); | 
					
						
							|  |  |  |           CodeMax[1] = AbsPair(CodeMax + 2); | 
					
						
							|  |  |  |           CodeMax += 2; | 
					
						
							|  |  |  |           th = Deref(lp[0]); | 
					
						
							|  |  |  |           tt = Deref(lp[1]); | 
					
						
							|  |  |  |         } while (IsAtomOrIntTerm(th) && IsPairTerm(tt) && | 
					
						
							|  |  |  |                  /* have same direction to avoid infinite terms X = [a|X] */ | 
					
						
							|  |  |  |                  (RepPair(tt) - lp) * direction > 0); | 
					
						
							|  |  |  |         if (lp >= tbase && lp <= StoPoint) { | 
					
						
							|  |  |  |           CodeMax[-1] = tt; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (IsAtomOrIntTerm(th) && IsAtomOrIntTerm(tt)) { | 
					
						
							|  |  |  |           CheckDBOverflow(2); | 
					
						
							|  |  |  |           CodeMax[0] = th; | 
					
						
							|  |  |  |           CodeMax[1] = tt; | 
					
						
							|  |  |  |           CodeMax += 2; | 
					
						
							|  |  |  |           ++pt0; | 
					
						
							|  |  |  |           continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         d0 = AbsPair(lp); | 
					
						
							|  |  |  |         StoPoint = OldStoPoint; | 
					
						
							| 
									
										
										
										
											2006-09-20 20:03:51 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         db_check_trail(dbg->lr + 1); | 
					
						
							|  |  |  |         *dbg->lr++ = ToSmall((CELL)(StoPoint) - (CELL)(tbase)); | 
					
						
							|  |  |  |         *StoPoint++ = AbsPair(CodeMax); | 
					
						
							| 
									
										
										
										
											2006-09-20 20:03:51 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | /* next, postpone analysis to the rest of the current list */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       to_visit[0] = pt0 + 1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       to_visit[1] = pt0_end; | 
					
						
							|  |  |  |       to_visit[2] = StoPoint; | 
					
						
							|  |  |  |       to_visit[3] = (CELL *)*pt0; | 
					
						
							|  |  |  |       to_visit += 4; | 
					
						
							|  |  |  |       *pt0 = StoPoint[-1]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |       if (pt0 < pt0_end) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         to_visit[0] = pt0 + 1; | 
					
						
							|  |  |  |         to_visit[1] = pt0_end; | 
					
						
							|  |  |  |         to_visit[2] = StoPoint; | 
					
						
							|  |  |  |         to_visit += 3; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |       CheckVisitOverflow(); | 
					
						
							|  |  |  |       /* new list */ | 
					
						
							|  |  |  |       /* we are working at CodeMax */ | 
					
						
							|  |  |  |       StoPoint = CodeMax; | 
					
						
							|  |  |  |       /* set ptr to new term being analysed */ | 
					
						
							|  |  |  |       pt0 = RepPair(d0); | 
					
						
							|  |  |  |       pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  |       /* reserve space for our new list */ | 
					
						
							|  |  |  |       CodeMax += 2; | 
					
						
							| 
									
										
										
										
											2004-08-11 16:14:55 +00:00
										 |  |  |       CheckDBOverflow(2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       continue; | 
					
						
							|  |  |  |     } else if (IsAtomOrIntTerm(d0)) { | 
					
						
							|  |  |  |       *StoPoint++ = d0; | 
					
						
							|  |  |  |       ++pt0; | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* the code to dereference a  variable */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   deref_var: | 
					
						
							| 
									
										
										
										
											2003-10-31 12:09:49 +00:00
										 |  |  |     if (!DB_MARKED(d0)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if ( | 
					
						
							| 
									
										
										
										
											2011-03-30 15:32:59 +01:00
										 |  |  | #if YAPOR_SBA
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |           d0 != 0 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |           d0 != (CELL)ptd0 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |           ) { | 
					
						
							|  |  |  |         ptd0 = (Term *)d0; | 
					
						
							|  |  |  |         d0 = *ptd0; | 
					
						
							|  |  |  |         goto restart; /* continue dereferencing */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  |       /* else just drop to found_var */ | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     /* else just drop to found_var */ | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       CELL displacement = (CELL)(StoPoint) - (CELL)(tbase); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       pt0++; | 
					
						
							|  |  |  |       /* first time we found this variable! */ | 
					
						
							| 
									
										
										
										
											2003-10-31 12:09:49 +00:00
										 |  |  |       if (!DB_MARKED(d0)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /* store previous value */ | 
					
						
							|  |  |  |         visited--; | 
					
						
							|  |  |  |         visited->addr = ptd0; | 
					
						
							|  |  |  |         CheckDBOverflow(1); | 
					
						
							|  |  |  |         /* variables need to be offset at read time */ | 
					
						
							|  |  |  |         *ptd0 = (CELL)StoPoint; | 
					
						
							| 
									
										
										
										
											2011-03-30 15:32:59 +01:00
										 |  |  | #if YAPOR_SBA
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         /* the copy we keep will be an empty variable   */ | 
					
						
							|  |  |  |         *StoPoint++ = 0; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         /* the copy we keep will be the current displacement   */ | 
					
						
							|  |  |  |         *StoPoint = (CELL)StoPoint; | 
					
						
							|  |  |  |         StoPoint++; | 
					
						
							|  |  |  |         db_check_trail(dbg->lr + 1); | 
					
						
							|  |  |  |         *dbg->lr++ = ToSmall(displacement); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         /* indicate we found variables */ | 
					
						
							|  |  |  |         vars_found++; | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         if (SafeIsAttachedTerm((CELL)ptd0)) { | 
					
						
							|  |  |  |           Term t[4]; | 
					
						
							|  |  |  |           int sz = to_visit - to_visit_base; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           HR = (CELL *)to_visit; | 
					
						
							|  |  |  |           /* store the constraint away for: we need a back pointer to
 | 
					
						
							|  |  |  |              the variable, the constraint in some cannonical form, what type | 
					
						
							|  |  |  |              of constraint, and a list pointer */ | 
					
						
							|  |  |  |           t[0] = (CELL)ptd0; | 
					
						
							|  |  |  |           t[1] = GLOBAL_attas[ExtFromCell(ptd0)].to_term_op(ptd0); | 
					
						
							|  |  |  |           t[2] = MkIntegerTerm(ExtFromCell(ptd0)); | 
					
						
							|  |  |  |           t[3] = ConstraintsTerm; | 
					
						
							|  |  |  |           ConstraintsTerm = Yap_MkApplTerm(FunctorClist, 4, t); | 
					
						
							|  |  |  |           if (HR + sz >= ASP) { | 
					
						
							|  |  |  |             goto error2; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           memcpy((void *)HR, (void *)(to_visit_base), sz * sizeof(CELL *)); | 
					
						
							|  |  |  |           to_visit_base = (CELL **)HR; | 
					
						
							|  |  |  |           to_visit = to_visit_base + sz; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         continue; | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         /* references need to be offset at read time */ | 
					
						
							|  |  |  |         db_check_trail(dbg->lr + 1); | 
					
						
							|  |  |  |         *dbg->lr++ = ToSmall(displacement); | 
					
						
							|  |  |  |         /* store the offset */ | 
					
						
							|  |  |  |         *StoPoint = d0; | 
					
						
							|  |  |  |         StoPoint++; | 
					
						
							|  |  |  |         continue; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  |   if (to_visit > to_visit_base) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     to_visit -= 4; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     StoPoint = to_visit[2]; | 
					
						
							|  |  |  |     pt0[-1] = (CELL)to_visit[3]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							| 
									
										
										
										
											2004-08-11 16:14:55 +00:00
										 |  |  |     CheckDBOverflow(1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     StoPoint = to_visit[2]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							|  |  |  |   /* we still may have constraints to do */ | 
					
						
							| 
									
										
										
										
											2004-05-13 20:54:58 +00:00
										 |  |  |   if (ConstraintsTerm != TermNil && | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       !IN_BETWEEN(tbase, RepAppl(ConstraintsTerm), CodeMax)) { | 
					
						
							|  |  |  |     *attachmentsp = (CELL)(CodeMax + 1); | 
					
						
							|  |  |  |     pt0 = RepAppl(ConstraintsTerm) + 1; | 
					
						
							|  |  |  |     pt0_end = RepAppl(ConstraintsTerm) + 4; | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  |     StoPoint = CodeMax; | 
					
						
							| 
									
										
										
										
											2004-05-13 20:54:58 +00:00
										 |  |  |     *StoPoint++ = RepAppl(ConstraintsTerm)[0]; | 
					
						
							|  |  |  |     ConstraintsTerm = AbsAppl(CodeMax); | 
					
						
							| 
									
										
										
										
											2004-08-11 16:14:55 +00:00
										 |  |  |     CheckDBOverflow(1); | 
					
						
							| 
									
										
										
										
											2004-05-13 20:54:58 +00:00
										 |  |  |     CodeMax += 5; | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   /* we're done */ | 
					
						
							|  |  |  |   *vars_foundp = vars_found; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   DB_UNWIND_CUNIF(); | 
					
						
							| 
									
										
										
										
											2001-12-27 22:38:41 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = origH; | 
					
						
							| 
									
										
										
										
											2001-12-27 22:38:41 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-10-28 17:38:50 +00:00
										 |  |  |   return CodeMax; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | error: | 
					
						
							|  |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK; | 
					
						
							|  |  |  |   LOCAL_Error_Size = 1024 + ((char *)AuxSp - (char *)CodeMaxBase); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   *vars_foundp = vars_found; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  |   while (to_visit > to_visit_base) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     to_visit -= 4; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     StoPoint = to_visit[2]; | 
					
						
							|  |  |  |     pt0[-1] = (CELL)to_visit[3]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   DB_UNWIND_CUNIF(); | 
					
						
							| 
									
										
										
										
											2001-12-27 22:38:41 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = origH; | 
					
						
							| 
									
										
										
										
											2001-12-27 22:38:41 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-10-28 17:38:50 +00:00
										 |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | error2: | 
					
						
							|  |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_STACK; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   *vars_foundp = vars_found; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  |   while (to_visit > to_visit_base) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     to_visit -= 4; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     StoPoint = to_visit[2]; | 
					
						
							|  |  |  |     pt0[-1] = (CELL)to_visit[3]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   DB_UNWIND_CUNIF(); | 
					
						
							| 
									
										
										
										
											2001-12-27 22:38:41 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = origH; | 
					
						
							| 
									
										
										
										
											2001-12-27 22:38:41 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-10-28 17:38:50 +00:00
										 |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | error_tr_overflow: | 
					
						
							|  |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_TRAIL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   *vars_foundp = vars_found; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  |   while (to_visit > to_visit_base) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     to_visit -= 4; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     StoPoint = to_visit[2]; | 
					
						
							|  |  |  |     pt0[-1] = (CELL)to_visit[3]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   DB_UNWIND_CUNIF(); | 
					
						
							| 
									
										
										
										
											2001-12-27 22:38:41 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = origH; | 
					
						
							| 
									
										
										
										
											2001-12-27 22:38:41 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-10-28 17:38:50 +00:00
										 |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | #if THREADS
 | 
					
						
							|  |  |  | #undef Yap_REGS
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #define Yap_REGS (*Yap_regp)
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | #endif /* THREADS */
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SFUNC
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * The sparse terms existing in the structure are to be included now. This | 
					
						
							|  |  |  |  * means simple copy for constant terms but, some care about variables If | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |  * they have appeared before, we will know by their position number | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void sf_include(SFKeep *sfp, struct db_globs *dbg) SFKeep *sfp; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Term Tm = sfp->SName; | 
					
						
							|  |  |  |   CELL *tp = ArgsOfSFTerm(Tm); | 
					
						
							|  |  |  |   Register Term *StoPoint = ntp; | 
					
						
							|  |  |  |   CELL *displacement = CodeAbs; | 
					
						
							|  |  |  |   CELL arg_no; | 
					
						
							|  |  |  |   Term tvalue; | 
					
						
							|  |  |  |   int j = 3; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (sfp->SFather != NIL) | 
					
						
							|  |  |  |     *(sfp->SFather) = AbsAppl(displacement); | 
					
						
							|  |  |  |   *StoPoint++ = FunctorOfTerm(Tm); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   db_check_trail(dbg->lr + 1); | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |   *dbg->lr++ = ToSmall(displacement + 1); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   *StoPoint++ = (Term)(displacement + 1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   while (*tp) { | 
					
						
							|  |  |  |     arg_no = *tp++; | 
					
						
							|  |  |  |     tvalue = Derefa(tp++); | 
					
						
							|  |  |  |     if (IsVarTerm(tvalue)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (((VarKeep *)tvalue)->NOfVars != 0) { | 
					
						
							|  |  |  |         *StoPoint++ = arg_no; | 
					
						
							|  |  |  |         db_check_trail(dbg->lr + 1); | 
					
						
							|  |  |  |         *dbg->lr++ = ToSmall(displacement + j); | 
					
						
							|  |  |  |         if (((VarKeep *)tvalue)->New == 0) | 
					
						
							|  |  |  |           *StoPoint++ = ((VarKeep *)tvalue)->New = Unsigned(displacement + j); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           *StoPoint++ = ((VarKeep *)tvalue)->New; | 
					
						
							|  |  |  |         j += 2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } else if (IsAtomicTerm(tvalue)) { | 
					
						
							|  |  |  |       *StoPoint++ = arg_no; | 
					
						
							|  |  |  |       *StoPoint++ = tvalue; | 
					
						
							|  |  |  |       j += 2; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       LOCAL_Error_TYPE = TYPE_ERROR_DBTERM; | 
					
						
							|  |  |  |       LOCAL_Error_Term = d0; | 
					
						
							|  |  |  |       LOCAL_ErrorMessage = "wrong term in SF"; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       return (NULL); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   *StoPoint++ = 0; | 
					
						
							|  |  |  |   ntp = StoPoint; | 
					
						
							|  |  |  |   CodeAbs = displacement + j; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * This function is used to check if one of the terms in the idb is the | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |  * constant to_compare | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | inline static DBRef check_if_cons(DBRef p, Term to_compare) { | 
					
						
							|  |  |  |   while (p != NIL && | 
					
						
							|  |  |  |          (p->Flags & (DBCode | ErasedMask | DBVar | DBNoVars | DBComplex) || | 
					
						
							|  |  |  |           p->DBT.Entry != Unsigned(to_compare))) | 
					
						
							| 
									
										
										
										
											2003-02-12 13:20:52 +00:00
										 |  |  |     p = NextDBRef(p); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return p; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * This function is used to check if one of the terms in the idb is a prolog | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |  * variable | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBRef check_if_var(DBRef p) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   while (p != NIL && | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |          p->Flags & (DBCode | ErasedMask | DBAtomic | DBNoVars | DBComplex)) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     p = NextDBRef(p); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return p; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * This function is used to check if a Prolog complex term with variables | 
					
						
							|  |  |  |  * already exists in the idb for that key. The comparison is alike ==, but | 
					
						
							|  |  |  |  * only the relative binding of variables, not their position is used. The | 
					
						
							|  |  |  |  * comparison is done using the function cmpclls only. The function could | 
					
						
							|  |  |  |  * only fail if a functor was matched to a Prolog term, but then, it should | 
					
						
							|  |  |  |  * have failed before because the structure of term would have been very | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |  * different | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBRef check_if_wvars(DBRef p, unsigned int NOfCells, CELL *BTptr) { | 
					
						
							|  |  |  |   CELL *memptr; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     while (p != NIL && | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |            p->Flags & (DBCode | ErasedMask | DBAtomic | DBNoVars | DBVar)) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       p = NextDBRef(p); | 
					
						
							|  |  |  |     if (p == NIL) | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |       return p; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     memptr = CellPtr(&(p->DBT.Contents)); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (NOfCells == p->DBT.NOfCells && cmpclls(memptr, BTptr, NOfCells)) | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |       return p; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     else | 
					
						
							|  |  |  |       p = NextDBRef(p); | 
					
						
							|  |  |  |   } while (TRUE); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return NIL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static int scheckcells(int NOfCells, register CELL *m1, register CELL *m2, | 
					
						
							|  |  |  |                        link_entry *lp, register CELL bp) { | 
					
						
							|  |  |  |   CELL base = Unsigned(m1); | 
					
						
							|  |  |  |   link_entry *lp1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-01-30 00:26:43 +00:00
										 |  |  |   while (NOfCells-- > 0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Register CELL r1, r2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     r1 = *m1++; | 
					
						
							|  |  |  |     r2 = *m2++; | 
					
						
							|  |  |  |     if (r1 == r2) | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     else if (r2 + bp == r1) { | 
					
						
							|  |  |  |       /* link pointers may not have been generated in the */ | 
					
						
							|  |  |  |       /* same order */ | 
					
						
							|  |  |  |       /* make sure r1 is really an offset. */ | 
					
						
							|  |  |  |       lp1 = lp; | 
					
						
							|  |  |  |       r1 = m1 - (CELL *)base; | 
					
						
							|  |  |  |       while (*lp1 != r1 && *lp1) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         lp1++; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       if (!(*lp1)) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* keep the old link pointer for future search. */ | 
					
						
							|  |  |  |       /* vsc: this looks like a bug!!!! */ | 
					
						
							|  |  |  |       /* *lp1 = *lp++; */ | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * the cousin of the previous, but with things a bit more sophisticated. | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |  * mtchcells, if an error was an found, needs to test ........ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBRef check_if_nvars(DBRef p, unsigned int NOfCells, CELL *BTptr, | 
					
						
							|  |  |  |                             struct db_globs *dbg) { | 
					
						
							|  |  |  |   CELL *memptr; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     while (p != NIL && | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |            p->Flags & (DBCode | ErasedMask | DBAtomic | DBComplex | DBVar)) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       p = NextDBRef(p); | 
					
						
							|  |  |  |     if (p == NIL) | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |       return p; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     memptr = CellPtr(p->DBT.Contents); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (scheckcells(NOfCells, memptr, BTptr, dbg->LinkAr, | 
					
						
							|  |  |  |                     Unsigned(p->DBT.Contents - 1))) | 
					
						
							|  |  |  |       return p; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       p = NextDBRef(p); | 
					
						
							|  |  |  |   } while (TRUE); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return NIL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBRef generate_dberror_msg(int errnumb, UInt sz, char *msg) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = sz; | 
					
						
							|  |  |  |   LOCAL_Error_TYPE = errnumb; | 
					
						
							|  |  |  |   LOCAL_Error_Term = TermNil; | 
					
						
							|  |  |  |   LOCAL_ErrorMessage = msg; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBRef CreateDBWithDBRef(Term Tm, DBProp p, struct db_globs *dbg) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   DBRef pp, dbr = DBRefOfTerm(Tm); | 
					
						
							|  |  |  |   DBTerm *ppt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (p == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     UInt sz = sizeof(DBTerm) + 2 * sizeof(CELL); | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |     ppt = (DBTerm *)AllocDBSpace(sz); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     if (ppt == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       return generate_dberror_msg(RESOURCE_ERROR_HEAP, TermNil, | 
					
						
							|  |  |  |                                   "could not allocate heap"); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |     dbg->sz = sz; | 
					
						
							|  |  |  |     Yap_LUClauseSpace += sz; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     pp = (DBRef)ppt; | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     UInt sz = DBLength(2 * sizeof(DBRef)); | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |     pp = AllocDBSpace(sz); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     if (pp == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       return generate_dberror_msg(RESOURCE_ERROR_HEAP, 0, | 
					
						
							|  |  |  |                                   "could not allocate space"); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |     Yap_LUClauseSpace += sz; | 
					
						
							|  |  |  |     dbg->sz = sz; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     pp->id = FunctorDBRef; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     pp->Flags = DBNoVars | DBComplex | DBWithRefs; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     INIT_LOCK(pp->lock); | 
					
						
							|  |  |  |     INIT_DBREF_COUNT(pp); | 
					
						
							|  |  |  |     ppt = &(pp->DBT); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-12-27 00:38:53 +00:00
										 |  |  |   if (dbr->Flags & LogUpdMask) { | 
					
						
							|  |  |  |     LogUpdClause *cl = (LogUpdClause *)dbr; | 
					
						
							|  |  |  |     cl->ClRefCount++; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     dbr->NOfRefsTo++; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   ppt->Entry = Tm; | 
					
						
							|  |  |  |   ppt->NOfCells = 0; | 
					
						
							|  |  |  |   ppt->Contents[0] = (CELL)NULL; | 
					
						
							|  |  |  |   ppt->Contents[1] = (CELL)dbr; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   ppt->DBRefs = (DBRef *)(ppt->Contents + 2); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |   ppt->ag.attachments = 0L; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   return pp; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBTerm *CreateDBTermForAtom(Term Tm, UInt extra_size, | 
					
						
							|  |  |  |                                    struct db_globs *dbg) { | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   DBTerm *ppt; | 
					
						
							|  |  |  |   ADDR ptr; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   UInt sz = extra_size + sizeof(DBTerm); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |   ptr = (ADDR)AllocDBSpace(sz); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   if (ptr == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return (DBTerm *)generate_dberror_msg(RESOURCE_ERROR_HEAP, 0, | 
					
						
							|  |  |  |                                           "could not allocate space"); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |   Yap_LUClauseSpace += sz; | 
					
						
							|  |  |  |   dbg->sz = sz; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   ppt = (DBTerm *)(ptr + extra_size); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   ppt->NOfCells = 0; | 
					
						
							|  |  |  |   ppt->DBRefs = NULL; | 
					
						
							|  |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |   ppt->ag.attachments = 0; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   ppt->DBRefs = NULL; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   ppt->Entry = Tm; | 
					
						
							|  |  |  |   return ppt; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBTerm *CreateDBTermForVar(UInt extra_size, struct db_globs *dbg) { | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   DBTerm *ppt; | 
					
						
							|  |  |  |   ADDR ptr; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   UInt sz = extra_size + sizeof(DBTerm); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |   ptr = (ADDR)AllocDBSpace(sz); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   if (ptr == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return (DBTerm *)generate_dberror_msg(RESOURCE_ERROR_HEAP, 0, | 
					
						
							|  |  |  |                                           "could not allocate space"); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |   Yap_LUClauseSpace += sz; | 
					
						
							|  |  |  |   dbg->sz = sz; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   ppt = (DBTerm *)(ptr + extra_size); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   ppt->NOfCells = 0; | 
					
						
							|  |  |  |   ppt->DBRefs = NULL; | 
					
						
							|  |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |   ppt->ag.attachments = 0; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   ppt->DBRefs = NULL; | 
					
						
							|  |  |  |   ppt->Entry = (CELL)(&(ppt->Entry)); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   return ppt; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBRef CreateDBRefForAtom(Term Tm, DBProp p, int InFlag, | 
					
						
							|  |  |  |                                 struct db_globs *dbg) { | 
					
						
							|  |  |  |   Register DBRef pp; | 
					
						
							|  |  |  |   SMALLUNSGN flag; | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |   UInt sz = DBLength(NIL); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   flag = DBAtomic; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (InFlag &MkIfNot && (dbg->found_one = check_if_cons(p->First, Tm))) | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |     return dbg->found_one; | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |   pp = AllocDBSpace(sz); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (pp == NIL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return generate_dberror_msg(RESOURCE_ERROR_HEAP, 0, | 
					
						
							|  |  |  |                                 "could not allocate space"); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |   Yap_LUClauseSpace += sz; | 
					
						
							|  |  |  |   dbg->sz = sz; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   pp->id = FunctorDBRef; | 
					
						
							|  |  |  |   INIT_LOCK(pp->lock); | 
					
						
							|  |  |  |   INIT_DBREF_COUNT(pp); | 
					
						
							|  |  |  |   pp->Flags = flag; | 
					
						
							|  |  |  |   pp->Code = NULL; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   pp->DBT.Entry = Tm; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   pp->DBT.DBRefs = NULL; | 
					
						
							|  |  |  |   pp->DBT.NOfCells = 0; | 
					
						
							|  |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |   pp->DBT.ag.attachments = 0; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return (pp); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBRef CreateDBRefForVar(Term Tm, DBProp p, int InFlag, | 
					
						
							|  |  |  |                                struct db_globs *dbg) { | 
					
						
							|  |  |  |   Register DBRef pp; | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |   UInt sz = DBLength(NULL); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (InFlag &MkIfNot && (dbg->found_one = check_if_var(p->First))) | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |     return dbg->found_one; | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |   pp = AllocDBSpace(sz); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (pp == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return generate_dberror_msg(RESOURCE_ERROR_HEAP, 0, | 
					
						
							|  |  |  |                                 "could not allocate space"); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |   Yap_LUClauseSpace += sz; | 
					
						
							|  |  |  |   dbg->sz = sz; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   pp->id = FunctorDBRef; | 
					
						
							|  |  |  |   pp->Flags = DBVar; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   pp->DBT.Entry = (CELL)Tm; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   pp->Code = NULL; | 
					
						
							|  |  |  |   pp->DBT.NOfCells = 0; | 
					
						
							|  |  |  |   pp->DBT.DBRefs = NULL; | 
					
						
							|  |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |   pp->DBT.ag.attachments = 0; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   INIT_LOCK(pp->lock); | 
					
						
							|  |  |  |   INIT_DBREF_COUNT(pp); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return pp; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBRef CreateDBStruct(Term Tm, DBProp p, int InFlag, int *pstat, | 
					
						
							|  |  |  |                             UInt extra_size, struct db_globs *dbg) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Register Term tt, *nar = NIL; | 
					
						
							|  |  |  |   SMALLUNSGN flag; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   int NOfLinks = 0; | 
					
						
							|  |  |  |   /* place DBRefs in ConsultStack */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   DBRef *TmpRefBase = (DBRef *)LOCAL_TrailTop; | 
					
						
							|  |  |  |   CELL *CodeAbs; /* how much code did we find	 */ | 
					
						
							| 
									
										
										
										
											2008-01-27 11:01:07 +00:00
										 |  |  |   int vars_found = FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   if (p == NULL) { | 
					
						
							|  |  |  |     if (IsVarTerm(Tm)) { | 
					
						
							|  |  |  | #ifdef COROUTINING
 | 
					
						
							|  |  |  |       if (!SafeIsAttachedTerm(Tm)) { | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         DBRef out = (DBRef)CreateDBTermForVar(extra_size, dbg); | 
					
						
							|  |  |  |         *pstat = TRUE; | 
					
						
							|  |  |  |         return out; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     } else if (IsAtomOrIntTerm(Tm)) { | 
					
						
							| 
									
										
										
										
											2006-11-06 18:35:05 +00:00
										 |  |  |       DBRef out = (DBRef)CreateDBTermForAtom(Tm, extra_size, dbg); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       *pstat = FALSE; | 
					
						
							|  |  |  |       return out; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     if (IsVarTerm(Tm) | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         && !SafeIsAttachedTerm(Tm) | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |             ) { | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       *pstat = TRUE; | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |       return CreateDBRefForVar(Tm, p, InFlag, dbg); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |     } else if (IsAtomOrIntTerm(Tm)) { | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |       return CreateDBRefForAtom(Tm, p, InFlag, dbg); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-12-07 16:54:58 +00:00
										 |  |  |   /* next, let's process a compound term */ | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     DBTerm *ppt, *ppt0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     DBRef pp, pp0; | 
					
						
							|  |  |  |     Term *ntp0, *ntp; | 
					
						
							|  |  |  |     unsigned int NOfCells = 0; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							|  |  |  |     CELL attachments = 0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |     dbg->tofref = TmpRefBase; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     if (p == NULL) { | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       ADDR ptr = Yap_PreAllocCodeSpace(); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       ppt0 = (DBTerm *)(ptr + extra_size); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       pp0 = (DBRef)ppt0; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       pp0 = (DBRef)Yap_PreAllocCodeSpace(); | 
					
						
							|  |  |  |       ppt0 = &(pp0->DBT); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if ((ADDR)ppt0 >= (ADDR)AuxSp - 1024) { | 
					
						
							|  |  |  |       LOCAL_Error_Size = (UInt)(extra_size + sizeof(ppt0)); | 
					
						
							|  |  |  |       LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK; | 
					
						
							|  |  |  |       Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2004-12-07 16:54:58 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     ntp0 = ppt0->Contents; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if ((ADDR)TR >= LOCAL_TrailTop - 1024) { | 
					
						
							|  |  |  |       LOCAL_Error_Size = 0; | 
					
						
							|  |  |  |       LOCAL_Error_TYPE = RESOURCE_ERROR_TRAIL; | 
					
						
							|  |  |  |       Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2006-10-11 14:53:57 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |     dbg->lr = dbg->LinkAr = (link_entry *)TR; | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     /* attachment */ | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  |     if (IsVarTerm(Tm)) { | 
					
						
							| 
									
										
										
										
											2004-05-13 20:54:58 +00:00
										 |  |  |       tt = (CELL)(ppt0->Contents); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       ntp = MkDBTerm(VarOfTerm(Tm), VarOfTerm(Tm), ntp0, ntp0 + 1, ntp0 - 1, | 
					
						
							|  |  |  |                      &attachments, &vars_found, dbg); | 
					
						
							| 
									
										
										
										
											2002-10-21 22:14:29 +00:00
										 |  |  |       if (ntp == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2002-10-21 22:14:29 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  |     } else | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         if (IsPairTerm(Tm)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* avoid null pointers!! */ | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       tt = AbsPair(ppt0->Contents); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       ntp = MkDBTerm(RepPair(Tm), RepPair(Tm) + 1, ntp0, ntp0 + 2, ntp0 - 1, | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |                      &attachments, | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |                      &vars_found, dbg); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       if (ntp == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       unsigned int arity; | 
					
						
							|  |  |  |       Functor fun; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       tt = AbsAppl(ppt0->Contents); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* we need to store the functor manually */ | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       fun = FunctorOfTerm(Tm); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       if (IsExtensionFunctor(fun)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         switch ((CELL)fun) { | 
					
						
							|  |  |  |         case (CELL) FunctorDouble: | 
					
						
							|  |  |  |           ntp = copy_double(ntp0, RepAppl(Tm)); | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         case (CELL) FunctorString: | 
					
						
							|  |  |  |           ntp = copy_string(ntp0, RepAppl(Tm)); | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         case (CELL) FunctorDBRef: | 
					
						
							|  |  |  |           Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							|  |  |  |           return CreateDBWithDBRef(Tm, p, dbg); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         case (CELL) FunctorBigInt: | 
					
						
							|  |  |  |           ntp = copy_big_int(ntp0, RepAppl(Tm)); | 
					
						
							|  |  |  |           break; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         default: /* LongInt */ | 
					
						
							|  |  |  |           ntp = copy_long_int(ntp0, RepAppl(Tm)); | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         *ntp0 = (CELL)fun; | 
					
						
							|  |  |  |         arity = ArityOfFunctor(fun); | 
					
						
							|  |  |  |         ntp = MkDBTerm(RepAppl(Tm) + 1, RepAppl(Tm) + arity, ntp0 + 1, | 
					
						
							|  |  |  |                        ntp0 + 1 + arity, ntp0 - 1, | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |                        &attachments, | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |                        &vars_found, dbg); | 
					
						
							|  |  |  |         if (ntp == NULL) { | 
					
						
							|  |  |  |           Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							|  |  |  |           return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     CodeAbs = (CELL *)((CELL)ntp - (CELL)ntp0); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if (LOCAL_Error_TYPE) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |       Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       return NULL; /* Error Situation */ | 
					
						
							| 
									
										
										
										
											2002-10-21 22:14:29 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     NOfCells = ntp - ntp0; /* End Of Code Info */ | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |     *dbg->lr++ = 0; | 
					
						
							|  |  |  |     NOfLinks = (dbg->lr - dbg->LinkAr); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (vars_found || InFlag & InQueue) { | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /*
 | 
					
						
							|  |  |  |        * Take into account the fact that one needs an entry | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |        * for the number of links | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |        */ | 
					
						
							|  |  |  |       flag = DBComplex; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       CodeAbs += (NOfLinks + (sizeof(CELL) / sizeof(BITS32) - 1)) / | 
					
						
							|  |  |  |                  (sizeof(CELL) / sizeof(BITS32)); | 
					
						
							|  |  |  |       if ((CELL *)((char *)ntp0 + (CELL)CodeAbs) > AuxSp) { | 
					
						
							|  |  |  |         LOCAL_Error_Size = (UInt)DBLength(CodeAbs); | 
					
						
							|  |  |  |         LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK; | 
					
						
							|  |  |  |         Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if ((InFlag & MkIfNot) && | 
					
						
							|  |  |  |           (dbg->found_one = check_if_wvars(p->First, NOfCells, ntp0))) { | 
					
						
							|  |  |  |         Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							|  |  |  |         return dbg->found_one; | 
					
						
							| 
									
										
										
										
											2002-10-21 22:14:29 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       flag = DBNoVars; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if ((InFlag & MkIfNot) && | 
					
						
							|  |  |  |           (dbg->found_one = check_if_nvars(p->First, NOfCells, ntp0, dbg))) { | 
					
						
							|  |  |  |         Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							|  |  |  |         return dbg->found_one; | 
					
						
							| 
									
										
										
										
											2002-10-21 22:14:29 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |     if (dbg->tofref != TmpRefBase) { | 
					
						
							|  |  |  |       CodeAbs += (TmpRefBase - dbg->tofref) + 1; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if ((CELL *)((char *)ntp0 + (CELL)CodeAbs) > AuxSp) { | 
					
						
							|  |  |  |         LOCAL_Error_Size = (UInt)DBLength(CodeAbs); | 
					
						
							|  |  |  |         LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK; | 
					
						
							|  |  |  |         Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       flag |= DBWithRefs; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #if SIZEOF_LINK_ENTRY == 2
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (Unsigned(CodeAbs) >= 0x40000) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |       Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       return generate_dberror_msg(SYSTEM_ERROR_INTERNAL, 0, | 
					
						
							|  |  |  |                                   "trying to store term larger than 256KB"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     if (p == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       UInt sz = (CELL)CodeAbs + extra_size + sizeof(DBTerm); | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |       ADDR ptr = Yap_AllocCodeSpace(sz); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       ppt = (DBTerm *)(ptr + extra_size); | 
					
						
							| 
									
										
										
										
											2004-01-29 13:37:10 +00:00
										 |  |  |       if (ptr == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							|  |  |  |         return generate_dberror_msg(RESOURCE_ERROR_HEAP, sz, | 
					
						
							|  |  |  |                                     "heap crashed against stacks"); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |       Yap_LUClauseSpace += sz; | 
					
						
							|  |  |  |       dbg->sz = sz; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       pp = (DBRef)ppt; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |       UInt sz = DBLength(CodeAbs); | 
					
						
							|  |  |  |       pp = AllocDBSpace(sz); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       if (pp == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							|  |  |  |         return generate_dberror_msg(RESOURCE_ERROR_HEAP, sz, | 
					
						
							|  |  |  |                                     "heap crashed against stacks"); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-08-31 13:58:41 -07:00
										 |  |  |       Yap_LUClauseSpace += sz; | 
					
						
							|  |  |  |       dbg->sz = sz; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       pp->id = FunctorDBRef; | 
					
						
							|  |  |  |       pp->Flags = flag; | 
					
						
							|  |  |  |       INIT_LOCK(pp->lock); | 
					
						
							|  |  |  |       INIT_DBREF_COUNT(pp); | 
					
						
							|  |  |  |       ppt = &(pp->DBT); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (flag & DBComplex) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       link_entry *woar; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       ppt->NOfCells = NOfCells; | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |       ppt->ag.attachments = attachments; | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       if (pp0 != pp) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         nar = ppt->Contents; | 
					
						
							|  |  |  |         nar = (Term *)cpcells(CellPtr(nar), ntp0, Unsigned(NOfCells)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         nar = ppt->Contents + Unsigned(NOfCells); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-11-29 20:29:52 +00:00
										 |  |  |       woar = (link_entry *)nar; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       memcpy((void *)woar, (const void *)dbg->LinkAr, | 
					
						
							|  |  |  |              (size_t)(NOfLinks * sizeof(link_entry))); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       woar += NOfLinks; | 
					
						
							|  |  |  | #ifdef ALIGN_LONGS
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #if SIZEOF_INT_P == 8
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       while ((Unsigned(woar) & 7) != 0) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         woar++; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  |       if ((Unsigned(woar) & 3) != 0) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         woar++; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       nar = (Term *)(woar); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       *pstat = TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } else if (flag & DBNoVars) { | 
					
						
							|  |  |  |       if (pp0 != pp) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         nar = (Term *)cpcells(CellPtr(ppt->Contents), ntp0, Unsigned(NOfCells)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         nar = ppt->Contents + Unsigned(NOfCells); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       ppt->NOfCells = NOfCells; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (ppt != ppt0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       linkblk(dbg->LinkAr, CellPtr(ppt->Contents - 1), (CELL)ppt - (CELL)ppt0); | 
					
						
							|  |  |  |       ppt->Entry = AdjustIDBPtr(tt, (CELL)ppt - (CELL)ppt0); | 
					
						
							| 
									
										
										
										
											2003-09-15 01:25:29 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2004-11-23 21:16:21 +00:00
										 |  |  |       if (attachments) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         ppt->ag.attachments = AdjustIDBPtr(attachments, (CELL)ppt - (CELL)ppt0); | 
					
						
							| 
									
										
										
										
											2004-11-23 21:16:21 +00:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         ppt->ag.attachments = 0L; | 
					
						
							| 
									
										
										
										
											2003-09-15 01:25:29 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       ppt->Entry = tt; | 
					
						
							| 
									
										
										
										
											2004-11-23 21:16:21 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |       ppt->ag.attachments = attachments; | 
					
						
							| 
									
										
										
										
											2004-11-23 21:16:21 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (flag & DBWithRefs) { | 
					
						
							|  |  |  |       DBRef *ptr = TmpRefBase, *rfnar = (DBRef *)nar; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       *rfnar++ = NULL; | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |       while (ptr != dbg->tofref) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         *rfnar++ = *--ptr; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       ppt->DBRefs = rfnar; | 
					
						
							| 
									
										
										
										
											2003-01-21 23:27:02 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       ppt->DBRefs = NULL; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_ReleasePreAllocCodeSpace((ADDR)pp0); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     return pp; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBRef record(int Flag, Term key, Term t_data, Term t_code USES_REGS) { | 
					
						
							|  |  |  |   Register Term twork = key; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Register DBProp p; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Register DBRef x; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   int needs_vars; | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |   struct db_globs dbg; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  |   LOCAL_s_dbg = &dbg; | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |   dbg.found_one = NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef SFUNC
 | 
					
						
							|  |  |  |   FathersPlace = NIL; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (EndOfPAEntr( | 
					
						
							|  |  |  |           p = FetchDBPropFromKey(twork, Flag & MkCode, TRUE, "record/3"))) { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |   if ((x = CreateDBStruct(t_data, p, Flag, &needs_vars, 0, &dbg)) == NULL) { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |   if ((Flag & MkIfNot) && dbg.found_one) | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2001-06-08 14:52:54 +00:00
										 |  |  |   TRAIL_REF(x); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (x->Flags & (DBNoVars | DBComplex)) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     x->Mask = EvalMasks(t_data, &x->Key); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     x->Mask = x->Key = 0; | 
					
						
							|  |  |  |   if (Flag & MkCode) | 
					
						
							|  |  |  |     x->Flags |= DBCode; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     x->Flags |= DBNoCode; | 
					
						
							|  |  |  |   x->Parent = p; | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   x->Flags |= DBClMask; | 
					
						
							|  |  |  |   x->ref_count = 1; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   x->Flags |= (InUseMask | DBClMask); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   x->NOfRefsTo = 0; | 
					
						
							|  |  |  |   WRITE_LOCK(p->DBRWLock); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (p->F0 == NULL) { | 
					
						
							|  |  |  |     p->F0 = p->L0 = x; | 
					
						
							|  |  |  |     x->p = x->n = NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     if (Flag & MkFirst) { | 
					
						
							|  |  |  |       x->n = p->F0; | 
					
						
							|  |  |  |       p->F0->p = x; | 
					
						
							|  |  |  |       p->F0 = x; | 
					
						
							|  |  |  |       x->p = NULL; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       x->p = p->L0; | 
					
						
							|  |  |  |       p->L0->n = x; | 
					
						
							|  |  |  |       p->L0 = x; | 
					
						
							|  |  |  |       x->n = NULL; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (p->First == NIL) { | 
					
						
							|  |  |  |     p->First = p->Last = x; | 
					
						
							|  |  |  |     x->Prev = x->Next = NIL; | 
					
						
							|  |  |  |   } else if (Flag & MkFirst) { | 
					
						
							|  |  |  |     x->Prev = NIL; | 
					
						
							|  |  |  |     (p->First)->Prev = x; | 
					
						
							|  |  |  |     x->Next = p->First; | 
					
						
							|  |  |  |     p->First = x; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     x->Next = NIL; | 
					
						
							|  |  |  |     (p->Last)->Next = x; | 
					
						
							|  |  |  |     x->Prev = p->Last; | 
					
						
							|  |  |  |     p->Last = x; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-02-12 14:02:42 +00:00
										 |  |  |   if (Flag & MkCode) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     x->Code = (yamop *)IntegerOfTerm(t_code); | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   WRITE_UNLOCK(p->DBRWLock); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return x; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* add a new entry next to an old one */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBRef record_at(int Flag, DBRef r0, Term t_data, Term t_code USES_REGS) { | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   Register DBProp p; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Register DBRef x; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   int needs_vars; | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |   struct db_globs dbg; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  |   LOCAL_s_dbg = &dbg; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  | #ifdef SFUNC
 | 
					
						
							|  |  |  |   FathersPlace = NIL; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   p = r0->Parent; | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |   if ((x = CreateDBStruct(t_data, p, Flag, &needs_vars, 0, &dbg)) == NULL) { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   TRAIL_REF(x); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (x->Flags & (DBNoVars | DBComplex)) | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |     x->Mask = EvalMasks(t_data, &x->Key); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     x->Mask = x->Key = 0; | 
					
						
							|  |  |  |   if (Flag & MkCode) | 
					
						
							|  |  |  |     x->Flags |= DBCode; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     x->Flags |= DBNoCode; | 
					
						
							|  |  |  |   x->Parent = p; | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   x->Flags |= DBClMask; | 
					
						
							|  |  |  |   x->ref_count = 1; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   x->Flags |= (InUseMask | DBClMask); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   x->NOfRefsTo = 0; | 
					
						
							|  |  |  |   WRITE_LOCK(p->DBRWLock); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (Flag & MkFirst) { | 
					
						
							|  |  |  |     x->n = r0; | 
					
						
							|  |  |  |     x->p = r0->p; | 
					
						
							|  |  |  |     if (p->F0 == r0) { | 
					
						
							|  |  |  |       p->F0 = x; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       r0->p->n = x; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     r0->p = x; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     x->p = r0; | 
					
						
							|  |  |  |     x->n = r0->n; | 
					
						
							|  |  |  |     if (p->L0 == r0) { | 
					
						
							|  |  |  |       p->L0 = x; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       r0->n->p = x; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     r0->n = x; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (Flag & MkFirst) { | 
					
						
							|  |  |  |     x->Prev = r0->Prev; | 
					
						
							|  |  |  |     x->Next = r0; | 
					
						
							|  |  |  |     if (p->First == r0) { | 
					
						
							|  |  |  |       p->First = x; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       r0->Prev->Next = x; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     r0->Prev = x; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |     x->Next = r0->Next; | 
					
						
							|  |  |  |     x->Prev = r0; | 
					
						
							|  |  |  |     if (p->Last == r0) { | 
					
						
							|  |  |  |       p->Last = x; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       r0->Next->Prev = x; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     r0->Next = x; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (Flag & WithRef) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     x->Code = (yamop *)IntegerOfTerm(t_code); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   WRITE_UNLOCK(p->DBRWLock); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return x; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static LogUpdClause *new_lu_db_entry(Term t, PredEntry *pe) { | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   DBTerm *x; | 
					
						
							|  |  |  |   LogUpdClause *cl; | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  |   yamop *ipc; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   int needs_vars = FALSE; | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |   struct db_globs dbg; | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  |   int d_flag = 0; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   /* we cannot allow sharing between threads (for now) */ | 
					
						
							| 
									
										
										
										
											2014-10-11 01:38:32 +01:00
										 |  |  |   if (!pe || !(pe->PredFlags & ThreadLocalPredFlag)) | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  |     d_flag |= InQueue; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  |   LOCAL_s_dbg = &dbg; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   ipc = NEXTOP(((LogUpdClause *)NULL)->ClCode, e); | 
					
						
							|  |  |  |   if ((x = (DBTerm *)CreateDBStruct(t, NULL, d_flag, &needs_vars, (UInt)ipc, | 
					
						
							|  |  |  |                                     &dbg)) == NULL) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     return NULL; /* crash */ | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   cl = (LogUpdClause *)((ADDR)x - (UInt)ipc); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   ipc = cl->ClCode; | 
					
						
							|  |  |  |   cl->Id = FunctorDBRef; | 
					
						
							|  |  |  |   cl->ClFlags = LogUpdMask; | 
					
						
							| 
									
										
										
										
											2013-11-05 17:59:19 +00:00
										 |  |  |   cl->lusl.ClSource = x; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   cl->ClRefCount = 0; | 
					
						
							|  |  |  |   cl->ClPred = pe; | 
					
						
							|  |  |  |   cl->ClExt = NULL; | 
					
						
							|  |  |  |   cl->ClPrev = cl->ClNext = NULL; | 
					
						
							| 
									
										
										
										
											2006-11-06 18:35:05 +00:00
										 |  |  |   cl->ClSize = dbg.sz; | 
					
						
							| 
									
										
										
										
											2006-10-10 14:08:17 +00:00
										 |  |  |   /* Support for timestamps */ | 
					
						
							| 
									
										
										
										
											2006-10-11 15:08:03 +00:00
										 |  |  |   if (pe && pe->LastCallOfPred != LUCALL_ASSERT) { | 
					
						
							| 
									
										
										
										
											2006-11-15 00:13:37 +00:00
										 |  |  |     if (pe->TimeStampOfPred >= TIMESTAMP_RESET) | 
					
						
							|  |  |  |       Yap_UpdateTimestamps(pe); | 
					
						
							| 
									
										
										
										
											2006-10-10 14:08:17 +00:00
										 |  |  |     ++pe->TimeStampOfPred; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     /*  fprintf(stderr,"+
 | 
					
						
							|  |  |  |      * %x--%d--%ul\n",pe,pe->TimeStampOfPred,pe->ArityOfPE);*/ | 
					
						
							| 
									
										
										
										
											2006-10-10 14:08:17 +00:00
										 |  |  |     pe->LastCallOfPred = LUCALL_ASSERT; | 
					
						
							| 
									
										
										
										
											2006-10-11 15:08:03 +00:00
										 |  |  |     cl->ClTimeStart = pe->TimeStampOfPred; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     cl->ClTimeStart = 0L; | 
					
						
							| 
									
										
										
										
											2006-10-10 14:08:17 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   cl->ClTimeEnd = TIMESTAMP_EOT; | 
					
						
							| 
									
										
										
										
											2016-01-08 03:18:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2008-08-07 20:51:23 +00:00
										 |  |  |   //  INIT_LOCK(cl->ClLock);
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   INIT_CLREF_COUNT(cl); | 
					
						
							| 
									
										
										
										
											2008-08-08 14:05:34 +00:00
										 |  |  |   ipc->opc = Yap_opcode(_copy_idb_term); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (needs_vars) | 
					
						
							|  |  |  |     ipc->opc = Yap_opcode(_copy_idb_term); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     ipc->opc = Yap_opcode(_unify_idb_term); | 
					
						
							| 
									
										
										
										
											2008-08-08 14:05:34 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return cl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | LogUpdClause *Yap_new_ludbe(Term t, PredEntry *pe, UInt nargs) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |   LogUpdClause *x; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |   while ((x = new_lu_db_entry(t, pe)) == NULL) { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if (LOCAL_Error_TYPE == YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       XREGS[nargs + 1] = t; | 
					
						
							|  |  |  |       if (recover_from_record_error(nargs + 1)) { | 
					
						
							|  |  |  |         t = Deref(XREGS[nargs + 1]); | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         return FALSE; | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return x; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static LogUpdClause *record_lu(PredEntry *pe, Term t, int position) { | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  |   LogUpdClause *cl; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  |   if ((cl = new_lu_db_entry(t, pe)) == NULL) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-12-20 21:33:20 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_inform_profiler_of_clause(cl, (char *)cl + cl->ClSize, pe, | 
					
						
							|  |  |  |                                   GPROF_NEW_LU_CLAUSE); | 
					
						
							| 
									
										
										
										
											2012-12-20 21:33:20 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   Yap_add_logupd_clause(pe, cl, (position == MkFirst ? 2 : 0)); | 
					
						
							|  |  |  |   return cl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static LogUpdClause *record_lu_at(int position, LogUpdClause *ocl, Term t) { | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  |   LogUpdClause *cl; | 
					
						
							|  |  |  |   PredEntry *pe; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   pe = ocl->ClPred; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   PELOCK(62, pe); | 
					
						
							|  |  |  |   if ((cl = new_lu_db_entry(t, pe)) == NULL) { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     UNLOCK(pe->PELock); | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (pe->cs.p_code.NOfClauses > 1) | 
					
						
							| 
									
										
										
										
											2005-04-28 19:47:56 +00:00
										 |  |  |     Yap_RemoveIndexation(pe); | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  |   if (position == MkFirst) { | 
					
						
							|  |  |  |     /* add before current clause */ | 
					
						
							|  |  |  |     cl->ClNext = ocl; | 
					
						
							|  |  |  |     if (ocl->ClCode == pe->cs.p_code.FirstClause) { | 
					
						
							|  |  |  |       cl->ClPrev = NULL; | 
					
						
							|  |  |  |       pe->cs.p_code.FirstClause = cl->ClCode; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       cl->ClPrev = ocl->ClPrev; | 
					
						
							|  |  |  |       ocl->ClPrev->ClNext = cl; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ocl->ClPrev = cl; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     /* add after current clause */ | 
					
						
							|  |  |  |     cl->ClPrev = ocl; | 
					
						
							|  |  |  |     if (ocl->ClCode == pe->cs.p_code.LastClause) { | 
					
						
							|  |  |  |       cl->ClNext = NULL; | 
					
						
							|  |  |  |       pe->cs.p_code.LastClause = cl->ClCode; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       cl->ClNext = ocl->ClNext; | 
					
						
							|  |  |  |       ocl->ClNext->ClPrev = cl; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ocl->ClNext = cl; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   pe->cs.p_code.NOfClauses++; | 
					
						
							| 
									
										
										
										
											2010-01-21 10:00:24 +00:00
										 |  |  |   if (pe->cs.p_code.NOfClauses > 1) { | 
					
						
							|  |  |  |     pe->OpcodeOfPred = INDEX_OPCODE; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     pe->CodeOfPred = (yamop *)(&(pe->OpcodeOfPred)); | 
					
						
							| 
									
										
										
										
											2010-01-21 10:00:24 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   UNLOCK(pe->PELock); | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  |   return cl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* recorda(+Functor,+Term,-Ref) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_rcda(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   /* Idiotic xlc's cpp does not work with ARG1 within MkDBRefTerm */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Term TRef, t1 = Deref(ARG1); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   PredEntry *pe = NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!IsVarTerm(Deref(ARG3))) | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   pe = find_lu_entry(t1); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | restart_record: | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (pe) { | 
					
						
							| 
									
										
										
										
											2003-12-01 17:27:42 +00:00
										 |  |  |     LogUpdClause *cl; | 
					
						
							| 
									
										
										
										
											2008-02-07 23:30:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     PELOCK(61, pe); | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  |     cl = record_lu(pe, Deref(ARG2), MkFirst); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     if (cl != NULL) { | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       TRAIL_CLREF(cl); | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2003-12-27 00:38:53 +00:00
										 |  |  |       INC_CLREF_COUNT(cl); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       cl->ClFlags |= InUseMask; | 
					
						
							| 
									
										
										
										
											2003-12-27 00:38:53 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       TRef = MkDBRefTerm((DBRef)cl); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       TRef = TermNil; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-02-07 23:30:23 +00:00
										 |  |  |     UNLOCK(pe->PELock); | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     TRef = MkDBRefTerm(record(MkFirst, t1, Deref(ARG2), Unsigned(0) PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   if (LOCAL_Error_TYPE != YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |     if (recover_from_record_error(3)) { | 
					
						
							|  |  |  |       goto restart_record; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2004-02-05 16:57:02 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-02-07 23:30:23 +00:00
										 |  |  |   if (!pe) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |   return Yap_unify(ARG3, TRef); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* '$recordap'(+Functor,+Term,-Ref) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_rcdap(USES_REGS1) { | 
					
						
							|  |  |  |   Term TRef, t1 = Deref(ARG1), t2 = Deref(ARG2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!IsVarTerm(Deref(ARG3))) | 
					
						
							| 
									
										
										
										
											2003-01-21 23:27:02 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | restart_record: | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   TRef = MkDBRefTerm(record(MkFirst | MkCode, t1, t2, Unsigned(0) PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   if (LOCAL_Error_TYPE != YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |     if (recover_from_record_error(3)) { | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |       t2 = Deref(ARG2); | 
					
						
							|  |  |  |       goto restart_record; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2004-02-05 16:57:02 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2003-01-21 23:27:02 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |   return Yap_unify(ARG3, TRef); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  | /* recorda_at(+DBRef,+Term,-Ref) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | /** @pred  recorda_at(+ _R0_, _T_,- _R_)
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Makes term  _T_ the record preceding record with reference | 
					
						
							|  |  |  |  _R0_, and unifies  _R_ with its reference. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_rcda_at(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   /* Idiotic xlc's cpp does not work with ARG1 within MkDBRefTerm */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Term TRef, t1 = Deref(ARG1), t2 = Deref(ARG2); | 
					
						
							|  |  |  |   DBRef dbr; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!IsVarTerm(Deref(ARG3))) | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   if (IsVarTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR, t1, "recorda_at/3"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (!IsDBRefTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(TYPE_ERROR_DBREF, t1, "recorda_at/3"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | restart_record: | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  |   dbr = DBRefOfTerm(t1); | 
					
						
							|  |  |  |   if (dbr->Flags & ErasedMask) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     /* doesn't make sense */ | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (dbr->Flags & LogUpdMask) { | 
					
						
							|  |  |  |     TRef = MkDBRefTerm((DBRef)record_lu_at(MkFirst, (LogUpdClause *)dbr, t2)); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     TRef = MkDBRefTerm( | 
					
						
							|  |  |  |         record_at(MkFirst, DBRefOfTerm(t1), t2, Unsigned(0) PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   if (LOCAL_Error_TYPE != YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |     if (recover_from_record_error(3)) { | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |       t2 = Deref(ARG2); | 
					
						
							|  |  |  |       goto restart_record; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2004-02-05 16:57:02 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |   return Yap_unify(ARG3, TRef); | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* recordz(+Functor,+Term,-Ref) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | /** @pred  recordz(+ _K_, _T_,- _R_)
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | Makes term  _T_ the last record under key  _K_ and unifies  _R_ | 
					
						
							|  |  |  | with its reference. | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_rcdz(USES_REGS1) { | 
					
						
							|  |  |  |   Term TRef, t1 = Deref(ARG1), t2 = Deref(ARG2); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   PredEntry *pe; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!IsVarTerm(Deref(ARG3))) | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   pe = find_lu_entry(t1); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | restart_record: | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (pe) { | 
					
						
							| 
									
										
										
										
											2008-02-07 23:30:23 +00:00
										 |  |  |     LogUpdClause *cl; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     PELOCK(62, pe); | 
					
						
							| 
									
										
										
										
											2008-02-07 23:30:23 +00:00
										 |  |  |     cl = record_lu(pe, t2, MkLast); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     if (cl != NULL) { | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       TRAIL_CLREF(cl); | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2003-12-27 00:38:53 +00:00
										 |  |  |       INC_CLREF_COUNT(cl); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       cl->ClFlags |= InUseMask; | 
					
						
							| 
									
										
										
										
											2003-12-27 00:38:53 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       TRef = MkDBRefTerm((DBRef)cl); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       TRef = TermNil; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-02-07 23:30:23 +00:00
										 |  |  |     UNLOCK(pe->PELock); | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     TRef = MkDBRefTerm(record(MkLast, t1, t2, Unsigned(0) PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   if (LOCAL_Error_TYPE != YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |     if (recover_from_record_error(3)) { | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |       t2 = Deref(ARG2); | 
					
						
							|  |  |  |       goto restart_record; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2004-02-05 16:57:02 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-02-07 23:30:23 +00:00
										 |  |  |   if (!pe) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |   return Yap_unify(ARG3, TRef); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-06 16:55:48 +00:00
										 |  |  | /* recordz(+Functor,+Term,-Ref) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | Int Yap_Recordz(Atom at, Term t2) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2004-10-06 16:55:48 +00:00
										 |  |  |   PredEntry *pe; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   pe = find_lu_entry(MkAtomTerm(at)); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | restart_record: | 
					
						
							| 
									
										
										
										
											2004-10-06 16:55:48 +00:00
										 |  |  |   if (pe) { | 
					
						
							|  |  |  |     record_lu(pe, t2, MkLast); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     record(MkLast, MkAtomTerm(at), t2, Unsigned(0) PASS_REGS); | 
					
						
							| 
									
										
										
										
											2004-10-06 16:55:48 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   if (LOCAL_Error_TYPE != YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |     ARG1 = t2; | 
					
						
							|  |  |  |     if (recover_from_record_error(1)) { | 
					
						
							|  |  |  |       t2 = ARG1; | 
					
						
							|  |  |  |       goto restart_record; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2004-10-06 16:55:48 +00:00
										 |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2004-10-06 16:55:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* '$recordzp'(+Functor,+Term,-Ref) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_rcdzp(USES_REGS1) { | 
					
						
							|  |  |  |   Term TRef, t1 = Deref(ARG1), t2 = Deref(ARG2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!IsVarTerm(Deref(ARG3))) | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | restart_record: | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   TRef = MkDBRefTerm(record(MkLast | MkCode, t1, t2, Unsigned(0) PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   if (LOCAL_Error_TYPE != YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |     if (recover_from_record_error(3)) { | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |       t2 = Deref(ARG2); | 
					
						
							|  |  |  |       goto restart_record; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2004-02-05 16:57:02 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |   return Yap_unify(ARG3, TRef); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  | /* recordz_at(+Functor,+Term,-Ref) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | /** @pred  recordz_at(+ _R0_, _T_,- _R_)
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Makes term  _T_ the record following record with reference | 
					
						
							|  |  |  |  _R0_, and unifies  _R_ with its reference. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_rcdz_at(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   /* Idiotic xlc's cpp does not work with ARG1 within MkDBRefTerm */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Term TRef, t1 = Deref(ARG1), t2 = Deref(ARG2); | 
					
						
							|  |  |  |   DBRef dbr; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!IsVarTerm(Deref(ARG3))) | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							|  |  |  |   if (IsVarTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR, t1, "recordz_at/3"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (!IsDBRefTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(TYPE_ERROR_DBREF, t1, "recordz_at/3"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | restart_record: | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  |   dbr = DBRefOfTerm(t1); | 
					
						
							|  |  |  |   if (dbr->Flags & ErasedMask) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     /* doesn't make sense */ | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (dbr->Flags & LogUpdMask) { | 
					
						
							|  |  |  |     TRef = MkDBRefTerm((DBRef)record_lu_at(MkLast, (LogUpdClause *)dbr, t2)); | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     TRef = MkDBRefTerm(record_at(MkLast, dbr, t2, Unsigned(0) PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2005-04-10 04:01:15 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   if (LOCAL_Error_TYPE != YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |     if (recover_from_record_error(3)) { | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |       t2 = Deref(ARG2); | 
					
						
							|  |  |  |       goto restart_record; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2004-02-05 16:57:02 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |   return Yap_unify(ARG3, TRef); | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* '$record_stat_source'(+Functor,+Term) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_rcdstatp(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term t1 = Deref(ARG1), t2 = Deref(ARG2), t3 = Deref(ARG3); | 
					
						
							|  |  |  |   int mk_first; | 
					
						
							|  |  |  |   Term TRef; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t3) || !IsIntTerm(t3)) | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							|  |  |  |   if (IsVarTerm(t3) || !IsIntTerm(t3)) | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							|  |  |  |   mk_first = ((IntOfTerm(t3) % 4) == 2); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | restart_record: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (mk_first) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     TRef = | 
					
						
							|  |  |  |         MkDBRefTerm(record(MkFirst | MkCode, t1, t2, MkIntTerm(0) PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     TRef = MkDBRefTerm(record(MkLast | MkCode, t1, t2, MkIntTerm(0) PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   if (LOCAL_Error_TYPE != YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |     if (recover_from_record_error(4)) { | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |       t2 = Deref(ARG2); | 
					
						
							|  |  |  |       t3 = Deref(ARG3); | 
					
						
							|  |  |  |       goto restart_record; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2004-02-05 16:57:02 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |   return Yap_unify(ARG4, TRef); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* '$recordap'(+Functor,+Term,-Ref,+CRef) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_drcdap(USES_REGS1) { | 
					
						
							|  |  |  |   Term TRef, t1 = Deref(ARG1), t2 = Deref(ARG2), t4 = Deref(ARG4); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!IsVarTerm(Deref(ARG3))) | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							|  |  |  |   if (IsVarTerm(t4) || !IsIntegerTerm(t4)) | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | restart_record: | 
					
						
							|  |  |  |   TRef = MkDBRefTerm(record(MkFirst | MkCode | WithRef, t1, t2, t4 PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   if (LOCAL_Error_TYPE != YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |     if (recover_from_record_error(4)) { | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |       t2 = Deref(ARG2); | 
					
						
							|  |  |  |       t4 = Deref(ARG4); | 
					
						
							|  |  |  |       goto restart_record; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2004-02-05 16:57:02 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |   return Yap_unify(ARG3, TRef); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* '$recordzp'(+Functor,+Term,-Ref,+CRef) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_drcdzp(USES_REGS1) { | 
					
						
							|  |  |  |   Term TRef, t1 = Deref(ARG1), t2 = Deref(ARG2), t4 = Deref(ARG4); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!IsVarTerm(Deref(ARG3))) | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							|  |  |  |   if (IsVarTerm(t4) || !IsIntegerTerm(t4)) | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | restart_record: | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   TRef = MkDBRefTerm(record(MkLast | MkCode | WithRef, t1, t2, t4 PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   if (LOCAL_Error_TYPE != YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |     if (recover_from_record_error(4)) { | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |       t2 = Deref(ARG2); | 
					
						
							|  |  |  |       t4 = Deref(ARG4); | 
					
						
							|  |  |  |       goto restart_record; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2004-02-05 16:57:02 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |   return Yap_unify(ARG3, TRef); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_still_variant(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   CELL *old_h = B->cp_h; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   tr_fr_ptr old_tr = B->cp_tr; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   Term t1 = Deref(ARG1), t2 = Deref(ARG2); | 
					
						
							|  |  |  |   DBTerm *dbt; | 
					
						
							|  |  |  |   DBRef dbr; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   if (IsVarTerm(t1) || !IsDBRefTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2004-02-13 18:39:29 +00:00
										 |  |  |     return (FALSE); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |     /* limited sanity checking */ | 
					
						
							|  |  |  |     if (dbr->id != FunctorDBRef) { | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     dbr = DBRefOfTerm(t1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   /* ok, we assume there was a choicepoint before we copied the term */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-28 22:09:02 +00:00
										 |  |  |   /* skip binding for argument variable */ | 
					
						
							|  |  |  |   old_tr++; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   if (dbr->Flags & LogUpdMask) { | 
					
						
							|  |  |  |     LogUpdClause *cl = (LogUpdClause *)dbr; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (old_tr == TR - 1) { | 
					
						
							| 
									
										
										
										
											2004-07-28 22:09:02 +00:00
										 |  |  |       if (TrailTerm(old_tr) != CLREF_TO_TRENTRY(cl)) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         return FALSE; | 
					
						
							| 
									
										
										
										
											2004-07-28 22:09:02 +00:00
										 |  |  |     } else if (old_tr != TR) | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       return FALSE; | 
					
						
							|  |  |  |     if (Yap_op_from_opcode(cl->ClCode->opc) == _unify_idb_term) { | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2013-11-05 17:59:19 +00:00
										 |  |  |       dbt = cl->lusl.ClSource; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (old_tr == TR - 1) { | 
					
						
							| 
									
										
										
										
											2004-07-28 22:09:02 +00:00
										 |  |  |       if (TrailTerm(old_tr) != REF_TO_TRENTRY(dbr)) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         return FALSE; | 
					
						
							| 
									
										
										
										
											2004-07-28 22:09:02 +00:00
										 |  |  |     } else if (old_tr != TR) | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (dbr->Flags & (DBNoVars | DBAtomic)) | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       return TRUE; | 
					
						
							|  |  |  |     if (dbr->Flags & DBVar) | 
					
						
							|  |  |  |       return IsVarTerm(t2); | 
					
						
							|  |  |  |     dbt = &(dbr->DBT); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-07-28 22:09:02 +00:00
										 |  |  |   /*
 | 
					
						
							|  |  |  |     we checked the trail, so we are sure only variables in the new term | 
					
						
							|  |  |  |     were bound | 
					
						
							|  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     link_entry *lp = (link_entry *)(dbt->Contents + dbt->NOfCells); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |     link_entry link; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-05 03:06:31 +00:00
										 |  |  |     if (!dbt->NOfCells) { | 
					
						
							|  |  |  |       return IsVarTerm(t2); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |     while ((link = *lp++)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       Term t2 = Deref(old_h[link - 1]); | 
					
						
							|  |  |  |       if (IsUnboundVar(dbt->Contents + (link - 1))) { | 
					
						
							|  |  |  |         if (IsVarTerm(t2)) { | 
					
						
							|  |  |  |           Yap_unify(t2, MkAtomTerm(AtomFoundVar)); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           return FALSE; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static int copy_attachments(CELL *ts USES_REGS) { | 
					
						
							| 
									
										
										
										
											2005-11-26 02:57:25 +00:00
										 |  |  |   /* we will change delayed vars, and that also means the trail */ | 
					
						
							|  |  |  |   tr_fr_ptr tr0 = TR; | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-16 05:57:32 +00:00
										 |  |  |   while (TRUE) { | 
					
						
							| 
									
										
										
										
											2002-05-15 03:57:09 +00:00
										 |  |  |     /* store away in case there is an overflow */ | 
					
						
							| 
									
										
										
										
											2005-11-26 02:57:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (GLOBAL_attas[IntegerOfTerm(ts[2])].term_to_op(ts[1], ts[0] PASS_REGS) == | 
					
						
							|  |  |  |         FALSE) { | 
					
						
							| 
									
										
										
										
											2004-09-17 19:34:53 +00:00
										 |  |  |       /* oops, we did not have enough space to copy the elements */ | 
					
						
							|  |  |  |       /* reset queue of woken up goals */ | 
					
						
							| 
									
										
										
										
											2005-11-26 02:57:25 +00:00
										 |  |  |       TR = tr0; | 
					
						
							| 
									
										
										
										
											2004-09-17 19:34:53 +00:00
										 |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (ts[3] == TermNil) | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							|  |  |  |     ts = RepAppl(ts[3]) + 1; | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Term GetDBLUKey(PredEntry *ap) { | 
					
						
							|  |  |  |   PELOCK(63, ap); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (ap->PredFlags & NumberDBPredFlag) { | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     CACHE_REGS | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     Int id = ap->src.IndxId; | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     UNLOCK(ap->PELock); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     return MkIntegerTerm(id); | 
					
						
							| 
									
										
										
										
											2005-04-10 04:31:12 +00:00
										 |  |  |   } else if (ap->PredFlags & AtomDBPredFlag || | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |              (ap->ModuleOfPred != IDB_MODULE && ap->ArityOfPE == 0)) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     Atom at = (Atom)ap->FunctorOfPred; | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     UNLOCK(ap->PELock); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     return MkAtomTerm(at); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     Functor f = ap->FunctorOfPred; | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     UNLOCK(ap->PELock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return Yap_MkNewApplTerm(f, ArityOfFunctor(f)); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static int UnifyDBKey(DBRef DBSP, PropFlags flags, Term t) { | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |   DBProp p = DBSP->Parent; | 
					
						
							|  |  |  |   Term t1, tf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   READ_LOCK(p->DBRWLock); | 
					
						
							|  |  |  |   /* get the key */ | 
					
						
							|  |  |  |   if (p->ArityOfDB == 0) { | 
					
						
							|  |  |  |     t1 = MkAtomTerm((Atom)(p->FunctorOfDB)); | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     t1 = Yap_MkNewApplTerm(p->FunctorOfDB, p->ArityOfDB); | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  |   if ((p->KindOfPE & CodeDBBit) && (flags & CodeDBBit)) { | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |     Term t[2]; | 
					
						
							| 
									
										
										
										
											2004-02-12 12:37:12 +00:00
										 |  |  |     if (p->ModuleOfDB) | 
					
						
							|  |  |  |       t[0] = p->ModuleOfDB; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       t[0] = TermProlog; | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  |     t[1] = t1; | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |     tf = Yap_MkApplTerm(FunctorModule, 2, t); | 
					
						
							| 
									
										
										
										
											2002-12-10 00:32:22 +00:00
										 |  |  |   } else if (!(flags & CodeDBBit)) { | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |     tf = t1; | 
					
						
							| 
									
										
										
										
											2002-12-10 00:32:22 +00:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   READ_UNLOCK(p->DBRWLock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return Yap_unify(tf, t); | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static int UnifyDBNumber(DBRef DBSP, Term t) { | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  |   DBProp p = DBSP->Parent; | 
					
						
							|  |  |  |   DBRef ref; | 
					
						
							|  |  |  |   Int i = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   READ_LOCK(p->DBRWLock); | 
					
						
							|  |  |  |   ref = p->First; | 
					
						
							|  |  |  |   while (ref != NIL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (ref == DBSP) | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     if (!DEAD_REF(ref)) | 
					
						
							|  |  |  |       i++; | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  |     ref = ref->Next; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (ref == NIL) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   READ_UNLOCK(p->DBRWLock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return Yap_unify(MkIntegerTerm(i), t); | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | Int Yap_unify_immediate_ref(DBRef ref USES_REGS) { | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:30 +00:00
										 |  |  |   // old immediate semantics style
 | 
					
						
							|  |  |  |   LOCK(ref->lock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (ref == NULL || DEAD_REF(ref) || !UnifyDBKey(ref, 0, ARG1) || | 
					
						
							|  |  |  |       !UnifyDBNumber(ref, ARG2)) { | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:30 +00:00
										 |  |  |     UNLOCK(ref->lock); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     UNLOCK(ref->lock); | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Term GetDBTerm(DBTerm *DBSP, int src USES_REGS) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   Term t = DBSP->Entry; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (IsVarTerm(t) | 
					
						
							| 
									
										
										
										
											2004-05-13 20:54:58 +00:00
										 |  |  | #if COROUTINING
 | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |       && !DBSP->ag.attachments | 
					
						
							| 
									
										
										
										
											2004-05-13 20:54:58 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |       ) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     return MkVarTerm(); | 
					
						
							|  |  |  |   } else if (IsAtomOrIntTerm(t)) { | 
					
						
							|  |  |  |     return t; | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     CELL *HOld = HR; | 
					
						
							|  |  |  |     CELL *HeapPtr; | 
					
						
							|  |  |  |     CELL *pt; | 
					
						
							|  |  |  |     CELL NOf; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     if (!(NOf = DBSP->NOfCells)) { | 
					
						
							|  |  |  |       return t; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     pt = CellPtr(DBSP->Contents); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     CalculateStackGap(PASS_REGS1); | 
					
						
							|  |  |  |     if (HR + NOf > ASP - EventFlag / sizeof(CELL)) { | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  |       if (LOCAL_PrologMode & InErrorMode) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         if (HR + NOf > ASP) | 
					
						
							|  |  |  |           fprintf(stderr, | 
					
						
							|  |  |  |                   "\n\n [ FATAL ERROR: No Stack for Error Handling ]\n"); | 
					
						
							|  |  |  |         Yap_exit(1); | 
					
						
							| 
									
										
										
										
											2002-01-03 16:27:00 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         LOCAL_Error_TYPE = RESOURCE_ERROR_STACK; | 
					
						
							|  |  |  |         LOCAL_Error_Size = NOf * sizeof(CELL); | 
					
						
							|  |  |  |         return (Term)0; | 
					
						
							| 
									
										
										
										
											2002-01-03 16:27:00 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     HeapPtr = cpcells(HOld, pt, NOf); | 
					
						
							|  |  |  |     pt += HeapPtr - HOld; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     HR = HeapPtr; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |       link_entry *lp = (link_entry *)pt; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       linkblk(lp, HOld - 1, (CELL)HOld - (CELL)(DBSP->Contents)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (DBSP->ag.attachments != 0L && !src) { | 
					
						
							|  |  |  |       if (!copy_attachments((CELL *)AdjustIDBPtr( | 
					
						
							|  |  |  |               DBSP->ag.attachments, (CELL)HOld - (CELL)(DBSP->Contents)) | 
					
						
							|  |  |  |                                 PASS_REGS)) { | 
					
						
							|  |  |  |         HR = HOld; | 
					
						
							|  |  |  |         LOCAL_Error_TYPE = RESOURCE_ERROR_ATTRIBUTED_VARIABLES; | 
					
						
							|  |  |  |         LOCAL_Error_Size = 0; | 
					
						
							|  |  |  |         return (Term)0; | 
					
						
							| 
									
										
										
										
											2004-09-17 19:34:53 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-12-17 18:31:11 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return AdjustIDBPtr(t, Unsigned(HOld) - (CELL)(DBSP->Contents)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Term GetDBTermFromDBEntry(DBRef DBSP USES_REGS) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (DBSP->Flags & (DBNoVars | DBAtomic)) | 
					
						
							|  |  |  |     return DBSP->DBT.Entry; | 
					
						
							| 
									
										
										
										
											2013-11-05 17:59:19 +00:00
										 |  |  |   return GetDBTerm(&(DBSP->DBT), FALSE PASS_REGS); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void init_int_keys(void) { | 
					
						
							|  |  |  |   INT_KEYS = (Prop *)Yap_AllocCodeSpace(sizeof(Prop) * INT_KEYS_SIZE); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (INT_KEYS != NULL) { | 
					
						
							|  |  |  |     UInt i = 0; | 
					
						
							|  |  |  |     Prop *p = INT_KEYS; | 
					
						
							|  |  |  |     for (i = 0; i < INT_KEYS_SIZE; i++) { | 
					
						
							|  |  |  |       p[0] = NIL; | 
					
						
							|  |  |  |       p++; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_LUClauseSpace += sizeof(Prop) * INT_KEYS_SIZE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void init_int_lu_keys(void) { | 
					
						
							|  |  |  |   INT_LU_KEYS = (Prop *)Yap_AllocCodeSpace(sizeof(Prop) * INT_KEYS_SIZE); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (INT_LU_KEYS != NULL) { | 
					
						
							|  |  |  |     UInt i = 0; | 
					
						
							|  |  |  |     Prop *p = INT_LU_KEYS; | 
					
						
							|  |  |  |     for (i = 0; i < INT_KEYS_SIZE; i++) { | 
					
						
							|  |  |  |       p[0] = NULL; | 
					
						
							|  |  |  |       p++; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_LUClauseSpace += sizeof(Prop) * INT_KEYS_SIZE; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static int resize_int_keys(UInt new_size) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Prop *new; | 
					
						
							|  |  |  |   UInt i; | 
					
						
							| 
									
										
										
										
											2006-11-06 18:35:05 +00:00
										 |  |  |   UInt old_size = INT_KEYS_SIZE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   YAPEnterCriticalSection(); | 
					
						
							|  |  |  |   if (INT_KEYS == NULL) { | 
					
						
							|  |  |  |     INT_KEYS_SIZE = new_size; | 
					
						
							|  |  |  |     YAPLeaveCriticalSection(); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   new = (Prop *)Yap_AllocCodeSpace(sizeof(Prop) * new_size); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (new == NULL) { | 
					
						
							|  |  |  |     YAPLeaveCriticalSection(); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     LOCAL_Error_TYPE = RESOURCE_ERROR_HEAP; | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     LOCAL_Error_Term = TermNil; | 
					
						
							|  |  |  |     LOCAL_ErrorMessage = "could not allocate space"; | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Yap_LUClauseSpace += sizeof(Prop) * new_size; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   for (i = 0; i < new_size; i++) { | 
					
						
							|  |  |  |     new[i] = NIL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   for (i = 0; i < INT_KEYS_SIZE; i++) { | 
					
						
							|  |  |  |     if (INT_KEYS[i] != NIL) { | 
					
						
							|  |  |  |       Prop p0 = INT_KEYS[i]; | 
					
						
							|  |  |  |       while (p0 != NIL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         DBProp p = RepDBProp(p0); | 
					
						
							|  |  |  |         CELL key = (CELL)(p->FunctorOfDB); | 
					
						
							|  |  |  |         UInt hash_key = (CELL)key % new_size; | 
					
						
							|  |  |  |         p0 = p->NextOfPE; | 
					
						
							|  |  |  |         p->NextOfPE = new[hash_key]; | 
					
						
							|  |  |  |         new[hash_key] = AbsDBProp(p); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Yap_LUClauseSpace -= sizeof(Prop) * old_size; | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |   Yap_FreeCodeSpace((char *)INT_KEYS); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   INT_KEYS = new; | 
					
						
							|  |  |  |   INT_KEYS_SIZE = new_size; | 
					
						
							|  |  |  |   INT_KEYS_TIMESTAMP++; | 
					
						
							|  |  |  |   if (INT_KEYS_TIMESTAMP == MAX_ABS_INT) | 
					
						
							|  |  |  |     INT_KEYS_TIMESTAMP = 0; | 
					
						
							|  |  |  |   YAPLeaveCriticalSection(); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static PredEntry *find_lu_int_key(Int key) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   UInt hash_key = (CELL)key % INT_KEYS_SIZE; | 
					
						
							|  |  |  |   Prop p0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (INT_LU_KEYS != NULL) { | 
					
						
							|  |  |  |     p0 = INT_LU_KEYS[hash_key]; | 
					
						
							|  |  |  |     while (p0) { | 
					
						
							|  |  |  |       PredEntry *pe = RepPredProp(p0); | 
					
						
							|  |  |  |       if (pe->src.IndxId == key) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         return pe; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       p0 = pe->NextOfPE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (UPDATE_MODE == UPDATE_MODE_LOGICAL && find_int_key(key) == NULL) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     return new_lu_int_key(key); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | PredEntry *Yap_FindLUIntKey(Int key) { return find_lu_int_key(key); } | 
					
						
							| 
									
										
										
										
											2008-09-15 04:30:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBProp find_int_key(Int key) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   UInt hash_key = (CELL)key % INT_KEYS_SIZE; | 
					
						
							|  |  |  |   Prop p0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (INT_KEYS == NULL) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   p0 = INT_KEYS[hash_key]; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   while (p0) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     DBProp p = RepDBProp(p0); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     if (p->FunctorOfDB == (Functor)key) | 
					
						
							|  |  |  |       return p; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     p0 = p->NextOfPE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static PredEntry *new_lu_int_key(Int key) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   UInt hash_key = (CELL)key % INT_KEYS_SIZE; | 
					
						
							|  |  |  |   PredEntry *p; | 
					
						
							|  |  |  |   Prop p0; | 
					
						
							| 
									
										
										
										
											2007-10-11 14:25:09 +00:00
										 |  |  |   Atom ae; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (INT_LU_KEYS == NULL) { | 
					
						
							|  |  |  |     init_int_lu_keys(); | 
					
						
							|  |  |  |     if (INT_LU_KEYS == NULL) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |       CACHE_REGS | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       LOCAL_Error_TYPE = RESOURCE_ERROR_HEAP; | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       LOCAL_Error_Term = TermNil; | 
					
						
							|  |  |  |       LOCAL_ErrorMessage = "could not allocate space"; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-23 01:53:52 +00:00
										 |  |  |   ae = AtomDInteger; | 
					
						
							| 
									
										
										
										
											2007-10-11 21:42:09 +00:00
										 |  |  |   WRITE_LOCK(ae->ARWLock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   p0 = Yap_NewPredPropByAtom(ae, IDB_MODULE); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   p = RepPredProp(p0); | 
					
						
							|  |  |  |   p->NextOfPE = INT_LU_KEYS[hash_key]; | 
					
						
							|  |  |  |   p->src.IndxId = key; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   p->PredFlags |= LogUpdatePredFlag | NumberDBPredFlag; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   p->ArityOfPE = 3; | 
					
						
							|  |  |  |   p->OpcodeOfPred = Yap_opcode(_op_fail); | 
					
						
							|  |  |  |   p->cs.p_code.TrueCodeOfPred = p->CodeOfPred = FAILCODE; | 
					
						
							|  |  |  |   INT_LU_KEYS[hash_key] = p0; | 
					
						
							|  |  |  |   return p; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static PredEntry *new_lu_entry(Term t) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   Prop p0; | 
					
						
							|  |  |  |   PredEntry *pe; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsApplTerm(t)) { | 
					
						
							|  |  |  |     Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-11 19:44:01 +01:00
										 |  |  |     FUNC_WRITE_LOCK(f); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     p0 = Yap_NewPredPropByFunctor(f, IDB_MODULE); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } else if (IsAtomTerm(t)) { | 
					
						
							| 
									
										
										
										
											2003-12-01 17:27:42 +00:00
										 |  |  |     Atom at = AtomOfTerm(t); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     WRITE_LOCK(RepAtom(at)->ARWLock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     p0 = Yap_NewPredPropByAtom(at, IDB_MODULE); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2014-06-11 19:44:01 +01:00
										 |  |  |     FUNC_WRITE_LOCK(FunctorList); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     p0 = Yap_NewPredPropByFunctor(FunctorList, IDB_MODULE); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   pe = RepPredProp(p0); | 
					
						
							|  |  |  |   pe->PredFlags |= LogUpdatePredFlag; | 
					
						
							|  |  |  |   if (IsAtomTerm(t)) { | 
					
						
							|  |  |  |     pe->PredFlags |= AtomDBPredFlag; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   pe->ArityOfPE = 3; | 
					
						
							|  |  |  |   pe->OpcodeOfPred = Yap_opcode(_op_fail); | 
					
						
							| 
									
										
										
										
											2016-01-08 03:18:36 +00:00
										 |  |  |   if (CurrentModule == PROLOG_MODULE) | 
					
						
							|  |  |  |     pe->PredFlags |= StandardPredFlag; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   pe->cs.p_code.TrueCodeOfPred = pe->CodeOfPred = FAILCODE; | 
					
						
							|  |  |  |   return pe; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBProp find_entry(Term t) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   Atom at; | 
					
						
							|  |  |  |   UInt arity; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return RepDBProp(NIL); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } else if (IsAtomTerm(t)) { | 
					
						
							|  |  |  |     at = AtomOfTerm(t); | 
					
						
							|  |  |  |     arity = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   } else if (IsIntegerTerm(t)) { | 
					
						
							|  |  |  |     return find_int_key(IntegerOfTerm(t)); | 
					
						
							|  |  |  |   } else if (IsApplTerm(t)) { | 
					
						
							|  |  |  |     Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     at = NameOfFunctor(f); | 
					
						
							|  |  |  |     arity = ArityOfFunctor(f); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     at = AtomDot; | 
					
						
							|  |  |  |     arity = 2; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return RepDBProp(FindDBProp(RepAtom(at), 0, arity, 0)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static PredEntry *find_lu_entry(Term t) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   Prop p; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							|  |  |  |     Yap_Error(INSTANTIATION_ERROR, t, "while accessing database key"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (IsIntegerTerm(t)) { | 
					
						
							|  |  |  |     return find_lu_int_key(IntegerOfTerm(t)); | 
					
						
							|  |  |  |   } else if (IsApplTerm(t)) { | 
					
						
							|  |  |  |     Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  |       Yap_Error(TYPE_ERROR_KEY, t, "while accessing database key"); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     p = Yap_GetPredPropByFuncInThisModule(FunctorOfTerm(t), IDB_MODULE); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } else if (IsAtomTerm(t)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     p = Yap_GetPredPropByAtomInThisModule(AtomOfTerm(t), IDB_MODULE); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     p = Yap_GetPredPropByFuncInThisModule(FunctorList, IDB_MODULE); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (p == NIL) { | 
					
						
							|  |  |  |     if (UPDATE_MODE == UPDATE_MODE_LOGICAL && !find_entry(t)) { | 
					
						
							|  |  |  |       return new_lu_entry(t); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return RepPredProp(p); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBProp FetchIntDBPropFromKey(Int key, int flag, int new, | 
					
						
							|  |  |  |                                     char *error_mssg) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   Functor fun = (Functor)key; | 
					
						
							|  |  |  |   UInt hash_key = (CELL)key % INT_KEYS_SIZE; | 
					
						
							|  |  |  |   Prop p0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (INT_KEYS == NULL) { | 
					
						
							|  |  |  |     init_int_keys(); | 
					
						
							|  |  |  |     if (INT_KEYS == NULL) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |       CACHE_REGS | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       LOCAL_Error_TYPE = RESOURCE_ERROR_HEAP; | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       LOCAL_Error_Term = TermNil; | 
					
						
							|  |  |  |       LOCAL_ErrorMessage = "could not allocate space"; | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   p0 = INT_KEYS[hash_key]; | 
					
						
							|  |  |  |   while (p0 != NIL) { | 
					
						
							|  |  |  |     DBProp p = RepDBProp(p0); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     if (p->FunctorOfDB == fun) | 
					
						
							|  |  |  |       return p; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     p0 = p->NextOfPE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* p is NULL, meaning we did not find the functor */ | 
					
						
							|  |  |  |   if (new) { | 
					
						
							|  |  |  |     DBProp p; | 
					
						
							|  |  |  |     /* create a new DBProp				 */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     p = (DBProp)Yap_AllocAtomSpace(sizeof(*p)); | 
					
						
							|  |  |  |     p->KindOfPE = DBProperty | flag; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     p->F0 = p->L0 = NULL; | 
					
						
							|  |  |  |     p->ArityOfDB = 0; | 
					
						
							|  |  |  |     p->First = p->Last = NULL; | 
					
						
							|  |  |  |     p->ModuleOfDB = 0; | 
					
						
							|  |  |  |     p->FunctorOfDB = fun; | 
					
						
							|  |  |  |     p->NextOfPE = INT_KEYS[hash_key]; | 
					
						
							|  |  |  |     INIT_RWLOCK(p->DBRWLock); | 
					
						
							|  |  |  |     INT_KEYS[hash_key] = AbsDBProp(p); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return p; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return RepDBProp(NULL); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBProp FetchDBPropFromKey(Term twork, int flag, int new, | 
					
						
							|  |  |  |                                  char *error_mssg) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Atom At; | 
					
						
							|  |  |  |   Int arity; | 
					
						
							| 
									
										
										
										
											2004-02-12 12:37:12 +00:00
										 |  |  |   Term dbmod; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-15 00:01:43 +00:00
										 |  |  |   if (flag & MkCode) { | 
					
						
							|  |  |  |     if (IsVarTerm(twork)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |       Yap_Error(INSTANTIATION_ERROR, twork, error_mssg); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       return RepDBProp(NULL); | 
					
						
							| 
									
										
										
										
											2001-11-15 00:01:43 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (!IsApplTerm(twork)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       Yap_Error(SYSTEM_ERROR_INTERNAL, twork, "missing module"); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       return RepDBProp(NULL); | 
					
						
							| 
									
										
										
										
											2001-11-15 00:01:43 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       Functor f = FunctorOfTerm(twork); | 
					
						
							|  |  |  |       if (f != FunctorModule) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         Yap_Error(SYSTEM_ERROR_INTERNAL, twork, "missing module"); | 
					
						
							|  |  |  |         return RepDBProp(NULL); | 
					
						
							| 
									
										
										
										
											2001-11-15 00:01:43 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2004-02-12 12:37:12 +00:00
										 |  |  |       dbmod = ArgOfTerm(1, twork); | 
					
						
							|  |  |  |       if (IsVarTerm(dbmod)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         Yap_Error(INSTANTIATION_ERROR, twork, "var in module"); | 
					
						
							|  |  |  |         return RepDBProp(NIL); | 
					
						
							| 
									
										
										
										
											2001-11-15 00:01:43 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2004-02-12 12:37:12 +00:00
										 |  |  |       if (!IsAtomTerm(dbmod)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         Yap_Error(TYPE_ERROR_ATOM, twork, "not atom in module"); | 
					
						
							|  |  |  |         return RepDBProp(NIL); | 
					
						
							| 
									
										
										
										
											2001-11-15 00:01:43 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       twork = ArgOfTerm(2, twork); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2001-11-15 00:01:43 +00:00
										 |  |  |     dbmod = 0; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (IsVarTerm(twork)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR, twork, error_mssg); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return RepDBProp(NIL); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else if (IsAtomTerm(twork)) { | 
					
						
							|  |  |  |     arity = 0, At = AtomOfTerm(twork); | 
					
						
							|  |  |  |   } else if (IsIntegerTerm(twork)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return FetchIntDBPropFromKey(IntegerOfTerm(twork), flag, new, error_mssg); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else if (IsApplTerm(twork)) { | 
					
						
							|  |  |  |     Register Functor f = FunctorOfTerm(twork); | 
					
						
							|  |  |  |     if (IsExtensionFunctor(f)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |       Yap_Error(TYPE_ERROR_KEY, twork, error_mssg); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       return RepDBProp(NIL); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     At = NameOfFunctor(f); | 
					
						
							|  |  |  |     arity = ArityOfFunctor(f); | 
					
						
							|  |  |  |   } else if (IsPairTerm(twork)) { | 
					
						
							|  |  |  |     At = AtomDot; | 
					
						
							|  |  |  |     arity = 2; | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(TYPE_ERROR_KEY, twork, error_mssg); | 
					
						
							|  |  |  |     return RepDBProp(NIL); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (new) { | 
					
						
							|  |  |  |     DBProp p; | 
					
						
							|  |  |  |     AtomEntry *ae = RepAtom(At); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     WRITE_LOCK(ae->ARWLock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (EndOfPAEntr( | 
					
						
							|  |  |  |             p = RepDBProp(FindDBPropHavingLock(ae, flag, arity, dbmod)))) { | 
					
						
							|  |  |  |       /* create a new DBProp				 */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       int OLD_UPDATE_MODE = UPDATE_MODE; | 
					
						
							|  |  |  |       if (flag & MkCode) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         PredEntry *pp; | 
					
						
							|  |  |  |         pp = RepPredProp(Yap_GetPredPropHavingLock(At, arity, dbmod)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!EndOfPAEntr(pp)) { | 
					
						
							|  |  |  |           PELOCK(64, pp); | 
					
						
							|  |  |  |           if (pp->PredFlags & LogUpdatePredFlag) | 
					
						
							|  |  |  |             UPDATE_MODE = UPDATE_MODE_LOGICAL; | 
					
						
							|  |  |  |           UNLOCK(pp->PELock); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       p = (DBProp)Yap_AllocAtomSpace(sizeof(*p)); | 
					
						
							|  |  |  |       p->KindOfPE = DBProperty | flag; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       p->F0 = p->L0 = NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       UPDATE_MODE = OLD_UPDATE_MODE; | 
					
						
							|  |  |  |       p->ArityOfDB = arity; | 
					
						
							|  |  |  |       p->First = p->Last = NIL; | 
					
						
							| 
									
										
										
										
											2001-11-15 00:01:43 +00:00
										 |  |  |       p->ModuleOfDB = dbmod; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* This is NOT standard but is QUITE convenient */ | 
					
						
							|  |  |  |       INIT_RWLOCK(p->DBRWLock); | 
					
						
							|  |  |  |       if (arity == 0) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         p->FunctorOfDB = (Functor)At; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         p->FunctorOfDB = Yap_UnlockedMkFunctor(ae, arity); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:16:21 -07:00
										 |  |  |       AddPropToAtom(ae, (PropEntry *)p); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     WRITE_UNLOCK(ae->ARWLock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return p; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return RepDBProp(FindDBProp(RepAtom(At), flag, arity, dbmod)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int lu_nth_recorded(PredEntry *pe, Int Count USES_REGS) { | 
					
						
							| 
									
										
										
										
											2005-03-09 06:35:52 +00:00
										 |  |  |   LogUpdClause *cl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   XREGS[2] = MkVarTerm(); | 
					
						
							|  |  |  |   cl = Yap_NthClause(pe, Count); | 
					
						
							|  |  |  |   if (cl == NULL) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   TRAIL_CLREF(cl); /* So that fail will erase it */ | 
					
						
							| 
									
										
										
										
											2005-03-09 06:35:52 +00:00
										 |  |  |   INC_CLREF_COUNT(cl); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   if (!(cl->ClFlags & InUseMask)) { | 
					
						
							|  |  |  |     cl->ClFlags |= InUseMask; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     TRAIL_CLREF(cl); /* So that fail will erase it */ | 
					
						
							| 
									
										
										
										
											2005-03-09 06:35:52 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:30 +00:00
										 |  |  |   UNLOCK(pe->PELock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return Yap_unify(MkDBRefTerm((DBRef)cl), ARG4); | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Finds a term recorded under the key ARG1			 */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int nth_recorded(DBProp AtProp, Int Count USES_REGS) { | 
					
						
							|  |  |  |   Register DBRef ref; | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   READ_LOCK(AtProp->DBRWLock); | 
					
						
							| 
									
										
										
										
											2005-03-09 06:35:52 +00:00
										 |  |  |   ref = AtProp->First; | 
					
						
							|  |  |  |   Count--; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   while (ref != NULL && DEAD_REF(ref)) | 
					
						
							| 
									
										
										
										
											2005-03-09 06:35:52 +00:00
										 |  |  |     ref = NextDBRef(ref); | 
					
						
							|  |  |  |   if (ref == NULL) { | 
					
						
							|  |  |  |     READ_UNLOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   while (Count) { | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  |     Count--; | 
					
						
							| 
									
										
										
										
											2005-03-09 06:35:52 +00:00
										 |  |  |     ref = NextDBRef(ref); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     while (ref != NULL && DEAD_REF(ref)) | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  |       ref = NextDBRef(ref); | 
					
						
							|  |  |  |     if (ref == NULL) { | 
					
						
							|  |  |  |       READ_UNLOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  |   LOCK(ref->lock); | 
					
						
							|  |  |  |   READ_UNLOCK(AtProp->DBRWLock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   TRAIL_REF(ref); /* So that fail will erase it */ | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  |   INC_DBREF_COUNT(ref); | 
					
						
							|  |  |  |   UNLOCK(ref->lock); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   if (!(ref->Flags & InUseMask)) { | 
					
						
							|  |  |  |     ref->Flags |= InUseMask; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     TRAIL_REF(ref); /* So that fail will erase it */ | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   READ_UNLOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return Yap_unify(MkDBRefTerm(ref), ARG4); | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | Int Yap_db_nth_recorded(PredEntry *pe, Int Count USES_REGS) { | 
					
						
							|  |  |  |   DBProp AtProp; | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:30 +00:00
										 |  |  |   if (pe == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return lu_nth_recorded(pe, Count PASS_REGS); | 
					
						
							| 
									
										
										
										
											2005-03-09 06:35:52 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (EndOfPAEntr(AtProp = FetchDBPropFromKey(Deref(ARG1), 0, FALSE, | 
					
						
							|  |  |  |                                               "nth_instance/3"))) { | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:30 +00:00
										 |  |  |     UNLOCK(pe->PELock); | 
					
						
							| 
									
										
										
										
											2005-03-09 06:35:52 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:30 +00:00
										 |  |  |   return nth_recorded(AtProp, Count PASS_REGS); | 
					
						
							| 
									
										
										
										
											2002-12-13 20:00:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_db_key(USES_REGS1) { | 
					
						
							|  |  |  |   Register Term twork = Deref(ARG1); /* fetch the key */ | 
					
						
							|  |  |  |   DBProp AtProp; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (EndOfPAEntr(AtProp = FetchDBPropFromKey(twork, 0, TRUE, "db_key/3"))) { | 
					
						
							|  |  |  |     /* should never happen */ | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return Yap_unify(ARG2, MkIntegerTerm((Int)AtProp)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Finds a term recorded under the key ARG1			 */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int i_recorded(DBProp AtProp, Term t3 USES_REGS) { | 
					
						
							|  |  |  |   Term TermDB, TRef; | 
					
						
							|  |  |  |   Register DBRef ref; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term twork; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   READ_LOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |   ref = AtProp->First; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   while (ref != NULL && DEAD_REF(ref)) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     ref = NextDBRef(ref); | 
					
						
							|  |  |  |   READ_UNLOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |   if (ref == NULL) { | 
					
						
							|  |  |  |     cut_fail(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   twork = Deref(ARG2); /* now working with ARG2 */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (IsVarTerm(twork)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     EXTRA_CBACK_ARG(3, 2) = MkIntegerTerm(0); | 
					
						
							|  |  |  |     EXTRA_CBACK_ARG(3, 3) = MkIntegerTerm(0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     B->cp_h = HR; | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     while ((TermDB = GetDBTermFromDBEntry(ref PASS_REGS)) == (CELL)0) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* make sure the garbage collector sees what we want it to see! */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       EXTRA_CBACK_ARG(3, 1) = (CELL)ref; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* oops, we are in trouble, not enough stack space */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) { | 
					
						
							|  |  |  |         LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |         if (!Yap_growglobal(NULL)) { | 
					
						
							|  |  |  |           Yap_Error(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil, | 
					
						
							|  |  |  |                     LOCAL_ErrorMessage); | 
					
						
							|  |  |  |           return FALSE; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-09-17 19:34:53 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |         if (!Yap_gcl(LOCAL_Error_Size, 3, ENV, CP)) { | 
					
						
							|  |  |  |           Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							|  |  |  |           return FALSE; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2002-10-10 05:58:49 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       twork = Deref(ARG2); | 
					
						
							|  |  |  |       t3 = Deref(ARG3); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     if (!Yap_unify(twork, TermDB)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       cut_fail(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else if (IsAtomOrIntTerm(twork)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     EXTRA_CBACK_ARG(3, 2) = MkIntegerTerm(0); | 
					
						
							|  |  |  |     EXTRA_CBACK_ARG(3, 3) = MkIntegerTerm((Int)twork); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     B->cp_h = HR; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     READ_LOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |     do { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       if (((twork == ref->DBT.Entry) || IsVarTerm(ref->DBT.Entry)) && | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |           !DEAD_REF(ref)) | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       ref = NextDBRef(ref); | 
					
						
							|  |  |  |       if (ref == NIL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         READ_UNLOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |         cut_fail(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } while (TRUE); | 
					
						
							|  |  |  |     READ_UNLOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     CELL key; | 
					
						
							|  |  |  |     CELL mask = EvalMasks(twork, &key); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     B->cp_h = HR; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     READ_LOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       while ((mask & ref->Key) != (key & ref->Mask) && !DEAD_REF(ref)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         ref = NextDBRef(ref); | 
					
						
							|  |  |  |         if (ref == NULL) { | 
					
						
							|  |  |  |           READ_UNLOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |           cut_fail(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |       if ((TermDB = GetDBTermFromDBEntry(ref PASS_REGS)) != (CELL)0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         if (Yap_unify(TermDB, ARG2)) { | 
					
						
							|  |  |  |           /* success */ | 
					
						
							|  |  |  |           EXTRA_CBACK_ARG(3, 2) = MkIntegerTerm(((Int)mask)); | 
					
						
							|  |  |  |           EXTRA_CBACK_ARG(3, 3) = MkIntegerTerm(((Int)key)); | 
					
						
							|  |  |  |           B->cp_h = HR; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           while ((ref = NextDBRef(ref)) != NULL && DEAD_REF(ref)) | 
					
						
							|  |  |  |             ; | 
					
						
							|  |  |  |           if (ref == NULL) { | 
					
						
							|  |  |  |             READ_UNLOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |             cut_fail(); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         /* make sure the garbage collector sees what we want it to see! */ | 
					
						
							|  |  |  |         EXTRA_CBACK_ARG(3, 1) = (CELL)ref; | 
					
						
							|  |  |  |         READ_UNLOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |         EXTRA_CBACK_ARG(3, 2) = MkIntegerTerm(((Int)mask)); | 
					
						
							|  |  |  |         EXTRA_CBACK_ARG(3, 3) = MkIntegerTerm(((Int)key)); | 
					
						
							|  |  |  |         /* oops, we are in trouble, not enough stack space */ | 
					
						
							|  |  |  |         if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) { | 
					
						
							|  |  |  |           LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |           if (!Yap_growglobal(NULL)) { | 
					
						
							|  |  |  |             Yap_Error(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil, | 
					
						
							|  |  |  |                       LOCAL_ErrorMessage); | 
					
						
							|  |  |  |             return FALSE; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |           if (!Yap_gcl(LOCAL_Error_Size, 3, ENV, CP)) { | 
					
						
							|  |  |  |             Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							|  |  |  |             return FALSE; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         READ_LOCK(AtProp->DBRWLock); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } while (TRUE); | 
					
						
							|  |  |  |     READ_UNLOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   EXTRA_CBACK_ARG(3, 1) = (CELL)ref; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   /* This should be after any non-tagged terms, because the routines in grow.c
 | 
					
						
							|  |  |  |      go from upper to lower addresses */ | 
					
						
							|  |  |  |   TRef = MkDBRefTerm(ref); | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   LOCK(ref->lock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   TRAIL_REF(ref); /* So that fail will erase it */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   INC_DBREF_COUNT(ref); | 
					
						
							|  |  |  |   UNLOCK(ref->lock); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   if (!(ref->Flags & InUseMask)) { | 
					
						
							|  |  |  |     ref->Flags |= InUseMask; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     TRAIL_REF(ref); /* So that fail will erase it */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |   return (Yap_unify(ARG3, TRef)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int c_recorded(int flags USES_REGS) { | 
					
						
							|  |  |  |   Term TermDB, TRef; | 
					
						
							|  |  |  |   Register DBRef ref, ref0; | 
					
						
							|  |  |  |   CELL *PreviousHeap = HR; | 
					
						
							|  |  |  |   CELL mask, key; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term t1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   t1 = EXTRA_CBACK_ARG(3, 1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   ref0 = (DBRef)t1; | 
					
						
							|  |  |  |   READ_LOCK(ref0->Parent->DBRWLock); | 
					
						
							|  |  |  |   ref = NextDBRef(ref0); | 
					
						
							|  |  |  |   if (ref == NIL) { | 
					
						
							|  |  |  |     if (ref0->Flags & ErasedMask) { | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |       ref = ref0; | 
					
						
							|  |  |  |       while ((ref = ref->n) != NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         if (!(ref->Flags & ErasedMask)) | 
					
						
							|  |  |  |           break; | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* we have used the DB entry, so we can remove it now, although
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |          first we have to make sure noone is pointing to it */ | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |       if (ref == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         READ_UNLOCK(ref0->Parent->DBRWLock); | 
					
						
							|  |  |  |         cut_fail(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       READ_UNLOCK(ref0->Parent->DBRWLock); | 
					
						
							|  |  |  |       cut_fail(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Term ttmp = EXTRA_CBACK_ARG(3, 2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (IsLongIntTerm(ttmp)) | 
					
						
							|  |  |  |       mask = (CELL)LongIntOfTerm(ttmp); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       mask = (CELL)IntOfTerm(ttmp); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Term ttmp = EXTRA_CBACK_ARG(3, 3); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (IsLongIntTerm(ttmp)) | 
					
						
							|  |  |  |       key = (CELL)LongIntOfTerm(ttmp); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       key = (CELL)IntOfTerm(ttmp); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   while (ref != NIL && DEAD_REF(ref)) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     ref = NextDBRef(ref); | 
					
						
							|  |  |  |   if (ref == NIL) { | 
					
						
							|  |  |  |     READ_UNLOCK(ref0->Parent->DBRWLock); | 
					
						
							|  |  |  |     cut_fail(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (mask == 0 && key == 0) { /* ARG2 is a variable */ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     while ((TermDB = GetDBTermFromDBEntry(ref PASS_REGS)) == (CELL)0) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* make sure the garbage collector sees what we want it to see! */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       EXTRA_CBACK_ARG(3, 1) = (CELL)ref; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* oops, we are in trouble, not enough stack space */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) { | 
					
						
							|  |  |  |         LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |         if (!Yap_growglobal(NULL)) { | 
					
						
							|  |  |  |           Yap_Error(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil, | 
					
						
							|  |  |  |                     LOCAL_ErrorMessage); | 
					
						
							|  |  |  |           return FALSE; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-09-17 19:34:53 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |         if (!Yap_gcl(LOCAL_Error_Size, 3, ENV, CP)) { | 
					
						
							|  |  |  |           Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							|  |  |  |           return FALSE; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2002-10-10 05:58:49 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       PreviousHeap = HR; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_unify(ARG2, TermDB); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   } else if (mask == 0) { /* ARG2 is a constant */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     do { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       if (((key == Unsigned(ref->DBT.Entry)) || (ref->Flags & DBVar)) && | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |           !DEAD_REF(ref)) | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       ref = NextDBRef(ref); | 
					
						
							|  |  |  |     } while (ref != NIL); | 
					
						
							|  |  |  |     if (ref == NIL) { | 
					
						
							|  |  |  |       READ_UNLOCK(ref0->Parent->DBRWLock); | 
					
						
							|  |  |  |       cut_fail(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     do { /* ARG2 is a structure */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       HR = PreviousHeap; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       while ((mask & ref->Key) != (key & ref->Mask)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         while ((ref = NextDBRef(ref)) != NIL && DEAD_REF(ref)) | 
					
						
							|  |  |  |           ; | 
					
						
							|  |  |  |         if (ref == NIL) { | 
					
						
							|  |  |  |           READ_UNLOCK(ref0->Parent->DBRWLock); | 
					
						
							|  |  |  |           cut_fail(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |       while ((TermDB = GetDBTermFromDBEntry(ref PASS_REGS)) == (CELL)0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         /* make sure the garbage collector sees what we want it to see! */ | 
					
						
							|  |  |  |         EXTRA_CBACK_ARG(3, 1) = (CELL)ref; | 
					
						
							|  |  |  |         /* oops, we are in trouble, not enough stack space */ | 
					
						
							|  |  |  |         if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) { | 
					
						
							|  |  |  |           LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |           if (!Yap_growglobal(NULL)) { | 
					
						
							|  |  |  |             Yap_Error(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil, | 
					
						
							|  |  |  |                       LOCAL_ErrorMessage); | 
					
						
							|  |  |  |             return FALSE; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |           if (!Yap_gcl(LOCAL_Error_Size, 3, ENV, CP)) { | 
					
						
							|  |  |  |             Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							|  |  |  |             return FALSE; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         LOCAL_Error_Size = 0; | 
					
						
							|  |  |  |         PreviousHeap = HR; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |       if (Yap_unify(ARG2, TermDB)) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         break; | 
					
						
							|  |  |  |       while ((ref = NextDBRef(ref)) != NIL && DEAD_REF(ref)) | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       if (ref == NIL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         READ_UNLOCK(ref0->Parent->DBRWLock); | 
					
						
							|  |  |  |         cut_fail(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } while (1); | 
					
						
							|  |  |  |   READ_UNLOCK(ref0->Parent->DBRWLock); | 
					
						
							|  |  |  |   TRef = MkDBRefTerm(ref); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   EXTRA_CBACK_ARG(3, 1) = (CELL)ref; | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   LOCK(ref->lock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   TRAIL_REF(ref); /* So that fail will erase it */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   INC_DBREF_COUNT(ref); | 
					
						
							|  |  |  |   UNLOCK(ref->lock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (!(ref->Flags & InUseMask)) { | 
					
						
							|  |  |  |     ref->Flags |= InUseMask; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     TRAIL_REF(ref); /* So that fail will erase it */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |   return (Yap_unify(ARG3, TRef)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * The arguments for this 4 functions are the flags for terms which should be | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |  * skipped | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int lu_recorded(PredEntry *pe USES_REGS) { | 
					
						
							| 
									
										
										
										
											2003-09-24 14:51:42 +00:00
										 |  |  |   op_numbers opc = Yap_op_from_opcode(P->opc); | 
					
						
							| 
									
										
										
										
											2004-02-26 13:37:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  | #if defined(YAPOR) || defined(THREADS)
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   PELOCK(66, pe); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   PP = pe; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-10-12 22:02:51 +01:00
										 |  |  |   if (opc == _procceed) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     P = pe->CodeOfPred; | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2008-08-28 04:43:00 +01:00
										 |  |  |     if (P->opc != Yap_opcode(_execute_cpred)) { | 
					
						
							|  |  |  |       CP = P; | 
					
						
							|  |  |  |       ENV = YENV; | 
					
						
							|  |  |  |       YENV = ASP; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       YENV[E_CB] = (CELL)B; | 
					
						
							| 
									
										
										
										
											2008-08-28 04:43:00 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     P = pe->CodeOfPred; | 
					
						
							| 
									
										
										
										
											2009-04-16 12:55:47 -05:00
										 |  |  | #if defined(YAPOR) || defined(THREADS)
 | 
					
						
							|  |  |  |     /* avoid holding a lock if we don't have anything in the database */ | 
					
						
							|  |  |  |     if (P == FAILCODE) { | 
					
						
							|  |  |  |       UNLOCK(pe->PELock); | 
					
						
							|  |  |  |       PP = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   if (pe->PredFlags & ProfiledPredFlag) { | 
					
						
							| 
									
										
										
										
											2015-04-21 16:09:43 -06:00
										 |  |  |     LOCK(pe->StatisticsForPred->lock); | 
					
						
							|  |  |  |     pe->StatisticsForPred->NOfEntries++; | 
					
						
							|  |  |  |     UNLOCK(pe->StatisticsForPred->lock); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* recorded(+Functor,+Term,-Ref) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int in_rded_with_key(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   DBProp AtProp = (DBProp)IntegerOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return (i_recorded(AtProp, Deref(ARG3) PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* recorded(+Functor,+Term,-Ref) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_recorded(USES_REGS1) { | 
					
						
							|  |  |  |   DBProp AtProp; | 
					
						
							|  |  |  |   Register Term twork = Deref(ARG1); /* initially working with
 | 
					
						
							|  |  |  |                                       * ARG1 */ | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |   Term t3 = Deref(ARG3); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   PredEntry *pe; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |   if (!IsVarTerm(t3)) { | 
					
						
							| 
									
										
										
										
											2004-02-09 14:19:05 +00:00
										 |  |  |     DBRef ref = DBRefOfTerm(t3); | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |     if (!IsDBRefTerm(t3)) { | 
					
						
							| 
									
										
										
										
											2004-02-13 18:39:29 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2004-02-09 14:19:05 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       ref = DBRefOfTerm(t3); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ref = DBRefOfTerm(t3); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (ref == NULL) | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2004-02-09 14:19:05 +00:00
										 |  |  |     if (DEAD_REF(ref)) { | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (ref->Flags & LogUpdMask) { | 
					
						
							|  |  |  |       LogUpdClause *cl = (LogUpdClause *)ref; | 
					
						
							| 
									
										
										
										
											2005-04-10 04:31:12 +00:00
										 |  |  |       PredEntry *ap = cl->ClPred; | 
					
						
							|  |  |  |       op_numbers opc = Yap_op_from_opcode(P->opc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!Yap_unify(GetDBLUKey(ap), ARG1)) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         return FALSE; | 
					
						
							| 
									
										
										
										
											2005-04-10 04:31:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-12 22:02:51 +01:00
										 |  |  |       if (opc == _procceed) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         P = cl->ClCode; | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         CP = P; | 
					
						
							| 
									
										
										
										
											2008-01-28 18:21:26 +00:00
										 |  |  | #if defined(YAPOR) || defined(THREADS)
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         PP = cl->ClPred; | 
					
						
							| 
									
										
										
										
											2008-01-28 18:21:26 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         P = cl->ClCode; | 
					
						
							|  |  |  |         ENV = YENV; | 
					
						
							|  |  |  |         YENV = ASP; | 
					
						
							|  |  |  |         YENV[E_CB] = (CELL)B; | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2005-04-10 04:31:12 +00:00
										 |  |  |       return TRUE; | 
					
						
							| 
									
										
										
										
											2004-02-09 14:19:05 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |       Term TermDB; | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |       while ((TermDB = GetDBTermFromDBEntry(ref PASS_REGS)) == (CELL)0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         /* oops, we are in trouble, not enough stack space */ | 
					
						
							|  |  |  |         if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) { | 
					
						
							|  |  |  |           LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |           if (!Yap_growglobal(NULL)) { | 
					
						
							|  |  |  |             Yap_Error(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil, | 
					
						
							|  |  |  |                       LOCAL_ErrorMessage); | 
					
						
							|  |  |  |             return FALSE; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |           if (!Yap_gcl(LOCAL_Error_Size, 3, ENV, gc_P(P, CP))) { | 
					
						
							|  |  |  |             Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							|  |  |  |             return FALSE; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (!Yap_unify(ARG2, TermDB) || !UnifyDBKey(ref, 0, ARG1)) { | 
					
						
							|  |  |  |         return FALSE; | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         return TRUE; | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if ((pe = find_lu_entry(twork)) != NULL) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     return lu_recorded(pe PASS_REGS); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (EndOfPAEntr(AtProp = FetchDBPropFromKey(twork, 0, FALSE, "recorded/3"))) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   ARG1 = MkIntegerTerm((Int)AtProp); | 
					
						
							|  |  |  |   P = PredRecordedWithKey->CodeOfPred; | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   return (i_recorded(AtProp, t3 PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int co_rded(USES_REGS1) { return (c_recorded(0 PASS_REGS)); } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* '$recordedp'(+Functor,+Term,-Ref) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int in_rdedp(USES_REGS1) { | 
					
						
							|  |  |  |   DBProp AtProp; | 
					
						
							|  |  |  |   register choiceptr b0 = B; | 
					
						
							|  |  |  |   Register Term twork = Deref(ARG1); /* initially working with
 | 
					
						
							|  |  |  |                                       * ARG1 */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |   Term t3 = Deref(ARG3); | 
					
						
							|  |  |  |   if (!IsVarTerm(t3)) { | 
					
						
							|  |  |  |     if (!IsDBRefTerm(t3)) { | 
					
						
							|  |  |  |       cut_fail(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       DBRef ref = DBRefOfTerm(t3); | 
					
						
							|  |  |  |       LOCK(ref->lock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (ref == NULL || DEAD_REF(ref) || | 
					
						
							|  |  |  |           !Yap_unify(ARG2, GetDBTermFromDBEntry(ref PASS_REGS)) || | 
					
						
							|  |  |  |           !UnifyDBKey(ref, CodeDBBit, ARG1)) { | 
					
						
							|  |  |  |         UNLOCK(ref->lock); | 
					
						
							|  |  |  |         cut_fail(); | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         UNLOCK(ref->lock); | 
					
						
							|  |  |  |         cut_succeed(); | 
					
						
							| 
									
										
										
										
											2002-12-10 00:22:01 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (EndOfPAEntr(AtProp = | 
					
						
							|  |  |  |                       FetchDBPropFromKey(twork, MkCode, FALSE, "recorded/3"))) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (b0 == B) | 
					
						
							|  |  |  |       cut_fail(); | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return (i_recorded(AtProp, t3 PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int co_rdedp(USES_REGS1) { return (c_recorded(MkCode PASS_REGS)); } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* '$some_recordedp'(Functor)				 */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_somercdedp(USES_REGS1) { | 
					
						
							|  |  |  |   Register DBRef ref; | 
					
						
							|  |  |  |   DBProp AtProp; | 
					
						
							|  |  |  |   Register Term twork = Deref(ARG1); /* initially working with
 | 
					
						
							|  |  |  |                                               * ARG1 */ | 
					
						
							|  |  |  |   if (EndOfPAEntr(AtProp = FetchDBPropFromKey(twork, MkCode, FALSE, | 
					
						
							|  |  |  |                                               "some_recorded/3"))) { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   READ_LOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |   ref = FrstDBRef(AtProp); | 
					
						
							|  |  |  |   while (ref != NIL && (ref->Flags & (DBNoCode | ErasedMask))) | 
					
						
							|  |  |  |     ref = NextDBRef(ref); | 
					
						
							|  |  |  |   READ_UNLOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |   if (ref == NIL) | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     return (TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Finds the first instance recorded under key ARG1			 */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_first_instance(USES_REGS1) { | 
					
						
							|  |  |  |   Term TRef; | 
					
						
							|  |  |  |   Register DBRef ref; | 
					
						
							|  |  |  |   DBProp AtProp; | 
					
						
							|  |  |  |   Register Term twork = Deref(ARG1); /* initially working with
 | 
					
						
							|  |  |  |                                       * ARG1 */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term TermDB; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ARG3 = Deref(ARG3); | 
					
						
							|  |  |  |   if (!IsVarTerm(ARG3)) { | 
					
						
							|  |  |  |     cut_fail(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (EndOfPAEntr( | 
					
						
							|  |  |  |           AtProp = FetchDBPropFromKey(twork, 0, FALSE, "first_instance/3"))) { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   READ_LOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |   ref = AtProp->First; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   while (ref != NIL && (ref->Flags & (DBCode | ErasedMask))) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     ref = NextDBRef(ref); | 
					
						
							|  |  |  |   READ_UNLOCK(AtProp->DBRWLock); | 
					
						
							|  |  |  |   if (ref == NIL) { | 
					
						
							|  |  |  |     cut_fail(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   TRef = MkDBRefTerm(ref); | 
					
						
							|  |  |  |   /* we have a pointer to the term available */ | 
					
						
							|  |  |  |   LOCK(ref->lock); | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   TRAIL_REF(ref); /* So that fail will erase it */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   INC_DBREF_COUNT(ref); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (!(ref->Flags & InUseMask)) { | 
					
						
							|  |  |  |     ref->Flags |= InUseMask; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     TRAIL_REF(ref); /* So that fail will erase it */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  |   UNLOCK(ref->lock); | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   while ((TermDB = GetDBTermFromDBEntry(ref PASS_REGS)) == (CELL)0) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     /* oops, we are in trouble, not enough stack space */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							| 
									
										
										
										
											2004-09-17 19:34:53 +00:00
										 |  |  |       if (!Yap_growglobal(NULL)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         Yap_Error(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil, | 
					
						
							|  |  |  |                   LOCAL_ErrorMessage); | 
					
						
							|  |  |  |         return FALSE; | 
					
						
							| 
									
										
										
										
											2004-09-17 19:34:53 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (!Yap_gcl(LOCAL_Error_Size, 3, ENV, gc_P(P, CP))) { | 
					
						
							|  |  |  |         Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							|  |  |  |         return FALSE; | 
					
						
							| 
									
										
										
										
											2004-09-17 19:34:53 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2002-10-10 05:58:49 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (IsVarTerm(TermDB)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_unify(TermDB, ARG2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return Yap_unify(ARG2, TermDB); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return Yap_unify(ARG3, TRef); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static UInt index_sz(LogUpdIndex *x) { | 
					
						
							| 
									
										
										
										
											2004-03-05 15:26:33 +00:00
										 |  |  |   UInt sz = x->ClSize; | 
					
						
							| 
									
										
										
										
											2006-10-10 20:21:42 +00:00
										 |  |  |   yamop *start = x->ClCode; | 
					
						
							|  |  |  |   op_numbers op = Yap_op_from_opcode(start->opc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* add try-retry-trust children */ | 
					
						
							|  |  |  |   while (op == _jump_if_nonvar) { | 
					
						
							|  |  |  |     start = NEXTOP(start, xll); | 
					
						
							|  |  |  |     op = Yap_op_from_opcode(start->opc); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (op == _enter_lu_pred) { | 
					
						
							|  |  |  |     PredEntry *ap = x->ClPred; | 
					
						
							|  |  |  |     OPCODE endop, op1; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     UInt count = 0, dead = 0; | 
					
						
							| 
									
										
										
										
											2006-10-10 20:21:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (ap->PredFlags & CountPredFlag) | 
					
						
							|  |  |  |       endop = Yap_opcode(_count_trust_logical); | 
					
						
							|  |  |  |     else if (ap->PredFlags & ProfiledPredFlag) | 
					
						
							|  |  |  |       endop = Yap_opcode(_profiled_trust_logical); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       endop = Yap_opcode(_trust_logical); | 
					
						
							| 
									
										
										
										
											2014-05-30 01:06:09 +01:00
										 |  |  |     start = start->y_u.Illss.l1; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (start->y_u.Illss.s) | 
					
						
							|  |  |  |       do { | 
					
						
							|  |  |  |         sz += (UInt)NEXTOP((yamop *)NULL, OtaLl); | 
					
						
							|  |  |  |         op1 = start->opc; | 
					
						
							|  |  |  |         count++; | 
					
						
							|  |  |  |         if (start->y_u.OtaLl.d->ClFlags & ErasedMask) | 
					
						
							|  |  |  |           dead++; | 
					
						
							|  |  |  |         start = start->y_u.OtaLl.n; | 
					
						
							|  |  |  |       } while (op1 != endop); | 
					
						
							| 
									
										
										
										
											2006-10-10 20:21:42 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-10-28 01:16:03 +00:00
										 |  |  |   x = x->ChildIndex; | 
					
						
							|  |  |  |   while (x != NULL) { | 
					
						
							|  |  |  |     sz += index_sz(x); | 
					
						
							|  |  |  |     x = x->SiblingIndex; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return sz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int lu_statistics(PredEntry *pe USES_REGS) { | 
					
						
							| 
									
										
										
										
											2013-01-23 09:58:02 +00:00
										 |  |  |   UInt sz = sizeof(PredEntry), cls = 0, isz = 0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-10-28 01:16:03 +00:00
										 |  |  |   /* count number of clauses and size */ | 
					
						
							|  |  |  |   LogUpdClause *x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (pe->cs.p_code.FirstClause == NULL) { | 
					
						
							|  |  |  |     cls = 0; | 
					
						
							|  |  |  |     sz = 0; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     x = ClauseCodeToLogUpdClause(pe->cs.p_code.FirstClause); | 
					
						
							|  |  |  |     while (x != NULL) { | 
					
						
							|  |  |  |       cls++; | 
					
						
							| 
									
										
										
										
											2004-03-05 15:26:33 +00:00
										 |  |  |       sz += x->ClSize; | 
					
						
							| 
									
										
										
										
											2003-10-28 01:16:03 +00:00
										 |  |  |       x = x->ClNext; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-01-23 09:58:02 +00:00
										 |  |  |   isz = 0; | 
					
						
							| 
									
										
										
										
											2003-10-28 01:16:03 +00:00
										 |  |  |   if (pe->PredFlags & IndexedPredFlag) { | 
					
						
							| 
									
										
										
										
											2013-01-23 09:58:02 +00:00
										 |  |  |     /* expand clause blocks */ | 
					
						
							|  |  |  |     yamop *ep = ExpandClausesFirst; | 
					
						
							|  |  |  |     while (ep) { | 
					
						
							| 
									
										
										
										
											2014-05-30 01:06:09 +01:00
										 |  |  |       if (ep->y_u.sssllp.p == pe) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         isz += (UInt)NEXTOP((yamop *)NULL, sssllp) + | 
					
						
							|  |  |  |                ep->y_u.sssllp.s1 * sizeof(yamop *); | 
					
						
							| 
									
										
										
										
											2014-05-30 01:06:09 +01:00
										 |  |  |       ep = ep->y_u.sssllp.snext; | 
					
						
							| 
									
										
										
										
											2013-01-23 09:58:02 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     isz += index_sz(ClauseCodeToLogUpdIndex(pe->cs.p_code.TrueCodeOfPred)); | 
					
						
							| 
									
										
										
										
											2003-10-28 01:16:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return Yap_unify(ARG2, MkIntegerTerm(cls)) && | 
					
						
							|  |  |  |          Yap_unify(ARG3, MkIntegerTerm(sz)) && | 
					
						
							|  |  |  |          Yap_unify(ARG4, MkIntegerTerm(isz)); | 
					
						
							| 
									
										
										
										
											2003-10-28 01:16:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | /** @pred  key_statistics(+ _K_,- _Entries_,- _Size_,- _IndexSize_)
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-10-28 01:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | Returns several statistics for a key  _K_. Currently, it says how | 
					
						
							|  |  |  | many entries we have for that key,  _Entries_, what is the | 
					
						
							|  |  |  | total size spent on entries,  _Size_, and what is the amount of | 
					
						
							|  |  |  | space spent in indices. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_key_statistics(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2002-12-10 14:36:22 +00:00
										 |  |  |   Register DBProp p; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Register DBRef x; | 
					
						
							| 
									
										
										
										
											2002-12-10 14:36:22 +00:00
										 |  |  |   UInt sz = 0, cls = 0; | 
					
						
							| 
									
										
										
										
											2003-10-28 01:16:03 +00:00
										 |  |  |   Term twork = Deref(ARG1); | 
					
						
							|  |  |  |   PredEntry *pe; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((pe = find_lu_entry(twork)) != NULL) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     return lu_statistics(pe PASS_REGS); | 
					
						
							| 
									
										
										
										
											2003-10-28 01:16:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2006-10-10 20:21:42 +00:00
										 |  |  |   if (EndOfPAEntr(p = FetchDBPropFromKey(twork, 0, TRUE, "key_statistics/4"))) { | 
					
						
							| 
									
										
										
										
											2002-12-10 14:36:22 +00:00
										 |  |  |     /* This is not a key property */ | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2002-12-10 14:36:22 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   /* count number of clauses and size */ | 
					
						
							|  |  |  |   x = p->First; | 
					
						
							|  |  |  |   while (x != NULL) { | 
					
						
							|  |  |  |     cls++; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     sz += sizeof(DBStruct) + sizeof(CELL) * x->DBT.NOfCells; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |     if (x->Code) { | 
					
						
							|  |  |  |       DynamicClause *cl = ClauseCodeToDynamicClause(x->Code); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       sz += cl->ClSize; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2002-12-10 14:36:22 +00:00
										 |  |  |     x = NextDBRef(x); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return Yap_unify(ARG2, MkIntegerTerm(cls)) && | 
					
						
							|  |  |  |          Yap_unify(ARG3, MkIntegerTerm(sz)) && Yap_unify(ARG4, MkIntTerm(0)); | 
					
						
							| 
									
										
										
										
											2002-12-10 14:36:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_lu_statistics(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2006-10-10 20:21:42 +00:00
										 |  |  |   Term t = Deref(ARG1); | 
					
						
							|  |  |  |   Term mod = Deref(ARG5); | 
					
						
							|  |  |  |   PredEntry *pe; | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							|  |  |  |   } else if (IsAtomTerm(t)) { | 
					
						
							|  |  |  |     Atom at = AtomOfTerm(t); | 
					
						
							|  |  |  |     pe = RepPredProp(Yap_GetPredPropByAtom(at, mod)); | 
					
						
							| 
									
										
										
										
											2008-09-15 04:30:09 +01:00
										 |  |  |   } else if (IsIntegerTerm(t) && mod == IDB_MODULE) { | 
					
						
							|  |  |  |     pe = find_lu_int_key(IntegerOfTerm(t)); | 
					
						
							| 
									
										
										
										
											2006-10-10 20:21:42 +00:00
										 |  |  |   } else if (IsApplTerm(t)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Functor fun = FunctorOfTerm(t); | 
					
						
							| 
									
										
										
										
											2006-10-10 20:21:42 +00:00
										 |  |  |     pe = RepPredProp(Yap_GetPredPropByFunc(fun, mod)); | 
					
						
							|  |  |  |   } else | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   if (pe == NIL) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   if (!(pe->PredFlags & LogUpdatePredFlag)) { | 
					
						
							|  |  |  |     /* should use '$recordedp' in this case */ | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   return lu_statistics(pe PASS_REGS); | 
					
						
							| 
									
										
										
										
											2006-10-10 20:21:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_total_erased(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   UInt sz = 0, cls = 0; | 
					
						
							|  |  |  |   UInt isz = 0, icls = 0; | 
					
						
							|  |  |  |   LogUpdClause *cl = DBErasedList; | 
					
						
							|  |  |  |   LogUpdIndex *icl = DBErasedIList; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* only for log upds */ | 
					
						
							|  |  |  |   while (cl) { | 
					
						
							|  |  |  |     cls++; | 
					
						
							| 
									
										
										
										
											2004-03-05 15:26:33 +00:00
										 |  |  |     sz += cl->ClSize; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |     cl = cl->ClNext; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   while (icl) { | 
					
						
							|  |  |  |     icls++; | 
					
						
							| 
									
										
										
										
											2004-03-05 15:26:33 +00:00
										 |  |  |     isz += icl->ClSize; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |     icl = icl->SiblingIndex; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return Yap_unify(ARG1, MkIntegerTerm(cls)) && | 
					
						
							|  |  |  |          Yap_unify(ARG2, MkIntegerTerm(sz)) && | 
					
						
							|  |  |  |          Yap_unify(ARG3, MkIntegerTerm(icls)) && | 
					
						
							|  |  |  |          Yap_unify(ARG4, MkIntegerTerm(isz)); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int lu_erased_statistics(PredEntry *pe USES_REGS) { | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   UInt sz = 0, cls = 0; | 
					
						
							|  |  |  |   UInt isz = 0, icls = 0; | 
					
						
							|  |  |  |   LogUpdClause *cl = DBErasedList; | 
					
						
							|  |  |  |   LogUpdIndex *icl = DBErasedIList; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while (cl) { | 
					
						
							|  |  |  |     if (cl->ClPred == pe) { | 
					
						
							|  |  |  |       cls++; | 
					
						
							| 
									
										
										
										
											2004-03-05 15:26:33 +00:00
										 |  |  |       sz += cl->ClSize; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     cl = cl->ClNext; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   while (icl) { | 
					
						
							| 
									
										
										
										
											2005-12-17 03:25:39 +00:00
										 |  |  |     if (pe == icl->ClPred) { | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       icls++; | 
					
						
							| 
									
										
										
										
											2005-12-17 03:25:39 +00:00
										 |  |  |       isz += icl->ClSize; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     icl = icl->SiblingIndex; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return Yap_unify(ARG2, MkIntegerTerm(cls)) && | 
					
						
							|  |  |  |          Yap_unify(ARG3, MkIntegerTerm(sz)) && | 
					
						
							|  |  |  |          Yap_unify(ARG4, MkIntegerTerm(icls)) && | 
					
						
							|  |  |  |          Yap_unify(ARG5, MkIntegerTerm(isz)); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_key_erased_statistics(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2006-10-10 20:21:42 +00:00
										 |  |  |   Term twork = Deref(ARG1); | 
					
						
							|  |  |  |   PredEntry *pe; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* only for log upds */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if ((pe = find_lu_entry(twork)) == NULL) | 
					
						
							| 
									
										
										
										
											2006-10-10 20:21:42 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   return lu_erased_statistics(pe PASS_REGS); | 
					
						
							| 
									
										
										
										
											2006-10-10 20:21:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_heap_space_info(USES_REGS1) { | 
					
						
							|  |  |  |   return Yap_unify(ARG1, MkIntegerTerm(HeapUsed)) && | 
					
						
							|  |  |  |          Yap_unify(ARG2, MkIntegerTerm(HeapMax - HeapUsed)) && | 
					
						
							|  |  |  |          Yap_unify(ARG3, MkIntegerTerm(Yap_expand_clauses_sz)); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This is called when we are erasing a data base clause, because we may have | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |  * pending references | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void ErasePendingRefs(DBTerm *entryref USES_REGS) { | 
					
						
							|  |  |  |   DBRef *cp; | 
					
						
							|  |  |  |   DBRef ref; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   cp = entryref->DBRefs; | 
					
						
							|  |  |  |   if (entryref->DBRefs == NULL) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   while ((ref = *--cp) != NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if ((ref->Flags & DBClMask) && (--(ref->NOfRefsTo) == 0) && | 
					
						
							|  |  |  |         (ref->Flags & ErasedMask)) | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |       ErDBE(ref PASS_REGS); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | inline static void RemoveDBEntry(DBRef entryref USES_REGS) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   ErasePendingRefs(&(entryref->DBT)PASS_REGS); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   /* We may be backtracking back to a deleted entry. If we just remove
 | 
					
						
							|  |  |  |      the space then the info on the entry may be corrupt.  */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if ((B->cp_ap == RETRY_C_RECORDED_K_CODE || | 
					
						
							|  |  |  |        B->cp_ap == RETRY_C_RECORDEDP_CODE) && | 
					
						
							|  |  |  |       EXTRA_CBACK_ARG(3, 1) == (CELL)entryref) { | 
					
						
							|  |  |  | /* make it clear the entry has been released */ | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     DEC_DBREF_COUNT(entryref); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     entryref->Flags &= ~InUseMask; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     DBErasedMarker->Next = NULL; | 
					
						
							|  |  |  |     DBErasedMarker->Parent = entryref->Parent; | 
					
						
							|  |  |  |     DBErasedMarker->n = entryref->n; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     EXTRA_CBACK_ARG(3, 1) = (CELL)DBErasedMarker; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (entryref->p != NULL) | 
					
						
							|  |  |  |     entryref->p->n = entryref->n; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     entryref->Parent->F0 = entryref->n; | 
					
						
							|  |  |  |   if (entryref->n != NULL) | 
					
						
							|  |  |  |     entryref->n->p = entryref->p; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     entryref->Parent->L0 = entryref->p; | 
					
						
							| 
									
										
										
										
											2006-11-06 18:35:05 +00:00
										 |  |  |   /*  Yap_LUClauseSpace -= entryref->Size; */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   FreeDBSpace((char *)entryref); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static yamop *find_next_clause(DBRef ref0 USES_REGS) { | 
					
						
							|  |  |  |   Register DBRef ref; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   yamop *newp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | /* fetch ref0 from the instruction we just started executing */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							|  |  |  |   if (!(ref0->Flags & ErasedMask)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, | 
					
						
							|  |  |  |               "find_next_clause (dead clause %x)", ref0); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   /* search for an newer entry that is to the left and points to code */ | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   ref = ref0; | 
					
						
							|  |  |  |   while ((ref = ref->n) != NULL) { | 
					
						
							|  |  |  |     if (!(ref->Flags & ErasedMask)) | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   /* no extra alternatives to try, let us leave gracefully */ | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   if (ref == NULL) { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     /* OK, we found a clause we can jump to, do a bit of hanky pancking with
 | 
					
						
							|  |  |  |        the choice-point, so that it believes we are actually working from that | 
					
						
							|  |  |  |        clause */ | 
					
						
							| 
									
										
										
										
											2003-02-12 13:20:52 +00:00
										 |  |  |     newp = ref->Code; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | /* and next let's tell the world this clause is being used, just
 | 
					
						
							|  |  |  |    like if we were executing a standard retry_and_mark */ | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2003-04-30 17:46:05 +00:00
										 |  |  |       DynamicClause *cl = ClauseCodeToDynamicClause(newp); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       LOCK(cl->ClLock); | 
					
						
							| 
									
										
										
										
											2001-10-30 22:13:18 +00:00
										 |  |  |       TRAIL_CLREF(cl); | 
					
						
							| 
									
										
										
										
											2003-12-18 17:23:22 +00:00
										 |  |  |       INC_CLREF_COUNT(cl); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       UNLOCK(cl->ClLock); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2009-11-18 13:06:37 +00:00
										 |  |  |     if (!(DynamicFlags(newp) & InUseMask)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       DynamicFlags(newp) |= InUseMask; | 
					
						
							| 
									
										
										
										
											2003-04-30 17:46:05 +00:00
										 |  |  |       TRAIL_CLREF(ClauseCodeToDynamicClause(newp)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return newp; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This procedure is called when a clause is officialy deleted. Its job
 | 
					
						
							|  |  |  |    is to find out where the code can go next, if it can go anywhere */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_jump_to_next_dynamic_clause(USES_REGS1) { | 
					
						
							|  |  |  |   DBRef ref = | 
					
						
							|  |  |  |       (DBRef)(((yamop *)((CODEADDR)P - (CELL)NEXTOP((yamop *)NULL, Osbpp))) | 
					
						
							|  |  |  |                   ->y_u.Osbpp.bmap); | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   yamop *newp = find_next_clause(ref PASS_REGS); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-12-27 16:53:09 +00:00
										 |  |  |   if (newp == NULL) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     cut_fail(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* the next alternative to try must be obtained from this clause */ | 
					
						
							|  |  |  |   B->cp_ap = newp; | 
					
						
							|  |  |  |   /* and next, enter the clause */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   P = NEXTOP(newp, Otapl); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   /* and return like if nothing had happened. */ | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void complete_lu_erase(LogUpdClause *clau) { | 
					
						
							| 
									
										
										
										
											2003-11-18 19:24:46 +00:00
										 |  |  |   DBRef *cp; | 
					
						
							| 
									
										
										
										
											2008-01-23 17:57:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-05 17:59:19 +00:00
										 |  |  |   if (clau->ClFlags & FactMask) | 
					
						
							| 
									
										
										
										
											2003-11-18 19:24:46 +00:00
										 |  |  |     cp = NULL; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2013-11-05 17:59:19 +00:00
										 |  |  |     cp = clau->lusl.ClSource->DBRefs; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   if (CL_IN_USE(clau)) { | 
					
						
							| 
									
										
										
										
											2003-04-30 17:46:05 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-02-21 20:25:45 +00:00
										 |  |  | #ifndef THREADS
 | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   if (clau->ClNext) | 
					
						
							|  |  |  |     clau->ClNext->ClPrev = clau->ClPrev; | 
					
						
							|  |  |  |   if (clau->ClPrev) { | 
					
						
							|  |  |  |     clau->ClPrev->ClNext = clau->ClNext; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     DBErasedList = clau->ClNext; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   if (cp != NULL) { | 
					
						
							|  |  |  |     DBRef ref; | 
					
						
							|  |  |  |     while ((ref = *--cp) != NIL) { | 
					
						
							|  |  |  |       if (ref->Flags & LogUpdMask) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         LogUpdClause *cl = (LogUpdClause *)ref; | 
					
						
							|  |  |  |         cl->ClRefCount--; | 
					
						
							|  |  |  |         if (cl->ClFlags & ErasedMask && !(cl->ClFlags & InUseMask) && | 
					
						
							|  |  |  |             !(cl->ClRefCount)) { | 
					
						
							|  |  |  |           EraseLogUpdCl(cl); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         LOCK(ref->lock); | 
					
						
							|  |  |  |         ref->NOfRefsTo--; | 
					
						
							|  |  |  |         if (ref->Flags & ErasedMask && !(ref->Flags & InUseMask) && | 
					
						
							|  |  |  |             ref->NOfRefsTo) { | 
					
						
							|  |  |  |           CACHE_REGS | 
					
						
							|  |  |  |           UNLOCK(ref->lock); | 
					
						
							|  |  |  |           ErDBE(ref PASS_REGS); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           UNLOCK(ref->lock); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-03-09 11:46:34 +00:00
										 |  |  |   Yap_InformOfRemoval(clau); | 
					
						
							| 
									
										
										
										
											2006-11-06 18:35:05 +00:00
										 |  |  |   Yap_LUClauseSpace -= clau->ClSize; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   Yap_FreeCodeSpace((char *)clau); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void EraseLogUpdCl(LogUpdClause *clau) { | 
					
						
							| 
									
										
										
										
											2004-02-19 19:24:46 +00:00
										 |  |  |   PredEntry *ap; | 
					
						
							| 
									
										
										
										
											2004-06-23 17:24:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 19:24:46 +00:00
										 |  |  |   ap = clau->ClPred; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   /* no need to erase what has been erased */ | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (!(clau->ClFlags & ErasedMask)) { | 
					
						
							|  |  |  |     /* get ourselves out of the list */ | 
					
						
							|  |  |  |     if (clau->ClNext != NULL) { | 
					
						
							|  |  |  |       clau->ClNext->ClPrev = clau->ClPrev; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (clau->ClPrev != NULL) { | 
					
						
							|  |  |  |       clau->ClPrev->ClNext = clau->ClNext; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |     if (ap) { | 
					
						
							|  |  |  |       if (clau->ClCode == ap->cs.p_code.FirstClause) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         if (clau->ClNext == NULL) { | 
					
						
							|  |  |  |           ap->cs.p_code.FirstClause = NULL; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           ap->cs.p_code.FirstClause = clau->ClNext->ClCode; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |       if (clau->ClCode == ap->cs.p_code.LastClause) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         if (clau->ClPrev == NULL) { | 
					
						
							|  |  |  |           ap->cs.p_code.LastClause = NULL; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           ap->cs.p_code.LastClause = clau->ClPrev->ClCode; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |       ap->cs.p_code.NOfClauses--; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-02-20 15:00:51 +00:00
										 |  |  |     clau->ClFlags |= ErasedMask; | 
					
						
							| 
									
										
										
										
											2004-02-21 20:25:45 +00:00
										 |  |  | #ifndef THREADS
 | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |       LogUpdClause *er_head = DBErasedList; | 
					
						
							|  |  |  |       if (er_head == NULL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         clau->ClPrev = clau->ClNext = NULL; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         clau->ClNext = er_head; | 
					
						
							|  |  |  |         er_head->ClPrev = clau; | 
					
						
							|  |  |  |         clau->ClPrev = NULL; | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       DBErasedList = clau; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-11-12 13:31:28 +00:00
										 |  |  |     /* we are holding a reference to the clause */ | 
					
						
							|  |  |  |     clau->ClRefCount++; | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |     if (ap) { | 
					
						
							| 
									
										
										
										
											2006-10-10 14:08:17 +00:00
										 |  |  |       /* mark it as erased */ | 
					
						
							|  |  |  |       if (ap->LastCallOfPred != LUCALL_RETRACT) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         if (ap->cs.p_code.NOfClauses > 1) { | 
					
						
							|  |  |  |           if (ap->TimeStampOfPred >= TIMESTAMP_RESET) | 
					
						
							|  |  |  |             Yap_UpdateTimestamps(ap); | 
					
						
							|  |  |  |           ++ap->TimeStampOfPred; | 
					
						
							|  |  |  |           /*	  fprintf(stderr,"-
 | 
					
						
							|  |  |  |            * %x--%d--%ul\n",ap,ap->TimeStampOfPred,ap->ArityOfPE);*/ | 
					
						
							|  |  |  |           ap->LastCallOfPred = LUCALL_RETRACT; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  | /* OK, there's noone left */ | 
					
						
							| 
									
										
										
										
											2008-01-23 17:57:56 +00:00
										 |  |  | #ifndef THREADS
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |           if (ap->cs.p_code.NOfClauses == 0) { | 
					
						
							|  |  |  |             /* Other threads may hold refs to clauses */ | 
					
						
							|  |  |  |             ap->TimeStampOfPred = 0L; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2008-01-23 17:57:56 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |           /*	  fprintf(stderr,"-
 | 
					
						
							|  |  |  |            * %x--%d--%ul\n",ap,ap->TimeStampOfPred,ap->ArityOfPE);*/ | 
					
						
							|  |  |  |           ap->LastCallOfPred = LUCALL_ASSERT; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2006-10-10 14:08:17 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       clau->ClTimeEnd = ap->TimeStampOfPred; | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |       Yap_RemoveClauseFromIndex(ap, clau->ClCode); | 
					
						
							|  |  |  |       /* release the extra reference */ | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-11-12 13:31:28 +00:00
										 |  |  |     clau->ClRefCount--; | 
					
						
							| 
									
										
										
										
											2004-06-29 19:04:46 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   complete_lu_erase(clau); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void MyEraseClause(DynamicClause *clau USES_REGS) { | 
					
						
							|  |  |  |   DBRef ref; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (CL_IN_USE(clau)) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   /*
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     I don't need to lock the clause at this point because | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     I am the last one using it anyway. | 
					
						
							|  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   ref = (DBRef)NEXTOP(clau->ClCode, Otapl)->y_u.Osbpp.bmap; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   /* don't do nothing if the reference is still in use */ | 
					
						
							|  |  |  |   if (DBREF_IN_USE(ref)) | 
					
						
							|  |  |  |     return; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (P == clau->ClCode) { | 
					
						
							| 
									
										
										
										
											2002-05-14 18:24:34 +00:00
										 |  |  |     yamop *np = RTRYCODE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     /* make it the next alternative */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     np->y_u.Otapl.d = | 
					
						
							|  |  |  |         find_next_clause((DBRef)(NEXTOP(P, Otapl)->y_u.Osbpp.bmap)PASS_REGS); | 
					
						
							| 
									
										
										
										
											2014-05-30 01:06:09 +01:00
										 |  |  |     if (np->y_u.Otapl.d == NULL) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       P = (yamop *)FAILCODE; | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       /* with same arity as before */ | 
					
						
							| 
									
										
										
										
											2014-05-30 01:06:09 +01:00
										 |  |  |       np->y_u.Otapl.s = P->y_u.Otapl.s; | 
					
						
							|  |  |  |       np->y_u.Otapl.p = P->y_u.Otapl.p; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* go ahead and try this code */ | 
					
						
							|  |  |  |       P = np; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2012-03-09 11:46:34 +00:00
										 |  |  |     Yap_InformOfRemoval(clau); | 
					
						
							| 
									
										
										
										
											2006-11-06 18:35:05 +00:00
										 |  |  |     Yap_LUClauseSpace -= clau->ClSize; | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_FreeCodeSpace((char *)clau); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							|  |  |  |     if (ref->NOfRefsTo) | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |       fprintf(stderr, "Error: references to dynamic clause\n"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     RemoveDBEntry(ref PASS_REGS); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   This predicate is supposed to be called with a | 
					
						
							|  |  |  |   lock on the current predicate | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | void Yap_ErLogUpdCl(LogUpdClause *clau) { EraseLogUpdCl(clau); } | 
					
						
							| 
									
										
										
										
											2003-04-30 17:46:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   This predicate is supposed to be called with a | 
					
						
							|  |  |  |   lock on the current predicate | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | void Yap_ErCl(DynamicClause *clau) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   MyEraseClause(clau PASS_REGS); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void PrepareToEraseLogUpdClause(LogUpdClause *clau, DBRef dbr) { | 
					
						
							|  |  |  |   yamop *code_p = clau->ClCode; | 
					
						
							| 
									
										
										
										
											2004-06-23 17:24:20 +00:00
										 |  |  |   PredEntry *p = clau->ClPred; | 
					
						
							| 
									
										
										
										
											2002-12-27 16:53:09 +00:00
										 |  |  |   yamop *cl = code_p; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-23 17:57:56 +00:00
										 |  |  |   if (clau->ClFlags & ErasedMask) { | 
					
						
							| 
									
										
										
										
											2003-04-30 17:46:05 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2008-01-23 17:57:56 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-04-30 17:46:05 +00:00
										 |  |  |   clau->ClFlags |= ErasedMask; | 
					
						
							| 
									
										
										
										
											2002-12-27 16:53:09 +00:00
										 |  |  |   if (p->cs.p_code.FirstClause != cl) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     /* we are not the first clause... */ | 
					
						
							| 
									
										
										
										
											2003-02-12 13:20:52 +00:00
										 |  |  |     yamop *prev_code_p = (yamop *)(dbr->Prev->Code); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     prev_code_p->y_u.Otapl.d = code_p->y_u.Otapl.d; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     /* are we the last? */ | 
					
						
							| 
									
										
										
										
											2002-12-27 16:53:09 +00:00
										 |  |  |     if (p->cs.p_code.LastClause == cl) | 
					
						
							|  |  |  |       p->cs.p_code.LastClause = prev_code_p; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     /* we are the first clause, what about the last ? */ | 
					
						
							| 
									
										
										
										
											2002-12-27 16:53:09 +00:00
										 |  |  |     if (p->cs.p_code.LastClause == p->cs.p_code.FirstClause) { | 
					
						
							|  |  |  |       p->cs.p_code.LastClause = p->cs.p_code.FirstClause = NULL; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2014-05-30 01:06:09 +01:00
										 |  |  |       p->cs.p_code.FirstClause = code_p->y_u.Otapl.d; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       p->cs.p_code.FirstClause->opc = Yap_opcode(_try_me); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   dbr->Code = NULL; /* unlink the two now */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (p->PredFlags & IndexedPredFlag) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     p->cs.p_code.NOfClauses--; | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_RemoveIndexation(p); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2003-04-30 17:46:05 +00:00
										 |  |  |     EraseLogUpdCl(clau); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2002-12-27 16:53:09 +00:00
										 |  |  |   if (p->cs.p_code.FirstClause == p->cs.p_code.LastClause) { | 
					
						
							|  |  |  |     if (p->cs.p_code.FirstClause != NULL) { | 
					
						
							|  |  |  |       code_p = p->cs.p_code.FirstClause; | 
					
						
							| 
									
										
										
										
											2014-05-30 01:06:09 +01:00
										 |  |  |       code_p->y_u.Otapl.d = p->cs.p_code.FirstClause; | 
					
						
							| 
									
										
										
										
											2008-09-05 05:22:19 +01:00
										 |  |  |       p->cs.p_code.TrueCodeOfPred = NEXTOP(code_p, Otapl); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (p->PredFlags & (SpiedPredFlag | CountPredFlag | ProfiledPredFlag)) { | 
					
						
							|  |  |  |         p->OpcodeOfPred = Yap_opcode(_spy_pred); | 
					
						
							|  |  |  |         p->CodeOfPred = (yamop *)(&(p->OpcodeOfPred)); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  | #if defined(YAPOR) || defined(THREADS)
 | 
					
						
							| 
									
										
										
										
											2011-03-15 09:08:09 +00:00
										 |  |  |       } else if (p->ModuleOfPred != IDB_MODULE && | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |                  !(p->PredFlags & ThreadLocalPredFlag)) { | 
					
						
							|  |  |  |         p->OpcodeOfPred = LOCKPRED_OPCODE; | 
					
						
							|  |  |  |         p->CodeOfPred = (yamop *)(&(p->OpcodeOfPred)); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         p->CodeOfPred = p->cs.p_code.TrueCodeOfPred; | 
					
						
							|  |  |  |         p->OpcodeOfPred = p->cs.p_code.TrueCodeOfPred->opc; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  | #if defined(YAPOR) || defined(THREADS)
 | 
					
						
							| 
									
										
										
										
											2011-03-15 09:08:09 +00:00
										 |  |  |     } else if (p->ModuleOfPred != IDB_MODULE && | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |                !(p->PredFlags & ThreadLocalPredFlag)) { | 
					
						
							|  |  |  |       p->OpcodeOfPred = LOCKPRED_OPCODE; | 
					
						
							|  |  |  |       p->CodeOfPred = (yamop *)(&(p->OpcodeOfPred)); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2002-10-14 16:25:38 +00:00
										 |  |  |       p->OpcodeOfPred = FAIL_OPCODE; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       p->cs.p_code.TrueCodeOfPred = p->CodeOfPred = | 
					
						
							|  |  |  |           (yamop *)(&(p->OpcodeOfPred)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (p->PredFlags & (SpiedPredFlag | CountPredFlag | ProfiledPredFlag)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |       p->OpcodeOfPred = Yap_opcode(_spy_pred); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       p->CodeOfPred = (yamop *)(&(p->OpcodeOfPred)); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  | #if defined(YAPOR) || defined(THREADS)
 | 
					
						
							| 
									
										
										
										
											2011-03-15 09:08:09 +00:00
										 |  |  |     } else if (p->ModuleOfPred != IDB_MODULE && | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |                !(p->PredFlags & ThreadLocalPredFlag)) { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |       p->OpcodeOfPred = LOCKPRED_OPCODE; | 
					
						
							|  |  |  |       p->CodeOfPred = (yamop *)(&(p->OpcodeOfPred)); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       p->OpcodeOfPred = INDEX_OPCODE; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       p->CodeOfPred = (yamop *)(&(p->OpcodeOfPred)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void PrepareToEraseClause(DynamicClause *clau, DBRef dbr) {} | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void ErDBE(DBRef entryref USES_REGS) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-12 13:20:52 +00:00
										 |  |  |   if ((entryref->Flags & DBCode) && entryref->Code) { | 
					
						
							| 
									
										
										
										
											2003-04-30 17:46:05 +00:00
										 |  |  |     if (entryref->Flags & LogUpdMask) { | 
					
						
							|  |  |  |       LogUpdClause *clau = ClauseCodeToLogUpdClause(entryref->Code); | 
					
						
							|  |  |  |       if (CL_IN_USE(clau) || entryref->NOfRefsTo != 0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         PrepareToEraseLogUpdClause(clau, entryref); | 
					
						
							| 
									
										
										
										
											2003-04-30 17:46:05 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         if (!(clau->ClFlags & ErasedMask)) | 
					
						
							|  |  |  |           PrepareToEraseLogUpdClause(clau, entryref); | 
					
						
							|  |  |  |         /* the clause must have left the chain */ | 
					
						
							|  |  |  |         EraseLogUpdCl(clau); | 
					
						
							| 
									
										
										
										
											2003-04-30 17:46:05 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2003-04-30 17:46:05 +00:00
										 |  |  |       DynamicClause *clau = ClauseCodeToDynamicClause(entryref->Code); | 
					
						
							|  |  |  |       if (CL_IN_USE(clau) || entryref->NOfRefsTo != 0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         PrepareToEraseClause(clau, entryref); | 
					
						
							| 
									
										
										
										
											2003-04-30 17:46:05 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         if (!(clau->ClFlags & ErasedMask)) | 
					
						
							|  |  |  |           PrepareToEraseClause(clau, entryref); | 
					
						
							|  |  |  |         /* the clause must have left the chain */ | 
					
						
							|  |  |  |         MyEraseClause(clau PASS_REGS); | 
					
						
							| 
									
										
										
										
											2003-04-30 17:46:05 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } else if (!(DBREF_IN_USE(entryref))) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (entryref->NOfRefsTo == 0) | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |       RemoveDBEntry(entryref PASS_REGS); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     else if (!(entryref->Flags & ErasedMask)) { | 
					
						
							|  |  |  |       /* oops, I cannot remove it, but I at least have to tell
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |          the world what's going on */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       entryref->Flags |= ErasedMask; | 
					
						
							|  |  |  |       entryref->Next = entryref->Prev = NIL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | void Yap_ErDBE(DBRef entryref) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   ErDBE(entryref PASS_REGS); | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void EraseEntry(DBRef entryref) { | 
					
						
							|  |  |  |   DBProp p; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (entryref->Flags & ErasedMask) | 
					
						
							|  |  |  |     return; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (entryref->Flags & LogUpdMask && !(entryref->Flags & DBClMask)) { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     LogUpdClause *luclause = (LogUpdClause *)entryref; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     PELOCK(67, luclause->ClPred); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     EraseLogUpdCl(luclause); | 
					
						
							|  |  |  |     UNLOCK(luclause->ClPred->PELock); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   entryref->Flags |= ErasedMask; | 
					
						
							|  |  |  |   /* update FirstNEr */ | 
					
						
							|  |  |  |   p = entryref->Parent; | 
					
						
							|  |  |  |   /* exit the db chain */ | 
					
						
							|  |  |  |   if (entryref->Next != NIL) { | 
					
						
							|  |  |  |     entryref->Next->Prev = entryref->Prev; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     p->Last = entryref->Prev; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (entryref->Prev != NIL) | 
					
						
							|  |  |  |     entryref->Prev->Next = entryref->Next; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     p->First = entryref->Next; | 
					
						
							|  |  |  |   /* make sure we know the entry has been removed from the list */ | 
					
						
							|  |  |  |   entryref->Next = NIL; | 
					
						
							|  |  |  |   if (!DBREF_IN_USE(entryref)) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     CACHE_REGS | 
					
						
							|  |  |  |     ErDBE(entryref PASS_REGS); | 
					
						
							| 
									
										
										
										
											2003-02-12 13:20:52 +00:00
										 |  |  |   } else if ((entryref->Flags & DBCode) && entryref->Code) { | 
					
						
							| 
									
										
										
										
											2006-02-24 14:03:42 +00:00
										 |  |  |     PrepareToEraseClause(ClauseCodeToDynamicClause(entryref->Code), entryref); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* erase(+Ref)	 */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_erase(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term t1 = Deref(ARG1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR, t1, "erase"); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (!IsDBRefTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2004-02-13 18:39:29 +00:00
										 |  |  |     Yap_Error(TYPE_ERROR_DBREF, t1, "erase"); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   EraseEntry(DBRefOfTerm(t1)); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-01 21:29:12 +00:00
										 |  |  | /* increase_reference_counter(+Ref)	 */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_increase_reference_counter(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2010-11-01 21:29:12 +00:00
										 |  |  |   Term t1 = Deref(ARG1); | 
					
						
							|  |  |  |   LogUpdClause *cl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t1)) { | 
					
						
							|  |  |  |     Yap_Error(INSTANTIATION_ERROR, t1, "increase_reference_counter/1"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!IsDBRefTerm(t1)) { | 
					
						
							|  |  |  |     Yap_Error(TYPE_ERROR_DBREF, t1, "increase_reference_counter"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   cl = (LogUpdClause *)DBRefOfTerm(t1); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   PELOCK(67, cl->ClPred); | 
					
						
							| 
									
										
										
										
											2010-11-01 21:29:12 +00:00
										 |  |  |   cl->ClRefCount++; | 
					
						
							| 
									
										
										
										
											2012-12-20 21:33:20 +00:00
										 |  |  |   UNLOCK(cl->ClPred->PELock); | 
					
						
							| 
									
										
										
										
											2010-11-01 21:29:12 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* increase_reference_counter(+Ref)	 */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_decrease_reference_counter(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2010-11-01 21:29:12 +00:00
										 |  |  |   Term t1 = Deref(ARG1); | 
					
						
							|  |  |  |   LogUpdClause *cl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t1)) { | 
					
						
							|  |  |  |     Yap_Error(INSTANTIATION_ERROR, t1, "increase_reference_counter/1"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!IsDBRefTerm(t1)) { | 
					
						
							|  |  |  |     Yap_Error(TYPE_ERROR_DBREF, t1, "increase_reference_counter"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   cl = (LogUpdClause *)DBRefOfTerm(t1); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   PELOCK(67, cl->ClPred); | 
					
						
							| 
									
										
										
										
											2010-11-01 21:29:12 +00:00
										 |  |  |   if (cl->ClRefCount) { | 
					
						
							|  |  |  |     cl->ClRefCount--; | 
					
						
							| 
									
										
										
										
											2012-12-20 21:33:20 +00:00
										 |  |  |     UNLOCK(cl->ClPred->PELock); | 
					
						
							| 
									
										
										
										
											2010-11-01 21:29:12 +00:00
										 |  |  |     return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-12-20 21:33:20 +00:00
										 |  |  |   UNLOCK(cl->ClPred->PELock); | 
					
						
							| 
									
										
										
										
											2010-11-01 21:29:12 +00:00
										 |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* erase(+Ref)	 */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | /** @pred  erase(+ _R_)
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The term referred to by  _R_ is erased from the internal database. If | 
					
						
							|  |  |  | reference  _R_ does not exist in the database, `erase` just fails. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_current_reference_counter(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2010-11-01 21:29:12 +00:00
										 |  |  |   Term t1 = Deref(ARG1); | 
					
						
							|  |  |  |   LogUpdClause *cl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t1)) { | 
					
						
							|  |  |  |     Yap_Error(INSTANTIATION_ERROR, t1, "increase_reference_counter/1"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!IsDBRefTerm(t1)) { | 
					
						
							|  |  |  |     Yap_Error(TYPE_ERROR_DBREF, t1, "increase_reference_counter"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   cl = (LogUpdClause *)DBRefOfTerm(t1); | 
					
						
							|  |  |  |   return Yap_unify(ARG2, MkIntegerTerm(cl->ClRefCount)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_erase_clause(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2003-11-26 18:36:35 +00:00
										 |  |  |   Term t1 = Deref(ARG1); | 
					
						
							|  |  |  |   DBRef entryref; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t1)) { | 
					
						
							|  |  |  |     Yap_Error(INSTANTIATION_ERROR, t1, "erase"); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2003-11-26 18:36:35 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (!IsDBRefTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |     if (IsApplTerm(t1)) { | 
					
						
							|  |  |  |       if (FunctorOfTerm(t1) == FunctorStaticClause) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         Yap_EraseStaticClause(Yap_ClauseFromTerm(t1), | 
					
						
							|  |  |  |                               (PredEntry *)IntegerOfTerm(ArgOfTerm(2, t1)), | 
					
						
							|  |  |  |                               Deref(ARG2)); | 
					
						
							|  |  |  |         return TRUE; | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       if (FunctorOfTerm(t1) == FunctorMegaClause) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         Yap_EraseMegaClause(Yap_MegaClauseFromTerm(t1), | 
					
						
							|  |  |  |                             Yap_MegaClausePredicateFromTerm(t1)); | 
					
						
							|  |  |  |         return TRUE; | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2013-01-11 16:45:14 +00:00
										 |  |  |       if (FunctorOfTerm(t1) == FunctorExoClause) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         Yap_Error(TYPE_ERROR_DBREF, t1, "erase exo clause"); | 
					
						
							|  |  |  |         return FALSE; | 
					
						
							| 
									
										
										
										
											2013-01-11 16:45:14 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-02-13 18:39:29 +00:00
										 |  |  |     Yap_Error(TYPE_ERROR_DBREF, t1, "erase"); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2004-02-09 14:19:05 +00:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     entryref = DBRefOfTerm(t1); | 
					
						
							| 
									
										
										
										
											2003-11-26 18:36:35 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-02-09 14:19:05 +00:00
										 |  |  |   EraseEntry(entryref); | 
					
						
							| 
									
										
										
										
											2003-11-26 18:36:35 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* eraseall(+Key)	 */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | /** @pred  eraseall(+ _K_)
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | All terms belonging to the key `K` are erased from the internal | 
					
						
							|  |  |  | database. The predicate always succeeds. | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_eraseall(USES_REGS1) { | 
					
						
							|  |  |  |   Register Term twork = Deref(ARG1); | 
					
						
							|  |  |  |   Register DBRef entryref; | 
					
						
							|  |  |  |   DBProp p; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   PredEntry *pe; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((pe = find_lu_entry(twork)) != NULL) { | 
					
						
							|  |  |  |     LogUpdClause *cl; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     if (!pe->cs.p_code.NOfClauses) | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							| 
									
										
										
										
											2003-10-14 18:37:56 +00:00
										 |  |  |     if (pe->PredFlags & IndexedPredFlag) | 
					
						
							|  |  |  |       Yap_RemoveIndexation(pe); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     cl = ClauseCodeToLogUpdClause(pe->cs.p_code.FirstClause); | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       LogUpdClause *ncl = cl->ClNext; | 
					
						
							|  |  |  |       Yap_ErLogUpdCl(cl); | 
					
						
							|  |  |  |       cl = ncl; | 
					
						
							|  |  |  |     } while (cl != NULL); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |     return TRUE; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (EndOfPAEntr(p = FetchDBPropFromKey(twork, 0, FALSE, "eraseall/3"))) { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   WRITE_LOCK(p->DBRWLock); | 
					
						
							|  |  |  |   entryref = FrstDBRef(p); | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     DBRef next_entryref; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     while (entryref != NIL && (entryref->Flags & (DBCode | ErasedMask))) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       entryref = NextDBRef(entryref); | 
					
						
							|  |  |  |     if (entryref == NIL) | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     next_entryref = NextDBRef(entryref); | 
					
						
							|  |  |  |     /* exit the db chain */ | 
					
						
							|  |  |  |     if (entryref->Next != NIL) { | 
					
						
							|  |  |  |       entryref->Next->Prev = entryref->Prev; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       p->Last = entryref->Prev; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (entryref->Prev != NIL) | 
					
						
							|  |  |  |       entryref->Prev->Next = entryref->Next; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       p->First = entryref->Next; | 
					
						
							|  |  |  |     /* make sure we know the entry has been removed from the list */ | 
					
						
							|  |  |  |     entryref->Next = entryref->Prev = NIL; | 
					
						
							|  |  |  |     if (!DBREF_IN_USE(entryref)) | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |       ErDBE(entryref PASS_REGS); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     else { | 
					
						
							|  |  |  |       entryref->Flags |= ErasedMask; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     entryref = next_entryref; | 
					
						
							|  |  |  |   } while (entryref != NIL); | 
					
						
							|  |  |  |   WRITE_UNLOCK(p->DBRWLock); | 
					
						
							|  |  |  |   return (TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* erased(+Ref) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | /** @pred  erased(+ _R_)
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Succeeds if the object whose database reference is  _R_ has been | 
					
						
							|  |  |  | erased. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_erased(USES_REGS1) { | 
					
						
							|  |  |  |   Term t = Deref(ARG1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR, t, "erased"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return (FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!IsDBRefTerm(t)) { | 
					
						
							| 
									
										
										
										
											2004-02-13 18:39:29 +00:00
										 |  |  |     Yap_Error(TYPE_ERROR_DBREF, t, "erased"); | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   return (DBRefOfTerm(t)->Flags & ErasedMask); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int static_instance(StaticClause *cl, PredEntry *ap USES_REGS) { | 
					
						
							| 
									
										
										
										
											2003-11-24 00:00:43 +00:00
										 |  |  |   if (cl->ClFlags & ErasedMask) { | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (cl->ClFlags & FactMask) { | 
					
						
							|  |  |  |     if (ap->ArityOfPE == 0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       return Yap_unify(ARG2, MkAtomTerm((Atom)ap->FunctorOfPred)); | 
					
						
							| 
									
										
										
										
											2003-11-24 00:00:43 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       Functor f = ap->FunctorOfPred; | 
					
						
							|  |  |  |       UInt arity = ArityOfFunctor(ap->FunctorOfPred), i; | 
					
						
							|  |  |  |       Term t2 = Deref(ARG2); | 
					
						
							|  |  |  |       CELL *ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (IsVarTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         Yap_unify(ARG2, (t2 = Yap_MkNewApplTerm(f, arity))); | 
					
						
							| 
									
										
										
										
											2003-11-24 00:00:43 +00:00
										 |  |  |       } else if (!IsApplTerm(t2) || FunctorOfTerm(t2) != f) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         return FALSE; | 
					
						
							| 
									
										
										
										
											2003-11-24 00:00:43 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       ptr = RepAppl(t2) + 1; | 
					
						
							|  |  |  |       for (i = 0; i < arity; i++) { | 
					
						
							|  |  |  |         XREGS[i + 1] = ptr[i]; | 
					
						
							| 
									
										
										
										
											2003-11-24 00:00:43 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       CP = P; | 
					
						
							|  |  |  |       YENV = ASP; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       YENV[E_CB] = (CELL)B; | 
					
						
							| 
									
										
										
										
											2003-11-24 00:00:43 +00:00
										 |  |  |       P = cl->ClCode; | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     Term TermDB; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-05 17:59:19 +00:00
										 |  |  |     while ((TermDB = GetDBTerm(cl->usc.ClSource, TRUE PASS_REGS)) == 0L) { | 
					
						
							| 
									
										
										
										
											2003-11-24 00:00:43 +00:00
										 |  |  |       /* oops, we are in trouble, not enough stack space */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) { | 
					
						
							|  |  |  |         LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |         if (!Yap_growglobal(NULL)) { | 
					
						
							|  |  |  |           Yap_Error(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil, | 
					
						
							|  |  |  |                     LOCAL_ErrorMessage); | 
					
						
							|  |  |  |           return FALSE; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-09-17 19:34:53 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |         if (!Yap_gcl(LOCAL_Error_Size, 2, ENV, gc_P(P, CP))) { | 
					
						
							|  |  |  |           Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							|  |  |  |           return FALSE; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2003-11-24 00:00:43 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return Yap_unify(ARG2, TermDB); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int exo_instance(Int i, PredEntry *ap USES_REGS) { | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:30 +00:00
										 |  |  |   if (ap->ArityOfPE == 0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return Yap_unify(ARG2, MkAtomTerm((Atom)ap->FunctorOfPred)); | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:30 +00:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     MegaClause *mcl = ClauseCodeToMegaClause(ap->cs.p_code.FirstClause); | 
					
						
							|  |  |  |     Functor f = ap->FunctorOfPred; | 
					
						
							|  |  |  |     UInt arity = ArityOfFunctor(ap->FunctorOfPred); | 
					
						
							|  |  |  |     Term t2 = Deref(ARG2); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     CELL *ptr = (CELL *)((ADDR)mcl->ClCode + 2 * sizeof(struct index_t *) + | 
					
						
							|  |  |  |                          i * (mcl->ClItemSize)); | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:30 +00:00
										 |  |  |     if (IsVarTerm(t2)) { | 
					
						
							|  |  |  |       // fresh slate
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       t2 = Yap_MkApplTerm(f, arity, ptr); | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:30 +00:00
										 |  |  |       Yap_unify(ARG2, t2); | 
					
						
							|  |  |  |     } else if (!IsApplTerm(t2) || FunctorOfTerm(t2) != f) { | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     for (i = 0; i < arity; i++) { | 
					
						
							|  |  |  |       XREGS[i + 1] = ptr[i]; | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:30 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     S = ptr; | 
					
						
							|  |  |  |     CP = P; | 
					
						
							|  |  |  |     YENV = ASP; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     YENV[E_CB] = (CELL)B; | 
					
						
							| 
									
										
										
										
											2013-12-09 14:16:30 +00:00
										 |  |  |     P = mcl->ClCode; | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int mega_instance(yamop *code, PredEntry *ap USES_REGS) { | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |   if (ap->ArityOfPE == 0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return Yap_unify(ARG2, MkAtomTerm((Atom)ap->FunctorOfPred)); | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     Functor f = ap->FunctorOfPred; | 
					
						
							|  |  |  |     UInt arity = ArityOfFunctor(ap->FunctorOfPred), i; | 
					
						
							|  |  |  |     Term t2 = Deref(ARG2); | 
					
						
							|  |  |  |     CELL *ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (IsVarTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       t2 = Yap_MkNewApplTerm(f, arity); | 
					
						
							| 
									
										
										
										
											2004-10-06 21:15:49 +00:00
										 |  |  |       Yap_unify(ARG2, t2); | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |     } else if (!IsApplTerm(t2) || FunctorOfTerm(t2) != f) { | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     ptr = RepAppl(t2) + 1; | 
					
						
							|  |  |  |     for (i = 0; i < arity; i++) { | 
					
						
							|  |  |  |       XREGS[i + 1] = ptr[i]; | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     CP = P; | 
					
						
							|  |  |  |     YENV = ASP; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     YENV[E_CB] = (CELL)B; | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |     P = code; | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* instance(+Ref,?Term) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | /** @pred  instance(+ _R_,- _T_)
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If  _R_ refers to a clause or a recorded term,  _T_ is unified | 
					
						
							|  |  |  | with its most general instance. If  _R_ refers to an unit clause | 
					
						
							|  |  |  |  _C_, then  _T_ is unified with ` _C_ :- true`. When | 
					
						
							|  |  |  |  _R_ is not a reference to an existing clause or to a recorded term, | 
					
						
							|  |  |  | this goal fails. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 14:33:22 +01:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_instance(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term t1 = Deref(ARG1); | 
					
						
							| 
									
										
										
										
											2002-06-04 00:46:32 +00:00
										 |  |  |   DBRef dbr; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-10-14 20:48:57 +00:00
										 |  |  |   if (IsVarTerm(t1) || !IsDBRefTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |     if (IsApplTerm(t1)) { | 
					
						
							|  |  |  |       if (FunctorOfTerm(t1) == FunctorStaticClause) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         return static_instance(Yap_ClauseFromTerm(t1), | 
					
						
							|  |  |  |                                (PredEntry *)IntegerOfTerm(ArgOfTerm(2, t1)) | 
					
						
							|  |  |  |                                    PASS_REGS); | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       if (FunctorOfTerm(t1) == FunctorMegaClause) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         return mega_instance(Yap_MegaClauseFromTerm(t1), | 
					
						
							|  |  |  |                              Yap_MegaClausePredicateFromTerm(t1) PASS_REGS); | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2013-01-11 16:45:14 +00:00
										 |  |  |       if (FunctorOfTerm(t1) == FunctorExoClause) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         return exo_instance(Yap_ExoClauseFromTerm(t1), | 
					
						
							|  |  |  |                             Yap_ExoClausePredicateFromTerm(t1) PASS_REGS); | 
					
						
							| 
									
										
										
										
											2013-01-11 16:45:14 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2003-10-14 20:48:57 +00:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     dbr = DBRefOfTerm(t1); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-09-27 20:45:04 +00:00
										 |  |  |   if (dbr->Flags & LogUpdMask) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     op_numbers opc; | 
					
						
							|  |  |  |     LogUpdClause *cl = (LogUpdClause *)dbr; | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     PredEntry *ap = cl->ClPred; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     PELOCK(68, ap); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     if (cl->ClFlags & ErasedMask) { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |       UNLOCK(ap->PELock); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-11-05 17:59:19 +00:00
										 |  |  |     if (cl->ClFlags & FactMask) { | 
					
						
							| 
									
										
										
										
											2003-11-18 19:24:46 +00:00
										 |  |  |       if (ap->ArityOfPE == 0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         UNLOCK(ap->PELock); | 
					
						
							|  |  |  |         return Yap_unify(ARG2, MkAtomTerm((Atom)ap->FunctorOfPred)); | 
					
						
							| 
									
										
										
										
											2003-11-18 19:24:46 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         Functor f = ap->FunctorOfPred; | 
					
						
							|  |  |  |         UInt arity = ArityOfFunctor(ap->FunctorOfPred), i; | 
					
						
							|  |  |  |         Term t2 = Deref(ARG2); | 
					
						
							|  |  |  |         CELL *ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (IsVarTerm(t2)) { | 
					
						
							|  |  |  |           Yap_unify(ARG2, (t2 = Yap_MkNewApplTerm(f, arity))); | 
					
						
							|  |  |  |         } else if (!IsApplTerm(t2) || FunctorOfTerm(t2) != f) { | 
					
						
							|  |  |  |           UNLOCK(ap->PELock); | 
					
						
							|  |  |  |           return FALSE; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         ptr = RepAppl(t2) + 1; | 
					
						
							|  |  |  |         for (i = 0; i < arity; i++) { | 
					
						
							|  |  |  |           XREGS[i + 1] = ptr[i]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         CP = P; | 
					
						
							|  |  |  |         YENV = ASP; | 
					
						
							|  |  |  |         YENV[E_CB] = (CELL)B; | 
					
						
							|  |  |  |         P = cl->ClCode; | 
					
						
							| 
									
										
										
										
											2013-03-10 16:38:01 +00:00
										 |  |  | #if defined(YAPOR) || defined(THREADS)
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         if (ap->PredFlags & ThreadLocalPredFlag) { | 
					
						
							|  |  |  |           UNLOCK(ap->PELock); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           PP = ap; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-03-10 16:38:01 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         return TRUE; | 
					
						
							| 
									
										
										
										
											2003-11-18 19:24:46 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     opc = Yap_op_from_opcode(cl->ClCode->opc); | 
					
						
							|  |  |  |     if (opc == _unify_idb_term) { | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |       UNLOCK(ap->PELock); | 
					
						
							| 
									
										
										
										
											2013-11-05 17:59:19 +00:00
										 |  |  |       return Yap_unify(ARG2, cl->lusl.ClSource->Entry); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       Term TermDB; | 
					
						
							| 
									
										
										
										
											2013-11-05 17:59:19 +00:00
										 |  |  |       int in_cl = (opc != _copy_idb_term); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       while ((TermDB = GetDBTerm(cl->lusl.ClSource, in_cl PASS_REGS)) == 0L) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         /* oops, we are in trouble, not enough stack space */ | 
					
						
							|  |  |  |         if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) { | 
					
						
							|  |  |  |           LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |           if (!Yap_growglobal(NULL)) { | 
					
						
							|  |  |  |             Yap_Error(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil, | 
					
						
							|  |  |  |                       LOCAL_ErrorMessage); | 
					
						
							|  |  |  |             UNLOCK(ap->PELock); | 
					
						
							|  |  |  |             return FALSE; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |           if (!Yap_gcl(LOCAL_Error_Size, 2, ENV, gc_P(P, CP))) { | 
					
						
							|  |  |  |             Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							|  |  |  |             UNLOCK(ap->PELock); | 
					
						
							|  |  |  |             return FALSE; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |       UNLOCK(ap->PELock); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       return Yap_unify(ARG2, TermDB); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Term TermDB; | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     while ((TermDB = GetDBTermFromDBEntry(dbr PASS_REGS)) == 0L) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       /* oops, we are in trouble, not enough stack space */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) { | 
					
						
							|  |  |  |         LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |         if (!Yap_growglobal(NULL)) { | 
					
						
							|  |  |  |           Yap_Error(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil, | 
					
						
							|  |  |  |                     LOCAL_ErrorMessage); | 
					
						
							|  |  |  |           return FALSE; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-09-17 19:34:53 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |         if (!Yap_gcl(LOCAL_Error_Size, 2, ENV, gc_P(P, CP))) { | 
					
						
							|  |  |  |           Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							|  |  |  |           return FALSE; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							| 
									
										
										
										
											2002-10-10 05:58:49 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |     return Yap_unify(ARG2, TermDB); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | Term Yap_LUInstance(LogUpdClause *cl, UInt arity) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Term TermDB; | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |   op_numbers opc = Yap_op_from_opcode(cl->ClCode->opc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (opc == _unify_idb_term) { | 
					
						
							| 
									
										
										
										
											2013-11-05 17:59:19 +00:00
										 |  |  |     TermDB = cl->lusl.ClSource->Entry; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     CACHE_REGS | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     int in_src; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     in_src = (opc != _copy_idb_term); | 
					
						
							|  |  |  |     while ((TermDB = GetDBTerm(cl->lusl.ClSource, in_src PASS_REGS)) == 0L) { | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |       /* oops, we are in trouble, not enough stack space */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) { | 
					
						
							|  |  |  |         LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |         if (!Yap_growglobal(NULL)) { | 
					
						
							|  |  |  |           Yap_Error(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil, | 
					
						
							|  |  |  |                     LOCAL_ErrorMessage); | 
					
						
							|  |  |  |           return 0L; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |         if (!Yap_gcl(LOCAL_Error_Size, arity, ENV, gc_P(P, CP))) { | 
					
						
							|  |  |  |           Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							|  |  |  |           return 0L; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  |   cl->ClRefCount++; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   TRAIL_CLREF(cl); /* So that fail will erase it */ | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  |   if (!(cl->ClFlags & InUseMask)) { | 
					
						
							|  |  |  |     cl->ClFlags |= InUseMask; | 
					
						
							|  |  |  |     TRAIL_CLREF(cl); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   return TermDB; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2005-06-01 13:53:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-10-14 20:32:08 +00:00
										 |  |  | /* instance(+Ref,?Term) */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_instance_module(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2003-10-14 20:32:08 +00:00
										 |  |  |   Term t1 = Deref(ARG1); | 
					
						
							|  |  |  |   DBRef dbr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-18 16:38:40 +00:00
										 |  |  |   if (IsVarTerm(t1)) { | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (IsDBRefTerm(t1)) { | 
					
						
							|  |  |  |     dbr = DBRefOfTerm(t1); | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2004-02-13 18:39:29 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2003-10-14 20:48:57 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-10-14 20:32:08 +00:00
										 |  |  |   if (dbr->Flags & LogUpdMask) { | 
					
						
							|  |  |  |     LogUpdClause *cl = (LogUpdClause *)dbr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (cl->ClFlags & ErasedMask) { | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-02-12 12:37:12 +00:00
										 |  |  |     if (cl->ClPred->ModuleOfPred) | 
					
						
							|  |  |  |       return Yap_unify(ARG2, cl->ClPred->ModuleOfPred); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       return Yap_unify(ARG2, TermProlog); | 
					
						
							| 
									
										
										
										
											2003-10-14 20:32:08 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2004-02-12 12:37:12 +00:00
										 |  |  |     return Yap_unify(ARG2, dbr->Parent->ModuleOfDB); | 
					
						
							| 
									
										
										
										
											2003-10-14 20:32:08 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | inline static int NotActiveDB(DBRef my_dbref) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   while (my_dbref && (my_dbref->Flags & (DBCode | ErasedMask))) | 
					
						
							|  |  |  |     my_dbref = my_dbref->Next; | 
					
						
							|  |  |  |   return (my_dbref == NIL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | inline static DBEntry *NextDBProp(PropEntry *pp) { | 
					
						
							|  |  |  |   while (!EndOfPAEntr(pp) && (((pp->KindOfPE & ~0x1) != DBProperty) || | 
					
						
							|  |  |  |                               NotActiveDB(((DBProp)pp)->First))) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     pp = RepProp(pp->NextOfPE); | 
					
						
							|  |  |  |   return ((DBEntry *)pp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int init_current_key(USES_REGS1) { /* current_key(+Atom,?key)	 */ | 
					
						
							|  |  |  |   Int i = 0; | 
					
						
							|  |  |  |   DBEntry *pp; | 
					
						
							|  |  |  |   Atom a; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term t1 = ARG1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   t1 = Deref(ARG1); | 
					
						
							|  |  |  |   if (!IsVarTerm(t1)) { | 
					
						
							|  |  |  |     if (IsAtomTerm(t1)) | 
					
						
							|  |  |  |       a = AtomOfTerm(t1); | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       cut_fail(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     /* ask for the first hash line */ | 
					
						
							|  |  |  |     while (TRUE) { | 
					
						
							|  |  |  |       READ_LOCK(HashChain[i].AERWLock); | 
					
						
							|  |  |  |       a = HashChain[i].Entry; | 
					
						
							|  |  |  |       if (a != NIL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       READ_UNLOCK(HashChain[i].AERWLock); | 
					
						
							|  |  |  |       i++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     READ_UNLOCK(HashChain[i].AERWLock); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   READ_LOCK(RepAtom(a)->ARWLock); | 
					
						
							| 
									
										
										
										
											2001-10-30 16:42:05 +00:00
										 |  |  |   pp = NextDBProp(RepProp(RepAtom(a)->PropsOfAE)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   READ_UNLOCK(RepAtom(a)->ARWLock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   EXTRA_CBACK_ARG(2, 3) = MkAtomTerm(a); | 
					
						
							|  |  |  |   EXTRA_CBACK_ARG(2, 2) = MkIntTerm(i); | 
					
						
							|  |  |  |   EXTRA_CBACK_ARG(2, 1) = MkIntegerTerm((Int)pp); | 
					
						
							|  |  |  |   return cont_current_key(PASS_REGS1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int cont_current_key(USES_REGS1) { | 
					
						
							|  |  |  |   unsigned int arity; | 
					
						
							|  |  |  |   Functor functor; | 
					
						
							|  |  |  |   Term term, AtT; | 
					
						
							|  |  |  |   Atom a; | 
					
						
							|  |  |  |   Int i = IntegerOfTerm(EXTRA_CBACK_ARG(2, 2)); | 
					
						
							|  |  |  |   Term first = Deref(ARG1); | 
					
						
							|  |  |  |   DBEntry *pp = (DBEntry *)IntegerOfTerm(EXTRA_CBACK_ARG(2, 1)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsIntTerm(term = EXTRA_CBACK_ARG(2, 3))) | 
					
						
							|  |  |  |     return cont_current_key_integer(PASS_REGS1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   a = AtomOfTerm(term); | 
					
						
							|  |  |  |   if (EndOfPAEntr(pp) && IsAtomTerm(first)) { | 
					
						
							|  |  |  |     cut_fail(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   while (EndOfPAEntr(pp)) { | 
					
						
							|  |  |  |     UInt j; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((a = RepAtom(a)->NextOfAE) == NIL) { | 
					
						
							|  |  |  |       i++; | 
					
						
							| 
									
										
										
										
											2003-10-28 01:16:03 +00:00
										 |  |  |       while (i < AtomHashTableSize) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         /* protect current hash table line, notice that the current
 | 
					
						
							|  |  |  |            LOCK/UNLOCK algorithm assumes new entries are added to | 
					
						
							|  |  |  |            the *front* of the list, otherwise I should have locked | 
					
						
							|  |  |  |            earlier. | 
					
						
							|  |  |  |         */ | 
					
						
							|  |  |  |         READ_LOCK(HashChain[i].AERWLock); | 
					
						
							|  |  |  |         a = HashChain[i].Entry; | 
					
						
							|  |  |  |         if (a != NIL) { | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         /* move to next entry */ | 
					
						
							|  |  |  |         READ_UNLOCK(HashChain[i].AERWLock); | 
					
						
							|  |  |  |         i++; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2003-10-28 01:16:03 +00:00
										 |  |  |       if (i == AtomHashTableSize) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         /* we have left the atom hash table */ | 
					
						
							|  |  |  |         /* we don't have a lock over the hash table any longer */ | 
					
						
							|  |  |  |         if (IsAtomTerm(first)) { | 
					
						
							|  |  |  |           cut_fail(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         j = 0; | 
					
						
							|  |  |  |         if (INT_KEYS == NULL) { | 
					
						
							|  |  |  |           cut_fail(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         for (j = 0; j < INT_KEYS_SIZE; j++) { | 
					
						
							|  |  |  |           if (INT_KEYS[j] != NIL) { | 
					
						
							|  |  |  |             DBProp pptr = RepDBProp(INT_KEYS[j]); | 
					
						
							|  |  |  |             EXTRA_CBACK_ARG(2, 1) = MkIntegerTerm((Int)(pptr->NextOfPE)); | 
					
						
							|  |  |  |             EXTRA_CBACK_ARG(2, 2) = MkIntegerTerm(j + 1); | 
					
						
							|  |  |  |             EXTRA_CBACK_ARG(2, 3) = MkIntTerm(INT_KEYS_TIMESTAMP); | 
					
						
							|  |  |  |             term = MkIntegerTerm((Int)(pptr->FunctorOfDB)); | 
					
						
							|  |  |  |             return Yap_unify(term, ARG1) && Yap_unify(term, ARG2); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (j == INT_KEYS_SIZE) { | 
					
						
							|  |  |  |           cut_fail(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return cont_current_key_integer(PASS_REGS1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         /* release our lock over the hash table */ | 
					
						
							|  |  |  |         READ_UNLOCK(HashChain[i].AERWLock); | 
					
						
							|  |  |  |         EXTRA_CBACK_ARG(2, 2) = MkIntTerm(i); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     READ_LOCK(RepAtom(a)->ARWLock); | 
					
						
							| 
									
										
										
										
											2001-10-30 16:42:05 +00:00
										 |  |  |     if (!EndOfPAEntr(pp = NextDBProp(RepProp(RepAtom(a)->PropsOfAE)))) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       EXTRA_CBACK_ARG(2, 3) = (CELL)MkAtomTerm(a); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     READ_UNLOCK(RepAtom(a)->ARWLock); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   READ_LOCK(RepAtom(a)->ARWLock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   EXTRA_CBACK_ARG(2, 1) = MkIntegerTerm((Int)NextDBProp(RepProp(pp->NextOfPE))); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   READ_UNLOCK(RepAtom(a)->ARWLock); | 
					
						
							|  |  |  |   arity = (unsigned int)(pp->ArityOfDB); | 
					
						
							|  |  |  |   if (arity == 0) { | 
					
						
							|  |  |  |     term = AtT = MkAtomTerm(a); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     unsigned int j; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     CELL *p = HR; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (j = 0; j < arity; j++) { | 
					
						
							|  |  |  |       p[j] = MkVarTerm(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     functor = Yap_MkFunctor(a, arity); | 
					
						
							|  |  |  |     term = Yap_MkApplTerm(functor, arity, p); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     AtT = MkAtomTerm(a); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |   return (Yap_unify_constant(ARG1, AtT) && Yap_unify(ARG2, term)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int cont_current_key_integer(USES_REGS1) { | 
					
						
							|  |  |  |   Term term; | 
					
						
							|  |  |  |   UInt i = IntOfTerm(EXTRA_CBACK_ARG(2, 2)); | 
					
						
							|  |  |  |   Prop pp = (Prop)IntegerOfTerm(EXTRA_CBACK_ARG(2, 1)); | 
					
						
							|  |  |  |   UInt tstamp = (UInt)IntOfTerm(EXTRA_CBACK_ARG(2, 3)); | 
					
						
							|  |  |  |   DBProp pptr; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (tstamp != INT_KEYS_TIMESTAMP) { | 
					
						
							|  |  |  |     cut_fail(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   while (pp == NIL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     for (; i < INT_KEYS_SIZE; i++) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       if (INT_KEYS[i] != NIL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         EXTRA_CBACK_ARG(2, 2) = MkIntTerm(i + 1); | 
					
						
							|  |  |  |         pp = INT_KEYS[i]; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (i == INT_KEYS_SIZE) { | 
					
						
							|  |  |  |       cut_fail(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   pptr = RepDBProp(pp); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   EXTRA_CBACK_ARG(2, 1) = MkIntegerTerm((Int)(pptr->NextOfPE)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   term = MkIntegerTerm((Int)(pptr->FunctorOfDB)); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return Yap_unify(term, ARG1) && Yap_unify(term, ARG2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | Term Yap_FetchTermFromDB(DBTerm *ref) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return GetDBTerm(ref, FALSE PASS_REGS); | 
					
						
							| 
									
										
										
										
											2013-11-05 17:59:19 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | Term Yap_FetchClauseTermFromDB(DBTerm *ref) { | 
					
						
							| 
									
										
										
										
											2013-11-05 17:59:19 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   return GetDBTerm(ref, TRUE PASS_REGS); | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | Term Yap_PopTermFromDB(DBTerm *ref) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2013-11-05 17:59:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Term t = GetDBTerm(ref, FALSE PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-02-01 21:43:45 +00:00
										 |  |  |   if (t != 0L) | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     ReleaseTermFromDB(ref PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-06-13 13:06:02 -05:00
										 |  |  |   return t; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static DBTerm *StoreTermInDB(Term t, int nargs USES_REGS) { | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   DBTerm *x; | 
					
						
							|  |  |  |   int needs_vars; | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |   struct db_globs dbg; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  |   LOCAL_s_dbg = &dbg; | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   while ((x = (DBTerm *)CreateDBStruct(t, (DBProp)NULL, InQueue, &needs_vars, 0, | 
					
						
							|  |  |  |                                        &dbg)) == NULL) { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if (LOCAL_Error_TYPE == YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |     } else if (nargs == -1) { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2004-10-27 15:56:34 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       XREGS[nargs + 1] = t; | 
					
						
							|  |  |  |       if (recover_from_record_error(nargs + 1)) { | 
					
						
							|  |  |  |         t = Deref(XREGS[nargs + 1]); | 
					
						
							| 
									
										
										
										
											2004-06-29 19:04:46 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2002-02-26 15:51:54 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |   return x; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | DBTerm *Yap_StoreTermInDB(Term t, int nargs) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   return StoreTermInDB(t, nargs PASS_REGS); | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | DBTerm *Yap_StoreTermInDBPlusExtraSpace(Term t, UInt extra_size, UInt *sz) { | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2003-11-18 19:24:46 +00:00
										 |  |  |   int needs_vars; | 
					
						
							| 
									
										
										
										
											2004-02-17 19:00:12 +00:00
										 |  |  |   struct db_globs dbg; | 
					
						
							| 
									
										
										
										
											2006-11-06 18:35:05 +00:00
										 |  |  |   DBTerm *o; | 
					
						
							| 
									
										
										
										
											2003-11-18 19:24:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  |   LOCAL_s_dbg = &dbg; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   o = (DBTerm *)CreateDBStruct(t, (DBProp)NULL, InQueue, &needs_vars, | 
					
						
							|  |  |  |                                extra_size, &dbg); | 
					
						
							| 
									
										
										
										
											2006-11-06 18:35:05 +00:00
										 |  |  |   *sz = dbg.sz; | 
					
						
							|  |  |  |   return o; | 
					
						
							| 
									
										
										
										
											2003-11-18 19:24:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | void Yap_init_tqueue(db_queue *dbq) { | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   dbq->id = FunctorDBRef; | 
					
						
							|  |  |  |   dbq->Flags = DBClMask; | 
					
						
							|  |  |  |   dbq->FirstInQueue = dbq->LastInQueue = NULL; | 
					
						
							|  |  |  |   INIT_RWLOCK(dbq->QRWLock); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | void Yap_destroy_tqueue(db_queue *dbq USES_REGS) { | 
					
						
							|  |  |  |   QueueEntry *cur_instance = dbq->FirstInQueue; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   while (cur_instance) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     /* release space for cur_instance */ | 
					
						
							|  |  |  |     keepdbrefs(cur_instance->DBT PASS_REGS); | 
					
						
							|  |  |  |     ErasePendingRefs(cur_instance->DBT PASS_REGS); | 
					
						
							|  |  |  |     FreeDBSpace((char *)cur_instance->DBT); | 
					
						
							|  |  |  |     FreeDBSpace((char *)cur_instance); | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   dbq->FirstInQueue = dbq->LastInQueue = NULL; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | bool Yap_enqueue_tqueue(db_queue *father_key, Term t USES_REGS) { | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   QueueEntry *x; | 
					
						
							|  |  |  |   while ((x = (QueueEntry *)AllocDBSpace(sizeof(QueueEntry))) == NULL) { | 
					
						
							|  |  |  |     if (!Yap_growheap(FALSE, sizeof(QueueEntry), NULL)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       Yap_Error(RESOURCE_ERROR_HEAP, TermNil, "in findall"); | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |       return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Yap_LUClauseSpace += sizeof(QueueEntry); */ | 
					
						
							|  |  |  |   x->DBT = StoreTermInDB(Deref(t), 2 PASS_REGS); | 
					
						
							|  |  |  |   if (x->DBT == NULL) { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   x->next = NULL; | 
					
						
							|  |  |  |   if (father_key->LastInQueue != NULL) | 
					
						
							|  |  |  |     father_key->LastInQueue->next = x; | 
					
						
							|  |  |  |   father_key->LastInQueue = x; | 
					
						
							|  |  |  |   if (father_key->FirstInQueue == NULL) { | 
					
						
							|  |  |  |     father_key->FirstInQueue = x; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | bool Yap_dequeue_tqueue(db_queue *father_key, Term t, bool first, | 
					
						
							|  |  |  |                         bool release USES_REGS) { | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   Term TDB; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   CELL *oldH = HR; | 
					
						
							| 
									
										
										
										
											2014-10-19 01:51:02 +01:00
										 |  |  |   tr_fr_ptr oldTR = TR; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   QueueEntry *cur_instance = father_key->FirstInQueue, *prev = NULL; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   while (cur_instance) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     HR = oldH; | 
					
						
							|  |  |  |     HB = LCL0; | 
					
						
							|  |  |  |     while ((TDB = GetDBTerm(cur_instance->DBT, false PASS_REGS)) == 0L) { | 
					
						
							|  |  |  |       if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) { | 
					
						
							|  |  |  |         LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |         if (!Yap_growglobal(NULL)) { | 
					
						
							|  |  |  |           Yap_Error(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil, | 
					
						
							|  |  |  |                     LOCAL_ErrorMessage); | 
					
						
							|  |  |  |           return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  |         if (!Yap_gcl(LOCAL_Error_Size, 2, ENV, gc_P(P, CP))) { | 
					
						
							|  |  |  |           Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							|  |  |  |           return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       oldTR = TR; | 
					
						
							|  |  |  |       oldH = HR; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (Yap_unify(t, TDB)) { | 
					
						
							|  |  |  |       if (release) { | 
					
						
							|  |  |  |         if (cur_instance == father_key->FirstInQueue) { | 
					
						
							|  |  |  |           father_key->FirstInQueue = cur_instance->next; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (cur_instance == father_key->LastInQueue) { | 
					
						
							|  |  |  |           father_key->LastInQueue = prev; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (prev) { | 
					
						
							|  |  |  |           prev->next = cur_instance->next; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         /* release space for cur_instance */ | 
					
						
							|  |  |  |         keepdbrefs(cur_instance->DBT PASS_REGS); | 
					
						
							|  |  |  |         ErasePendingRefs(cur_instance->DBT PASS_REGS); | 
					
						
							|  |  |  |         FreeDBSpace((char *)cur_instance->DBT); | 
					
						
							|  |  |  |         FreeDBSpace((char *)cur_instance); | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         // undo if you'rejust peeking
 | 
					
						
							|  |  |  |         while (oldTR < TR) { | 
					
						
							|  |  |  |           CELL d1 = TrailTerm(TR - 1); | 
					
						
							|  |  |  |           TR--; | 
					
						
							|  |  |  |           /* normal variable */ | 
					
						
							|  |  |  |           RESET_VARIABLE(d1); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       return true; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       // just getting the first
 | 
					
						
							|  |  |  |       if (first) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |       // but keep on going, if we want to check everything.
 | 
					
						
							|  |  |  |       prev = cur_instance; | 
					
						
							|  |  |  |       cur_instance = cur_instance->next; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   } | 
					
						
							|  |  |  |   return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_init_queue(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   db_queue *dbq; | 
					
						
							|  |  |  |   Term t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-24 11:01:01 +00:00
										 |  |  |   while ((dbq = (db_queue *)AllocDBSpace(sizeof(db_queue))) == NULL) { | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     if (!Yap_growheap(FALSE, sizeof(db_queue), NULL)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       Yap_Error(RESOURCE_ERROR_HEAP, TermNil, "in findall"); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-02-24 11:01:01 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2006-11-06 18:35:05 +00:00
										 |  |  |   /* Yap_LUClauseSpace += sizeof(db_queue); */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Yap_init_tqueue(dbq); | 
					
						
							| 
									
										
										
										
											2004-06-05 03:37:01 +00:00
										 |  |  |   t = MkIntegerTerm((Int)dbq); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return Yap_unify(ARG1, t); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_enqueue(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term Father = Deref(ARG1); | 
					
						
							|  |  |  |   db_queue *father_key; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   bool rc; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(Father)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR, Father, "enqueue"); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2004-06-05 03:37:01 +00:00
										 |  |  |   } else if (!IsIntegerTerm(Father)) { | 
					
						
							|  |  |  |     Yap_Error(TYPE_ERROR_INTEGER, Father, "enqueue"); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else | 
					
						
							| 
									
										
										
										
											2004-06-05 03:37:01 +00:00
										 |  |  |     father_key = (db_queue *)IntegerOfTerm(Father); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   WRITE_LOCK(father_key->QRWLock); | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   rc = Yap_enqueue_tqueue(father_key, Deref(ARG2) PASS_REGS); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   WRITE_UNLOCK(father_key->QRWLock); | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   return rc; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_enqueue_unlocked(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2008-08-08 14:05:34 +00:00
										 |  |  |   Term Father = Deref(ARG1); | 
					
						
							|  |  |  |   db_queue *father_key; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(Father)) { | 
					
						
							|  |  |  |     Yap_Error(INSTANTIATION_ERROR, Father, "enqueue"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } else if (!IsIntegerTerm(Father)) { | 
					
						
							|  |  |  |     Yap_Error(TYPE_ERROR_INTEGER, Father, "enqueue"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } else | 
					
						
							|  |  |  |     father_key = (db_queue *)IntegerOfTerm(Father); | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   return Yap_enqueue_tqueue(father_key, Deref(ARG2) PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-08-08 14:05:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* when reading an entry in the data base we are making it accessible from
 | 
					
						
							|  |  |  |    the outside. If the entry was removed, and this was the last pointer, the | 
					
						
							|  |  |  |    target entry would be immediately removed, leading to dangling pointers. | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |    We avoid this problem by making every entry accessible. | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    Note that this could not happen with recorded, because the original db | 
					
						
							|  |  |  |    entry itself is still accessible from a trail entry, so we could not remove | 
					
						
							|  |  |  |    the target entry, | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void keepdbrefs(DBTerm *entryref USES_REGS) { | 
					
						
							|  |  |  |   DBRef *cp; | 
					
						
							|  |  |  |   DBRef ref; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-12 13:20:52 +00:00
										 |  |  |   cp = entryref->DBRefs; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   if (cp == NULL) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   while ((ref = *--cp) != NIL) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     if (!(ref->Flags & LogUpdMask)) { | 
					
						
							|  |  |  |       LOCK(ref->lock); | 
					
						
							|  |  |  |       if (!(ref->Flags & InUseMask)) { | 
					
						
							|  |  |  |         ref->Flags |= InUseMask; | 
					
						
							|  |  |  |         TRAIL_REF(ref); /* So that fail will erase it */ | 
					
						
							| 
									
										
										
										
											2003-12-27 00:38:53 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       UNLOCK(ref->lock); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_dequeue(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   db_queue *father_key; | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   QueueEntry *cur_instance; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term Father = Deref(ARG1); | 
					
						
							| 
									
										
										
										
											2016-01-04 14:11:09 +00:00
										 |  |  |   Int rc; | 
					
						
							| 
									
										
										
										
											2016-01-08 03:18:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (IsVarTerm(Father)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR, Father, "dequeue"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2004-06-05 03:37:01 +00:00
										 |  |  |   } else if (!IsIntegerTerm(Father)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(TYPE_ERROR_INTEGER, Father, "dequeue"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     father_key = (db_queue *)IntegerOfTerm(Father); | 
					
						
							|  |  |  |     WRITE_LOCK(father_key->QRWLock); | 
					
						
							|  |  |  |     if ((cur_instance = father_key->FirstInQueue) == NULL) { | 
					
						
							|  |  |  |       /* an empty queue automatically goes away */ | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |       WRITE_UNLOCK(father_key->QRWLock); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       FreeDBSpace((char *)father_key); | 
					
						
							| 
									
										
										
										
											2016-01-04 14:11:09 +00:00
										 |  |  |       return false; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-01-04 14:11:09 +00:00
										 |  |  |     rc = Yap_dequeue_tqueue(father_key, ARG2, true, true PASS_REGS); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     WRITE_UNLOCK(father_key->QRWLock); | 
					
						
							| 
									
										
										
										
											2016-01-04 14:11:09 +00:00
										 |  |  |     return rc; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_dequeue_unlocked(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2008-08-08 14:05:34 +00:00
										 |  |  |   db_queue *father_key; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   QueueEntry *cur_instance; | 
					
						
							| 
									
										
										
										
											2008-08-08 14:05:34 +00:00
										 |  |  |   Term Father = Deref(ARG1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(Father)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR, Father, "dequeue"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2008-08-08 14:05:34 +00:00
										 |  |  |   } else if (!IsIntegerTerm(Father)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(TYPE_ERROR_INTEGER, Father, "dequeue"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     father_key = (db_queue *)IntegerOfTerm(Father); | 
					
						
							|  |  |  |     if ((cur_instance = father_key->FirstInQueue) == NULL) { | 
					
						
							|  |  |  |       /* an empty queue automatically goes away */ | 
					
						
							|  |  |  |       FreeDBSpace((char *)father_key); | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-01-04 14:11:09 +00:00
										 |  |  |     return Yap_dequeue_tqueue(father_key, ARG2, true, true PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-08-08 14:05:34 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_peek_queue(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2008-08-08 14:05:34 +00:00
										 |  |  |   db_queue *father_key; | 
					
						
							|  |  |  |   QueueEntry *cur_instance; | 
					
						
							|  |  |  |   Term Father = Deref(ARG1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(Father)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR, Father, "dequeue"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2008-08-08 14:05:34 +00:00
										 |  |  |   } else if (!IsIntegerTerm(Father)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(TYPE_ERROR_INTEGER, Father, "dequeue"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     father_key = (db_queue *)IntegerOfTerm(Father); | 
					
						
							|  |  |  |     if ((cur_instance = father_key->FirstInQueue) == NULL) { | 
					
						
							|  |  |  |       /* an empty queue automatically goes away */ | 
					
						
							|  |  |  |       FreeDBSpace((char *)father_key); | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!Yap_dequeue_tqueue(father_key, ARG2, true, false PASS_REGS)) | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     if (cur_instance == father_key->LastInQueue) | 
					
						
							|  |  |  |       father_key->FirstInQueue = father_key->LastInQueue = NULL; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       father_key->FirstInQueue = cur_instance->next; | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							| 
									
										
										
										
											2008-08-08 14:05:34 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_clean_queues(USES_REGS1) { return TRUE; } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* set the logical updates flag */ | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_slu(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term t = Deref(ARG1); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR, t, "switch_logical_updates/1"); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (!IsIntTerm(t)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_Error(TYPE_ERROR_INTEGER, t, "switch_logical_updates/1"); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   UPDATE_MODE = IntOfTerm(t); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | /* get a hold over the index table for logical update predicates */ | 
					
						
							|  |  |  | static Int p_hold_index(USES_REGS1) { | 
					
						
							|  |  |  |   Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "hold_index in debugger"); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_fetch_reference_from_index(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term t1 = Deref(ARG1), t2 = Deref(ARG2); | 
					
						
							|  |  |  |   DBRef table, el; | 
					
						
							|  |  |  |   Int pos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t1) || !IsDBRefTerm(t1)) | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   table = DBRefOfTerm(t1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t2) || !IsIntTerm(t2)) | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   pos = IntOfTerm(t2); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   el = (DBRef)(table->DBT.Contents[pos]); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   LOCK(el->lock); | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   TRAIL_REF(el); /* So that fail will erase it */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   INC_DBREF_COUNT(el); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   if (!(el->Flags & InUseMask)) { | 
					
						
							|  |  |  |     el->Flags |= InUseMask; | 
					
						
							| 
									
										
										
										
											2001-06-08 14:52:54 +00:00
										 |  |  |     TRAIL_REF(el); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  |   UNLOCK(el->lock); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return Yap_unify(ARG3, MkDBRefTerm(el)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_resize_int_keys(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term t1 = Deref(ARG1); | 
					
						
							|  |  |  |   if (IsVarTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     return Yap_unify(ARG1, MkIntegerTerm((Int)INT_KEYS_SIZE)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (!IsIntegerTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_Error(TYPE_ERROR_INTEGER, t1, "yap_flag(resize_db_int_keys,T)"); | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2007-11-26 23:43:10 +00:00
										 |  |  |   return resize_int_keys(IntegerOfTerm(t1)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static void ReleaseTermFromDB(DBTerm *ref USES_REGS) { | 
					
						
							| 
									
										
										
										
											2009-12-03 17:48:25 +00:00
										 |  |  |   if (!ref) | 
					
						
							|  |  |  |     return; | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   keepdbrefs(ref PASS_REGS); | 
					
						
							|  |  |  |   ErasePendingRefs(ref PASS_REGS); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   FreeDBSpace((char *)ref); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | void Yap_ReleaseTermFromDB(DBTerm *ref) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   ReleaseTermFromDB(ref PASS_REGS); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | static Int p_install_thread_local(USES_REGS1) { /* '$is_dynamic'(+P)	 */ | 
					
						
							|  |  |  |   PredEntry *pe; | 
					
						
							|  |  |  |   Term t = Deref(ARG1); | 
					
						
							|  |  |  |   Term mod = Deref(ARG2); | 
					
						
							| 
									
										
										
										
											2004-02-11 16:09:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							|  |  |  |     return (FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (mod == IDB_MODULE) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     pe = find_lu_entry(t); | 
					
						
							| 
									
										
										
										
											2004-02-11 16:09:15 +00:00
										 |  |  |     if (!pe->cs.p_code.NOfClauses) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (IsIntegerTerm(t)) | 
					
						
							|  |  |  |         pe->PredFlags |= LogUpdatePredFlag | NumberDBPredFlag; | 
					
						
							| 
									
										
										
										
											2004-02-11 16:09:15 +00:00
										 |  |  |       else if (IsAtomTerm(t)) | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         pe->PredFlags |= LogUpdatePredFlag | AtomDBPredFlag; | 
					
						
							| 
									
										
										
										
											2004-02-11 16:09:15 +00:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |         pe->PredFlags |= LogUpdatePredFlag; | 
					
						
							| 
									
										
										
										
											2004-02-11 16:09:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } else if (IsAtomTerm(t)) { | 
					
						
							|  |  |  |     Atom at = AtomOfTerm(t); | 
					
						
							|  |  |  |     pe = RepPredProp(PredPropByAtom(at, mod)); | 
					
						
							|  |  |  |   } else if (IsApplTerm(t)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Functor fun = FunctorOfTerm(t); | 
					
						
							| 
									
										
										
										
											2004-02-11 16:09:15 +00:00
										 |  |  |     pe = RepPredProp(PredPropByFunc(fun, mod)); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   PELOCK(69, pe); | 
					
						
							|  |  |  |   if (pe->PredFlags & (ThreadLocalPredFlag | LogUpdatePredFlag)) { | 
					
						
							| 
									
										
										
										
											2014-04-24 14:25:21 +01:00
										 |  |  |     // second declaration, just ignore
 | 
					
						
							|  |  |  |     UNLOCK(pe->PELock); | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (pe->PredFlags & | 
					
						
							|  |  |  |           (UserCPredFlag | HiddenPredFlag | CArgsPredFlag | SyncPredFlag | | 
					
						
							|  |  |  |            TestPredFlag | AsmPredFlag | StandardPredFlag | CPredFlag | | 
					
						
							|  |  |  |            SafePredFlag | IndexedPredFlag | BinaryPredFlag) || | 
					
						
							| 
									
										
										
										
											2004-02-11 16:09:15 +00:00
										 |  |  |       pe->cs.p_code.NOfClauses) { | 
					
						
							| 
									
										
										
										
											2014-04-24 14:25:21 +01:00
										 |  |  |     UNLOCK(pe->PELock); | 
					
						
							| 
									
										
										
										
											2004-02-11 16:09:15 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-07-28 23:22:24 +01:00
										 |  |  | #if THREADS
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   pe->PredFlags |= ThreadLocalPredFlag | LogUpdatePredFlag; | 
					
						
							| 
									
										
										
										
											2004-02-11 16:09:15 +00:00
										 |  |  |   pe->OpcodeOfPred = Yap_opcode(_thread_local); | 
					
						
							|  |  |  |   pe->CodeOfPred = (yamop *)&pe->OpcodeOfPred; | 
					
						
							| 
									
										
										
										
											2010-07-28 23:22:24 +01:00
										 |  |  | #else
 | 
					
						
							|  |  |  |   pe->PredFlags |= LogUpdatePredFlag; | 
					
						
							| 
									
										
										
										
											2004-02-11 16:18:16 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-07-28 23:22:24 +01:00
										 |  |  |   UNLOCK(pe->PELock); | 
					
						
							| 
									
										
										
										
											2004-02-11 16:09:15 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | void Yap_InitDBPreds(void) { | 
					
						
							| 
									
										
										
										
											2016-01-03 01:28:21 +00:00
										 |  |  |   Yap_InitCPred("$set_pred_flags", 2, p_rcdz, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   /** @pred  recorded(+ _K_, _T_, _R_)
 | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Searches in the internal database under the key  _K_, a term that | 
					
						
							|  |  |  |   unifies with  _T_ and whose reference matches  _R_. This | 
					
						
							|  |  |  |   built-in may be used in one of two ways: | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   + _K_ may be given, in this case the built-in will return all | 
					
						
							|  |  |  |   elements of the internal data-base that match the key. | 
					
						
							|  |  |  |   + _R_ may be given, if so returning the key and element that | 
					
						
							|  |  |  |   match the reference. | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2016-01-03 01:28:21 +00:00
										 |  |  |   Yap_InitCPred("recorded", 3, p_recorded, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   Yap_InitCPred("recorda", 3, p_rcda, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   /** @pred  recorda(+ _K_, _T_,- _R_)
 | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Makes term  _T_ the first record under key  _K_ and  unifies  _R_ | 
					
						
							|  |  |  |   with its reference. | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2003-08-27 13:37:10 +00:00
										 |  |  |   Yap_InitCPred("recordz", 3, p_rcdz, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2012-10-19 18:10:48 +01:00
										 |  |  |   Yap_InitCPred("$still_variant", 2, p_still_variant, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2003-01-21 16:14:52 +00:00
										 |  |  |   Yap_InitCPred("recorda_at", 3, p_rcda_at, SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("recordz_at", 3, p_rcdz_at, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2012-10-19 18:10:48 +01:00
										 |  |  |   Yap_InitCPred("$recordap", 3, p_rcdap, SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$recordzp", 3, p_rcdzp, SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$recordap", 4, p_drcdap, SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$recordzp", 4, p_drcdzp, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Yap_InitCPred("erase", 1, p_erase, SafePredFlag | SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$erase_clause", 2, p_erase_clause, | 
					
						
							|  |  |  |                 SafePredFlag | SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("increase_reference_count", 1, p_increase_reference_counter, | 
					
						
							|  |  |  |                 SafePredFlag | SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("decrease_reference_count", 1, p_decrease_reference_counter, | 
					
						
							|  |  |  |                 SafePredFlag | SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("current_reference_count", 2, p_current_reference_counter, | 
					
						
							|  |  |  |                 SafePredFlag | SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("erased", 1, p_erased, | 
					
						
							|  |  |  |                 TestPredFlag | SafePredFlag | SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |   Yap_InitCPred("instance", 2, p_instance, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2012-10-19 18:10:48 +01:00
										 |  |  |   Yap_InitCPred("$instance_module", 2, p_instance_module, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Yap_InitCPred("eraseall", 1, p_eraseall, SafePredFlag | SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$record_stat_source", 4, p_rcdstatp, | 
					
						
							|  |  |  |                 SafePredFlag | SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$some_recordedp", 1, p_somercdedp, | 
					
						
							|  |  |  |                 SafePredFlag | SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$first_instance", 3, p_first_instance, | 
					
						
							|  |  |  |                 SafePredFlag | SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$init_db_queue", 1, p_init_queue, SafePredFlag | SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2012-10-19 18:10:48 +01:00
										 |  |  |   Yap_InitCPred("$db_key", 2, p_db_key, 0L); | 
					
						
							|  |  |  |   Yap_InitCPred("$db_enqueue", 2, p_enqueue, SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$db_enqueue_unlocked", 2, p_enqueue_unlocked, SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$db_dequeue", 2, p_dequeue, SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$db_dequeue_unlocked", 2, p_dequeue_unlocked, SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$db_peek_queue", 2, p_peek_queue, SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$db_clean_queues", 1, p_clean_queues, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Yap_InitCPred("$switch_log_upd", 1, p_slu, SafePredFlag | SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$hold_index", 3, p_hold_index, SafePredFlag | SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$fetch_reference_from_index", 3, p_fetch_reference_from_index, | 
					
						
							|  |  |  |                 SafePredFlag | SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$resize_int_keys", 1, p_resize_int_keys, | 
					
						
							|  |  |  |                 SafePredFlag | SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2003-10-28 01:16:03 +00:00
										 |  |  |   Yap_InitCPred("key_statistics", 4, p_key_statistics, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2006-10-10 20:21:42 +00:00
										 |  |  |   Yap_InitCPred("$lu_statistics", 5, p_lu_statistics, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2003-11-12 12:33:31 +00:00
										 |  |  |   Yap_InitCPred("total_erased", 4, p_total_erased, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Yap_InitCPred("key_erased_statistics", 5, p_key_erased_statistics, | 
					
						
							|  |  |  |                 SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2004-09-03 03:11:09 +00:00
										 |  |  |   Yap_InitCPred("heap_space_info", 3, p_heap_space_info, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Yap_InitCPred("$jump_to_next_dynamic_clause", 0, | 
					
						
							|  |  |  |                 p_jump_to_next_dynamic_clause, SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$install_thread_local", 2, p_install_thread_local, | 
					
						
							|  |  |  |                 SafePredFlag); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | void Yap_InitBackDB(void) { | 
					
						
							|  |  |  |   Yap_InitCPredBack("$recorded_with_key", 3, 3, in_rded_with_key, co_rded, | 
					
						
							|  |  |  |                     SyncPredFlag); | 
					
						
							|  |  |  |   RETRY_C_RECORDED_K_CODE = | 
					
						
							|  |  |  |       NEXTOP(PredRecordedWithKey->cs.p_code.FirstClause, OtapFs); | 
					
						
							| 
									
										
										
										
											2012-10-19 18:10:48 +01:00
										 |  |  |   Yap_InitCPredBack("$recordedp", 3, 3, in_rdedp, co_rdedp, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   RETRY_C_RECORDEDP_CODE = | 
					
						
							|  |  |  |       NEXTOP(RepPredProp(PredPropByFunc(Yap_MkFunctor(AtomRecordedP, 3), 0)) | 
					
						
							|  |  |  |                  ->cs.p_code.FirstClause, | 
					
						
							|  |  |  |              OtapFs); | 
					
						
							|  |  |  |   Yap_InitCPredBack("$current_immediate_key", 2, 4, init_current_key, | 
					
						
							|  |  |  |                     cont_current_key, SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  | @} | 
					
						
							|  |  |  | */ |