YAP 7.1.0
TermExt.h
Go to the documentation of this file.
1/*************************************************************************
2* *
3* YAP Prolog %W% %G% *
4* Yap Prolog was developed at NCCUP - Universidade do Porto *
5* *
6* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
7* *
8**************************************************************************
9* *
10* File: TermExt.h *
11* mods: *
12* comments: Extensions to standard terms for YAP *
13* version: $Id: TermExt.h,v 1.15 2008-03-25 22:03:13 vsc Exp $ *
14*************************************************************************/
15
22#ifndef TERMEXT_H_INCLUDED
23#define TERMEXT_H_INCLUDED
24
25#pragma once
26
27#ifdef USE_SYSTEM_MALLOC
28#define SF_STORE (&(Yap_heap_regs->funcs))
29#else
30#define SF_STORE ((special_functors *)HEAP_INIT_BASE)
31#endif
32
33
34#if 1
35extern Atom AtomFoundVar, AtomFreeTerm, AtomNil, AtomDot;
36#elif defined(USE_OFFSETS)
37#define AtomFoundVar ((Atom)(&(((special_functors *)(NULL))->AtFoundVar)))
38#define AtomFreeTerm ((Atom)(&(((special_functors *)(NULL))->AtFreeTerm)))
39#define AtomNil ((Atom)(&(((special_functors *)(NULL))->AtNil)))
40#define AtomDot ((Atom)(&(((special_functors *)(NULL))->AtDot)))
41#elif OLD_STYLE_INITIAL_ATOMS
42#define AtomFoundVar AbsAtom((AtomEntry *)&(SF_STORE->AtFoundVar))
43#define AtomFreeTerm AbsAtom((AtomEntry *)&(SF_STORE->AtFreeTerm))
44#define AtomNil AbsAtom((AtomEntry *)&(SF_STORE->AtNil))
45#define AtomDot AbsAtom((AtomEntry *)&(SF_STORE->AtDot))
46#else
47#define AtomFoundVar AbsAtom(SF_STORE->AtFoundVar)
48#define AtomFreeTerm AbsAtom(SF_STORE->AtFreeTerm)
49#define AtomNil AbsAtom(SF_STORE->AtNil)
50#define AtomDot AbsAtom(SF_STORE->AtDot)
51#endif
52
53#define TermFoundVar MkAtomTerm(AtomFoundVar)
54#define TermFreeTerm MkAtomTerm(AtomFreeTerm)
55#define TermNil MkAtomTerm(AtomNil)
56#define TermDot MkAtomTerm(AtomDot)
57
58typedef enum {
59 db_ref_e = sizeof(Functor *),
60 blob_e = 2 * sizeof(Functor *),
61 double_e = 3 * sizeof(Functor *),
62 long_int_e = 4 * sizeof(Functor *),
63 big_int_e = 5 * sizeof(Functor *),
64 string_e = 6 * sizeof(Functor *)
65} blob_type;
66#define end_e (8 * sizeof(Functor *))
67
68#define FunctorDBRef ((Functor)(db_ref_e))
69#define FunctorDouble ((Functor)(double_e))
70#define FunctorLongInt ((Functor)(long_int_e))
71#define FunctorBigInt ((Functor)(big_int_e))
72#define FunctorString ((Functor)(string_e))
73#define FunctorBlob ((Functor)(blob_e))
74
75#include "inline-only.h"
76
77typedef enum {
78 BIG_INT = 0x01,
79 BIG_RATIONAL = 0x02,
80 BIG_FLOAT = 0x04,
81 EMPTY_ARENA = 0x10,
82 ARRAY_INT = 0x21,
83 ARRAY_FLOAT = 0x22,
84 CLAUSE_LIST = 0x40,
85 EXTERNAL_BLOB = 0x0A0, /* generic data */
86 GOAL_CUT_POINT = 0x0A1,
87 USER_BLOB_START = 0x0100, /* user defined blob */
88 USER_BLOB_END = 0x0200 /* end of user defined blob */
89} big_blob_type;
90
91INLINE_ONLY blob_type BlobOfFunctor(Functor f);
92
93INLINE_ONLY blob_type BlobOfFunctor(Functor f) {
94 return (blob_type)((CELL)f);
95}
96
97#ifdef COROUTINING
98
99typedef struct {
100 /* what to do when someone tries to bind our term to someone else
101 in some predefined context */
102 void (*bind_op)(Term *, Term CACHE_TYPE);
103 /* what to do if someone wants to copy our constraint */
104 int (*copy_term_op)(CELL *, void*, CELL *CACHE_TYPE);
105 /* copy the constraint into a term and back */
106 Term (*to_term_op)(CELL *);
107 int (*term_to_op)(Term, Term CACHE_TYPE);
108 /* op called to do marking in GC */
109 void (*mark_op)(CELL *);
110} ext_op;
111
112/* known delays */
113typedef enum {
114 empty_ext = 0 * sizeof(ext_op), /* default op, this should never be called */
115 attvars_ext = 1 * sizeof(ext_op) /* support for attributed variables */
116 /* add your own extensions here */
117 /* keep this one */
118} exts;
119
120#endif
121
122#define CloseExtension(x) MkAtomTerm((Atom)(x))
123
124#define GetStartOfExtension(x) ((CELL*)AtomOfTerm(*x))
125
126inline static bool IsEndExtension(CELL *x) {
127 CELL c = *x;
128 if (!IsAtomTerm(c)) return false;
129 Atom a = AtomOfTerm(c);
130 CELL *ca = (CELL*)a;
131 if (ca < H0 || ca >= HR)
132 return false;
133 // if (!IsExtensionFunctor((Functor)ca[0]))
134 // return false;
135 return true;
136}
137
138
139
140#if defined(YAP_H)
141/* make sure that these data structures are the first thing to be allocated
142 in the heap when we start the system */
143typedef struct special_functors_struct {
144
145#if 0
146 struct ExtraAtomEntryStruct AtFoundVar;
147 struct ExtraAtomEntryStruct AtFreeTerm;
148 struct ExtraAtomEntryStruct AtNil;
149 struct ExtraAtomEntryStruct AtDot;
150#else
151 struct AtomEntryStruct *AtFoundVar;
152 struct AtomEntryStruct *AtFreeTerm;
153 struct AtomEntryStruct *AtNil;
154 struct AtomEntryStruct *AtDot;
155#endif
156} special_functors;
157#endif /* YAP_H */
158
159
160extern size_t
161SizeOfOpaqueTerm(Term *next, CELL cnext);
162
163INLINE_ONLY Float CpFloatUnaligned(CELL *ptr);
164
165#define MkFloatTerm(fl) __MkFloatTerm((fl)PASS_REGS)
166
167INLINE_ONLY Term __MkFloatTerm(Float USES_REGS);
168
169INLINE_ONLY Float FloatOfTerm(Term t);
170
171#if SIZEOF_DOUBLE == SIZEOF_INT_P
172
173INLINE_ONLY Term __MkFloatTerm(Float dbl USES_REGS) {
174 return (Term)((HR[0] = (CELL)FunctorDouble, *(Float *)(HR + 1) = dbl,
175 HR[2] = CloseExtension(HR), HR += 3, AbsAppl(HR - 3)));
176}
177
178INLINE_ONLY Float FloatOfTerm(Term t) {
179 return (Float)(*(Float *)(RepAppl(t) + 1));
180}
181
182#define InitUnalignedFloat()
183
184INLINE_ONLY Float CpFloatUnaligned(CELL *ptr) {
185 return *((Float *)ptr);
186}
187
188#else
189
190#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
191
192#define DOUBLE_ALIGNED(ADDR) ((CELL)(ADDR)&0x4)
193
194INLINE_ONLY inline void AlignGlobalForDouble(USES_REGS1);
195
196INLINE_ONLY inline void AlignGlobalForDouble(USES_REGS1) {
197 /* Force Alignment for floats. Note that garbage collector may
198 break the alignment; */
199 if (!DOUBLE_ALIGNED(HR)) {
200 RESET_VARIABLE(HR);
201 HR++;
202 }
203}
204
205#ifdef i386
206INLINE_ONLY Float CpFloatUnaligned(CELL *ptr) {
207 return *((Float *)(ptr + 1));
208}
209
210#else
211/* first, need to address the alignment problem */
212INLINE_ONLY Float CpFloatUnaligned(CELL *ptr) {
213 union {
214 Float f;
215 CELL d[2];
216 } u;
217 u.d[0] = ptr[1];
218 u.d[1] = ptr[2];
219 return (u.f);
220}
221
222#endif
223
224INLINE_ONLY Term __MkFloatTerm(Float dbl USES_REGS) {
225 return (Term)((AlignGlobalForDouble(PASS_REGS1), HR[0] = (CELL)FunctorDouble,
226 *(Float *)(HR + 1) = dbl, HR[3] = CloseExtension(HR), HR += 4,
227 AbsAppl(HR - 4)));
228}
229
230INLINE_ONLY Float FloatOfTerm(Term t) {
231 return (Float)((DOUBLE_ALIGNED(RepAppl(t)) ? *(Float *)(RepAppl(t) + 1)
232 : CpFloatUnaligned(RepAppl(t))));
233}
234
235/* no alignment problems for 64 bit machines */
236#else
237/* OOPS, YAP only understands Floats that are as large as cells or that
238 take two cells!!! */
239
240OOPS
241
242#endif
243#endif
244
245#ifndef YAP_H
246#include <stddef.h>
247#endif
248
249INLINE_ONLY bool IsFloatTerm(Term);
250
251INLINE_ONLY bool IsFloatTerm(Term t) {
252 return (int)(IsApplTerm(t) && FunctorOfTerm(t) == FunctorDouble);
253}
254
255/* extern Functor FunctorLongInt; */
256
257#define MkLongIntTerm(i) __MkLongIntTerm((i)PASS_REGS)
258
259INLINE_ONLY Term __MkLongIntTerm(Int USES_REGS);
260
261INLINE_ONLY Term __MkLongIntTerm(Int i USES_REGS) {
262 HR[0] = (CELL)FunctorLongInt;
263 HR[1] = (CELL)(i);
264 HR[2] = CloseExtension(HR);
265 HR += 3;
266 return AbsAppl(HR - 3);
267}
268
269INLINE_ONLY Int LongIntOfTerm(Term t);
270
271INLINE_ONLY Int LongIntOfTerm(Term t) {
272 return (Int)(RepAppl(t)[1]);
273}
274
275INLINE_ONLY bool IsLongIntTerm(Term);
276
277INLINE_ONLY bool IsLongIntTerm(Term t) {
278 return IsApplTerm(t) &&
279 FunctorOfTerm(t) == FunctorLongInt;
280}
281
282/****************************************************/
283
284/*********** strings, coded as UTF-8 ****************/
285
286#include <string.h>
287
288/* extern Functor FunctorString; */
289
290#define MkStringTerm(i) __MkStringTerm((i)PASS_REGS)
291// < functor, request (size in cells ), cells, eot >
292INLINE_ONLY Term
293__MkStringTerm(const char *s USES_REGS);
294
295INLINE_ONLY Term __MkStringTerm(const char *s USES_REGS) {
296 Term t = AbsAppl(HR);
297 size_t sz = s[0] == '\0' ? 1 : strlen((const char *) s) + 1;
298 size_t request = (sz + CELLSIZE - 1) / CELLSIZE; // request is in cells >= 1
299 HR[0] = (CELL) FunctorString;
300 HR[1] = request;
301 HR[1 + request] = 0;
302 memcpy((HR + 2), s, sz);
303 HR[2 + request] = CloseExtension(HR);
304 HR += 3 + request;
305 return t;
306}
307
308#define MkUStringTerm(i) __MkStringTerm((const char *)(i)PASS_REGS)
309
310
311INLINE_ONLY const unsigned char *UStringOfTerm(Term t);
312
313INLINE_ONLY const unsigned char *UStringOfTerm(Term t) {
314 return (const unsigned char *)(RepAppl(t) + 2);
315}
316
317INLINE_ONLY const char *StringOfTerm(Term t);
318
319INLINE_ONLY const char *StringOfTerm(Term t) {
320 return (const char *)(RepAppl(t) + 2);
321}
322
323INLINE_ONLY bool IsStringTerm(Term);
324
325INLINE_ONLY bool IsStringTerm(Term t) {
326 return IsApplTerm(t) &&
327 FunctorOfTerm(t) == FunctorString;
328}
329
330
331/****************************************************/
332
333#ifdef USE_GMP
334
335#include <stdio.h>
336
337#if !defined(__cplusplus)
338#include <gmp.h>
339#endif
340
341#else
342
343typedef UInt mp_limb_t;
344
345typedef struct {
346 Int _mp_size, _mp_alloc;
347 mp_limb_t *_mp_d;
348} MP_INT;
349
350typedef struct {
351 MP_INT _mp_num;
352 MP_INT _mp_den;
353} MP_RAT;
354
355#endif
356
357INLINE_ONLY bool IsBigIntTerm(Term t) {
358 return IsApplTerm(t) &&
359 FunctorOfTerm(t) == FunctorBigInt;
360}
361
362INLINE_ONLY bool IsBlobTerm(Term t) {
363 return IsApplTerm(t) &&
364 FunctorOfTerm(t) == FunctorBlob;
365}
366
367#ifdef USE_GMP
368
369Term Yap_MkBigIntTerm(MP_INT *);
370MP_INT *Yap_BigIntOfTerm(Term);
371
372Term Yap_MkBigRatTerm(MP_RAT *);
373MP_RAT *Yap_BigRatOfTerm(Term);
374
375INLINE_ONLY void MPZ_SET(mpz_t, MP_INT *);
376
377INLINE_ONLY void MPZ_SET(mpz_t dest, MP_INT *src) {
378 dest->_mp_size = src->_mp_size;
379 dest->_mp_alloc = src->_mp_alloc;
380 dest->_mp_d = src->_mp_d;
381}
382
383INLINE_ONLY bool IsLargeIntTerm(Term);
384
385INLINE_ONLY bool IsLargeIntTerm(Term t) {
386 return IsApplTerm(t) &&
387 ((FunctorOfTerm(t) <= FunctorBigInt) &&
388 (FunctorOfTerm(t) >= FunctorLongInt));
389}
390
391INLINE_ONLY UInt Yap_SizeOfExtensiont(Term);
392
399INLINE_ONLY UInt Yap_SizeOfBigInt(Term t) {
400
401 CELL *pt = RepAppl(t) + 1;
402 if (pt[0 ] == BIG_RATIONAL) {
403 return 2 +
404 (sizeof(MP_INT) + (((MP_INT *)(pt+1))->_mp_alloc * sizeof(mp_limb_t))) /
405 sizeof(CELL)+
406 (sizeof(MP_INT) + ((((MP_INT *)(pt+1))+1)->_mp_alloc * sizeof(mp_limb_t))) /
407 sizeof(CELL);
408
409 }
410 return 2 +
411 (sizeof(MP_INT) + (((MP_INT *)(pt+1))->_mp_alloc * sizeof(mp_limb_t))) /
412 sizeof(CELL);
413}
414
415#else
416
417INLINE_ONLY int IsLargeIntTerm(Term);
418
419INLINE_ONLY int IsLargeIntTerm(Term t) {
420 return (int)(IsApplTerm(t) && FunctorOfTerm(t) == FunctorLongInt);
421}
422
423#endif
424
425/* extern Functor FunctorLongInt; */
426
427INLINE_ONLY bool IsLargeNumTerm(Term);
428
429INLINE_ONLY bool IsLargeNumTerm(Term t) {
430 return IsApplTerm(t) &&
431 ((FunctorOfTerm(t) <= FunctorBigInt) &&
432 (FunctorOfTerm(t) >= FunctorDouble));
433}
434
435INLINE_ONLY bool IsExternalBlobTerm(Term, CELL);
436
437INLINE_ONLY bool IsExternalBlobTerm(Term t, CELL tag) {
438 return IsApplTerm(t) &&
439 FunctorOfTerm(t) == FunctorBlob &&
440 RepAppl(t)[1] == tag;
441}
442
443INLINE_ONLY void *ExternalBlobFromTerm(Term);
444
445INLINE_ONLY void *ExternalBlobFromTerm(Term t) {
446 return RepAppl(t)+3;
447}
448
449INLINE_ONLY bool IsNumTerm(Term);
450
451INLINE_ONLY bool IsNumTerm(Term t) {
452 return (IsIntTerm(t) || IsLargeNumTerm(t));
453}
454
455INLINE_ONLY bool IsAtomicTerm(Term);
456
457INLINE_ONLY bool IsAtomicTerm(Term t) {
458 return IsAtomOrIntTerm(t) ||
459 IsLargeNumTerm(t) ||
460 IsStringTerm(t);
461}
462
463INLINE_ONLY bool IsExtensionFunctor(Functor);
464
465INLINE_ONLY bool IsExtensionFunctor(Functor f) {
466 return f <= (Functor)end_e;
467}
468
469INLINE_ONLY bool IsBlobFunctor(Functor);
470
471INLINE_ONLY bool IsBlobFunctor(Functor f) {
472 return (f <= FunctorString &&
473 f >= FunctorDBRef);
474}
475
476INLINE_ONLY bool IsPrimitiveTerm(Term);
477
478INLINE_ONLY bool IsPrimitiveTerm(Term t) {
479 return (IsAtomOrIntTerm(t) ||
480 (IsApplTerm(t) &&
481 IsBlobFunctor(FunctorOfTerm(t))));
482}
483
484INLINE_ONLY exts ExtFromCell(CELL *);
485
486INLINE_ONLY exts ExtFromCell(CELL *pt) { return attvars_ext; }
487
488INLINE_ONLY Int Yap_BlobTag(Term t);
489
490INLINE_ONLY Int Yap_BlobTag(Term t) {
491 CELL *pt = RepAppl(t);
492
493 return pt[1];
494}
495
496INLINE_ONLY void *Yap_BlobInfo(Term t);
497
498INLINE_ONLY void *Yap_BlobInfo(Term t) {
499 CELL *pt = RepAppl(t);
500
501 return pt+3;
502}
503
504#ifdef YAP_H
505
506INLINE_ONLY bool unify_extension(Functor, CELL, CELL *, CELL);
507
508EXTERN bool unify_extension(Functor, CELL, CELL *, CELL);
509
510int Yap_gmp_tcmp_big_big(Term, Term);
511
512INLINE_ONLY bool unify_extension(Functor f, CELL d0, CELL *pt0, CELL d1)
513{
514 switch (BlobOfFunctor(f)) {
515 case db_ref_e:
516 return (d0 == d1);
517 case long_int_e:
518 return (pt0[1] == RepAppl(d1)[1]);
519 case blob_e:
520 return (pt0[2] == RepAppl(d1)[2] && !memcmp(pt0+3, RepAppl(d1)+3, pt0[2]*sizeof(CELL) ) );
521 case string_e:
522 return strcmp((char *)(pt0 + 2), (char *)(RepAppl(d1) + 2)) == 0;
523 case big_int_e:
524#ifdef USE_GMP
525 return (Yap_gmp_tcmp_big_big(d0, d1) == 0);
526#else
527 return d0 == d1;
528#endif /* USE_GMP */
529 case double_e: {
530 CELL *pt1 = RepAppl(d1);
531 return (pt0[1] == pt1[1]
532#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
533 && pt0[2] == pt1[2]
534#endif
535 );
536 }
537 }
538 return false;
539}
540
541static inline CELL Yap_IntP_key(CELL *pt) {
542#ifdef USE_GMP
543 if (((Functor)pt[-1] == FunctorBigInt)) {
544 MP_INT *b1 = Yap_BigIntOfTerm(AbsAppl(pt - 1));
545 /* first cell in program */
546 CELL val = ((CELL *)(b1 + 1))[0];
547 return MkIntTerm(val & (MAX_ABS_INT - 1));
548 }
549#endif
550 return MkIntTerm(pt[0] & (MAX_ABS_INT - 1));
551}
552
553static inline CELL Yap_Int_key(Term t) { return Yap_IntP_key(RepAppl(t) + 1); }
554
555static inline CELL Yap_DoubleP_key(CELL *pt) {
556#if SIZEOF_DOUBLE1 == 2 * SIZEOF_INT_P
557 CELL val = pt[0] ^ pt[1];
558#else
559 CELL val = pt[0];
560#endif
561 return MkIntTerm(val & (MAX_ABS_INT - 1));
562}
563
564static inline CELL Yap_Double_key(Term t) {
565 return Yap_DoubleP_key(RepAppl(t) + 1);
566}
567
568static inline CELL Yap_StringP_key(CELL *pt) {
569 UInt n = pt[1], i;
570 CELL val = pt[2];
571 for (i = 1; i < n; i++) {
572 val ^= pt[i + 1];
573 }
574 return MkIntTerm(val & (MAX_ABS_INT - 1));
575}
576
577static inline CELL Yap_String_key(Term t) {
578 return Yap_StringP_key(RepAppl(t) + 1);
579}
580
581#endif
582
583
584#endif // TERMEXT_H_INCLUDED
Definition: TermExt.h:99