| 
									
										
										
										
											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:		utilpreds.c						 * | 
					
						
							|  |  |  | * Last rev:	4/03/88							 * | 
					
						
							|  |  |  | * mods:									 * | 
					
						
							|  |  |  | * comments:	new utility predicates for YAP				 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | *************************************************************************/ | 
					
						
							|  |  |  | #ifdef SCCS
 | 
					
						
							|  |  |  | static char     SccsId[] = "@(#)utilpreds.c	1.3"; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /** @addtogroup YAP_Terms
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-23 15:50:01 +01:00
										 |  |  | #include "absmi.h"
 | 
					
						
							| 
									
										
										
										
											2009-10-23 14:22:17 +01:00
										 |  |  | #include "YapHeap.h"
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #include "yapio.h"
 | 
					
						
							| 
									
										
										
										
											2005-02-18 21:34:02 +00:00
										 |  |  | #include "attvar.h"
 | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | #ifdef HAVE_STRING_H
 | 
					
						
							|  |  |  | #include "string.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	Term            old_var; | 
					
						
							|  |  |  | 	Term            new_var; | 
					
						
							|  |  |  | }              *vcell; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-25 17:15:04 -05:00
										 |  |  | static int   copy_complex_term(CELL *, CELL *, int, int, CELL *, CELL * CACHE_TYPE); | 
					
						
							|  |  |  | static CELL  vars_in_complex_term(CELL *, CELL *, Term CACHE_TYPE); | 
					
						
							|  |  |  | static Int   p_non_singletons_in_term( USES_REGS1); | 
					
						
							|  |  |  | static CELL  non_singletons_in_complex_term(CELL *, CELL * CACHE_TYPE); | 
					
						
							|  |  |  | static Int   p_variables_in_term( USES_REGS1 ); | 
					
						
							|  |  |  | static Int   ground_complex_term(CELL *, CELL * CACHE_TYPE); | 
					
						
							|  |  |  | static Int   p_ground( USES_REGS1 ); | 
					
						
							|  |  |  | static Int   p_copy_term( USES_REGS1 ); | 
					
						
							|  |  |  | static Int   var_in_complex_term(CELL *, CELL *, Term CACHE_TYPE); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2013-04-25 17:15:04 -05:00
										 |  |  | static Int  p_force_trail_expansion( USES_REGS1 ); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif /* DEBUG */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | clean_tr(tr_fr_ptr TR0 USES_REGS) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (TR != TR0) { | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       Term p = TrailTerm(--TR); | 
					
						
							| 
									
										
										
										
											2004-04-20 22:08:57 +00:00
										 |  |  |       RESET_VARIABLE(p); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } while (TR != TR0); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-16 14:10:20 +00:00
										 |  |  | static inline void | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | clean_dirty_tr(tr_fr_ptr TR0 USES_REGS) { | 
					
						
							| 
									
										
										
										
											2004-06-16 14:10:20 +00:00
										 |  |  |   if (TR != TR0) { | 
					
						
							|  |  |  |     tr_fr_ptr pt = TR0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       Term p = TrailTerm(pt++); | 
					
						
							| 
									
										
										
										
											2010-03-12 08:24:58 +00:00
										 |  |  |       RESET_VARIABLE(p); | 
					
						
							| 
									
										
										
										
											2004-06-16 14:10:20 +00:00
										 |  |  |     } while (pt != TR); | 
					
						
							|  |  |  |     TR = TR0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | copy_complex_term(CELL *pt0, CELL *pt0_end, int share, int newattvs, CELL *ptf, CELL *HLow USES_REGS) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |   struct cp_frame *to_visit0, *to_visit = (struct cp_frame *)Yap_PreAllocCodeSpace(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   CELL *HB0 = HB; | 
					
						
							| 
									
										
										
										
											2004-04-19 17:06:51 +00:00
										 |  |  |   tr_fr_ptr TR0 = TR; | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |   int ground = TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   HB = HLow; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   to_visit0 = to_visit; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, copy_term_unk); | 
					
						
							|  |  |  |   copy_term_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							|  |  |  | 	CELL *ap2 = RepPair(d0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	if (ap2 >= HB && ap2 < HR) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  /* If this is newer than the current term, just reuse */ | 
					
						
							|  |  |  | 	  *ptf++ = d0; | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	}  | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	*ptf = AbsPair(HR); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	ptf++; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	if (to_visit+1 >= (struct cp_frame *)AuxSp) { | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  | 	  goto heap_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	to_visit->to = ptf; | 
					
						
							|  |  |  | 	to_visit->oldv = *pt0; | 
					
						
							|  |  |  | 	to_visit->ground = ground; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	/* fool the system into thinking we had a variable there */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	*pt0 = AbsPair(HR); | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	to_visit ++; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	  if (to_visit+1 >= (struct cp_frame *)AuxSp) { | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  | 	    goto heap_overflow; | 
					
						
							|  |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	  to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	  to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	  to_visit->to = ptf; | 
					
						
							|  |  |  | 	  to_visit->ground = ground; | 
					
						
							|  |  |  | 	  to_visit ++; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	ground = TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	pt0 = ap2 - 1; | 
					
						
							|  |  |  | 	pt0_end = ap2 + 1; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	ptf = HR; | 
					
						
							|  |  |  | 	HR += 2; | 
					
						
							|  |  |  | 	if (HR > ASP - 2048) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  goto overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	if (ap2 >= HB && ap2 <= HR) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  /* If this is newer than the current term, just reuse */ | 
					
						
							|  |  |  | 	  *ptf++ = d0; | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	}  | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							| 
									
										
										
										
											2011-04-14 18:51:11 +01:00
										 |  |  | #if MULTIPLE_STACKS
 | 
					
						
							| 
									
										
										
										
											2008-05-10 23:24:13 +00:00
										 |  |  | 	  if (f == FunctorDBRef) { | 
					
						
							|  |  |  | 	    DBRef  entryref = DBRefOfTerm(d0); | 
					
						
							|  |  |  | 	    if (entryref->Flags & LogUpdMask) { | 
					
						
							|  |  |  | 	      LogUpdClause *luclause = (LogUpdClause *)entryref; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:22:16 +01:00
										 |  |  | 	      PELOCK(100,luclause->ClPred); | 
					
						
							| 
									
										
										
										
											2008-05-10 23:24:13 +00:00
										 |  |  | 	      UNLOCK(luclause->ClPred->PELock); | 
					
						
							|  |  |  | 	    } else { | 
					
						
							|  |  |  | 	      LOCK(entryref->lock); | 
					
						
							|  |  |  | 	      TRAIL_REF(entryref);	/* So that fail will erase it */ | 
					
						
							|  |  |  | 	      INC_DBREF_COUNT(entryref); | 
					
						
							|  |  |  | 	      UNLOCK(entryref->lock); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | 	    *ptf++ = d0;  /* you can just copy other extensions. */ | 
					
						
							| 
									
										
										
										
											2008-08-12 01:27:23 +00:00
										 |  |  | 	  } else | 
					
						
							| 
									
										
										
										
											2008-05-10 23:24:13 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-08-12 01:27:23 +00:00
										 |  |  | 	  if (!share) { | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | 	    UInt sz; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	    *ptf++ = AbsAppl(HR);  /* you can just copy other extensions. */ | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | 	    /* make sure to copy floats */ | 
					
						
							|  |  |  | 	    if (f== FunctorDouble) { | 
					
						
							|  |  |  | 	      sz = sizeof(Float)/sizeof(CELL)+2; | 
					
						
							|  |  |  | 	    } else if (f== FunctorLongInt) { | 
					
						
							|  |  |  | 	      sz = 3; | 
					
						
							| 
									
										
										
										
											2013-12-02 14:49:41 +00:00
										 |  |  | 	    } else if (f== FunctorString) { | 
					
						
							|  |  |  | 	      sz = 3+ap2[1]; | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | 	    } else { | 
					
						
							|  |  |  | 	      CELL *pt = ap2+1; | 
					
						
							|  |  |  | 	      sz = 2+sizeof(MP_INT)+(((MP_INT *)(pt+1))->_mp_alloc*sizeof(mp_limb_t)); | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	    if (HR+sz > ASP - 2048) { | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | 	      goto overflow; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	    memcpy((void *)HR, (void *)ap2, sz*sizeof(CELL)); | 
					
						
							|  |  |  | 	    HR += sz; | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | 	  } else { | 
					
						
							|  |  |  | 	    *ptf++ = d0;  /* you can just copy other extensions. */ | 
					
						
							|  |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	*ptf = AbsAppl(HR); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	ptf++; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	if (to_visit+1 >= (struct cp_frame *)AuxSp) { | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  | 	  goto heap_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	to_visit->to = ptf; | 
					
						
							|  |  |  | 	to_visit->oldv = *pt0; | 
					
						
							|  |  |  | 	to_visit->ground = ground; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	/* fool the system into thinking we had a variable there */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	*pt0 = AbsAppl(HR); | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	to_visit ++; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	  if (to_visit+1 >= (struct cp_frame *)AuxSp) { | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  | 	    goto heap_overflow; | 
					
						
							|  |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	  to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	  to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	  to_visit->to = ptf; | 
					
						
							|  |  |  | 	  to_visit->ground = ground; | 
					
						
							|  |  |  | 	  to_visit ++; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	ground = (f != FunctorMutable); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  | 	/* store the functor for the new term */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR[0] = (CELL)f; | 
					
						
							|  |  |  | 	ptf = HR+1; | 
					
						
							|  |  |  | 	HR += 1+d0; | 
					
						
							|  |  |  | 	if (HR > ASP - 2048) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  goto overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  | 	/* just copy atoms or integers */ | 
					
						
							|  |  |  | 	*ptf++ = d0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     derefa_body(d0, ptd0, copy_term_unk, copy_term_nvar); | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |     ground = FALSE; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     if (ptd0 >= HLow && ptd0 < HR) {  | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* we have already found this cell */ | 
					
						
							|  |  |  |       *ptf++ = (CELL) ptd0; | 
					
						
							| 
									
										
										
										
											2011-03-18 19:34:58 +00:00
										 |  |  |     } else  | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #if COROUTINING
 | 
					
						
							| 
									
										
										
										
											2007-10-11 14:25:09 +00:00
										 |  |  |       if (newattvs && IsAttachedTerm((CELL)ptd0)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	/* if unbound, call the standard copy term routine */ | 
					
						
							| 
									
										
										
										
											2010-03-10 14:06:07 +00:00
										 |  |  | 	struct cp_frame *bp; | 
					
						
							| 
									
										
										
										
											2011-03-18 19:34:58 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	CELL new; | 
					
						
							| 
									
										
										
										
											2004-04-20 22:08:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-18 19:34:58 +00:00
										 |  |  | 	bp = to_visit; | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  | 	if (!GLOBAL_attas[ExtFromCell(ptd0)].copy_term_op(ptd0, &bp, ptf PASS_REGS)) { | 
					
						
							| 
									
										
										
										
											2011-03-18 19:34:58 +00:00
										 |  |  | 	  goto overflow; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-03-18 19:34:58 +00:00
										 |  |  | 	to_visit = bp; | 
					
						
							|  |  |  | 	new = *ptf; | 
					
						
							|  |  |  | 	Bind_NonAtt(ptd0, new); | 
					
						
							|  |  |  | 	ptf++; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } else { | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	/* first time we met this term */ | 
					
						
							|  |  |  | 	RESET_VARIABLE(ptf); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  | 	if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { | 
					
						
							| 
									
										
										
										
											2007-11-12 10:39:49 +00:00
										 |  |  | 	  /* Trail overflow */ | 
					
						
							|  |  |  | 	  if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) { | 
					
						
							|  |  |  | 	    goto trail_overflow; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-03-18 19:34:58 +00:00
										 |  |  | 	Bind_NonAtt(ptd0, (CELL)ptf); | 
					
						
							| 
									
										
										
										
											2010-03-15 16:20:47 +00:00
										 |  |  | 	ptf++; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef COROUTINING
 | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-03-18 19:34:58 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   if (to_visit > to_visit0) { | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |     to_visit --; | 
					
						
							|  |  |  |     if (ground && share) { | 
					
						
							|  |  |  |       CELL old = to_visit->oldv; | 
					
						
							|  |  |  |       CELL *newp = to_visit->to-1; | 
					
						
							|  |  |  |       CELL new = *newp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       *newp = old; | 
					
						
							|  |  |  |       if (IsApplTerm(new)) | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR = RepAppl(new); | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR = RepPair(new); | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |     *pt0 = to_visit->oldv; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |     ground = (ground && to_visit->ground); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_dirty_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-03-15 14:17:30 +00:00
										 |  |  |   HB = HB0; | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |   return ground; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |  overflow: | 
					
						
							|  |  |  |   /* oops, we're in trouble */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HLow; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   /* we've done it */ | 
					
						
							|  |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							|  |  |  |   HB = HB0; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   while (to_visit > to_visit0) { | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							|  |  |  |     *pt0 = to_visit->oldv; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-09-07 20:20:12 +00:00
										 |  |  |   reset_trail(TR0); | 
					
						
							| 
									
										
										
										
											2010-03-15 14:17:30 +00:00
										 |  |  |   /* follow chain of multi-assigned variables */ | 
					
						
							| 
									
										
										
										
											2004-09-07 20:20:12 +00:00
										 |  |  |   return -1; | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  | trail_overflow: | 
					
						
							|  |  |  |   /* oops, we're in trouble */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HLow; | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |   /* we've done it */ | 
					
						
							|  |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							|  |  |  |   HB = HB0; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							|  |  |  |     *pt0 = to_visit->oldv; | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     tr_fr_ptr oTR =  TR; | 
					
						
							|  |  |  |     reset_trail(TR0); | 
					
						
							| 
									
										
										
										
											2009-05-04 21:26:47 -05:00
										 |  |  |     if (!Yap_growtrail((oTR-TR0)*sizeof(tr_fr_ptr *), TRUE)) { | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |       return -4; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return -2; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  |  heap_overflow: | 
					
						
							|  |  |  |   /* oops, we're in trouble */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HLow; | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  |   /* we've done it */ | 
					
						
							|  |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							|  |  |  |   HB = HB0; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   while (to_visit > to_visit0) { | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							|  |  |  |     *pt0 = to_visit->oldv; | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-09-09 20:00:59 +00:00
										 |  |  |   reset_trail(TR0); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = (ADDR)AuxSp-(ADDR)to_visit0; | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |   return -3; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Term | 
					
						
							| 
									
										
										
										
											2009-05-04 21:26:47 -05:00
										 |  |  | handle_cp_overflow(int res, tr_fr_ptr TR0, UInt arity, Term t) | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |   XREGS[arity+1] = t; | 
					
						
							|  |  |  |   switch(res) { | 
					
						
							|  |  |  |   case -1: | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     if (!Yap_gcl((ASP-HR)*sizeof(CELL), arity+1, ENV, gc_P(P,CP))) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |       return 0L; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return Deref(XREGS[arity+1]); | 
					
						
							|  |  |  |   case -2: | 
					
						
							|  |  |  |     return Deref(XREGS[arity+1]); | 
					
						
							|  |  |  |   case -3: | 
					
						
							| 
									
										
										
										
											2007-11-12 10:39:49 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       UInt size = LOCAL_Error_Size; | 
					
						
							|  |  |  |       LOCAL_Error_Size = 0L; | 
					
						
							| 
									
										
										
										
											2007-11-12 10:39:49 +00:00
										 |  |  |       if (size > 4*1024*1024) | 
					
						
							|  |  |  | 	size = 4*1024*1024; | 
					
						
							| 
									
										
										
										
											2009-05-22 18:35:24 -05:00
										 |  |  |       if (!Yap_ExpandPreAllocCodeSpace(size, NULL, TRUE)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	Yap_Error(RESOURCE_ERROR_AUXILIARY_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							| 
									
										
										
										
											2007-11-12 10:39:49 +00:00
										 |  |  | 	return 0L; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     return Deref(XREGS[arity+1]); | 
					
						
							| 
									
										
										
										
											2009-05-04 21:26:47 -05:00
										 |  |  |   case -4: | 
					
						
							|  |  |  |     if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), FALSE)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       Yap_Error(RESOURCE_ERROR_TRAIL, TermNil, LOCAL_ErrorMessage); | 
					
						
							| 
									
										
										
										
											2009-05-04 21:26:47 -05:00
										 |  |  |       return 0L; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return Deref(XREGS[arity+1]); | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |   default: | 
					
						
							|  |  |  |     return 0L; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | static Term | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | CopyTerm(Term inp, UInt arity, int share, int newattvs USES_REGS) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term t = Deref(inp); | 
					
						
							| 
									
										
										
										
											2009-05-04 21:26:47 -05:00
										 |  |  |   tr_fr_ptr TR0 = TR; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							|  |  |  | #if COROUTINING
 | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |     if (newattvs && IsAttachedTerm(t)) { | 
					
						
							| 
									
										
										
										
											2001-12-11 03:34:03 +00:00
										 |  |  |       CELL *Hi; | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  |       int res; | 
					
						
							| 
									
										
										
										
											2001-12-11 03:34:03 +00:00
										 |  |  |     restart_attached: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       *HR = t; | 
					
						
							|  |  |  |       Hi = HR+1; | 
					
						
							|  |  |  |       HR += 2; | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |       if ((res = copy_complex_term(Hi-2, Hi-1, share, newattvs, Hi, Hi PASS_REGS)) < 0) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR = Hi-1; | 
					
						
							| 
									
										
										
										
											2009-05-04 21:26:47 -05:00
										 |  |  | 	if ((t = handle_cp_overflow(res, TR0, arity, t))== 0L) | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  | 	  return FALSE; | 
					
						
							|  |  |  | 	goto restart_attached; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2005-10-30 00:32:55 +00:00
										 |  |  |       return Hi[0]; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-10-30 00:32:55 +00:00
										 |  |  |     return MkVarTerm(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else if (IsPrimitiveTerm(t)) { | 
					
						
							| 
									
										
										
										
											2005-10-30 00:32:55 +00:00
										 |  |  |     return t; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |     Term tf; | 
					
						
							|  |  |  |     CELL *ap; | 
					
						
							|  |  |  |     CELL *Hi; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   restart_list: | 
					
						
							|  |  |  |     ap = RepPair(t); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     Hi = HR; | 
					
						
							|  |  |  |     tf = AbsPair(HR); | 
					
						
							|  |  |  |     HR += 2; | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |       int res; | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |       if ((res = copy_complex_term(ap-1, ap+1, share, newattvs, Hi, Hi PASS_REGS)) < 0) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR = Hi; | 
					
						
							| 
									
										
										
										
											2009-05-04 21:26:47 -05:00
										 |  |  | 	if ((t = handle_cp_overflow(res, TR0, arity, t))== 0L) | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  | 	  return FALSE; | 
					
						
							|  |  |  | 	goto restart_list; | 
					
						
							| 
									
										
										
										
											2009-06-17 14:43:24 -05:00
										 |  |  |       } else if (res && share) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR = Hi; | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	return t; | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-10-30 00:32:55 +00:00
										 |  |  |     return tf; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |     Term tf; | 
					
						
							|  |  |  |     CELL *HB0; | 
					
						
							|  |  |  |     CELL *ap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   restart_appl: | 
					
						
							|  |  |  |     f = FunctorOfTerm(t); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     HB0 = HR; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     ap = RepAppl(t); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     tf = AbsAppl(HR); | 
					
						
							|  |  |  |     HR[0] = (CELL)f; | 
					
						
							|  |  |  |     HR += 1+ArityOfFunctor(f); | 
					
						
							|  |  |  |     if (HR > ASP-128) { | 
					
						
							|  |  |  |       HR = HB0; | 
					
						
							| 
									
										
										
										
											2009-05-04 21:26:47 -05:00
										 |  |  |       if ((t = handle_cp_overflow(-1, TR0, arity, t))== 0L) | 
					
						
							| 
									
										
										
										
											2006-12-27 01:32:38 +00:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |       goto restart_appl; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  |       int res; | 
					
						
							| 
									
										
										
										
											2004-12-16 05:57:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |       if ((res = copy_complex_term(ap, ap+ArityOfFunctor(f), share, newattvs, HB0+1, HB0 PASS_REGS)) < 0) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR = HB0; | 
					
						
							| 
									
										
										
										
											2009-05-04 21:26:47 -05:00
										 |  |  | 	if ((t = handle_cp_overflow(res, TR0, arity, t))== 0L) | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  | 	  return FALSE; | 
					
						
							|  |  |  | 	goto restart_appl; | 
					
						
							| 
									
										
										
										
											2009-06-17 14:43:24 -05:00
										 |  |  |       } else if (res && share && FunctorOfTerm(t) != FunctorMutable) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR = HB0; | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | 	return t; | 
					
						
							| 
									
										
										
										
											2002-04-08 22:10:14 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-10-30 00:32:55 +00:00
										 |  |  |     return tf; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  |   | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | Term | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | Yap_CopyTerm(Term inp) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   return CopyTerm(inp, 0, TRUE, TRUE PASS_REGS); | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | Term | 
					
						
							|  |  |  | Yap_CopyTermNoShare(Term inp) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   return CopyTerm(inp, 0, FALSE, FALSE PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_copy_term( USES_REGS1 )		/* copy term t to a new instance  */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   Term t = CopyTerm(ARG1, 2, TRUE, TRUE PASS_REGS);  | 
					
						
							| 
									
										
										
										
											2004-12-16 05:57:32 +00:00
										 |  |  |   if (t == 0L) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   /* be careful, there may be a stack shift here */ | 
					
						
							| 
									
										
										
										
											2004-09-18 14:03:42 +00:00
										 |  |  |   return Yap_unify(ARG2,t); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_duplicate_term( USES_REGS1 )		/* copy term t to a new instance  */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   Term t = CopyTerm(ARG1, 2, FALSE, TRUE PASS_REGS);  | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |   if (t == 0L) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   /* be careful, there may be a stack shift here */ | 
					
						
							|  |  |  |   return Yap_unify(ARG2,t); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_copy_term_no_delays( USES_REGS1 )		/* copy term t to a new instance  */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   Term t = CopyTerm(ARG1, 2, TRUE, FALSE PASS_REGS); | 
					
						
							| 
									
										
										
										
											2005-02-18 21:34:02 +00:00
										 |  |  |   if (t == 0L) { | 
					
						
							| 
									
										
										
										
											2004-12-16 05:57:32 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2005-02-18 21:34:02 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-12-16 05:57:32 +00:00
										 |  |  |   /* be careful, there may be a stack shift here */ | 
					
						
							|  |  |  |   return(Yap_unify(ARG2,t)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | typedef struct copy_frame { | 
					
						
							|  |  |  |   CELL *start_cp; | 
					
						
							|  |  |  |   CELL *end_cp; | 
					
						
							|  |  |  |   CELL *to; | 
					
						
							|  |  |  | } copy_frame_t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  | static Term * | 
					
						
							|  |  |  | add_to_list( Term *out_e, Term v, Term t USES_REGS) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Term ta[2], tv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ta[0] = v; | 
					
						
							|  |  |  |   ta[1] = t; | 
					
						
							|  |  |  |   *out_e = tv = MkPairTerm(Yap_MkApplTerm( FunctorEq, 2, ta ), TermNil); | 
					
						
							|  |  |  |   return RepPair(tv)+1;   | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  | break_rationals_complex_term(CELL *pt0, CELL *pt0_end, CELL *ptf, Term *of, Term oi, CELL *HLow USES_REGS) | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct copy_frame *to_visit0, *to_visit = (struct copy_frame *)Yap_PreAllocCodeSpace(); | 
					
						
							|  |  |  |   CELL *HB0 = HB; | 
					
						
							|  |  |  |   tr_fr_ptr TR0 = TR; | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |   CELL new = 0L; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   HB = HLow; | 
					
						
							|  |  |  |   to_visit0 = to_visit; | 
					
						
							|  |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |     if (new) { | 
					
						
							|  |  |  |       /* mark cell as pointing to new copy */ | 
					
						
							|  |  |  |       /* we can only mark after reading the value of the first argument */ | 
					
						
							|  |  |  |       MaBind(pt0, new); | 
					
						
							|  |  |  |       new = 0L; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  |     deref_head(d0, break_rationals_unk); | 
					
						
							|  |  |  |   break_rationals_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |       CELL first; | 
					
						
							|  |  |  |       CELL *newp; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  |       if (IsPairTerm(d0)) { | 
					
						
							|  |  |  | 	CELL *ap2 = RepPair(d0); | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (IsVarTerm(first = *ap2) && (newp = (CELL*)first) && newp >= HB && newp < HR) { | 
					
						
							|  |  |  | 	  // found a marked term:
 | 
					
						
							|  |  |  | 	found_term: | 
					
						
							|  |  |  | 	  if (!IsVarTerm(*newp)) { | 
					
						
							|  |  |  | 	    Term v = (CELL)newp, t = *newp; | 
					
						
							|  |  |  | 	    RESET_VARIABLE(newp); | 
					
						
							|  |  |  | 	    of = add_to_list( of, v, t PASS_REGS);  | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  *ptf++ = (CELL)newp; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | 	  continue; | 
					
						
							|  |  |  | 	}  | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  | 	new = (CELL)ptf; | 
					
						
							|  |  |  | 	*ptf++ = AbsPair(HR); | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  if (to_visit+1 >= (struct copy_frame *)AuxSp) { | 
					
						
							|  |  |  | 	    goto heap_overflow; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	  to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	  to_visit->to = ptf; | 
					
						
							|  |  |  | 	  to_visit ++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	pt0 = ap2 - 1; | 
					
						
							|  |  |  | 	pt0_end = ap2 + 1; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	ptf = HR; | 
					
						
							|  |  |  | 	HR += 2; | 
					
						
							|  |  |  | 	if (HR > ASP - 2048) { | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | 	  goto overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  | 	  *ptf++ = d0;  /* you can just share extensions, what about DB? */ | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  | 	if (IsVarTerm(first = ap2[1]) && (newp = (CELL*)first) && newp >= HB && newp < HR) { | 
					
						
							|  |  |  | 	  goto found_term; | 
					
						
							|  |  |  | 	}  | 
					
						
							|  |  |  | 	// new 
 | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | 	/* store the terms to visit */ | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  | 	new = (CELL)ptf; | 
					
						
							|  |  |  | 	*ptf++ = AbsAppl(HR); | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  if (to_visit+1 >= (struct copy_frame *)AuxSp) { | 
					
						
							|  |  |  | 	    goto heap_overflow; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	  to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	  to_visit->to = ptf; | 
					
						
							|  |  |  | 	  to_visit ++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  | 	/* store the functor for the new term */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR[0] = (CELL)f; | 
					
						
							|  |  |  | 	ptf = HR+1; | 
					
						
							|  |  |  | 	HR += 1+d0; | 
					
						
							|  |  |  | 	if (HR > ASP - 2048) { | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | 	  goto overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  | 	/* just copy atoms or integers */ | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  | 	*ptf++ = d0; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     derefa_body(d0, ptd0, break_rationals_unk, break_rationals_nvar); | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |     *ptf++ = d0; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							|  |  |  |   HB = HB0; | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |   reset_trail(TR0); | 
					
						
							|  |  |  |   RESET_VARIABLE(of); | 
					
						
							|  |  |  |   Yap_unify((CELL)of, oi); | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |  overflow: | 
					
						
							|  |  |  |   /* oops, we're in trouble */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HLow; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  |   /* we've done it */ | 
					
						
							|  |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							|  |  |  |   HB = HB0; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   reset_trail(TR0); | 
					
						
							|  |  |  |   /* follow chain of multi-assigned variables */ | 
					
						
							|  |  |  |   return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  heap_overflow: | 
					
						
							|  |  |  |   /* oops, we're in trouble */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HLow; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  |   /* we've done it */ | 
					
						
							|  |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							|  |  |  |   HB = HB0; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   reset_trail(TR0); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = (ADDR)AuxSp-(ADDR)to_visit0; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  |   return -3; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Term | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  | BreakRational(Term inp, UInt arity, Term *of, Term oi USES_REGS) { | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  |   Term t = Deref(inp); | 
					
						
							|  |  |  |   tr_fr_ptr TR0 = TR; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							|  |  |  |     return t; | 
					
						
							|  |  |  |   } else if (IsPrimitiveTerm(t)) { | 
					
						
							|  |  |  |     return t; | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |   } else  { | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  |     CELL *ap; | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |     CELL *Hi = HR; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |   restart_term: | 
					
						
							|  |  |  |     ap = &t; | 
					
						
							|  |  |  |     Hi = HR++; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |       int res; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |       if ((res = break_rationals_complex_term(ap-1, ap, Hi, of, oi, Hi PASS_REGS)) < 0) { | 
					
						
							|  |  |  | 	HR = Hi; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | 	if ((t = handle_cp_overflow(res, TR0, arity, t))== 0L) | 
					
						
							|  |  |  | 	  return FALSE; | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  | 	goto restart_term; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |     return Hi[0]; | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_break_rational( USES_REGS1 )  | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |   Term tf; | 
					
						
							|  |  |  |   return Yap_unify(ARG2, BreakRational(ARG1, 4, &tf, ARG4 PASS_REGS)) && | 
					
						
							|  |  |  |     Yap_unify(tf, ARG3); | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  | p_break_rational3( USES_REGS1 )  | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |   Term tf; | 
					
						
							|  |  |  |   return Yap_unify(ARG2, BreakRational(ARG1, 4, &tf, TermNil PASS_REGS)) && | 
					
						
							|  |  |  |     Yap_unify(tf, ARG3); | 
					
						
							| 
									
										
										
										
											2010-11-01 20:11:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-15 17:46:52 +01:00
										 |  |  | /* 
 | 
					
						
							|  |  |  |    FAST EXPORT ROUTINE. Export a Prolog term to something like: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    CELL 0: offset for start of term | 
					
						
							|  |  |  |    CELL 1: size of actual term (to be copied to stack) | 
					
						
							|  |  |  |    CELL 2: the original term (just for reference) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Atoms and functors: | 
					
						
							|  |  |  |    - atoms are either: | 
					
						
							|  |  |  |      0 and a char *string | 
					
						
							|  |  |  |      -1 and a wchar_t *string | 
					
						
							|  |  |  |    - functors are a CELL with arity and a string. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Compiled Term. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | static inline | 
					
						
							|  |  |  | CELL *CellDifH(CELL *hptr, CELL *hlow) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return (CELL *)((char *)hptr-(char *)hlow); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 17:04:28 +01:00
										 |  |  | #define AdjustSizeAtom(X)	(((CELL)(X)+(8-1)) & ~(8-1))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline | 
					
						
							|  |  |  | CELL *AdjustSize(CELL *x, char *buf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   UInt offset = (char *)x-buf; | 
					
						
							|  |  |  |   return (CELL*)(buf+AdjustSizeAtom(offset)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 12:55:34 +01:00
										 |  |  | /* export an atom from the symbol table to a buffer */ | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | static inline  | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  | Atom export_atom(Atom at, char **hpp, char *buf, size_t len) | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | {				  | 
					
						
							|  |  |  |   char *ptr, *p0; | 
					
						
							|  |  |  |   size_t sz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ptr = *hpp; | 
					
						
							| 
									
										
										
										
											2012-05-08 17:04:28 +01:00
										 |  |  |   ptr = (char *)AdjustSize((CELL*)ptr, buf); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |    | 
					
						
							|  |  |  |   p0 = ptr; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:46:52 +01:00
										 |  |  |   if (IsWideAtom(at)) { | 
					
						
							|  |  |  |     wchar_t *wptr = (wchar_t *)ptr; | 
					
						
							|  |  |  |     *wptr++ = -1; | 
					
						
							|  |  |  |     sz = wcslen(RepAtom(at)->WStrOfAE); | 
					
						
							|  |  |  |     if (sizeof(wchar_t)*(sz+1) >= len) | 
					
						
							|  |  |  |       return (Atom)NULL; | 
					
						
							|  |  |  |     wcsncpy(wptr, RepAtom(at)->WStrOfAE, len); | 
					
						
							|  |  |  |     *hpp = (char *)(wptr+(sz+1)); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     *ptr++ = 0; | 
					
						
							|  |  |  |     sz = strlen(RepAtom(at)->StrOfAE); | 
					
						
							| 
									
										
										
										
											2012-05-08 12:55:34 +01:00
										 |  |  |     if (sz + 1 + sizeof(wchar_t) >= len) | 
					
						
							| 
									
										
										
										
											2010-07-15 17:46:52 +01:00
										 |  |  |       return (Atom)NULL; | 
					
						
							|  |  |  |     strcpy(ptr, RepAtom(at)->StrOfAE); | 
					
						
							|  |  |  |     *hpp = ptr+(sz+1); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   return (Atom)(p0-buf); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 12:55:34 +01:00
										 |  |  | /* place a buffer: first arity then the atom */ | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | static inline  | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  | Functor export_functor(Functor f, char **hpp, char *buf, size_t len) | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 17:04:28 +01:00
										 |  |  |   CELL *hptr = AdjustSize((CELL *)*hpp, buf); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   UInt arity = ArityOfFunctor(f); | 
					
						
							|  |  |  |   if (2*sizeof(CELL) >= len) | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   hptr[0] = arity; | 
					
						
							|  |  |  |   *hpp = (char *)(hptr+1); | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   if (!export_atom(NameOfFunctor(f), hpp, buf, len)) | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2012-05-08 12:55:34 +01:00
										 |  |  |   /* increment so that it cannot be mistaken with a functor on the stack,
 | 
					
						
							|  |  |  |      (increment is used as a tag ........01 | 
					
						
							|  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   return (Functor)(((char *)hptr-buf)+1); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define export_derefa_body(D,A,LabelUnk,LabelNonVar)                \
 | 
					
						
							|  |  |  | 		do {                                         \ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 		  if ((CELL *)(D) < CellDifH(HR,HLow)) { (A) = (CELL *)(D); break; } \ | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |                    (A) = (CELL *)(D);                        \ | 
					
						
							|  |  |  |                    (D) = *(CELL *)(D);                       \ | 
					
						
							|  |  |  |                    if(!IsVarTerm(D)) goto LabelNonVar;       \ | 
					
						
							|  |  |  | 		LabelUnk:      ;                             \ | 
					
						
							|  |  |  | 		} while (Unsigned(A) != (D)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | export_term_to_buffer(Term inpt, char *buf, char *bptr, CELL *t0 , CELL *tf, size_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char *td = bptr; | 
					
						
							|  |  |  |   CELL *bf = (CELL *)buf; | 
					
						
							| 
									
										
										
										
											2012-05-08 12:55:34 +01:00
										 |  |  |   if (buf + len < (char *)((CELL *)td + (tf-t0))) { | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2012-05-08 12:55:34 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-05-08 17:04:28 +01:00
										 |  |  |   memcpy((void *)td, (void *)t0, (tf-t0)* sizeof(CELL));  | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   bf[0] = (td-buf); | 
					
						
							|  |  |  |   bf[1] = (tf-t0); | 
					
						
							|  |  |  |   bf[2] = inpt; | 
					
						
							| 
									
										
										
										
											2010-07-15 23:35:37 +01:00
										 |  |  |   return bf[0]+sizeof(CELL)*bf[1]; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-02 09:58:05 +00:00
										 |  |  | static size_t | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | export_complex_term(Term tf, CELL *pt0, CELL *pt0_end, char * buf, size_t len0, int newattvs, CELL *ptf, CELL *HLow USES_REGS) | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   struct cp_frame *to_visit0, *to_visit = (struct cp_frame *)Yap_PreAllocCodeSpace(); | 
					
						
							|  |  |  |   CELL *HB0 = HB; | 
					
						
							|  |  |  |   tr_fr_ptr TR0 = TR; | 
					
						
							|  |  |  |   int ground = TRUE; | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   char *bptr = buf+ 3*sizeof(CELL); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   size_t len = len0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   HB = HLow; | 
					
						
							|  |  |  |   to_visit0 = to_visit; | 
					
						
							|  |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, export_term_unk); | 
					
						
							|  |  |  |   export_term_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							|  |  |  | 	CELL *ap2 = RepPair(d0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	if (ap2 < CellDifH(HR,HLow)) { | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	  /* If this is newer than the current term, just reuse */ | 
					
						
							|  |  |  | 	  *ptf++ = d0; | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	}  | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	*ptf = AbsPair(CellDifH(HR,HLow)); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	ptf++; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	if (to_visit+1 >= (struct cp_frame *)AuxSp) { | 
					
						
							|  |  |  | 	  goto heap_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	to_visit->to = ptf; | 
					
						
							|  |  |  | 	to_visit->oldv = *pt0; | 
					
						
							|  |  |  | 	to_visit->ground = ground; | 
					
						
							|  |  |  | 	/* fool the system into thinking we had a variable there */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	*pt0 = AbsPair(CellDifH(HR,HLow)); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	to_visit ++; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  if (to_visit+1 >= (struct cp_frame *)AuxSp) { | 
					
						
							|  |  |  | 	    goto heap_overflow; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	  to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	  to_visit->to = ptf; | 
					
						
							|  |  |  | 	  to_visit->ground = ground; | 
					
						
							|  |  |  | 	  to_visit ++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	pt0 = ap2 - 1; | 
					
						
							|  |  |  | 	pt0_end = ap2 + 1; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	ptf = HR; | 
					
						
							|  |  |  | 	HR += 2; | 
					
						
							|  |  |  | 	if (HR > ASP - 2048) { | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	  goto overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	if (ap2 < CellDifH(HR,HLow)) { | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	  /* If this is newer than the current term, just reuse */ | 
					
						
							|  |  |  | 	  *ptf++ = d0; | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	}  | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	*ptf++ = AbsAppl(CellDifH(HR,HLow)); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	  UInt sz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  /* make sure to export floats */ | 
					
						
							|  |  |  | 	  if (f== FunctorDouble) { | 
					
						
							|  |  |  | 	    sz = sizeof(Float)/sizeof(CELL)+2; | 
					
						
							|  |  |  | 	  } else if (f== FunctorLongInt) { | 
					
						
							|  |  |  | 	    sz = 3; | 
					
						
							| 
									
										
										
										
											2013-12-02 14:49:41 +00:00
										 |  |  | 	  } else if (f== FunctorString) { | 
					
						
							|  |  |  | 	    sz = 3+ap2[1]; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	  } else { | 
					
						
							|  |  |  | 	    CELL *pt = ap2+1; | 
					
						
							|  |  |  | 	    sz = 2+sizeof(MP_INT)+(((MP_INT *)(pt+1))->_mp_alloc*sizeof(mp_limb_t)); | 
					
						
							|  |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	  if (HR+sz > ASP - 2048) { | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	    goto overflow; | 
					
						
							|  |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	  memcpy((void *)HR, (void *)ap2, sz*sizeof(CELL)); | 
					
						
							|  |  |  | 	  HR += sz; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	if (to_visit+1 >= (struct cp_frame *)AuxSp) { | 
					
						
							|  |  |  | 	  goto heap_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	to_visit->to = ptf; | 
					
						
							|  |  |  | 	to_visit->oldv = *pt0; | 
					
						
							|  |  |  | 	to_visit->ground = ground; | 
					
						
							|  |  |  | 	/* fool the system into thinking we had a variable there */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	*pt0 = AbsAppl(HR); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	to_visit ++; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  if (to_visit+1 >= (struct cp_frame *)AuxSp) { | 
					
						
							|  |  |  | 	    goto heap_overflow; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	  to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	  to_visit->to = ptf; | 
					
						
							|  |  |  | 	  to_visit->ground = ground; | 
					
						
							|  |  |  | 	  to_visit ++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	ground = (f != FunctorMutable); | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  | 	/* store the functor for the new term */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	ptf = HR+1; | 
					
						
							|  |  |  | 	HR += 1+d0; | 
					
						
							|  |  |  | 	if (HR > ASP - 2048) { | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	  goto overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  | 	ptf[-1] = (CELL)export_functor(f, &bptr, buf, len); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	len = len0 - (bptr-buf); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	if (HR > ASP - 2048) { | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	  goto overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  | 	if (IsAtomTerm(d0)) { | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  | 	  *ptf = MkAtomTerm(export_atom(AtomOfTerm(d0), &bptr, buf, len)); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	  ptf++; | 
					
						
							|  |  |  | 	  len = len0 - (bptr-buf); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 	  *ptf++ = d0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     export_derefa_body(d0, ptd0, export_term_unk, export_term_nvar); | 
					
						
							|  |  |  |     ground = FALSE; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     if (ptd0 < CellDifH(HR,HLow)) {  | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |       /* we have already found this cell */ | 
					
						
							|  |  |  |       *ptf++ = (CELL) ptd0; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  | #if COROUTINING
 | 
					
						
							|  |  |  |       if (newattvs && IsAttachedTerm((CELL)ptd0) && FALSE) { | 
					
						
							|  |  |  | 	/* if unbound, call the standard export term routine */ | 
					
						
							|  |  |  | 	struct cp_frame *bp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-18 19:34:58 +00:00
										 |  |  | 	CELL new; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-18 19:34:58 +00:00
										 |  |  | 	bp = to_visit; | 
					
						
							| 
									
										
										
										
											2011-05-25 16:40:36 +01:00
										 |  |  | 	if (!GLOBAL_attas[ExtFromCell(ptd0)].copy_term_op(ptd0, &bp, ptf PASS_REGS)) { | 
					
						
							| 
									
										
										
										
											2011-03-18 19:34:58 +00:00
										 |  |  | 	  goto overflow; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-03-18 19:34:58 +00:00
										 |  |  | 	to_visit = bp; | 
					
						
							|  |  |  | 	new = *ptf; | 
					
						
							|  |  |  | 	Bind_NonAtt(ptd0, new); | 
					
						
							|  |  |  | 	ptf++; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |       } else { | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	/* first time we met this term */ | 
					
						
							|  |  |  | 	*ptf = (CELL)CellDifH(ptf,HLow); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  | 	if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	  /* Trail overflow */ | 
					
						
							|  |  |  | 	  if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) { | 
					
						
							|  |  |  | 	    goto trail_overflow; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-03-18 19:34:58 +00:00
										 |  |  | 	Bind_NonAtt(ptd0, (CELL)ptf); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 	ptf++; | 
					
						
							|  |  |  | #ifdef COROUTINING
 | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     *pt0 = to_visit->oldv; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     ground = (ground && to_visit->ground); | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_dirty_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   HB = HB0; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   return export_term_to_buffer(tf, buf, bptr, HLow, HR, len0); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |  overflow: | 
					
						
							|  |  |  |   /* oops, we're in trouble */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HLow; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   /* we've done it */ | 
					
						
							|  |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							|  |  |  |   HB = HB0; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							|  |  |  |     *pt0 = to_visit->oldv; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   reset_trail(TR0); | 
					
						
							|  |  |  |   /* follow chain of multi-assigned variables */ | 
					
						
							|  |  |  |   return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | trail_overflow: | 
					
						
							|  |  |  |   /* oops, we're in trouble */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HLow; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   /* we've done it */ | 
					
						
							|  |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							|  |  |  |   HB = HB0; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							|  |  |  |     *pt0 = to_visit->oldv; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     tr_fr_ptr oTR =  TR; | 
					
						
							|  |  |  |     reset_trail(TR0); | 
					
						
							|  |  |  |     if (!Yap_growtrail((oTR-TR0)*sizeof(tr_fr_ptr *), TRUE)) { | 
					
						
							|  |  |  |       return -4; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return -2; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  heap_overflow: | 
					
						
							|  |  |  |   /* oops, we're in trouble */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HLow; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   /* we've done it */ | 
					
						
							|  |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							|  |  |  |   HB = HB0; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							|  |  |  |     *pt0 = to_visit->oldv; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   reset_trail(TR0); | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = (ADDR)AuxSp-(ADDR)to_visit0; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   return -3; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-02 09:58:05 +00:00
										 |  |  | static size_t | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | ExportTerm(Term inp, char * buf, size_t len, UInt arity, int newattvs USES_REGS) { | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   Term t = Deref(inp); | 
					
						
							|  |  |  |   tr_fr_ptr TR0 = TR; | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   size_t res = 0; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   CELL *Hi = HR; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   do { | 
					
						
							| 
									
										
										
										
											2013-04-14 21:37:43 +01:00
										 |  |  |     if (IsVarTerm(t) || IsIntTerm(t)) { | 
					
						
							|  |  |  |       return export_term_to_buffer(t, buf, buf+ 3*sizeof(CELL), &inp, &inp, len); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (IsAtomTerm(t)) { | 
					
						
							|  |  |  |       Atom at = AtomOfTerm(t); | 
					
						
							|  |  |  |       char *b = buf+3*sizeof(CELL); | 
					
						
							|  |  |  |       export_atom(at, &b, b, len-3*sizeof(CELL)); | 
					
						
							|  |  |  |       return export_term_to_buffer(t, buf, b, &inp, &inp, len); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |     if ((Int)res < 0) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       HR = Hi; | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |       TR = TR0; | 
					
						
							|  |  |  |       if ((t = handle_cp_overflow(res, TR0, arity, t))== 0L) | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     Hi = HR; | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |     TR0 = TR; | 
					
						
							|  |  |  |     res = export_complex_term(inp, &t-1, &t, buf, len, newattvs, Hi, Hi PASS_REGS); | 
					
						
							|  |  |  |   } while ((Int)res < 0); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  |   | 
					
						
							| 
									
										
										
										
											2012-02-02 09:58:05 +00:00
										 |  |  | size_t | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  | Yap_ExportTerm(Term inp, char * buf, size_t len, UInt arity) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   return ExportTerm(inp, buf, len, arity, TRUE PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static CELL * | 
					
						
							|  |  |  | ShiftPtr(CELL t, char *base) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return (CELL *)(base+t); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Atom | 
					
						
							| 
									
										
										
										
											2013-11-15 18:25:33 +00:00
										 |  |  | addAtom(Atom t, char *buf) | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   char *s = buf+(UInt)t; | 
					
						
							| 
									
										
										
										
											2012-05-08 17:04:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-15 17:46:52 +01:00
										 |  |  |   if (!*s) { | 
					
						
							|  |  |  |     return Yap_LookupAtom(s+1); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     wchar_t *w = (wchar_t *)s; | 
					
						
							|  |  |  |     return Yap_LookupWideAtom(w+1); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static UInt | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  | FetchFunctor(CELL *pt, char *buf) | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   CELL *ptr = (CELL *)(buf+(*pt-1));  | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   // do arity first
 | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   UInt arity = *ptr++; | 
					
						
							|  |  |  |   Atom name, at; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   // and then an atom
 | 
					
						
							| 
									
										
										
										
											2012-05-08 17:04:28 +01:00
										 |  |  |   ptr = AdjustSize(ptr, buf); | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   name = (Atom)((char *)ptr-buf); | 
					
						
							| 
									
										
										
										
											2013-11-15 18:25:33 +00:00
										 |  |  |   at = addAtom(name, buf); | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   *pt = (CELL)Yap_MkFunctor(at, arity); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   return arity; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  | static CELL *import_compound(CELL *hp, char *abase, char *buf, CELL *amax); | 
					
						
							|  |  |  | static CELL *import_pair(CELL *hp, char *abase, char *buf, CELL *amax); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static CELL * | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  | import_arg(CELL *hp, char *abase, char *buf, CELL *amax) | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   Term t = *hp; | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							|  |  |  |     hp[0] = (CELL)ShiftPtr(t, abase); | 
					
						
							|  |  |  |   } else if (IsAtomTerm(t)) { | 
					
						
							| 
									
										
										
										
											2013-11-15 18:25:33 +00:00
										 |  |  |     hp[0] = MkAtomTerm(addAtom(AtomOfTerm(t), buf)); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   } else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |     CELL *newp = ShiftPtr((CELL)RepPair(t), abase); | 
					
						
							|  |  |  |     hp[0] = AbsPair(newp); | 
					
						
							|  |  |  |     if (newp > amax) { | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |       amax = import_pair(newp, abase, buf, newp); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-02-02 09:58:05 +00:00
										 |  |  |   } else if (IsApplTerm(t)) { | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |     CELL *newp = ShiftPtr((CELL)RepAppl(t), abase); | 
					
						
							|  |  |  |     hp[0] = AbsAppl(newp); | 
					
						
							|  |  |  |     if (newp > amax) { | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |       amax = import_compound(newp, abase, buf, newp); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return amax; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static CELL * | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  | import_compound(CELL *hp, char *abase, char *buf, CELL *amax) | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   Functor f = (Functor)*hp; | 
					
						
							|  |  |  |   UInt ar, i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   if (!((CELL)f & 1) && IsExtensionFunctor(f)) | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |     return amax; | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   ar = FetchFunctor(hp, buf); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   for (i=1; i<=ar; i++) { | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |     amax = import_arg(hp+i, abase, buf, amax); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   }     | 
					
						
							|  |  |  |   return amax; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static CELL * | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  | import_pair(CELL *hp, char *abase, char *buf, CELL *amax) | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-02-02 23:25:09 +00:00
										 |  |  |   amax = import_arg(hp, abase, buf, amax); | 
					
						
							|  |  |  |   amax = import_arg(hp+1, abase, buf, amax); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   return amax; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Term | 
					
						
							|  |  |  | Yap_ImportTerm(char * buf) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   CELL *bc = (CELL *)buf; | 
					
						
							|  |  |  |   size_t sz = bc[1]; | 
					
						
							|  |  |  |   Term tinp, tret; | 
					
						
							|  |  |  |   tinp = bc[2]; | 
					
						
							|  |  |  |   if (IsVarTerm(tinp)) | 
					
						
							|  |  |  |     return MkVarTerm(); | 
					
						
							| 
									
										
										
										
											2013-04-14 21:37:43 +01:00
										 |  |  |   else if (IsIntTerm(tinp)) | 
					
						
							|  |  |  |     return tinp; | 
					
						
							|  |  |  |   else if (IsAtomTerm(tinp)) { | 
					
						
							| 
									
										
										
										
											2013-11-15 18:25:33 +00:00
										 |  |  |     tret = MkAtomTerm(addAtom(NULL,(char *)(bc+3))); | 
					
						
							| 
									
										
										
										
											2013-04-14 21:37:43 +01:00
										 |  |  |     return tret; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-02-06 18:05:21 +00:00
										 |  |  |   // call the gc/stack shifter mechanism
 | 
					
						
							|  |  |  |   // if not enough stack available
 | 
					
						
							|  |  |  |   while (HR + sz > ASP - 4096) { | 
					
						
							|  |  |  |     if (!Yap_gcl( (sz+4096)*sizeof(CELL), PP->ArityOfPE, ENV, gc_P(P,CP))) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							| 
									
										
										
										
											2015-02-06 18:05:21 +00:00
										 |  |  |       return 0L; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   memcpy(HR, buf+bc[0], sizeof(CELL)*sz); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   if (IsApplTerm(tinp)) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     tret = AbsAppl(HR); | 
					
						
							|  |  |  |     import_compound(HR, (char *)HR, buf, HR); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     tret = AbsPair(HR); | 
					
						
							|  |  |  |     import_pair(HR, (char *)HR, buf, HR); | 
					
						
							| 
									
										
										
										
											2013-04-14 21:37:43 +01:00
										 |  |  |   }  | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR += sz; | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  |   return tret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-03 16:31:49 +00:00
										 |  |  | size_t | 
					
						
							|  |  |  | Yap_SizeOfExportedTerm(char * buf) { | 
					
						
							|  |  |  |   CELL *bc = (CELL *)buf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return bc[0]+bc[1]*sizeof(CELL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_export_term( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-02-05 11:20:30 +00:00
										 |  |  |   size_t sz = 4096, osz; | 
					
						
							|  |  |  |   char *export_buf; | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     export_buf  = malloc(sz); | 
					
						
							|  |  |  |     if (!export_buf) | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     if (!(osz = Yap_ExportTerm(ARG1, export_buf, sz, 1))) { | 
					
						
							|  |  |  |       sz += 4096; | 
					
						
							|  |  |  |       free(export_buf); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-02-05 11:57:03 +00:00
										 |  |  |   } while (!osz); | 
					
						
							|  |  |  |   return Yap_unify(ARG3,MkIntegerTerm(osz)) && | 
					
						
							|  |  |  |     Yap_unify(ARG2, MkIntegerTerm((Int)export_buf)); | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_import_term( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-02-05 11:20:30 +00:00
										 |  |  |   char *export_buf = (char *)IntegerOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  |   if (!export_buf) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   Int out = Yap_unify(ARG2,Yap_ImportTerm(export_buf)); | 
					
						
							|  |  |  |   return out;						  | 
					
						
							| 
									
										
										
										
											2010-07-15 17:19:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-05 11:57:03 +00:00
										 |  |  | static Int | 
					
						
							|  |  |  | p_kill_exported_term( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char *export_buf = (char *)IntegerOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  |   if (!export_buf) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   free(export_buf); | 
					
						
							|  |  |  |   return TRUE;						  | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | static Term vars_in_complex_term(register CELL *pt0, register CELL *pt0_end, Term inp USES_REGS) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   register CELL **to_visit0, **to_visit = (CELL **)Yap_PreAllocCodeSpace(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   register tr_fr_ptr TR0 = TR; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   CELL *InitialH = HR; | 
					
						
							|  |  |  |   CELL output = AbsPair(HR); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   to_visit0 = to_visit; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, vars_in_term_unk); | 
					
						
							|  |  |  |   vars_in_term_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							| 
									
										
										
										
											2007-11-14 09:23:42 +00:00
										 |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  | 	pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							| 
									
										
										
										
											2007-11-14 09:23:42 +00:00
										 |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     derefa_body(d0, ptd0, vars_in_term_unk, vars_in_term_nvar); | 
					
						
							|  |  |  |     /* do or pt2 are unbound  */ | 
					
						
							|  |  |  |     *ptd0 = TermNil; | 
					
						
							|  |  |  |     /* leave an empty slot to fill in later */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     if (HR+1024 > ASP) { | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |       goto global_overflow; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     HR[1] = AbsPair(HR+2); | 
					
						
							|  |  |  |     HR += 2; | 
					
						
							|  |  |  |     HR[-2] = (CELL)ptd0; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     /* next make sure noone will see this as a variable again */  | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |       /* Trail overflow */ | 
					
						
							|  |  |  |       if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) { | 
					
						
							|  |  |  | 	goto trail_overflow; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     TrailTerm(TR++) = (CELL)ptd0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   if (to_visit > to_visit0) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     to_visit -= 2; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   if (HR != InitialH) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     /* close the list */ | 
					
						
							| 
									
										
										
										
											2004-02-09 14:19:05 +00:00
										 |  |  |     Term t2 = Deref(inp); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (IsVarTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       RESET_VARIABLE(HR-1); | 
					
						
							|  |  |  |       Yap_unify((CELL)(HR-1),inp); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       HR[-1] = t2;		/* don't need to trail */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     return(output); | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2004-02-09 14:19:05 +00:00
										 |  |  |     return(inp); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |  trail_overflow: | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_TRAIL; | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = (TR-TR0)*sizeof(tr_fr_ptr *); | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2007-11-14 09:23:42 +00:00
										 |  |  |  aux_overflow: | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = (to_visit-to_visit0)*sizeof(CELL **); | 
					
						
							| 
									
										
										
										
											2007-11-14 09:23:42 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK; | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2007-11-14 09:23:42 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2007-11-14 09:23:42 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |  global_overflow: | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_STACK; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   LOCAL_Error_Size = (ASP-HR)*sizeof(CELL); | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | expand_vts( int args USES_REGS ) | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   UInt expand = LOCAL_Error_Size; | 
					
						
							|  |  |  |   yap_error_number yap_errno = LOCAL_Error_TYPE; | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |    | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = 0; | 
					
						
							|  |  |  |   LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   if (yap_errno == RESOURCE_ERROR_TRAIL) { | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |     /* Trail overflow */ | 
					
						
							|  |  |  |     if (!Yap_growtrail(expand, FALSE)) { | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   } else if (yap_errno == RESOURCE_ERROR_AUXILIARY_STACK) { | 
					
						
							| 
									
										
										
										
											2007-11-14 09:23:42 +00:00
										 |  |  |     /* Aux space overflow */ | 
					
						
							|  |  |  |     if (expand > 4*1024*1024) | 
					
						
							|  |  |  |       expand = 4*1024*1024; | 
					
						
							| 
									
										
										
										
											2009-05-22 18:35:24 -05:00
										 |  |  |     if (!Yap_ExpandPreAllocCodeSpace(expand, NULL, TRUE)) { | 
					
						
							| 
									
										
										
										
											2007-11-14 09:23:42 +00:00
										 |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2008-08-28 04:43:00 +01:00
										 |  |  |     if (!Yap_gcl(expand, 3, ENV, gc_P(P,CP))) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       Yap_Error(RESOURCE_ERROR_STACK, TermNil, "in term_variables"); | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_variables_in_term( USES_REGS1 )	/* variables in term t		 */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-03-09 14:15:41 +00:00
										 |  |  |   Term out, inp; | 
					
						
							|  |  |  |   int count; | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-09 14:15:41 +00:00
										 |  |  |  restart: | 
					
						
							|  |  |  |   count = 0; | 
					
						
							|  |  |  |   inp = Deref(ARG2); | 
					
						
							|  |  |  |   while (!IsVarTerm(inp) && IsPairTerm(inp)) { | 
					
						
							|  |  |  |     Term t = HeadOfTerm(inp); | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |       CELL *ptr = VarOfTerm(t); | 
					
						
							|  |  |  |       *ptr = TermFoundVar; | 
					
						
							|  |  |  |       TrailTerm(TR++) = t; | 
					
						
							| 
									
										
										
										
											2009-03-09 14:15:41 +00:00
										 |  |  |       count++; | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 	clean_tr(TR-count PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-09 14:15:41 +00:00
										 |  |  | 	if (!Yap_growtrail(count*sizeof(tr_fr_ptr *), FALSE)) { | 
					
						
							|  |  |  | 	  return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	goto restart; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     inp = TailOfTerm(inp); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |   do { | 
					
						
							|  |  |  |     Term t = Deref(ARG1); | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       out = AbsPair(HR); | 
					
						
							|  |  |  |       HR += 2; | 
					
						
							|  |  |  |       RESET_VARIABLE(HR-2); | 
					
						
							|  |  |  |       RESET_VARIABLE(HR-1); | 
					
						
							|  |  |  |       Yap_unify((CELL)(HR-2),ARG1); | 
					
						
							|  |  |  |       Yap_unify((CELL)(HR-1),ARG2); | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |     }  else if (IsPrimitiveTerm(t))  | 
					
						
							|  |  |  |       out = ARG2; | 
					
						
							|  |  |  |     else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |       out = vars_in_complex_term(RepPair(t)-1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				 RepPair(t)+1, ARG2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |       out = vars_in_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 				 RepAppl(t)+ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				 ArityOfFunctor(f), ARG2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (out == 0L) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |       if (!expand_vts( 3 PASS_REGS )) | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } while (out == 0L); | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR-count PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-09 14:15:41 +00:00
										 |  |  |   return Yap_unify(ARG3,out); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-09 14:19:05 +00:00
										 |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_term_variables( USES_REGS1 )	/* variables in term t		 */ | 
					
						
							| 
									
										
										
										
											2004-02-09 14:19:05 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Term out; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-18 00:07:06 +00:00
										 |  |  |   if (!Yap_IsListOrPartialListTerm(ARG2)) { | 
					
						
							|  |  |  |     Yap_Error(TYPE_ERROR_LIST,ARG2,"term_variables/2"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |   do { | 
					
						
							|  |  |  |     Term t = Deref(ARG1); | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2008-04-03 10:50:28 +00:00
										 |  |  |       Term out = Yap_MkNewPairTerm(); | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  | 	Yap_unify(t,HeadOfTerm(out)) && | 
					
						
							|  |  |  | 	Yap_unify(TermNil, TailOfTerm(out)) && | 
					
						
							|  |  |  | 	Yap_unify(out, ARG2); | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |     }  else if (IsPrimitiveTerm(t)) { | 
					
						
							|  |  |  |       return Yap_unify(TermNil, ARG2); | 
					
						
							|  |  |  |     } else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |       out = vars_in_complex_term(RepPair(t)-1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				 RepPair(t)+1, TermNil PASS_REGS); | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |       out = vars_in_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 				 RepAppl(t)+ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				 ArityOfFunctor(f), TermNil PASS_REGS); | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (out == 0L) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |       if (!expand_vts( 3 PASS_REGS )) | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } while (out == 0L); | 
					
						
							| 
									
										
										
										
											2004-02-09 14:19:05 +00:00
										 |  |  |   return Yap_unify(ARG2,out); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-04 22:08:37 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Exports a nil-terminated list with all the variables in a term. | 
					
						
							|  |  |  |  * @param[in] the term | 
					
						
							|  |  |  |  * @param[in] the arity of the calling predicate (required for exact garbage collection). | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | Term | 
					
						
							|  |  |  | Yap_TermVariables( Term t, UInt arity USES_REGS )	/* variables in term t		 */ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Term out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    do { | 
					
						
							|  |  |  |     t = Deref(t); | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							|  |  |  |       return MkPairTerm(t, TermNil); | 
					
						
							|  |  |  |     }  else if (IsPrimitiveTerm(t)) { | 
					
						
							|  |  |  |       return TermNil; | 
					
						
							|  |  |  |     } else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |       out = vars_in_complex_term(RepPair(t)-1, | 
					
						
							|  |  |  | 				 RepPair(t)+1, TermNil PASS_REGS); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |       out = vars_in_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 				 RepAppl(t)+ | 
					
						
							|  |  |  | 				 ArityOfFunctor(f), TermNil PASS_REGS); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (out == 0L) { | 
					
						
							|  |  |  |       if (!expand_vts( arity PASS_REGS )) | 
					
						
							|  |  |  | 	return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } while (out == 0L); | 
					
						
							|  |  |  |   return out; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | static Term attvars_in_complex_term(register CELL *pt0, register CELL *pt0_end, Term inp USES_REGS) | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   register CELL **to_visit0, **to_visit = (CELL **)Yap_PreAllocCodeSpace(); | 
					
						
							|  |  |  |   register tr_fr_ptr TR0 = TR; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   CELL *InitialH = HR; | 
					
						
							|  |  |  |   CELL output = AbsPair(HR); | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   to_visit0 = to_visit; | 
					
						
							|  |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, attvars_in_term_unk); | 
					
						
							|  |  |  |   attvars_in_term_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							| 
									
										
										
										
											2016-01-06 12:39:12 +00:00
										 |  |  |         if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  |           goto aux_overflow; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           CELL *npt0 = RepPair(d0); | 
					
						
							|  |  |  |           if(IsAtomicTerm(Deref(npt0[0]))) { | 
					
						
							|  |  |  |             pt0 = npt0; | 
					
						
							|  |  |  |             pt0_end = pt0 + 1; | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							| 
									
										
										
										
											2016-01-06 12:39:12 +00:00
										 |  |  |           pt0_end = pt0+2; | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     derefa_body(d0, ptd0, attvars_in_term_unk, attvars_in_term_nvar); | 
					
						
							|  |  |  |     if (IsAttVar(ptd0)) { | 
					
						
							|  |  |  |       /* do or pt2 are unbound  */ | 
					
						
							|  |  |  |       *ptd0 = TermNil; | 
					
						
							|  |  |  |       /* next make sure noone will see this as a variable again */  | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  | 	/* Trail overflow */ | 
					
						
							| 
									
										
										
										
											2016-01-06 12:39:12 +00:00
										 |  |  |         if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) { | 
					
						
							|  |  |  |           goto trail_overflow; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       TrailTerm(TR++) = (CELL)ptd0; | 
					
						
							|  |  |  |       /* leave an empty slot to fill in later */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       if (HR+1024 > ASP) { | 
					
						
							| 
									
										
										
										
											2016-01-06 12:39:12 +00:00
										 |  |  |         goto global_overflow; | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       HR[1] = AbsPair(HR+2); | 
					
						
							|  |  |  |       HR += 2; | 
					
						
							|  |  |  |       HR[-2] = (CELL)ptd0; | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |       /* store the terms to visit */ | 
					
						
							|  |  |  |       if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	goto aux_overflow; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |       to_visit[0] = pt0; | 
					
						
							|  |  |  |       to_visit[1] = pt0_end; | 
					
						
							|  |  |  |       to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  |       to_visit += 3; | 
					
						
							|  |  |  |       *pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |       if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit += 2; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |       pt0 = &RepAttVar(ptd0)->Value; | 
					
						
							|  |  |  |       pt0_end = &RepAttVar(ptd0)->Atts; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit > to_visit0) { | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     to_visit -= 2; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   if (HR != InitialH) { | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |     /* close the list */ | 
					
						
							|  |  |  |     Term t2 = Deref(inp); | 
					
						
							|  |  |  |     if (IsVarTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       RESET_VARIABLE(HR-1); | 
					
						
							|  |  |  |       Yap_unify((CELL)(HR-1), t2); | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       HR[-1] = t2;		/* don't need to trail */ | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     return(output); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     return(inp); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  trail_overflow: | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_TRAIL; | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = (TR-TR0)*sizeof(tr_fr_ptr *); | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |  aux_overflow: | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = (to_visit-to_visit0)*sizeof(CELL **); | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK; | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |  global_overflow: | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_STACK; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   LOCAL_Error_Size = (ASP-HR)*sizeof(CELL); | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_term_attvars( USES_REGS1 )	/* variables in term t		 */ | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Term out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     Term t = Deref(ARG1); | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							|  |  |  |       out = attvars_in_complex_term(VarOfTerm(t)-1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				    VarOfTerm(t)+1, TermNil PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |     }  else if (IsPrimitiveTerm(t)) { | 
					
						
							|  |  |  |       return Yap_unify(TermNil, ARG2); | 
					
						
							|  |  |  |     } else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |       out = attvars_in_complex_term(RepPair(t)-1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				 RepPair(t)+1, TermNil PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |       out = attvars_in_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 				 RepAppl(t)+ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				 ArityOfFunctor(f), TermNil PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (out == 0L) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |       if (!expand_vts( 3 PASS_REGS )) | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } while (out == 0L); | 
					
						
							|  |  |  |   return Yap_unify(ARG2,out); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-22 03:26:13 +00:00
										 |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_term_variables3( USES_REGS1 )	/* variables in term t		 */ | 
					
						
							| 
									
										
										
										
											2005-09-22 03:26:13 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Term out; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |   do { | 
					
						
							|  |  |  |     Term t = Deref(ARG1); | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2008-04-03 10:50:28 +00:00
										 |  |  |       Term out = Yap_MkNewPairTerm(); | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  | 	Yap_unify(t,HeadOfTerm(out)) && | 
					
						
							|  |  |  | 	Yap_unify(ARG3, TailOfTerm(out)) && | 
					
						
							|  |  |  | 	Yap_unify(out, ARG2); | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |     }  else if (IsPrimitiveTerm(t)) { | 
					
						
							|  |  |  |       return Yap_unify(ARG2, ARG3); | 
					
						
							|  |  |  |     } else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |       out = vars_in_complex_term(RepPair(t)-1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				 RepPair(t)+1, ARG3 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |       out = vars_in_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 				 RepAppl(t)+ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				 ArityOfFunctor(f), ARG3 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (out == 0L) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |       if (!expand_vts( 3 PASS_REGS )) | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } while (out == 0L); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-22 03:26:13 +00:00
										 |  |  |   return Yap_unify(ARG2,out); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | static Term vars_within_complex_term(register CELL *pt0, register CELL *pt0_end, Term inp USES_REGS) | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   register CELL **to_visit0, **to_visit = (CELL **)Yap_PreAllocCodeSpace(); | 
					
						
							|  |  |  |   register tr_fr_ptr TR0 = TR; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   CELL *InitialH = HR; | 
					
						
							|  |  |  |   CELL output = AbsPair(HR); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   to_visit0 = to_visit; | 
					
						
							|  |  |  |   while (!IsVarTerm(inp) && IsPairTerm(inp)) { | 
					
						
							|  |  |  |     Term t = HeadOfTerm(inp); | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							|  |  |  |       CELL *ptr = VarOfTerm(t); | 
					
						
							|  |  |  |       *ptr = TermFoundVar; | 
					
						
							|  |  |  |       TrailTerm(TR++) = t; | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | 	if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) { | 
					
						
							|  |  |  | 	  goto trail_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     inp = TailOfTerm(inp); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, vars_within_term_unk); | 
					
						
							|  |  |  |   vars_within_term_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							|  |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  | 	pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  |       } else if (d0 == TermFoundVar) { | 
					
						
							|  |  |  | 	/* leave an empty slot to fill in later */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	if (HR+1024 > ASP) { | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | 	  goto global_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR[1] = AbsPair(HR+2); | 
					
						
							|  |  |  | 	HR += 2; | 
					
						
							|  |  |  | 	HR[-2] = (CELL)ptd0; | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | 	*ptd0 = TermNil; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     derefa_body(d0, ptd0, vars_within_term_unk, vars_within_term_nvar); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit > to_visit0) { | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     to_visit -= 2; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   if (HR != InitialH) { | 
					
						
							|  |  |  |     HR[-1] = TermNil; | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |     return output; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     return TermNil; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  trail_overflow: | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_TRAIL; | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = (TR-TR0)*sizeof(tr_fr_ptr *); | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |  aux_overflow: | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = (to_visit-to_visit0)*sizeof(CELL **); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK; | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |  global_overflow: | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_STACK; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   LOCAL_Error_Size = (ASP-HR)*sizeof(CELL); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_variables_within_term( USES_REGS1 )	/* variables within term t		 */ | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Term out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     Term t = Deref(ARG2); | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							|  |  |  |       out = vars_within_complex_term(VarOfTerm(t)-1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				     VarOfTerm(t), Deref(ARG1) PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     }  else if (IsPrimitiveTerm(t))  | 
					
						
							|  |  |  |       out = TermNil; | 
					
						
							|  |  |  |     else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |       out = vars_within_complex_term(RepPair(t)-1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				     RepPair(t)+1, Deref(ARG1) PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |       out = vars_within_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 				 RepAppl(t)+ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				     ArityOfFunctor(f), Deref(ARG1) PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (out == 0L) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |       if (!expand_vts( 3 PASS_REGS )) | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } while (out == 0L); | 
					
						
							|  |  |  |   return Yap_unify(ARG3,out); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | static Term new_vars_in_complex_term(register CELL *pt0, register CELL *pt0_end, Term inp USES_REGS) | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   register CELL **to_visit0, **to_visit = (CELL **)Yap_PreAllocCodeSpace(); | 
					
						
							|  |  |  |   register tr_fr_ptr TR0 = TR; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   CELL *InitialH = HR; | 
					
						
							|  |  |  |   CELL output = AbsPair(HR); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   to_visit0 = to_visit; | 
					
						
							|  |  |  |   while (!IsVarTerm(inp) && IsPairTerm(inp)) { | 
					
						
							|  |  |  |     Term t = HeadOfTerm(inp); | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							|  |  |  |       CELL *ptr = VarOfTerm(t); | 
					
						
							|  |  |  |       *ptr = TermFoundVar; | 
					
						
							|  |  |  |       TrailTerm(TR++) = t; | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |       if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | 	if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) { | 
					
						
							|  |  |  | 	  goto trail_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     inp = TailOfTerm(inp); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, vars_within_term_unk); | 
					
						
							|  |  |  |   vars_within_term_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							|  |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  | 	pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     derefa_body(d0, ptd0, vars_within_term_unk, vars_within_term_nvar); | 
					
						
							|  |  |  |     /* do or pt2 are unbound  */ | 
					
						
							|  |  |  |     *ptd0 = TermNil; | 
					
						
							|  |  |  |     /* leave an empty slot to fill in later */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     if (HR+1024 > ASP) { | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |       goto global_overflow; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     HR[1] = AbsPair(HR+2); | 
					
						
							|  |  |  |     HR += 2; | 
					
						
							|  |  |  |     HR[-2] = (CELL)ptd0; | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |     /* next make sure noone will see this as a variable again */  | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |     if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |       /* Trail overflow */ | 
					
						
							|  |  |  |       if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) { | 
					
						
							|  |  |  | 	goto trail_overflow; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     TrailTerm(TR++) = (CELL)ptd0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit > to_visit0) { | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     to_visit -= 2; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   if (HR != InitialH) { | 
					
						
							|  |  |  |     HR[-1] = TermNil; | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |     return output; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     return TermNil; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  trail_overflow: | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_TRAIL; | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = (TR-TR0)*sizeof(tr_fr_ptr *); | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |  aux_overflow: | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   LOCAL_Error_Size = (to_visit-to_visit0)*sizeof(CELL **); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK; | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |  global_overflow: | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_STACK; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   LOCAL_Error_Size = (ASP-HR)*sizeof(CELL); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_new_variables_in_term( USES_REGS1 )	/* variables within term t		 */ | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Term out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     Term t = Deref(ARG2); | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							|  |  |  |       out = new_vars_in_complex_term(VarOfTerm(t)-1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				     VarOfTerm(t), Deref(ARG1) PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     }  else if (IsPrimitiveTerm(t))  | 
					
						
							|  |  |  |       out = TermNil; | 
					
						
							|  |  |  |     else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |       out = new_vars_in_complex_term(RepPair(t)-1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				     RepPair(t)+1, Deref(ARG1) PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |       out = new_vars_in_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 			     RepAppl(t)+ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 			     ArityOfFunctor(f), Deref(ARG1) PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (out == 0L) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |       if (!expand_vts( 3 PASS_REGS )) | 
					
						
							| 
									
										
										
										
											2009-03-10 16:21:05 +00:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } while (out == 0L); | 
					
						
							|  |  |  |   return Yap_unify(ARG3,out); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  | static Term free_vars_in_complex_term(register CELL *pt0, register CELL *pt0_end, tr_fr_ptr TR0 USES_REGS) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register CELL **to_visit0, **to_visit = (CELL **)Yap_PreAllocCodeSpace(); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   CELL *InitialH = HR; | 
					
						
							|  |  |  |   *HR++ = MkAtomTerm(AtomDollar); | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   to_visit0 = to_visit; | 
					
						
							|  |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, vars_within_term_unk); | 
					
						
							|  |  |  |   vars_within_term_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							|  |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  | 	pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     derefa_body(d0, ptd0, vars_within_term_unk, vars_within_term_nvar); | 
					
						
							|  |  |  |     /* do or pt2 are unbound  */ | 
					
						
							|  |  |  |     *ptd0 = TermNil; | 
					
						
							|  |  |  |     /* leave an empty slot to fill in later */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     if (HR+1024 > ASP) { | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |       goto global_overflow; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     HR[0] =  (CELL)ptd0; | 
					
						
							|  |  |  |     HR ++; | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |     /* next make sure noone will see this as a variable again */  | 
					
						
							|  |  |  |     if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { | 
					
						
							|  |  |  |       /* Trail overflow */ | 
					
						
							|  |  |  |       if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) { | 
					
						
							|  |  |  | 	goto trail_overflow; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     TrailTerm(TR++) = (CELL)ptd0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit > to_visit0) { | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     to_visit -= 2; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							|  |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   if (HR != InitialH+1) { | 
					
						
							|  |  |  |     InitialH[0] = (CELL)Yap_MkFunctor(AtomDollar, (HR-InitialH)-1); | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |     return AbsAppl(InitialH); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     return MkAtomTerm(AtomDollar); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  trail_overflow: | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_TRAIL; | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |   LOCAL_Error_Size = (TR-TR0)*sizeof(tr_fr_ptr *); | 
					
						
							|  |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							|  |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |  aux_overflow: | 
					
						
							|  |  |  |   LOCAL_Error_Size = (to_visit-to_visit0)*sizeof(CELL **); | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK; | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							|  |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |  global_overflow: | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							|  |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_STACK; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   LOCAL_Error_Size = (ASP-HR)*sizeof(CELL); | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Term bind_vars_in_complex_term(register CELL *pt0, register CELL *pt0_end, tr_fr_ptr TR0 USES_REGS) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register CELL **to_visit0, **to_visit = (CELL **)Yap_PreAllocCodeSpace(); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   CELL *InitialH = HR; | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   to_visit0 = to_visit; | 
					
						
							|  |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, vars_within_term_unk); | 
					
						
							|  |  |  |   vars_within_term_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							|  |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  | 	pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     derefa_body(d0, ptd0, vars_within_term_unk, vars_within_term_nvar); | 
					
						
							|  |  |  |     /* do or pt2 are unbound  */ | 
					
						
							|  |  |  |     *ptd0 = TermFoundVar; | 
					
						
							|  |  |  |     /* next make sure noone will see this as a variable again */  | 
					
						
							|  |  |  |     if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { | 
					
						
							|  |  |  |       /* Trail overflow */ | 
					
						
							|  |  |  |       if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) { | 
					
						
							|  |  |  | 	goto trail_overflow; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     TrailTerm(TR++) = (CELL)ptd0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit > to_visit0) { | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     to_visit -= 2; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							|  |  |  |   return TermNil; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  trail_overflow: | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_TRAIL; | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |   LOCAL_Error_Size = (TR-TR0)*sizeof(tr_fr_ptr *); | 
					
						
							|  |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							|  |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |  aux_overflow: | 
					
						
							|  |  |  |   LOCAL_Error_Size = (to_visit-to_visit0)*sizeof(CELL **); | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK; | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							|  |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |   return 0L; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_free_variables_in_term( USES_REGS1 )	/* variables within term t		 */ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Term out; | 
					
						
							|  |  |  |   Term t, t0; | 
					
						
							|  |  |  |   Term found_module = 0L; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     tr_fr_ptr TR0 = TR;  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     t = t0 = Deref(ARG1); | 
					
						
							|  |  |  |     while (!IsVarTerm(t) && IsApplTerm(t)) { | 
					
						
							|  |  |  |       Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |       if (f == FunctorHat) { | 
					
						
							|  |  |  | 	out = bind_vars_in_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 			     RepAppl(t)+1, TR0 PASS_REGS); | 
					
						
							|  |  |  | 	if (out == 0L) { | 
					
						
							|  |  |  | 	  goto trail_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } else if (f == FunctorModule) { | 
					
						
							|  |  |  | 	found_module = ArgOfTerm(1, t); | 
					
						
							| 
									
										
										
										
											2014-02-19 00:04:26 +00:00
										 |  |  |       } else if (f == FunctorCall) { | 
					
						
							|  |  |  | 	t = ArgOfTerm(1, t); | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  |       } else if (f == FunctorExecuteInMod) { | 
					
						
							|  |  |  | 	found_module = ArgOfTerm(2, t); | 
					
						
							|  |  |  | 	t = ArgOfTerm(1, t); | 
					
						
							|  |  |  | 	continue; | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |       } else { | 
					
						
							|  |  |  | 	break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       t = ArgOfTerm(2,t); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							|  |  |  |       out = free_vars_in_complex_term(VarOfTerm(t)-1, | 
					
						
							|  |  |  | 				      VarOfTerm(t), TR0 PASS_REGS); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }  else if (IsPrimitiveTerm(t))  | 
					
						
							|  |  |  |       out = TermNil; | 
					
						
							|  |  |  |     else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |       out = free_vars_in_complex_term(RepPair(t)-1, | 
					
						
							|  |  |  | 				      RepPair(t)+1, TR0 PASS_REGS); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |       out = free_vars_in_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 			     RepAppl(t)+ | 
					
						
							|  |  |  | 				      ArityOfFunctor(f), TR0 PASS_REGS); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (out == 0L) { | 
					
						
							|  |  |  |     trail_overflow: | 
					
						
							|  |  |  |       if (!expand_vts( 3 PASS_REGS )) | 
					
						
							|  |  |  | 	return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } while (out == 0L); | 
					
						
							|  |  |  |   if (found_module && t!=t0) { | 
					
						
							|  |  |  |     Term ts[2]; | 
					
						
							|  |  |  |     ts[0] = found_module; | 
					
						
							|  |  |  |     ts[1] = t; | 
					
						
							|  |  |  |     t = Yap_MkApplTerm(FunctorModule, 2, ts); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return | 
					
						
							|  |  |  |     Yap_unify(ARG2, t) && | 
					
						
							|  |  |  |     Yap_unify(ARG3,out); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | static Term non_singletons_in_complex_term(register CELL *pt0, register CELL *pt0_end USES_REGS) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   register CELL **to_visit0, **to_visit = (CELL **)Yap_PreAllocCodeSpace(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   register tr_fr_ptr TR0 = TR; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   CELL *InitialH = HR; | 
					
						
							|  |  |  |   CELL output = AbsPair(HR); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   to_visit0 = to_visit; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, vars_in_term_unk); | 
					
						
							|  |  |  |   vars_in_term_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  | 	pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  |       } else if (d0 == TermFoundVar) { | 
					
						
							|  |  |  | 	CELL *pt2 = pt0; | 
					
						
							|  |  |  | 	while(IsVarTerm(*pt2)) | 
					
						
							|  |  |  | 	  pt2 = (CELL *)(*pt2); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR[1] = AbsPair(HR+2); | 
					
						
							|  |  |  | 	HR += 2; | 
					
						
							|  |  |  | 	HR[-2] = (CELL)pt2; | 
					
						
							| 
									
										
										
										
											2015-08-18 14:55:58 -05:00
										 |  |  | 	*pt2 = TermRefoundVar; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     derefa_body(d0, ptd0, vars_in_term_unk, vars_in_term_nvar); | 
					
						
							|  |  |  |     /* do or pt2 are unbound  */ | 
					
						
							|  |  |  |     *ptd0 = TermFoundVar; | 
					
						
							|  |  |  |     /* next make sure we can recover the variable again */  | 
					
						
							|  |  |  |     TrailTerm(TR++) = (CELL)ptd0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   if (to_visit > to_visit0) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     to_visit -= 2; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   if (HR != InitialH) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     /* close the list */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     RESET_VARIABLE(HR-1); | 
					
						
							|  |  |  |     Yap_unify((CELL)(HR-1),ARG2); | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  |     return output; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  |     return ARG2; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  aux_overflow: | 
					
						
							| 
									
										
										
										
											2007-03-27 13:48:51 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   if (HR != InitialH) { | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  |     /* close the list */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     RESET_VARIABLE(HR-1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  |   return 0L; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_non_singletons_in_term( USES_REGS1 )	/* non_singletons in term t		 */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  |   Term t; | 
					
						
							|  |  |  |   Term out; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  |   while (TRUE) { | 
					
						
							|  |  |  |     t = Deref(ARG1); | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							|  |  |  |       out = MkPairTerm(t,ARG2); | 
					
						
							|  |  |  |     }  else if (IsPrimitiveTerm(t)) { | 
					
						
							|  |  |  |       out = ARG2; | 
					
						
							|  |  |  |     } else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |       out = non_singletons_in_complex_term(RepPair(t)-1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 					   RepPair(t)+1 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       out = non_singletons_in_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 					   RepAppl(t)+ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 					   ArityOfFunctor(FunctorOfTerm(t)) PASS_REGS); | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (out != 0L) { | 
					
						
							|  |  |  |       return Yap_unify(ARG3,out); | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2009-05-22 18:35:24 -05:00
										 |  |  |       if (!Yap_ExpandPreAllocCodeSpace(0, NULL, TRUE)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	Yap_Error(RESOURCE_ERROR_AUXILIARY_STACK, ARG1, "overflow in singletons"); | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }   | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | static Int ground_complex_term(register CELL *pt0, register CELL *pt0_end USES_REGS) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   register CELL **to_visit0, **to_visit = (CELL **)Yap_PreAllocCodeSpace(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   to_visit0 = to_visit; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ++pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, vars_in_term_unk); | 
					
						
							|  |  |  |   vars_in_term_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  | 	pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     derefa_body(d0, ptd0, vars_in_term_unk, vars_in_term_nvar); | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     while (to_visit > to_visit0) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       to_visit -= 3; | 
					
						
							|  |  |  |       pt0 = to_visit[0]; | 
					
						
							|  |  |  |       pt0_end = to_visit[1]; | 
					
						
							|  |  |  |       *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-04-15 20:26:45 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   if (to_visit > to_visit0) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     to_visit -= 2; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  aux_overflow: | 
					
						
							| 
									
										
										
										
											2005-04-15 20:26:45 +00:00
										 |  |  |   /* unwind stack */ | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  |   return -1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  |   | 
					
						
							| 
									
										
										
										
											2010-01-25 12:28:49 +00:00
										 |  |  | int Yap_IsGroundTerm(Term t) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  |   while (TRUE) { | 
					
						
							|  |  |  |     Int out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     }  else if (IsPrimitiveTerm(t)) { | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							|  |  |  |     } else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |       if ((out =ground_complex_term(RepPair(t)-1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				    RepPair(t)+1 PASS_REGS)) >= 0) { | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  | 	return out; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       Functor fun = FunctorOfTerm(t); | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       if (IsExtensionFunctor(fun)) | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  | 	return TRUE; | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  |       else if ((out = ground_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 					     RepAppl(t)+ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 					     ArityOfFunctor(fun) PASS_REGS)) >= 0) { | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  | 	     return out; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (out < 0) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       *HR++ = t; | 
					
						
							| 
									
										
										
										
											2009-05-22 18:35:24 -05:00
										 |  |  |       if (!Yap_ExpandPreAllocCodeSpace(0, NULL, TRUE)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	Yap_Error(RESOURCE_ERROR_AUXILIARY_STACK, ARG1, "overflow in ground"); | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |       }       | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       t = *--HR; | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-25 12:28:49 +00:00
										 |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_ground( USES_REGS1 )			/* ground(+T)		 */ | 
					
						
							| 
									
										
										
										
											2010-01-25 12:28:49 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-25 21:28:51 +00:00
										 |  |  |   return Yap_IsGroundTerm(Deref(ARG1)); | 
					
						
							| 
									
										
										
										
											2010-01-25 12:28:49 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | SizeOfExtension(Term t) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |   if (f== FunctorDouble) { | 
					
						
							|  |  |  |     return 2 + sizeof(Float)/sizeof(CELL); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-12-02 14:49:41 +00:00
										 |  |  |   if (f== FunctorString) { | 
					
						
							|  |  |  |     return 3 + RepAppl(t)[1]; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |   if (f== FunctorLongInt) { | 
					
						
							|  |  |  |     return 2 + sizeof(Float)/sizeof(CELL); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (f== FunctorDBRef) { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (f== FunctorBigInt) { | 
					
						
							| 
									
										
										
										
											2008-11-28 15:54:46 +00:00
										 |  |  |     CELL *pt = RepAppl(t)+2; | 
					
						
							|  |  |  |     return 3+sizeof(MP_INT)+(((MP_INT *)(pt))->_mp_alloc*sizeof(mp_limb_t)); | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | static Int sz_ground_complex_term(register CELL *pt0, register CELL *pt0_end, int ground USES_REGS) | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   register CELL **to_visit0, **to_visit = (CELL **)Yap_PreAllocCodeSpace(); | 
					
						
							|  |  |  |   Int sz = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   to_visit0 = to_visit; | 
					
						
							|  |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ++pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, vars_in_term_unk); | 
					
						
							|  |  |  |   vars_in_term_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							|  |  |  | 	sz += 2; | 
					
						
							|  |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  | 	pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	  sz += SizeOfExtension(d0); | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	sz += (1+d0); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     derefa_body(d0, ptd0, vars_in_term_unk, vars_in_term_nvar); | 
					
						
							|  |  |  |     if (!ground) | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     while (to_visit > to_visit0) { | 
					
						
							|  |  |  |       to_visit -= 3; | 
					
						
							|  |  |  |       pt0 = to_visit[0]; | 
					
						
							|  |  |  |       pt0_end = to_visit[1]; | 
					
						
							|  |  |  |       *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit > to_visit0) { | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     to_visit -= 2; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return sz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  aux_overflow: | 
					
						
							|  |  |  |   /* unwind stack */ | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | Yap_SizeGroundTerm(Term t, int ground) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |   if (IsVarTerm(t)) { | 
					
						
							|  |  |  |     if (!ground) | 
					
						
							|  |  |  |       return 1; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   }  else if (IsPrimitiveTerm(t)) { | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  |   } else if (IsPairTerm(t)) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     int sz = sz_ground_complex_term(RepPair(t)-1, RepPair(t)+1, ground PASS_REGS); | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |     if (sz <= 0) | 
					
						
							|  |  |  |       return sz; | 
					
						
							|  |  |  |     return sz+2; | 
					
						
							|  |  |  | } else { | 
					
						
							|  |  |  |   int sz = 0; | 
					
						
							|  |  |  |   Functor fun = FunctorOfTerm(t); | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |   if (IsExtensionFunctor(fun)) | 
					
						
							|  |  |  |     return 1+ SizeOfExtension(t); | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |    sz = sz_ground_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 			    RepAppl(t)+ | 
					
						
							|  |  |  | 			    ArityOfFunctor(fun), | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 			    ground PASS_REGS); | 
					
						
							| 
									
										
										
										
											2007-11-06 17:02:13 +00:00
										 |  |  |    if (sz <= 0) | 
					
						
							|  |  |  |      return sz; | 
					
						
							|  |  |  |    return 1+ArityOfFunctor(fun)+sz; | 
					
						
							|  |  |  |   }   | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | static Int var_in_complex_term(register CELL *pt0, | 
					
						
							|  |  |  | 			       register CELL *pt0_end, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 			       Term v USES_REGS) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   register CELL **to_visit0, **to_visit = (CELL **)Yap_PreAllocCodeSpace(); | 
					
						
							| 
									
										
										
										
											2002-03-07 05:13:21 +00:00
										 |  |  |   register tr_fr_ptr TR0 = TR; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   to_visit0 = to_visit; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							| 
									
										
										
										
											2002-03-07 05:13:21 +00:00
										 |  |  |     deref_head(d0, var_in_term_unk); | 
					
						
							|  |  |  |   var_in_term_nvar: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  | 	pt0_end = RepPair(d0) + 1; | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	continue; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-03-07 05:13:21 +00:00
										 |  |  |     deref_body(d0, ptd0, var_in_term_unk, var_in_term_nvar); | 
					
						
							|  |  |  |     if ((CELL)ptd0 == v) { /* we found it */ | 
					
						
							| 
									
										
										
										
											2009-09-12 17:17:16 -05:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |       while (to_visit > to_visit0) { | 
					
						
							|  |  |  | 	to_visit -= 3; | 
					
						
							|  |  |  | 	pt0 = to_visit[0]; | 
					
						
							|  |  |  | 	*pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |       clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       return(TRUE); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2002-03-07 05:13:21 +00:00
										 |  |  |     /* do or pt2 are unbound  */ | 
					
						
							|  |  |  |     *ptd0 = TermNil; | 
					
						
							|  |  |  |     /* next make sure noone will see this as a variable again */  | 
					
						
							|  |  |  |     TrailTerm(TR++) = (CELL)ptd0; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   if (to_visit > to_visit0) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     to_visit -= 2; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-09-12 17:17:16 -05:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2005-04-13 19:37:32 +00:00
										 |  |  |   return FALSE; | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  aux_overflow: | 
					
						
							|  |  |  |   /* unwind stack */ | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   return -1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  |   | 
					
						
							| 
									
										
										
										
											2002-03-07 05:13:21 +00:00
										 |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | var_in_term(Term v, Term t USES_REGS)	/* variables in term t		 */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-03-07 05:13:21 +00:00
										 |  |  |   if (IsVarTerm(t)) { | 
					
						
							|  |  |  |     return(v == t); | 
					
						
							|  |  |  |   } else if (IsPrimitiveTerm(t)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return(FALSE); | 
					
						
							| 
									
										
										
										
											2002-03-07 05:13:21 +00:00
										 |  |  |   } else if (IsPairTerm(t)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return(var_in_complex_term(RepPair(t)-1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 			       RepPair(t)+1,v PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else return(var_in_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 				  RepAppl(t)+ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 				  ArityOfFunctor(FunctorOfTerm(t)),v PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-03-07 05:13:21 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_var_in_term( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2002-03-07 05:13:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   return(var_in_term(Deref(ARG2), Deref(ARG1) PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2002-03-07 05:13:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* The code for TermHash was originally contributed by Gertjen Van Noor */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This code with max_depth == -1 will loop for infinite trees */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | //-----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | // MurmurHash2, by Austin Appleby
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Note - This code makes a few assumptions about how your machine behaves -
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | // 1. We can read a 4-byte value from any address without crashing
 | 
					
						
							|  |  |  | // 2. sizeof(int) == 4
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // And it has a few limitations -
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 1. It will not work incrementally.
 | 
					
						
							|  |  |  | // 2. It will not produce the same results on little-endian and big-endian
 | 
					
						
							|  |  |  | //    machines.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static unsigned int | 
					
						
							|  |  |  | MurmurHashNeutral2 ( const void * key, int len, unsigned int seed ) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	const unsigned int m = 0x5bd1e995; | 
					
						
							|  |  |  | 	const int r = 24; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	unsigned int h = seed ^ len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const unsigned char * data = (const unsigned char *)key; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(len >= 4) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		unsigned int k; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		k  = data[0]; | 
					
						
							|  |  |  | 		k |= data[1] << 8; | 
					
						
							|  |  |  | 		k |= data[2] << 16; | 
					
						
							|  |  |  | 		k |= data[3] << 24; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		k *= m;  | 
					
						
							|  |  |  | 		k ^= k >> r;  | 
					
						
							|  |  |  | 		k *= m; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		h *= m; | 
					
						
							|  |  |  | 		h ^= k; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		data += 4; | 
					
						
							|  |  |  | 		len -= 4; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	switch(len) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case 3: h ^= data[2] << 16; | 
					
						
							|  |  |  | 	case 2: h ^= data[1] << 8; | 
					
						
							|  |  |  | 	case 1: h ^= data[0]; | 
					
						
							|  |  |  | 	        h *= m; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	h ^= h >> 13; | 
					
						
							|  |  |  | 	h *= m; | 
					
						
							|  |  |  | 	h ^= h >> 15; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return h; | 
					
						
							|  |  |  | }  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static CELL * | 
					
						
							| 
									
										
										
										
											2013-11-15 18:25:33 +00:00
										 |  |  | addAtomToHash(CELL *st, Atom at) | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   unsigned int len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsWideAtom(at)) { | 
					
						
							|  |  |  |     wchar_t *c = RepAtom(at)->WStrOfAE; | 
					
						
							|  |  |  |     int ulen = wcslen(c); | 
					
						
							|  |  |  |     len = ulen*sizeof(wchar_t); | 
					
						
							|  |  |  |     if (len % CellSize == 0) { | 
					
						
							|  |  |  |       len /= CellSize; | 
					
						
							| 
									
										
										
										
											2006-09-01 20:14:42 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |       len /= CellSize; | 
					
						
							|  |  |  |       len++; | 
					
						
							| 
									
										
										
										
											2006-09-01 20:14:42 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |     st[len-1] = 0L; | 
					
						
							|  |  |  |     wcsncpy((wchar_t *)st, c, ulen); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |     char *c = RepAtom(at)->StrOfAE; | 
					
						
							|  |  |  |     int ulen = strlen(c); | 
					
						
							| 
									
										
										
										
											2010-01-21 15:21:26 +00:00
										 |  |  |     /* fix hashing over empty atom */ | 
					
						
							|  |  |  |     if (!ulen) { | 
					
						
							|  |  |  |       return st; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |     if (ulen % CellSize == 0) { | 
					
						
							|  |  |  |       len = ulen/CellSize; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       len = ulen/CellSize; | 
					
						
							|  |  |  |       len++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     st[len-1] = 0L; | 
					
						
							|  |  |  |     strncpy((char *)st, c, ulen); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return st+len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-06 17:26:53 -04:00
										 |  |  | typedef struct visited { | 
					
						
							|  |  |  |   CELL *start; | 
					
						
							|  |  |  |   CELL  *end; | 
					
						
							|  |  |  |   CELL old; | 
					
						
							|  |  |  |   UInt vdepth; | 
					
						
							|  |  |  | } visited_t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | static CELL * | 
					
						
							|  |  |  | hash_complex_term(register CELL *pt0, | 
					
						
							|  |  |  | 		  register CELL *pt0_end, | 
					
						
							|  |  |  | 		  Int depth, | 
					
						
							| 
									
										
										
										
											2009-03-31 21:56:12 +01:00
										 |  |  | 		  CELL *st, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 		  int variant USES_REGS) | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-07-06 17:26:53 -04:00
										 |  |  |   register visited_t *to_visit0, *to_visit = (visited_t *)Yap_PreAllocCodeSpace(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |   to_visit0 = to_visit; | 
					
						
							|  |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, hash_complex_unk); | 
					
						
							|  |  |  |   hash_complex_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (st + 1024 >= ASP) { | 
					
						
							|  |  |  | 	goto global_overflow; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-03-22 00:09:50 +00:00
										 |  |  |       if (IsAtomOrIntTerm(d0)) { | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	if (d0 != TermFoundVar) { | 
					
						
							|  |  |  | 	  if (IsAtomTerm(d0)) { | 
					
						
							| 
									
										
										
										
											2013-11-15 18:25:33 +00:00
										 |  |  | 	    st = addAtomToHash(st, AtomOfTerm(d0)); | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	  } else { | 
					
						
							|  |  |  | 	    *st++ = IntOfTerm(d0); | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  |       } else if (IsPairTerm(d0)) { | 
					
						
							| 
									
										
										
										
											2013-11-15 18:25:33 +00:00
										 |  |  | 	st = addAtomToHash(st, AtomDot); | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	if (depth == 1) | 
					
						
							|  |  |  | 	  continue; | 
					
						
							| 
									
										
										
										
											2011-07-06 17:26:53 -04:00
										 |  |  | 	if (to_visit + 256 >= (visited_t *)AuxSp) { | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-07-06 17:26:53 -04:00
										 |  |  | 	to_visit->start = pt0; | 
					
						
							|  |  |  | 	to_visit->end = pt0_end; | 
					
						
							|  |  |  | 	to_visit->old = *pt0; | 
					
						
							|  |  |  | 	to_visit->vdepth = depth; | 
					
						
							|  |  |  | 	to_visit++; | 
					
						
							|  |  |  | 	depth--; | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	*pt0 = TermFoundVar; | 
					
						
							|  |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  | 	pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							| 
									
										
										
										
											2010-03-22 00:09:50 +00:00
										 |  |  | 	  CELL fc = (CELL)f; | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	  switch(fc) { | 
					
						
							|  |  |  | 	     | 
					
						
							|  |  |  | 	  case (CELL)FunctorDBRef: | 
					
						
							|  |  |  | 	    *st++ = fc; | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 	  case (CELL)FunctorLongInt: | 
					
						
							|  |  |  | 	    *st++ = LongIntOfTerm(d0); | 
					
						
							|  |  |  | 	    break; | 
					
						
							| 
									
										
										
										
											2013-12-02 14:49:41 +00:00
										 |  |  | 	  case (CELL)FunctorString: | 
					
						
							|  |  |  | 	    memcpy(st, RepAppl(d0), (3+RepAppl(d0)[1])*sizeof(CELL)); | 
					
						
							|  |  |  | 	    st += 3+RepAppl(d0)[1]; | 
					
						
							|  |  |  | 	    break; | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							|  |  |  | 	  case (CELL)FunctorBigInt: | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 	      CELL *pt = RepAppl(d0); | 
					
						
							|  |  |  | 	      Int sz =  | 
					
						
							| 
									
										
										
										
											2008-11-28 15:54:46 +00:00
										 |  |  | 		sizeof(MP_INT)+1+ | 
					
						
							|  |  |  | 		(((MP_INT *)(pt+2))->_mp_alloc*sizeof(mp_limb_t)); | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	      if (st + (1024 + sz/CellSize) >= ASP) { | 
					
						
							|  |  |  | 		goto global_overflow; | 
					
						
							|  |  |  | 	      } | 
					
						
							|  |  |  | 	      /* then the actual number */ | 
					
						
							|  |  |  | 	      memcpy((void *)(st+1), (void *)(pt+1), sz); | 
					
						
							|  |  |  | 	      st = st+sz/CellSize; | 
					
						
							|  |  |  | 	    } | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	  case (CELL)FunctorDouble: | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 	      CELL *pt = RepAppl(d0); | 
					
						
							|  |  |  | 	      *st++ = pt[1]; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | #if  SIZEOF_DOUBLE == 2*SIZEOF_INT_P
 | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	      *st++ = pt[2]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	      break; | 
					
						
							|  |  |  | 	    } | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-11-15 18:25:33 +00:00
										 |  |  | 	st = addAtomToHash(st, NameOfFunctor(f)); | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	if (depth == 1) | 
					
						
							|  |  |  | 	  continue; | 
					
						
							| 
									
										
										
										
											2011-07-06 17:26:53 -04:00
										 |  |  | 	if (to_visit + 1024 >= (visited_t *)AuxSp) { | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-07-06 17:26:53 -04:00
										 |  |  | 	to_visit->start = pt0; | 
					
						
							|  |  |  | 	to_visit->end = pt0_end; | 
					
						
							|  |  |  | 	to_visit->old = *pt0; | 
					
						
							|  |  |  | 	to_visit->vdepth = depth; | 
					
						
							|  |  |  | 	to_visit++; | 
					
						
							|  |  |  | 	depth--; | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	*pt0 = TermFoundVar; | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |      | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     deref_body(d0, ptd0, hash_complex_unk, hash_complex_nvar); | 
					
						
							| 
									
										
										
										
											2009-03-31 21:56:12 +01:00
										 |  |  |     if (!variant) | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit > to_visit0) { | 
					
						
							| 
									
										
										
										
											2011-07-06 17:26:53 -04:00
										 |  |  |     to_visit--; | 
					
						
							|  |  |  |     pt0 = to_visit->start; | 
					
						
							|  |  |  |     pt0_end = to_visit->end; | 
					
						
							|  |  |  |     *pt0 = to_visit->old; | 
					
						
							|  |  |  |     depth = to_visit->vdepth; | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return st; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  aux_overflow: | 
					
						
							|  |  |  |   /* unwind stack */ | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							| 
									
										
										
										
											2011-07-06 17:26:53 -04:00
										 |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start; | 
					
						
							|  |  |  |     *pt0 = to_visit->old; | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   return (CELL *)-1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |  global_overflow: | 
					
						
							|  |  |  |   /* unwind stack */ | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							| 
									
										
										
										
											2011-07-06 17:26:53 -04:00
										 |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start; | 
					
						
							|  |  |  |     *pt0 = to_visit->old; | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   return (CELL *) -2; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  |   | 
					
						
							| 
									
										
										
										
											2010-08-02 19:48:17 +01:00
										 |  |  | Int | 
					
						
							|  |  |  | Yap_TermHash(Term t, Int size, Int depth, int variant) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2010-08-02 19:48:17 +01:00
										 |  |  |   unsigned int i1; | 
					
						
							|  |  |  |   Term t1 = Deref(t); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while (TRUE) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     CELL *ar = hash_complex_term(&t1-1, &t1, depth, HR, FALSE PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-08-02 19:48:17 +01:00
										 |  |  |     if (ar == (CELL *)-1) { | 
					
						
							|  |  |  |       if (!Yap_ExpandPreAllocCodeSpace(0, NULL, TRUE)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	Yap_Error(RESOURCE_ERROR_AUXILIARY_STACK, ARG1, "overflow in term_hash"); | 
					
						
							| 
									
										
										
										
											2010-08-02 19:48:17 +01:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |       }  | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |     } else if(ar == (CELL *)-2) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       if (!Yap_gcl((ASP-HR)*sizeof(CELL), 0, ENV, gc_P(P,CP))) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	Yap_Error(RESOURCE_ERROR_STACK, TermNil, "in term_hash"); | 
					
						
							| 
									
										
										
										
											2010-08-02 19:48:17 +01:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |     } else if (ar == NULL) { | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       i1 = MurmurHashNeutral2((const void *)HR, CellSize*(ar-HR),0x1a3be34a); | 
					
						
							| 
									
										
										
										
											2010-08-02 19:48:17 +01:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* got the seed and hash from SWI-Prolog */ | 
					
						
							|  |  |  |   return i1 % size; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_term_hash( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |   unsigned int i1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   Term t1 = Deref(ARG1); | 
					
						
							|  |  |  |   Term t2 = Deref(ARG2); | 
					
						
							|  |  |  |   Term t3 = Deref(ARG3); | 
					
						
							|  |  |  |   Term result; | 
					
						
							|  |  |  |   Int size, depth; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR,t2,"term_hash/4"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!IsIntegerTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_Error(TYPE_ERROR_INTEGER,t2,"term_hash/4"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   depth = IntegerOfTerm(t2); | 
					
						
							|  |  |  |   if (depth == 0) { | 
					
						
							|  |  |  |     if (IsVarTerm(t1)) return(TRUE); | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     return(Yap_unify(ARG4,MkIntTerm(0))); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (IsVarTerm(t3)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR,t3,"term_hash/4"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!IsIntegerTerm(t3)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_Error(TYPE_ERROR_INTEGER,t3,"term_hash/4"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   size = IntegerOfTerm(t3); | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |   while (TRUE) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     CELL *ar = hash_complex_term(&t1-1, &t1, depth, HR, FALSE PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-03-31 21:56:12 +01:00
										 |  |  |     if (ar == (CELL *)-1) { | 
					
						
							| 
									
										
										
										
											2009-05-22 18:35:24 -05:00
										 |  |  |       if (!Yap_ExpandPreAllocCodeSpace(0, NULL, TRUE)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	Yap_Error(RESOURCE_ERROR_AUXILIARY_STACK, ARG1, "overflow in term_hash"); | 
					
						
							| 
									
										
										
										
											2009-03-31 21:56:12 +01:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |       }  | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |     } else if(ar == (CELL *)-2) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       if (!Yap_gcl((ASP-HR)*sizeof(CELL), 4, ENV, gc_P(P,CP))) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	Yap_Error(RESOURCE_ERROR_STACK, TermNil, "in term_hash"); | 
					
						
							| 
									
										
										
										
											2009-03-31 21:56:12 +01:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |     } else if (ar == NULL) { | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       i1 = MurmurHashNeutral2((const void *)HR, CellSize*(ar-HR),0x1a3be34a); | 
					
						
							| 
									
										
										
										
											2009-03-31 21:56:12 +01:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* got the seed and hash from SWI-Prolog */ | 
					
						
							|  |  |  |   result = MkIntegerTerm(i1 % size); | 
					
						
							|  |  |  |   return Yap_unify(ARG4,result); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_instantiated_term_hash( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2009-03-31 21:56:12 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   unsigned int i1; | 
					
						
							|  |  |  |   Term t1 = Deref(ARG1); | 
					
						
							|  |  |  |   Term t2 = Deref(ARG2); | 
					
						
							|  |  |  |   Term t3 = Deref(ARG3); | 
					
						
							|  |  |  |   Term result; | 
					
						
							|  |  |  |   Int size, depth; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t2)) { | 
					
						
							|  |  |  |     Yap_Error(INSTANTIATION_ERROR,t2,"term_hash/4"); | 
					
						
							|  |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!IsIntegerTerm(t2)) { | 
					
						
							|  |  |  |     Yap_Error(TYPE_ERROR_INTEGER,t2,"term_hash/4"); | 
					
						
							|  |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   depth = IntegerOfTerm(t2); | 
					
						
							|  |  |  |   if (depth == 0) { | 
					
						
							|  |  |  |     if (IsVarTerm(t1)) return(TRUE); | 
					
						
							|  |  |  |     return(Yap_unify(ARG4,MkIntTerm(0))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (IsVarTerm(t3)) { | 
					
						
							|  |  |  |     Yap_Error(INSTANTIATION_ERROR,t3,"term_hash/4"); | 
					
						
							|  |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!IsIntegerTerm(t3)) { | 
					
						
							|  |  |  |     Yap_Error(TYPE_ERROR_INTEGER,t3,"term_hash/4"); | 
					
						
							|  |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   size = IntegerOfTerm(t3); | 
					
						
							|  |  |  |   while (TRUE) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     CELL *ar = hash_complex_term(&t1-1, &t1, depth, HR, TRUE PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |     if (ar == (CELL *)-1) { | 
					
						
							| 
									
										
										
										
											2009-05-22 18:35:24 -05:00
										 |  |  |       if (!Yap_ExpandPreAllocCodeSpace(0, NULL, TRUE)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	Yap_Error(RESOURCE_ERROR_AUXILIARY_STACK, ARG1, "overflow in term_hash"); | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |       }  | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |     } else if(ar == (CELL *)-2) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       if (!Yap_gcl((ASP-HR)*sizeof(CELL), 4, ENV, gc_P(P,CP))) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	Yap_Error(RESOURCE_ERROR_STACK, TermNil, "in term_hash"); | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  | 	return FALSE; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       t1 = Deref(ARG1); | 
					
						
							|  |  |  |     } else if (ar == NULL) { | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       i1 = MurmurHashNeutral2((const void *)HR, CellSize*(ar-HR),0x1a3be34a); | 
					
						
							| 
									
										
										
										
											2008-11-18 11:28:11 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* got the seed and hash from SWI-Prolog */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   result = MkIntegerTerm(i1 % size); | 
					
						
							| 
									
										
										
										
											2004-11-19 17:14:15 +00:00
										 |  |  |   return Yap_unify(ARG4,result); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int variant_complex(register CELL *pt0, register CELL *pt0_end, register | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 		   CELL *pt1 USES_REGS) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   tr_fr_ptr OLDTR = TR; | 
					
						
							|  |  |  |   register CELL **to_visit = (CELL **)ASP; | 
					
						
							|  |  |  |   /* make sure that unification always forces trailing */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HBREG = HR; | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |   | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0, d1; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ++ pt1; | 
					
						
							|  |  |  |     d0 = Derefa(pt0); | 
					
						
							|  |  |  |     d1 = Derefa(pt1); | 
					
						
							|  |  |  |     if (IsVarTerm(d0)) { | 
					
						
							|  |  |  |       if (IsVarTerm(d1)) { | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 	CELL *pt0 = VarOfTerm(d0); | 
					
						
							|  |  |  | 	CELL *pt1 = VarOfTerm(d1); | 
					
						
							|  |  |  | 	if (pt0 >= HBREG || pt1 >= HBREG) { | 
					
						
							|  |  |  | 	  /* one of the variables has been found before */ | 
					
						
							|  |  |  | 	  if (VarOfTerm(d0)+1 == VarOfTerm(d1)) continue; | 
					
						
							|  |  |  | 	  goto fail; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 	  /* two new occurrences of the same variable */ | 
					
						
							|  |  |  | 	  Term n0 = MkVarTerm(), n1 = MkVarTerm(); | 
					
						
							|  |  |  | 	  Bind_Global(VarOfTerm(d0), n0); | 
					
						
							|  |  |  | 	  Bind_Global(VarOfTerm(d1), n1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  | 	goto fail; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else if (IsVarTerm(d1)) { | 
					
						
							|  |  |  |       goto fail; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       if (d0 == d1) continue; | 
					
						
							|  |  |  |       else if (IsAtomOrIntTerm(d0)) { | 
					
						
							|  |  |  | 	goto fail; | 
					
						
							|  |  |  |       } else if (IsPairTerm(d0)) { | 
					
						
							|  |  |  | 	if (!IsPairTerm(d1)) { | 
					
						
							|  |  |  | 	  goto fail; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	/* now link the two structures so that no one else will */ | 
					
						
							|  |  |  | 	/* come here */ | 
					
						
							|  |  |  | 	to_visit -= 4; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	if ((CELL *)to_visit < HR+1024) | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  | 	  goto out_of_stack; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = pt1; | 
					
						
							| 
									
										
										
										
											2003-10-28 16:20:44 +00:00
										 |  |  | 	to_visit[3] = (CELL *)*pt0; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	*pt0 = d1; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit -= 3; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	  if ((CELL *)to_visit < HR+1024) | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  | 	    goto out_of_stack; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit[2] = pt1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  | 	pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  | 	pt1 = RepPair(d1) - 1; | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2, *ap3; | 
					
						
							|  |  |  | 	if (!IsApplTerm(d1)) { | 
					
						
							|  |  |  | 	  goto fail; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 	  /* store the terms to visit */ | 
					
						
							|  |  |  | 	  Functor f2; | 
					
						
							|  |  |  | 	  ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	  ap3 = RepAppl(d1); | 
					
						
							|  |  |  | 	  f = (Functor)(*ap2); | 
					
						
							|  |  |  | 	  f2 = (Functor)(*ap3); | 
					
						
							|  |  |  | 	  if (f != f2) | 
					
						
							|  |  |  | 	    goto fail; | 
					
						
							|  |  |  | 	  if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	    if (!unify_extension(f, d0, ap2, d1)) | 
					
						
							|  |  |  | 	      goto fail; | 
					
						
							|  |  |  | 	    continue; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	/* now link the two structures so that no one else will */ | 
					
						
							|  |  |  | 	/* come here */ | 
					
						
							|  |  |  | 	to_visit -= 4; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	if ((CELL *)to_visit < HR+1024) | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  | 	  goto out_of_stack; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = pt1; | 
					
						
							| 
									
										
										
										
											2003-10-28 16:20:44 +00:00
										 |  |  | 	to_visit[3] = (CELL *)*pt0; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	*pt0 = d1; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	  /* store the terms to visit */ | 
					
						
							|  |  |  | 	  if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	    to_visit -= 3; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	    if ((CELL *)to_visit < HR+1024) | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  | 	      goto out_of_stack; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	    to_visit[0] = pt0; | 
					
						
							|  |  |  | 	    to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	    to_visit[2] = pt1; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	  d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	  pt0 = ap2; | 
					
						
							|  |  |  | 	  pt0_end = ap2 + d0; | 
					
						
							|  |  |  | 	  pt1 = ap3; | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit < (CELL **)ASP) { | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     pt1 = to_visit[2]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[3]; | 
					
						
							|  |  |  |     to_visit += 4; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     pt1 = to_visit[2]; | 
					
						
							|  |  |  |     to_visit += 3; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HBREG; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   /* untrail all bindings made by variant */ | 
					
						
							|  |  |  |   while (TR != (tr_fr_ptr)OLDTR) { | 
					
						
							|  |  |  |     CELL *pt1 = (CELL *) TrailTerm(--TR); | 
					
						
							|  |  |  |     RESET_VARIABLE(pt1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   HBREG = B->cp_h; | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  out_of_stack: | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HBREG; | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |   /* untrail all bindings made by variant */ | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit < (CELL **)ASP) { | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     pt1 = to_visit[2]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[3]; | 
					
						
							|  |  |  |     to_visit += 4; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   while (TR != (tr_fr_ptr)OLDTR) { | 
					
						
							|  |  |  |     CELL *pt1 = (CELL *) TrailTerm(--TR); | 
					
						
							|  |  |  |     RESET_VARIABLE(pt1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   HBREG = B->cp_h; | 
					
						
							|  |  |  |   return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |  fail: | 
					
						
							|  |  |  |   /* failure */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HBREG; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit < (CELL **)ASP) { | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     pt1 = to_visit[2]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[3]; | 
					
						
							|  |  |  |     to_visit += 4; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   /* untrail all bindings made by variant */ | 
					
						
							|  |  |  |   while (TR != (tr_fr_ptr)OLDTR) { | 
					
						
							|  |  |  |     CELL *pt1 = (CELL *) TrailTerm(--TR); | 
					
						
							|  |  |  |     RESET_VARIABLE(pt1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   HBREG = B->cp_h; | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |   return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-02 19:48:17 +01:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | is_variant(Term t1, Term t2, int parity USES_REGS) | 
					
						
							|  |  |  | {   | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |   int out; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (t1 == t2) | 
					
						
							|  |  |  |     return (TRUE); | 
					
						
							|  |  |  |   if (IsVarTerm(t1)) { | 
					
						
							|  |  |  |     if (IsVarTerm(t2)) | 
					
						
							|  |  |  |       return(TRUE); | 
					
						
							|  |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } else if (IsVarTerm(t2)) | 
					
						
							|  |  |  |     return(FALSE); | 
					
						
							|  |  |  |   if (IsAtomOrIntTerm(t1)) { | 
					
						
							|  |  |  |     return(t1 == t2); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (IsPairTerm(t1)) { | 
					
						
							|  |  |  |     if (IsPairTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |       out = variant_complex(RepPair(t1)-1, | 
					
						
							|  |  |  | 			    RepPair(t1)+1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 			    RepPair(t2)-1 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |       if (out < 0) goto error; | 
					
						
							| 
									
										
										
										
											2004-10-06 16:55:48 +00:00
										 |  |  |       return out; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else return (FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |   if (!IsApplTerm(t2)) { | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     Functor f1 = FunctorOfTerm(t1); | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (f1 != FunctorOfTerm(t2)) return(FALSE); | 
					
						
							|  |  |  |     if (IsExtensionFunctor(f1)) { | 
					
						
							|  |  |  |       return(unify_extension(f1, t1, RepAppl(t1), t2)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |     out = variant_complex(RepAppl(t1), | 
					
						
							|  |  |  | 			  RepAppl(t1)+ArityOfFunctor(f1), | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 			  RepAppl(t2) PASS_REGS); | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |     if (out < 0) goto error; | 
					
						
							|  |  |  |     return out; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |  error: | 
					
						
							|  |  |  |   if (out == -1) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     if (!Yap_gcl((ASP-HR)*sizeof(CELL), parity, ENV, gc_P(P,CP))) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       Yap_Error(RESOURCE_ERROR_STACK, TermNil, "in variant"); | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |     return is_variant(t1, t2, parity PASS_REGS); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-09-17 20:47:35 +00:00
										 |  |  |   return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-02 19:48:17 +01:00
										 |  |  | int | 
					
						
							|  |  |  | Yap_Variant(Term t1, Term t2)  | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   return is_variant(t1, t2, 0 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-08-02 19:48:17 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_variant( USES_REGS1 ) /* variant terms t1 and t2	 */ | 
					
						
							| 
									
										
										
										
											2010-08-02 19:48:17 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   return is_variant(Deref(ARG1), Deref(ARG2), 2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-08-02 19:48:17 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 02:08:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | static int subsumes_complex(register CELL *pt0, register CELL *pt0_end, register | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 		   CELL *pt1 USES_REGS) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   register CELL **to_visit = (CELL **)ASP; | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  |   tr_fr_ptr OLDTR = TR, new_tr; | 
					
						
							| 
									
										
										
										
											2005-03-13 06:26:13 +00:00
										 |  |  |   UInt write_mode = TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HBREG = HR; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0, d1; | 
					
						
							| 
									
										
										
										
											2005-02-21 16:50:21 +00:00
										 |  |  |     Int our_write_mode = write_mode; | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ++ pt1; | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  |     /* this is a version of Derefa that checks whether we are trying to
 | 
					
						
							|  |  |  |        do something evil */ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       CELL *npt0 = pt0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     restart_d0: | 
					
						
							|  |  |  |       if (npt0 >= HBREG) { | 
					
						
							|  |  |  | 	our_write_mode = FALSE; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       d0 = *npt0; | 
					
						
							|  |  |  |       if (IsVarTerm(d0) && | 
					
						
							|  |  |  | 	  d0 != (CELL)npt0 | 
					
						
							|  |  |  | 	  ) { | 
					
						
							|  |  |  | 	npt0 = (CELL *)d0; | 
					
						
							|  |  |  | 	goto restart_d0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       CELL *npt1 = pt1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     restart_d1: | 
					
						
							|  |  |  |       d1 = *npt1; | 
					
						
							|  |  |  |       if (IsVarTerm(d1) | 
					
						
							|  |  |  | 	  && d1 != (CELL)npt1 | 
					
						
							|  |  |  | 	  ) { | 
					
						
							|  |  |  | 	/* never dereference through a variable from the left-side */ | 
					
						
							|  |  |  | 	if (npt1 >= HBREG) { | 
					
						
							|  |  |  | 	  goto fail; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 	  npt1 = (CELL *)d1; | 
					
						
							|  |  |  | 	  goto restart_d1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (IsVarTerm(d0)) { | 
					
						
							|  |  |  |       if (our_write_mode) { | 
					
						
							|  |  |  | 	/* generate a new binding */ | 
					
						
							|  |  |  | 	CELL *pt0 = VarOfTerm(d0); | 
					
						
							|  |  |  | 	Term new = MkVarTerm(); | 
					
						
							|  |  |  | 	   | 
					
						
							|  |  |  | 	Bind_Global(pt0, new); | 
					
						
							|  |  |  | 	if (d0 != d1) { /* avoid loops */ | 
					
						
							|  |  |  | 	  Bind_Global(VarOfTerm(new), d1); | 
					
						
							| 
									
										
										
										
											2009-11-17 02:08:01 +00:00
										 |  |  | 	  if (Yap_rational_tree_loop(VarOfTerm(new)-1,VarOfTerm(new),(CELL **)AuxSp,(CELL **)AuxBase)) | 
					
						
							|  |  |  | 	    goto fail; | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  | 	if (d0 == d1) continue; | 
					
						
							|  |  |  | 	goto fail; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } else if (IsVarTerm(d1)) { | 
					
						
							|  |  |  |       goto fail; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       if (d0 == d1) continue; | 
					
						
							|  |  |  |       else if (IsAtomOrIntTerm(d0)) { | 
					
						
							|  |  |  | 	goto fail; | 
					
						
							|  |  |  |       } else if (IsPairTerm(d0)) { | 
					
						
							|  |  |  | 	if (!IsPairTerm(d1)) { | 
					
						
							|  |  |  | 	  goto fail; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	/* now link the two structures so that no one else will */ | 
					
						
							|  |  |  | 	/* come here */ | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 	to_visit -= 5; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = pt1; | 
					
						
							| 
									
										
										
										
											2003-10-28 16:20:44 +00:00
										 |  |  | 	to_visit[3] = (CELL *)*pt0; | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 	to_visit[4] = (CELL *)write_mode; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	*pt0 = d1; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 	  to_visit -= 4; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit[2] = pt1; | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 	  to_visit[3] = (CELL *)write_mode; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 	write_mode = our_write_mode; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  | 	pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  | 	pt1 = RepPair(d1) - 1; | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2, *ap3; | 
					
						
							|  |  |  | 	if (!IsApplTerm(d1)) { | 
					
						
							|  |  |  | 	  goto fail; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 	  /* store the terms to visit */ | 
					
						
							|  |  |  | 	  Functor f2; | 
					
						
							|  |  |  | 	  ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	  ap3 = RepAppl(d1); | 
					
						
							|  |  |  | 	  f = (Functor)(*ap2); | 
					
						
							|  |  |  | 	  f2 = (Functor)(*ap3); | 
					
						
							|  |  |  | 	  if (f != f2) | 
					
						
							|  |  |  | 	    goto fail; | 
					
						
							|  |  |  | 	  if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	    if (!unify_extension(f, d0, ap2, d1)) | 
					
						
							|  |  |  | 	      goto fail; | 
					
						
							|  |  |  | 	    continue; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	  /* now link the two structures so that no one else will */ | 
					
						
							|  |  |  | 	  /* come here */ | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 	  to_visit -= 5; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit[2] = pt1; | 
					
						
							| 
									
										
										
										
											2003-10-28 16:20:44 +00:00
										 |  |  | 	  to_visit[3] = (CELL *)*pt0; | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 	  to_visit[4] = (CELL *)write_mode; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  *pt0 = d1; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	  /* store the terms to visit */ | 
					
						
							|  |  |  | 	  if (pt0 < pt0_end) { | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 	    to_visit -= 4; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	    to_visit[0] = pt0; | 
					
						
							|  |  |  | 	    to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	    to_visit[2] = pt1; | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 	    to_visit[3] = (CELL *)write_mode; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  | 	  write_mode = our_write_mode; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	  pt0 = ap2; | 
					
						
							|  |  |  | 	  pt0_end = ap2 + d0; | 
					
						
							|  |  |  | 	  pt1 = ap3; | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit < (CELL **)ASP) { | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     pt1 = to_visit[2]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[3]; | 
					
						
							| 
									
										
										
										
											2006-02-01 13:28:57 +00:00
										 |  |  |     write_mode = (Int)to_visit[ 4]; | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  |     to_visit += 5; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     pt1 = to_visit[2]; | 
					
						
							| 
									
										
										
										
											2005-07-20 13:54:42 +00:00
										 |  |  |     write_mode = (UInt)to_visit[3]; | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  |     to_visit += 4; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HBREG; | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  |   /* get rid of intermediate variables  */ | 
					
						
							|  |  |  |   new_tr = TR; | 
					
						
							|  |  |  |   while (TR != OLDTR) { | 
					
						
							|  |  |  |     /* cell we bound */ | 
					
						
							|  |  |  |     CELL *pt1 = (CELL *) TrailTerm(--TR); | 
					
						
							|  |  |  |     /* cell we created */ | 
					
						
							|  |  |  |     CELL *npt1 = (CELL *)*pt1; | 
					
						
							|  |  |  |     /* shorten the chain */ | 
					
						
							| 
									
										
										
										
											2004-09-18 14:03:42 +00:00
										 |  |  |     if (IsVarTerm(*pt1) && IsUnboundVar(pt1)) { | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  |       RESET_VARIABLE(pt1); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       *pt1 = *npt1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  |   TR = new_tr; | 
					
						
							|  |  |  |   HBREG = B->cp_h; | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |  fail: | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HBREG; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit < (CELL **)ASP) { | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     pt1 = to_visit[2]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[3]; | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  |     to_visit += 5; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-07-12 16:01:21 +00:00
										 |  |  |   /* untrail all bindings made by variant */ | 
					
						
							|  |  |  |   while (TR != (tr_fr_ptr)OLDTR) { | 
					
						
							|  |  |  |     CELL *pt1 = (CELL *) TrailTerm(--TR); | 
					
						
							|  |  |  |     RESET_VARIABLE(pt1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   HBREG = B->cp_h; | 
					
						
							|  |  |  |   return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_subsumes( USES_REGS1 ) /* subsumes terms t1 and t2	 */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Term t1 = Deref(ARG1); | 
					
						
							|  |  |  |   Term t2 = Deref(ARG2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (t1 == t2) | 
					
						
							|  |  |  |     return (TRUE); | 
					
						
							|  |  |  |   if (IsVarTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2014-05-29 11:32:28 +02:00
										 |  |  |     YapBind(VarOfTerm(t1), t2); | 
					
						
							| 
									
										
										
										
											2009-11-17 02:08:01 +00:00
										 |  |  |     if (Yap_rational_tree_loop(VarOfTerm(t1)-1,VarOfTerm(t1),(CELL **)AuxSp,(CELL **)AuxBase)) | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } else if (IsVarTerm(t2)) | 
					
						
							|  |  |  |     return(FALSE); | 
					
						
							|  |  |  |   if (IsAtomOrIntTerm(t1)) { | 
					
						
							|  |  |  |     return(t1 == t2); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (IsPairTerm(t1)) { | 
					
						
							|  |  |  |     if (IsPairTerm(t2)) { | 
					
						
							|  |  |  |       return(subsumes_complex(RepPair(t1)-1, | 
					
						
							|  |  |  | 			     RepPair(t1)+1, | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 			     RepPair(t2)-1 PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else return (FALSE); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     Functor f1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!IsApplTerm(t2)) return(FALSE); | 
					
						
							|  |  |  |     f1 = FunctorOfTerm(t1); | 
					
						
							|  |  |  |     if (f1 != FunctorOfTerm(t2)) | 
					
						
							|  |  |  |       return(FALSE); | 
					
						
							|  |  |  |     if (IsExtensionFunctor(f1)) { | 
					
						
							|  |  |  |       return(unify_extension(f1, t1, RepAppl(t1), t2)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return(subsumes_complex(RepAppl(t1), | 
					
						
							|  |  |  | 			   RepAppl(t1)+ArityOfFunctor(f1), | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | 			   RepAppl(t2) PASS_REGS)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static int term_subsumer_complex(register CELL *pt0, register CELL *pt0_end, register | 
					
						
							|  |  |  | 				 CELL *pt1, CELL *npt USES_REGS) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register CELL **to_visit = (CELL **)ASP; | 
					
						
							|  |  |  |   tr_fr_ptr OLDTR = TR; | 
					
						
							|  |  |  |   int out; | 
					
						
							|  |  |  |   CELL *bindings = NULL, *tbindings = NULL; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HB = HR; | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0, d1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ++ pt1; | 
					
						
							|  |  |  |     d0 = Derefa(pt0); | 
					
						
							|  |  |  |     d1 = Derefa(pt1); | 
					
						
							|  |  |  |     if (d0 == d1) { | 
					
						
							|  |  |  |       *npt++ = d0; | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } else if (IsVarTerm(d0)) { | 
					
						
							|  |  |  |       CELL *match, *omatch = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       match = VarOfTerm(d0);  | 
					
						
							|  |  |  |       if (match >= HB) { | 
					
						
							|  |  |  | 	while (match >= HB) { | 
					
						
							|  |  |  | 	  /* chained to a sequence */ | 
					
						
							|  |  |  | 	  if (Yap_eq(d1, match[1]) ) { | 
					
						
							|  |  |  | 	    *npt++ = match[2]; | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  omatch = match; | 
					
						
							|  |  |  | 	  match = (CELL *)match[3]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* found a match */ | 
					
						
							|  |  |  | 	if (match >= HB) | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	/* could not find a match, add to end of chain */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |  	RESET_VARIABLE(HR); /* key */ | 
					
						
							|  |  |  |  	HR[1] = d1; /* comparison value */ | 
					
						
							|  |  |  | 	HR[2] = (CELL)npt; /* new value */ | 
					
						
							|  |  |  | 	HR[3] = (CELL)match; /* end of chain points back to first cell */ | 
					
						
							|  |  |  | 	omatch[3] = (CELL)HR; | 
					
						
							|  |  |  | 	HR+=4; | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 	RESET_VARIABLE(npt); | 
					
						
							|  |  |  | 	npt++; | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { | 
					
						
							|  |  |  | 	goto trail_overflow; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       RESET_VARIABLE(HR); | 
					
						
							|  |  |  |       HR[1] = d1; | 
					
						
							|  |  |  |       HR[2] = (CELL)npt; | 
					
						
							|  |  |  |       HR[3] = d0; | 
					
						
							| 
									
										
										
										
											2014-05-29 11:32:28 +02:00
										 |  |  |       YapBind(VarOfTerm(d0), (CELL)HR); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       HR+=4; | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  |       RESET_VARIABLE(npt); | 
					
						
							|  |  |  |       npt++; | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } else if (IsPairTerm(d0) && IsPairTerm(d1)) { | 
					
						
							|  |  |  |       CELL *match = bindings; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       while (match) { | 
					
						
							|  |  |  | 	if (match[0] == d0 && match[1] == d1) { | 
					
						
							|  |  |  | 	  *npt++ = match[2]; | 
					
						
							|  |  |  | 	  break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	match = (CELL *)match[3]; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (match) { | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (bindings) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	*tbindings = (CELL)HR; | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	bindings = HR; | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       HR[0] = d0; | 
					
						
							|  |  |  |       HR[1] = d1; | 
					
						
							|  |  |  |       HR[2] = AbsPair(HR+4); | 
					
						
							|  |  |  |       HR[3] = (CELL)NULL; | 
					
						
							|  |  |  |       tbindings = HR+3; | 
					
						
							|  |  |  |       HR+=4; | 
					
						
							|  |  |  |       *npt++ = AbsPair(HR); | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |       /* now link the two structures so that no one else will */ | 
					
						
							|  |  |  |       /* come here */ | 
					
						
							|  |  |  |       to_visit -= 5; | 
					
						
							|  |  |  |       to_visit[0] = pt0; | 
					
						
							|  |  |  |       to_visit[1] = pt0_end; | 
					
						
							|  |  |  |       to_visit[2] = pt1; | 
					
						
							|  |  |  |       to_visit[3] = tbindings; | 
					
						
							|  |  |  |       to_visit[4] = npt; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |       /* store the terms to visit */ | 
					
						
							|  |  |  |       if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	to_visit -= 4; | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = pt1; | 
					
						
							|  |  |  | 	to_visit[3] = npt; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |       pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  |       pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  |       pt1 = RepPair(d1) - 1; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       npt = HR; | 
					
						
							|  |  |  |       HR += 2; | 
					
						
							|  |  |  |       if (HR > (CELL *)to_visit -1024) | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 	goto stack_overflow; | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } else if (IsApplTerm(d0) && IsApplTerm(d1)) { | 
					
						
							|  |  |  |       CELL *ap2 = RepAppl(d0); | 
					
						
							|  |  |  |       CELL *ap3 = RepAppl(d1); | 
					
						
							|  |  |  |       Functor f = (Functor)(*ap2); | 
					
						
							|  |  |  |       Functor f2 = (Functor)(*ap3); | 
					
						
							|  |  |  |       if (f == f2) { | 
					
						
							|  |  |  | 	CELL *match = bindings; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	  if (unify_extension(f, d0, ap2, d1)) { | 
					
						
							|  |  |  | 	    *npt++ = d0; | 
					
						
							|  |  |  | 	    continue; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	while (match) { | 
					
						
							|  |  |  | 	  if (match[0] == d0 && match[1] == d1) { | 
					
						
							|  |  |  | 	    *npt++ = match[2]; | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  match = (CELL *)match[3]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (match) { | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (bindings) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	  *tbindings = (CELL)HR; | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	  bindings = HR; | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR[0] = d0; | 
					
						
							|  |  |  | 	HR[1] = d1; | 
					
						
							|  |  |  | 	HR[2] = AbsAppl(HR+4); | 
					
						
							|  |  |  | 	HR[3] = (CELL)NULL; | 
					
						
							|  |  |  | 	tbindings = HR+3; | 
					
						
							|  |  |  | 	HR+=4; | 
					
						
							|  |  |  | 	*npt++ = AbsAppl(HR); | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	/* now link the two structures so that no one else will */ | 
					
						
							|  |  |  | 	/* come here */ | 
					
						
							|  |  |  | 	to_visit -= 5; | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = pt1; | 
					
						
							|  |  |  | 	to_visit[3] = tbindings; | 
					
						
							|  |  |  | 	to_visit[4] = npt; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit -= 4; | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit[2] = pt1; | 
					
						
							|  |  |  | 	  to_visit[3] = npt; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  | 	pt1 = ap3; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	npt = HR; | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 	*npt++ = (CELL)f; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR += d0; | 
					
						
							|  |  |  | 	if (HR > (CELL *)to_visit -1024) | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 	  goto stack_overflow; | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     RESET_VARIABLE(npt); | 
					
						
							|  |  |  |     npt++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit < (CELL **)ASP) { | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     pt1 = to_visit[2]; | 
					
						
							|  |  |  |     tbindings = to_visit[3]; | 
					
						
							|  |  |  |     npt = to_visit[ 4]; | 
					
						
							|  |  |  |     if (!tbindings) { | 
					
						
							|  |  |  |       bindings = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     to_visit += 5; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     pt1 = to_visit[2]; | 
					
						
							|  |  |  |     npt = to_visit[3]; | 
					
						
							|  |  |  |     to_visit += 4; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   out = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  complete: | 
					
						
							|  |  |  |   /* get rid of intermediate variables  */ | 
					
						
							|  |  |  |   while (TR != OLDTR) { | 
					
						
							|  |  |  |     CELL *pt1 = (CELL *) TrailTerm(--TR); | 
					
						
							|  |  |  |     RESET_VARIABLE(pt1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   HBREG = B->cp_h; | 
					
						
							|  |  |  |   return out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  stack_overflow: | 
					
						
							|  |  |  |   out = -1; | 
					
						
							|  |  |  |   goto complete; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  trail_overflow: | 
					
						
							|  |  |  |   out = -2; | 
					
						
							|  |  |  |   goto complete; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_term_subsumer( USES_REGS1 ) /* term_subsumer terms t1 and t2	 */ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int out = 0;  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while (out != 1) { | 
					
						
							|  |  |  |     Term t1 = Deref(ARG1); | 
					
						
							|  |  |  |     Term t2 = Deref(ARG2); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     CELL *oldH = HR; | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (t1 == t2) | 
					
						
							|  |  |  |       return Yap_unify(ARG3,t1); | 
					
						
							|  |  |  |     if (IsPairTerm(t1) && IsPairTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       Term tf = AbsAppl(HR); | 
					
						
							|  |  |  |       HR += 2; | 
					
						
							|  |  |  |       HB = HR; | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  |       if ((out = term_subsumer_complex(RepPair(t1)-1, | 
					
						
							|  |  |  | 				       RepPair(t1)+1, | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 				       RepPair(t2)-1, HR-2 PASS_REGS)) > 0) { | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 	HB = B->cp_h; | 
					
						
							|  |  |  | 	return Yap_unify(ARG3,tf); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   } else if (IsApplTerm(t1) && IsApplTerm(t2)) { | 
					
						
							|  |  |  |       Functor f1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if ((f1 = FunctorOfTerm(t1)) == FunctorOfTerm(t2)) { | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f1)) { | 
					
						
							|  |  |  | 	  if (unify_extension(f1, t1, RepAppl(t1), t2)) { | 
					
						
							|  |  |  | 	    return Yap_unify(ARG3,t1); | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	  Term tf = AbsAppl(HR); | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 	  UInt ar = ArityOfFunctor(f1); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	  HR[0] = (CELL)f1; | 
					
						
							|  |  |  | 	  HR += 1+ar; | 
					
						
							|  |  |  | 	  HB = HR; | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 	  if ((out = term_subsumer_complex(RepAppl(t1), | 
					
						
							|  |  |  | 					   RepAppl(t1)+ArityOfFunctor(f1), | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 					   RepAppl(t2), HR-ar PASS_REGS)) > 0) { | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 	    HB = B->cp_h; | 
					
						
							|  |  |  | 	    return Yap_unify(ARG3,tf); | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     HB = B->cp_h; | 
					
						
							|  |  |  |     if (out == 0) { | 
					
						
							|  |  |  |       return Yap_unify(ARG3, MkVarTerm()); | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |       HR = oldH; | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  |       if (out == -1) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	if (!Yap_gcl((ASP-HR)*sizeof(CELL), 0, ENV, gc_P(P,CP))) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	  Yap_Error(RESOURCE_ERROR_STACK, TermNil, "in term_subsumer"); | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 	  return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  | 	/* Trail overflow */ | 
					
						
							|  |  |  | 	if (!Yap_growtrail(0, FALSE)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	  Yap_Error(RESOURCE_ERROR_TRAIL, TermNil, "in term_subsumer"); | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  | 	  return FALSE; | 
					
						
							|  |  |  | 	}  | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_force_trail_expansion( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Int i = IntOfTerm(Deref(ARG1))*1024, j = 0; | 
					
						
							|  |  |  |   tr_fr_ptr OTR = TR; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (j = 0; j < i; j++) { | 
					
						
							|  |  |  |     TrailTerm(TR) = 0; | 
					
						
							|  |  |  |     TR++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   TR = OTR; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return(TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | camacho_dum( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Term t1, t2; | 
					
						
							|  |  |  |   int  max = 3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* build output list */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 01:53:52 +00:00
										 |  |  |   t1 = TermNil; | 
					
						
							|  |  |  |   t2 = MkPairTerm(MkIntegerTerm(max), t1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |   return(Yap_unify(t2, ARG1)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* DEBUG */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-24 10:31:53 -05:00
										 |  |  | int | 
					
						
							|  |  |  | Yap_IsListTerm(Term t) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-04 10:45:32 +00:00
										 |  |  |   Term *tailp; | 
					
						
							|  |  |  |   Yap_SkipList(&t, &tailp); | 
					
						
							|  |  |  |   return *tailp == TermNil; | 
					
						
							| 
									
										
										
										
											2009-04-24 10:31:53 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_is_list( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2009-04-24 10:31:53 -05:00
										 |  |  | { | 
					
						
							|  |  |  |   return Yap_IsListTerm(Deref(ARG1)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-18 01:32:13 +00:00
										 |  |  | bool | 
					
						
							| 
									
										
										
										
											2012-03-06 14:41:23 +00:00
										 |  |  | Yap_IsListOrPartialListTerm(Term t) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Term *tailp, tail; | 
					
						
							|  |  |  |   Yap_SkipList(&t, &tailp); | 
					
						
							|  |  |  |   tail = *tailp; | 
					
						
							|  |  |  |   return tail == TermNil || IsVarTerm(tail); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-06 14:12:25 +00:00
										 |  |  | static Int | 
					
						
							|  |  |  | p_is_list_or_partial_list( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-06 14:41:23 +00:00
										 |  |  |   return Yap_IsListOrPartialListTerm(Deref(ARG1)); | 
					
						
							| 
									
										
										
										
											2012-03-06 14:12:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | static Term | 
					
						
							| 
									
										
										
										
											2012-04-11 22:08:02 +01:00
										 |  |  | numbervar(Int id USES_REGS) | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | { | 
					
						
							|  |  |  |   Term ts[1]; | 
					
						
							|  |  |  |   ts[0] = MkIntegerTerm(id); | 
					
						
							| 
									
										
										
										
											2015-12-15 08:48:53 +00:00
										 |  |  |   return Yap_MkApplTerm(FunctorDollarVar, 1, ts); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  | static Term | 
					
						
							| 
									
										
										
										
											2012-04-11 22:08:02 +01:00
										 |  |  | numbervar_singleton(USES_REGS1) | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Term ts[1]; | 
					
						
							|  |  |  |   ts[0] = MkIntegerTerm(-1); | 
					
						
							| 
									
										
										
										
											2015-12-15 08:48:53 +00:00
										 |  |  |   return Yap_MkApplTerm(FunctorDollarVar, 1, ts); | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | renumbervar(Term t, Int id USES_REGS) | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Term *ts = RepAppl(t); | 
					
						
							|  |  |  |   ts[1] = MkIntegerTerm(id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  | static Int numbervars_in_complex_term(register CELL *pt0, register CELL *pt0_end, Int numbv, int singles USES_REGS) | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   register CELL **to_visit0, **to_visit = (CELL **)Yap_PreAllocCodeSpace(); | 
					
						
							|  |  |  |   register tr_fr_ptr TR0 = TR; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   CELL *InitialH = HR; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |   to_visit0 = to_visit; | 
					
						
							|  |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, vars_in_term_unk); | 
					
						
							|  |  |  |   vars_in_term_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							|  |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	pt0 = RepPair(d0) - 1; | 
					
						
							|  |  |  | 	pt0_end = RepPair(d0) + 1; | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	if (singles && ap2 >= InitialH && ap2 < HR) { | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | 	  renumbervar(d0, numbv++ PASS_REGS); | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	if (to_visit + 1024 >= (CELL **)AuxSp) { | 
					
						
							|  |  |  | 	  goto aux_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	to_visit[0] = pt0; | 
					
						
							|  |  |  | 	to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	to_visit[2] = (CELL *)*pt0; | 
					
						
							|  |  |  | 	to_visit += 3; | 
					
						
							|  |  |  | 	*pt0 = TermNil; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  to_visit[0] = pt0; | 
					
						
							|  |  |  | 	  to_visit[1] = pt0_end; | 
					
						
							|  |  |  | 	  to_visit += 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     derefa_body(d0, ptd0, vars_in_term_unk, vars_in_term_nvar); | 
					
						
							|  |  |  |     /* do or pt2 are unbound  */ | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  |     if (singles)  | 
					
						
							| 
									
										
										
										
											2012-04-11 22:08:02 +01:00
										 |  |  |       *ptd0 = numbervar_singleton( PASS_REGS1 ); | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2012-04-11 22:08:02 +01:00
										 |  |  |       *ptd0 = numbervar(numbv++ PASS_REGS); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |     /* leave an empty slot to fill in later */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     if (HR+1024 > ASP) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |       goto global_overflow; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /* next make sure noone will see this as a variable again */  | 
					
						
							|  |  |  |     if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { | 
					
						
							|  |  |  |       /* Trail overflow */ | 
					
						
							|  |  |  |       if (!Yap_growtrail((TR-TR0)*sizeof(tr_fr_ptr *), TRUE)) { | 
					
						
							|  |  |  | 	goto trail_overflow; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-04-23 15:50:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(TABLING) || defined(YAPOR_SBA)
 | 
					
						
							|  |  |  |     TrailVal(TR) = (CELL)ptd0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |     TrailTerm(TR++) = (CELL)ptd0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit > to_visit0) { | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     to_visit -= 2; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     pt0_end = to_visit[1]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-13 18:12:50 +00:00
										 |  |  |   prune(B PASS_REGS); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							|  |  |  |   return numbv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  trail_overflow: | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_TRAIL; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   LOCAL_Error_Size = (TR-TR0)*sizeof(tr_fr_ptr *); | 
					
						
							|  |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							|  |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2015-10-08 13:29:47 +01:00
										 |  |  |   return numbv-1; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |    | 
					
						
							|  |  |  |  aux_overflow: | 
					
						
							|  |  |  |   LOCAL_Error_Size = (to_visit-to_visit0)*sizeof(CELL **); | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							|  |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2015-10-08 13:29:47 +01:00
										 |  |  |   return numbv-1; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |    | 
					
						
							|  |  |  |  global_overflow: | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit -= 3; | 
					
						
							|  |  |  |     pt0 = to_visit[0]; | 
					
						
							|  |  |  |     *pt0 = (CELL)to_visit[2]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   clean_tr(TR0 PASS_REGS); | 
					
						
							|  |  |  |   Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = InitialH; | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   LOCAL_Error_TYPE = RESOURCE_ERROR_STACK; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   LOCAL_Error_Size = (ASP-HR)*sizeof(CELL); | 
					
						
							| 
									
										
										
										
											2015-10-08 13:29:47 +01:00
										 |  |  |   return numbv-1; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |    | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Int  | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  | Yap_NumberVars( Term inp, Int numbv, int handle_singles )	/* numbervariables in term t	 */ | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | { | 
					
						
							|  |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   Int out; | 
					
						
							|  |  |  |   Term t; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |  restart: | 
					
						
							|  |  |  |   t = Deref(inp); | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							|  |  |  |     CELL *ptd0 = VarOfTerm(t); | 
					
						
							|  |  |  |     TrailTerm(TR++) = (CELL)ptd0; | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  |     if (handle_singles) { | 
					
						
							| 
									
										
										
										
											2012-04-11 22:08:02 +01:00
										 |  |  |       *ptd0 = numbervar_singleton( PASS_REGS1 ); | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  |       return numbv; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2012-04-11 22:08:02 +01:00
										 |  |  |       *ptd0 = numbervar(numbv PASS_REGS); | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  |       return numbv+1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   }  else if (IsPrimitiveTerm(t)) { | 
					
						
							|  |  |  |     return numbv; | 
					
						
							|  |  |  |   } else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |     out = numbervars_in_complex_term(RepPair(t)-1, | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  | 				     RepPair(t)+1, numbv, handle_singles PASS_REGS); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     out = numbervars_in_complex_term(RepAppl(t), | 
					
						
							|  |  |  | 			       RepAppl(t)+ | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  | 				     ArityOfFunctor(f), numbv, handle_singles PASS_REGS); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-10-08 13:29:47 +01:00
										 |  |  |   if (out < numbv) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |     if (!expand_vts( 3 PASS_REGS )) | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     goto restart; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return out; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-11-04 09:28:33 +00:00
										 |  |  | p_numbervars( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | { | 
					
						
							|  |  |  |   Term t2 = Deref(ARG2); | 
					
						
							|  |  |  |   Int out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t2)) { | 
					
						
							|  |  |  |     Yap_Error(INSTANTIATION_ERROR,t2,"numbervars/3"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!IsIntegerTerm(t2)) { | 
					
						
							|  |  |  |     Yap_Error(TYPE_ERROR_INTEGER,t2,"term_hash/4"); | 
					
						
							|  |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-03-14 22:10:21 +00:00
										 |  |  |   if ((out = Yap_NumberVars(ARG1, IntegerOfTerm(t2), FALSE)) < 0) | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   return Yap_unify(ARG3, MkIntegerTerm(out)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											2011-11-04 09:28:33 +00:00
										 |  |  | unnumber_complex_term(CELL *pt0, CELL *pt0_end, CELL *ptf, CELL *HLow, int share USES_REGS) | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct cp_frame *to_visit0, *to_visit = (struct cp_frame *)Yap_PreAllocCodeSpace(); | 
					
						
							|  |  |  |   CELL *HB0 = HB; | 
					
						
							|  |  |  |   tr_fr_ptr TR0 = TR; | 
					
						
							| 
									
										
										
										
											2011-11-04 09:28:33 +00:00
										 |  |  |   int ground = share; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   Int max = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   HB = HLow; | 
					
						
							|  |  |  |   to_visit0 = to_visit; | 
					
						
							|  |  |  |  loop: | 
					
						
							|  |  |  |   while (pt0 < pt0_end) { | 
					
						
							|  |  |  |     register CELL d0; | 
					
						
							|  |  |  |     register CELL *ptd0; | 
					
						
							|  |  |  |     ++ pt0; | 
					
						
							|  |  |  |     ptd0 = pt0; | 
					
						
							|  |  |  |     d0 = *ptd0; | 
					
						
							|  |  |  |     deref_head(d0, unnumber_term_unk); | 
					
						
							|  |  |  |   unnumber_term_nvar: | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (IsPairTerm(d0)) { | 
					
						
							|  |  |  | 	CELL *ap2 = RepPair(d0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	if (ap2 >= HB && ap2 < HR) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	  /* If this is newer than the current term, just reuse */ | 
					
						
							|  |  |  | 	  *ptf++ = d0; | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	}  | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	*ptf = AbsPair(HR); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	ptf++; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	if (to_visit+1 >= (struct cp_frame *)AuxSp) { | 
					
						
							|  |  |  | 	  goto heap_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	to_visit->to = ptf; | 
					
						
							|  |  |  | 	to_visit->oldv = *pt0; | 
					
						
							|  |  |  | 	to_visit->ground = ground; | 
					
						
							|  |  |  | 	/* fool the system into thinking we had a variable there */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	*pt0 = AbsPair(HR); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	to_visit ++; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  if (to_visit+1 >= (struct cp_frame *)AuxSp) { | 
					
						
							|  |  |  | 	    goto heap_overflow; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	  to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	  to_visit->to = ptf; | 
					
						
							|  |  |  | 	  to_visit->ground = ground; | 
					
						
							|  |  |  | 	  to_visit ++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-11-04 09:28:33 +00:00
										 |  |  | 	ground = share; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	pt0 = ap2 - 1; | 
					
						
							|  |  |  | 	pt0_end = ap2 + 1; | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	ptf = HR; | 
					
						
							|  |  |  | 	HR += 2; | 
					
						
							|  |  |  | 	if (HR > ASP - 2048) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	  goto overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } else if (IsApplTerm(d0)) { | 
					
						
							|  |  |  | 	register Functor f; | 
					
						
							|  |  |  | 	register CELL *ap2; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | 	ap2 = RepAppl(d0); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	if (ap2 >= HB && ap2 <= HR) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	  /* If this is newer than the current term, just reuse */ | 
					
						
							|  |  |  | 	  *ptf++ = d0; | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	}  | 
					
						
							|  |  |  | 	f = (Functor)(*ap2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  | 	  *ptf++ = d0;  /* you can just unnumber other extensions. */ | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-12-15 08:48:53 +00:00
										 |  |  | 	if (f == FunctorDollarVar) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	  Int id = IntegerOfTerm(ap2[1]); | 
					
						
							|  |  |  | 	  ground = FALSE; | 
					
						
							|  |  |  | 	  if (id < -1) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	    Yap_Error(RESOURCE_ERROR_STACK, TermNil, "unnumber vars cannot cope with VAR(-%d)", id); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	    return 0L; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  if (id <= max) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	    if (ASP-(max+1) <= HR) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	      goto overflow; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2011-11-18 22:16:33 +00:00
										 |  |  | 	    /* we found this before? */ | 
					
						
							|  |  |  | 	    if (ASP[-id-1]) | 
					
						
							|  |  |  | 	      *ptf++ = ASP[-id-1]; | 
					
						
							|  |  |  | 	    else { | 
					
						
							|  |  |  | 	      RESET_VARIABLE(ptf); | 
					
						
							|  |  |  | 	      ASP[-id-1] = (CELL)ptf; | 
					
						
							|  |  |  | 	      ptf++; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	    continue; | 
					
						
							|  |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2011-11-18 22:16:33 +00:00
										 |  |  | 	  /* alloc more space */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	  if (ASP-(id+1) <= HR) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	    goto overflow; | 
					
						
							|  |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2011-11-18 22:16:33 +00:00
										 |  |  | 	  while (id > max) { | 
					
						
							|  |  |  | 	    ASP[-(id+1)] = 0L; | 
					
						
							|  |  |  | 	    max++; | 
					
						
							|  |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	  /* new variable */ | 
					
						
							|  |  |  | 	  RESET_VARIABLE(ptf); | 
					
						
							| 
									
										
										
										
											2011-11-18 22:16:33 +00:00
										 |  |  | 	  ASP[-(id+1)] = (CELL)ptf; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	  ptf++; | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	*ptf = AbsAppl(HR); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	ptf++; | 
					
						
							|  |  |  | 	/* store the terms to visit */ | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  | 	if (to_visit+1 >= (struct cp_frame *)AuxSp) { | 
					
						
							|  |  |  | 	  goto heap_overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	to_visit->to = ptf; | 
					
						
							|  |  |  | 	to_visit->oldv = *pt0; | 
					
						
							|  |  |  | 	to_visit->ground = ground; | 
					
						
							|  |  |  | 	/* fool the system into thinking we had a variable there */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	*pt0 = AbsAppl(HR); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	to_visit ++; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if (pt0 < pt0_end) { | 
					
						
							|  |  |  | 	  if (to_visit+1 >= (struct cp_frame *)AuxSp) { | 
					
						
							|  |  |  | 	    goto heap_overflow; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  to_visit->start_cp = pt0; | 
					
						
							|  |  |  | 	  to_visit->end_cp = pt0_end; | 
					
						
							|  |  |  | 	  to_visit->to = ptf; | 
					
						
							|  |  |  | 	  to_visit->ground = ground; | 
					
						
							|  |  |  | 	  to_visit ++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-11-04 09:28:33 +00:00
										 |  |  | 	ground = (f != FunctorMutable) && share; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	d0 = ArityOfFunctor(f); | 
					
						
							|  |  |  | 	pt0 = ap2; | 
					
						
							|  |  |  | 	pt0_end = ap2 + d0; | 
					
						
							|  |  |  | 	/* store the functor for the new term */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR[0] = (CELL)f; | 
					
						
							|  |  |  | 	ptf = HR+1; | 
					
						
							|  |  |  | 	HR += 1+d0; | 
					
						
							|  |  |  | 	if (HR > ASP - 2048) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	  goto overflow; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  | 	/* just unnumber atoms or integers */ | 
					
						
							|  |  |  | 	*ptf++ = d0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     derefa_body(d0, ptd0, unnumber_term_unk, unnumber_term_nvar); | 
					
						
							| 
									
										
										
										
											2011-11-04 09:28:33 +00:00
										 |  |  |     /* this should never happen ? */ | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |     ground = FALSE; | 
					
						
							|  |  |  |     *ptf++ = (CELL) ptd0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Do we still have compound terms to visit */ | 
					
						
							|  |  |  |   if (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit --; | 
					
						
							|  |  |  |     if (ground) { | 
					
						
							|  |  |  |       CELL old = to_visit->oldv; | 
					
						
							|  |  |  |       CELL *newp = to_visit->to-1; | 
					
						
							|  |  |  |       CELL new = *newp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       *newp = old; | 
					
						
							|  |  |  |       if (IsApplTerm(new)) | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR = RepAppl(new); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR = RepPair(new); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |     } | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |     *pt0 = to_visit->oldv; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     ground = (ground && to_visit->ground); | 
					
						
							|  |  |  |     goto loop; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-04-24 10:31:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							|  |  |  |   clean_dirty_tr(TR0 PASS_REGS); | 
					
						
							|  |  |  |   HB = HB0; | 
					
						
							|  |  |  |   return ground; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  overflow: | 
					
						
							|  |  |  |   /* oops, we're in trouble */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HLow; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   /* we've done it */ | 
					
						
							|  |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							|  |  |  |   HB = HB0; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							|  |  |  |     *pt0 = to_visit->oldv; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   reset_trail(TR0); | 
					
						
							|  |  |  |   /* follow chain of multi-assigned variables */ | 
					
						
							|  |  |  |   return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  heap_overflow: | 
					
						
							|  |  |  |   /* oops, we're in trouble */ | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |   HR = HLow; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   /* we've done it */ | 
					
						
							|  |  |  |   /* restore our nice, friendly, term to its original state */ | 
					
						
							|  |  |  |   HB = HB0; | 
					
						
							|  |  |  | #ifdef RATIONAL_TREES
 | 
					
						
							|  |  |  |   while (to_visit > to_visit0) { | 
					
						
							|  |  |  |     to_visit --; | 
					
						
							|  |  |  |     pt0 = to_visit->start_cp; | 
					
						
							|  |  |  |     pt0_end = to_visit->end_cp; | 
					
						
							|  |  |  |     ptf = to_visit->to; | 
					
						
							|  |  |  |     *pt0 = to_visit->oldv; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   reset_trail(TR0); | 
					
						
							|  |  |  |   LOCAL_Error_Size = (ADDR)AuxSp-(ADDR)to_visit0; | 
					
						
							|  |  |  |   return -3; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Term | 
					
						
							| 
									
										
										
										
											2011-11-04 09:28:33 +00:00
										 |  |  | UnnumberTerm(Term inp, UInt arity, int share USES_REGS) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   Term t = Deref(inp); | 
					
						
							|  |  |  |   tr_fr_ptr TR0 = TR; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							|  |  |  |     return inp; | 
					
						
							|  |  |  |   } else if (IsPrimitiveTerm(t)) { | 
					
						
							|  |  |  |     return t; | 
					
						
							|  |  |  |   } else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |     Term tf; | 
					
						
							|  |  |  |     CELL *ap; | 
					
						
							|  |  |  |     CELL *Hi; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   restart_list: | 
					
						
							|  |  |  |     ap = RepPair(t); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     Hi = HR; | 
					
						
							|  |  |  |     tf = AbsPair(HR); | 
					
						
							|  |  |  |     HR += 2; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |     { | 
					
						
							|  |  |  |       int res; | 
					
						
							| 
									
										
										
										
											2011-11-04 09:28:33 +00:00
										 |  |  |       if ((res = unnumber_complex_term(ap-1, ap+1, Hi, Hi, share PASS_REGS)) < 0) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR = Hi; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	if ((t = handle_cp_overflow(res, TR0, arity, t))== 0L) | 
					
						
							|  |  |  | 	  return FALSE; | 
					
						
							|  |  |  | 	goto restart_list; | 
					
						
							|  |  |  |       } else if (res) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR = Hi; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	return t; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return tf; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |     Term tf; | 
					
						
							|  |  |  |     CELL *HB0; | 
					
						
							|  |  |  |     CELL *ap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   restart_appl: | 
					
						
							|  |  |  |     f = FunctorOfTerm(t); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     HB0 = HR; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |     ap = RepAppl(t); | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  |     tf = AbsAppl(HR); | 
					
						
							|  |  |  |     HR[0] = (CELL)f; | 
					
						
							|  |  |  |     HR += 1+ArityOfFunctor(f); | 
					
						
							|  |  |  |     if (HR > ASP-128) { | 
					
						
							|  |  |  |       HR = HB0; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |       if ((t = handle_cp_overflow(-1, TR0, arity, t))== 0L) | 
					
						
							|  |  |  | 	return FALSE; | 
					
						
							|  |  |  |       goto restart_appl; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       int res; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-04 09:28:33 +00:00
										 |  |  |       if ((res = unnumber_complex_term(ap, ap+ArityOfFunctor(f), HB0+1, HB0, share PASS_REGS)) < 0) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR = HB0; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	if ((t = handle_cp_overflow(res, TR0, arity, t))== 0L) | 
					
						
							|  |  |  | 	  return FALSE; | 
					
						
							|  |  |  | 	goto restart_appl; | 
					
						
							|  |  |  |       } else if (res && FunctorOfTerm(t) != FunctorMutable) { | 
					
						
							| 
									
										
										
										
											2014-01-19 21:15:05 +00:00
										 |  |  | 	HR = HB0; | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | 	return t; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return tf; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | Term | 
					
						
							| 
									
										
										
										
											2011-11-04 09:28:33 +00:00
										 |  |  | Yap_UnNumberTerm(Term inp, int share) { | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2011-11-04 09:28:33 +00:00
										 |  |  |   return UnnumberTerm(inp, 0, share PASS_REGS); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-04 09:28:33 +00:00
										 |  |  | static Int | 
					
						
							|  |  |  | p_unnumbervars( USES_REGS1 ) { | 
					
						
							|  |  |  |   /* this should be a standard Prolog term, so we allow sharing? */ | 
					
						
							| 
									
										
										
										
											2011-11-16 14:59:28 +00:00
										 |  |  |   return Yap_unify(UnnumberTerm(ARG1, 2, FALSE PASS_REGS), ARG2); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-04-24 10:31:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-09 23:28:31 +00:00
										 |  |  | Int | 
					
						
							|  |  |  | Yap_SkipList(Term *l, Term **tailp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Int length = 0; | 
					
						
							|  |  |  |   Term *s; /* slow */ | 
					
						
							|  |  |  |   Term v; /* temporary */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   do_derefa(v,l,derefa_unk,derefa_nonvar); | 
					
						
							|  |  |  |   s = l; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( IsPairTerm(*l) ) | 
					
						
							|  |  |  |   { intptr_t power = 1, lam = 0; | 
					
						
							|  |  |  |     do | 
					
						
							|  |  |  |     { if ( power == lam ) | 
					
						
							|  |  |  |       { s = l; | 
					
						
							|  |  |  | 	power *= 2; | 
					
						
							|  |  |  | 	lam = 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       lam++; | 
					
						
							|  |  |  |       length++; | 
					
						
							|  |  |  |       l = RepPair(*l)+1;  | 
					
						
							|  |  |  |       do_derefa(v,l,derefa2_unk,derefa2_nonvar); | 
					
						
							|  |  |  |     } while ( *l != *s && IsPairTerm(*l) ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   *tailp = l; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return length; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-02 14:49:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-09 23:28:31 +00:00
										 |  |  | static Int  | 
					
						
							|  |  |  | p_skip_list( USES_REGS1 ) { | 
					
						
							|  |  |  |   Term *tail; | 
					
						
							|  |  |  |   Int len = Yap_SkipList(XREGS+2, &tail); | 
					
						
							| 
									
										
										
										
											2012-09-27 22:32:50 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-09 23:28:31 +00:00
										 |  |  |   return Yap_unify(MkIntegerTerm(len), ARG1) && | 
					
						
							|  |  |  |     Yap_unify(*tail, ARG3); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-27 22:32:50 +01:00
										 |  |  | static Int  | 
					
						
							|  |  |  | p_skip_list4( USES_REGS1 ) { | 
					
						
							|  |  |  |   Term *tail; | 
					
						
							| 
									
										
										
										
											2012-10-03 09:22:27 +01:00
										 |  |  |   Int len, len1 = -1; | 
					
						
							|  |  |  |   Term t2 = Deref(ARG2), t; | 
					
						
							| 
									
										
										
										
											2012-09-27 22:32:50 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!IsVarTerm(t2)) { | 
					
						
							|  |  |  |     if (!IsIntegerTerm(t2)) { | 
					
						
							|  |  |  |       Yap_Error(TYPE_ERROR_INTEGER, t2, "length/2"); | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ((len1 = IntegerOfTerm(t2)) < 0) { | 
					
						
							|  |  |  |       Yap_Error(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t2, "length/2"); | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-10-03 09:22:27 +01:00
										 |  |  |   /* we need len here */ | 
					
						
							|  |  |  |   len = Yap_SkipList(XREGS+1, &tail); | 
					
						
							|  |  |  |   t = *tail; | 
					
						
							| 
									
										
										
										
											2012-09-27 22:32:50 +01:00
										 |  |  |   /* don't set M0 if full list, just check M */ | 
					
						
							|  |  |  |   if (t == TermNil) { | 
					
						
							| 
									
										
										
										
											2012-10-03 09:22:27 +01:00
										 |  |  |     if (len1 >= 0) { /* ARG2 was bound */ | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  | 	len1 == len && | 
					
						
							|  |  |  | 	Yap_unify(t, ARG4); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       return Yap_unify_constant(ARG4, TermNil) && | 
					
						
							|  |  |  | 	Yap_unify_constant(ARG2, MkIntegerTerm(len)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-09-27 22:32:50 +01:00
										 |  |  |   } | 
					
						
							|  |  |  |   return Yap_unify(MkIntegerTerm(len), ARG3) && | 
					
						
							|  |  |  |     Yap_unify(t, ARG4); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-07 09:26:21 -05:00
										 |  |  | static Int | 
					
						
							|  |  |  | p_free_arguments( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Term t = Deref(ARG1); | 
					
						
							|  |  |  |   if (IsVarTerm(t)) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   if (IsAtomTerm(t) || IsIntTerm(t)) | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  |   if (IsPairTerm(t)) { | 
					
						
							|  |  |  |     Term th = HeadOfTerm(t); | 
					
						
							|  |  |  |     Term tl = TailOfTerm(t); | 
					
						
							|  |  |  |     return IsVarTerm(th) && IsVarTerm(tl) && th != tl; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |     UInt i, ar; | 
					
						
							|  |  |  |     Int ret = TRUE; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     if (IsExtensionFunctor(f)) | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							|  |  |  |     ar = ArityOfFunctor(f); | 
					
						
							|  |  |  |     for (i = 1 ; i <= ar; i++) { | 
					
						
							|  |  |  |       Term ta = ArgOfTerm(i, t); | 
					
						
							|  |  |  |       Int j; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ret = IsVarTerm(ta); | 
					
						
							|  |  |  |       if (!ret) break; | 
					
						
							|  |  |  |       /* stupid quadractic algorithm, but needs no testing for overflows */ | 
					
						
							|  |  |  |       for (j = 1 ; j < i; j++) { | 
					
						
							|  |  |  | 	ret = ArgOfTerm(j, t) != ta; | 
					
						
							|  |  |  | 	if (!ret) break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (!ret) break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-28 12:04:52 +01:00
										 |  |  | static Int | 
					
						
							|  |  |  | p_freshen_variables( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Term t = Deref(ARG1); | 
					
						
							|  |  |  |   Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |   UInt arity = ArityOfFunctor(f), i; | 
					
						
							|  |  |  |   Term tn = Yap_MkNewApplTerm(f, arity); | 
					
						
							|  |  |  |   CELL *src = RepAppl(t)+1; | 
					
						
							|  |  |  |   CELL *targ = RepAppl(tn)+1; | 
					
						
							|  |  |  |   for (i=0; i< arity; i++) { | 
					
						
							|  |  |  |     RESET_VARIABLE(targ); | 
					
						
							|  |  |  |     *VarOfTerm(*src) = (CELL)targ; | 
					
						
							|  |  |  |     targ++; | 
					
						
							|  |  |  |     src++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							|  |  |  | p_reset_variables( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Term t = Deref(ARG1); | 
					
						
							|  |  |  |   Functor f = FunctorOfTerm(t); | 
					
						
							|  |  |  |   UInt arity = ArityOfFunctor(f), i; | 
					
						
							|  |  |  |   CELL *src = RepAppl(t)+1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i=0; i< arity; i++) { | 
					
						
							|  |  |  |     RESET_VARIABLE(VarOfTerm(*src)); | 
					
						
							|  |  |  |     src++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | void Yap_InitUtilCPreds(void) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2004-05-13 20:54:58 +00:00
										 |  |  |   Term cm = CurrentModule; | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |   Yap_InitCPred("copy_term", 2, p_copy_term, 0); | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /** @pred  copy_term(? _TI_,- _TF_) is iso 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Term  _TF_ is a variant of the original term  _TI_, such that for | 
					
						
							|  |  |  | each variable  _V_ in the term  _TI_ there is a new variable  _V'_ | 
					
						
							|  |  |  | in term  _TF_. Notice that: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | + suspended goals and attributes for attributed variables in _TI_ are also duplicated; | 
					
						
							|  |  |  | + ground terms are shared between the new and the old term. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you do not want any sharing to occur please use | 
					
						
							|  |  |  | duplicate_term/2. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2007-09-21 13:52:52 +00:00
										 |  |  |   Yap_InitCPred("duplicate_term", 2, p_duplicate_term, 0); | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /** @pred  duplicate_term(? _TI_,- _TF_) 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Term  _TF_ is a variant of the original term  _TI_, such that | 
					
						
							|  |  |  | for each variable  _V_ in the term  _TI_ there is a new variable | 
					
						
							|  |  |  |  _V'_ in term  _TF_, and the two terms do not share any | 
					
						
							|  |  |  | structure. All suspended goals and attributes for attributed variables | 
					
						
							|  |  |  | in  _TI_ are also duplicated. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Also refer to copy_term/2. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2005-10-30 00:32:55 +00:00
										 |  |  |   Yap_InitCPred("copy_term_nat", 2, p_copy_term_no_delays, 0); | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /** @pred copy_term_nat(? _TI_,- _TF_)  
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | As copy_term/2.  Attributes however, are <em>not</em> copied but replaced | 
					
						
							|  |  |  | by fresh variables. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |   Yap_InitCPred("ground", 1, p_ground, SafePredFlag); | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /** @pred  ground( _T_) is iso 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Succeeds if there are no free variables in the term  _T_. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2012-10-19 18:10:48 +01:00
										 |  |  |   Yap_InitCPred("$variables_in_term", 3, p_variables_in_term, 0); | 
					
						
							| 
									
										
										
										
											2013-01-14 22:46:06 +00:00
										 |  |  |   Yap_InitCPred("$free_variables_in_term", 3, p_free_variables_in_term, 0); | 
					
						
							| 
									
										
										
										
											2012-10-19 18:10:48 +01:00
										 |  |  |   Yap_InitCPred("$non_singletons_in_term", 3, p_non_singletons_in_term, 0); | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |   Yap_InitCPred("term_variables", 2, p_term_variables, 0); | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /** @pred  term_variables(? _Term_, - _Variables_) is iso 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Unify  _Variables_ with the list of all variables of term | 
					
						
							|  |  |  |  _Term_.  The variables occur in the order of their first | 
					
						
							|  |  |  | appearance when traversing the term depth-first, left-to-right. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2006-03-30 01:11:10 +00:00
										 |  |  |   Yap_InitCPred("term_variables", 3, p_term_variables3, 0); | 
					
						
							| 
									
										
										
										
											2010-03-12 08:49:12 +00:00
										 |  |  |   Yap_InitCPred("term_attvars", 2, p_term_attvars, 0); | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /** @pred term_attvars(+ _Term_,- _AttVars_) 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  _AttVars_ is a list of all attributed variables in  _Term_ and | 
					
						
							|  |  |  | its attributes. I.e., term_attvars/2 works recursively through | 
					
						
							|  |  |  | attributes.  This predicate is Cycle-safe. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2012-03-06 14:41:23 +00:00
										 |  |  |   Yap_InitCPred("is_list", 1, p_is_list, SafePredFlag|TestPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$is_list_or_partial_list", 1, p_is_list_or_partial_list, SafePredFlag|TestPredFlag); | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |   Yap_InitCPred("rational_term_to_tree", 4, p_break_rational, 0); | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /** @pred  rational_term_to_tree(? _TI_,- _TF_, ?SubTerms, ?MoreSubterms) 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The term _TF_ is a forest representation (without cycles and repeated | 
					
						
							|  |  |  | terms) for the Prolog term _TI_. The term _TF_ is the main term.  The | 
					
						
							|  |  |  | difference list _SubTerms_-_MoreSubterms_ stores terms of the form | 
					
						
							|  |  |  | _V=T_, where _V_ is a new variable occuring in _TF_, and _T_ is a copy | 
					
						
							|  |  |  | of a sub-term from _TI_. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2014-02-02 21:45:47 +00:00
										 |  |  |   Yap_InitCPred("term_factorized", 3, p_break_rational3, 0); | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /** @pred  term_factorized(? _TI_,- _TF_, ?SubTerms) 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Similar to rational_term_to_tree/4, but _SubTerms_ is a proper list. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2009-11-23 10:10:14 +00:00
										 |  |  |   Yap_InitCPred("=@=", 2, p_variant, 0); | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   Yap_InitCPred("numbervars", 3, p_numbervars, 0); | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /** @pred  numbervars( _T_,+ _N1_,- _Nn_) 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Instantiates each variable in term  _T_ to a term of the form: | 
					
						
							|  |  |  | `$VAR( _I_)`, with  _I_ increasing from  _N1_ to  _Nn_. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2011-11-03 07:44:08 +09:00
										 |  |  |   Yap_InitCPred("unnumbervars", 2, p_unnumbervars, 0); | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /** @pred  unnumbervars( _T_,+ _NT_) 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Replace every `$VAR( _I_)` by a free variable. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2012-01-09 23:28:31 +00:00
										 |  |  |   /* use this carefully */ | 
					
						
							|  |  |  |   Yap_InitCPred("$skip_list", 3, p_skip_list, SafePredFlag|TestPredFlag); | 
					
						
							| 
									
										
										
										
											2012-09-27 22:32:50 +01:00
										 |  |  |   Yap_InitCPred("$skip_list", 4, p_skip_list4, SafePredFlag|TestPredFlag); | 
					
						
							| 
									
										
										
										
											2013-06-07 09:26:21 -05:00
										 |  |  |   Yap_InitCPred("$free_arguments", 1, p_free_arguments, TestPredFlag); | 
					
						
							| 
									
										
										
										
											2008-08-12 01:27:23 +00:00
										 |  |  |   CurrentModule = TERMS_MODULE; | 
					
						
							| 
									
										
										
										
											2011-07-06 17:26:53 -04:00
										 |  |  |   Yap_InitCPred("variable_in_term", 2, p_var_in_term, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("term_hash", 4, p_term_hash, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("instantiated_term_hash", 4, p_instantiated_term_hash, 0); | 
					
						
							| 
									
										
										
										
											2004-10-06 16:55:48 +00:00
										 |  |  |   Yap_InitCPred("variant", 2, p_variant, 0); | 
					
						
							| 
									
										
										
										
											2010-07-21 00:09:24 +01:00
										 |  |  |   Yap_InitCPred("subsumes", 2, p_subsumes, 0); | 
					
						
							| 
									
										
										
										
											2012-05-14 15:04:19 +01:00
										 |  |  |   Yap_InitCPred("term_subsumer", 3, p_term_subsumer, 0); | 
					
						
							| 
									
										
										
										
											2010-07-21 00:09:24 +01:00
										 |  |  |   Yap_InitCPred("variables_within_term", 3, p_variables_within_term, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("new_variables_in_term", 3, p_new_variables_in_term, 0); | 
					
						
							| 
									
										
										
										
											2012-02-05 11:20:30 +00:00
										 |  |  |   Yap_InitCPred("export_term", 3, p_export_term, 0); | 
					
						
							| 
									
										
										
										
											2012-02-05 11:57:03 +00:00
										 |  |  |   Yap_InitCPred("kill_exported_term", 1, p_kill_exported_term, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("import_term", 2, p_import_term, 0); | 
					
						
							| 
									
										
										
										
											2013-09-28 12:04:52 +01:00
										 |  |  |   Yap_InitCPred("freshen_variables", 1, p_freshen_variables, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("reset_variables", 1, p_reset_variables, 0); | 
					
						
							| 
									
										
										
										
											2004-05-13 20:54:58 +00:00
										 |  |  |   CurrentModule = cm; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2012-10-19 18:10:48 +01:00
										 |  |  |   Yap_InitCPred("$force_trail_expansion", 1, p_force_trail_expansion, SafePredFlag); | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |   Yap_InitCPred("dum", 1, camacho_dum, SafePredFlag); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |