18static char SccsId[] =
"%W% %G%";
37SizeOfOpaqueTerm(Term *next, CELL cnext)
42 case (CELL)FunctorLongInt:
46 case (CELL)FunctorDouble:
48 sz =2+ SIZEOF_DOUBLE / SIZEOF_INT_P;
51 case (CELL)FunctorString:
56 case (CELL)FunctorBigInt:
60 ((
MP_INT *)(next + 2))->_mp_alloc *
sizeof(mp_limb_t)) /
64 case (CELL)FunctorBlob:
80Term Yap_MkBigIntTerm(
MP_INT *big) {
87 if (mpz_fits_slong_p(big)) {
88 long int out = mpz_get_si(big);
89 return MkIntegerTerm((Int)out);
94 nlimbs = big->_mp_alloc;
95 bytes = nlimbs *
sizeof(mp_limb_t);
96 if (nlimbs > (ASP - ret) - 1024) {
99 HR[0] = (CELL)FunctorBigInt;
102 dst->_mp_size = big->_mp_size;
103 dst->_mp_alloc = nlimbs * (CellSize /
sizeof(mp_limb_t));
104 memmove((
void *)(dst + 1), (
const void *)(big->_mp_d), bytes);
105 HR = (CELL *)(dst + 1) + bytes/CellSize;
106 HR[0] = CloseExtension(ret);
111MP_INT *Yap_BigIntOfTerm(Term t) {
114 new->_mp_d = (mp_limb_t *)(
new + 1);
118Term Yap_MkBigRatTerm(
MP_RAT *big) {
122 MP_INT *num = mpq_numref(big);
123 MP_INT *den = mpq_denref(big);
127 if (mpz_cmp_si(den, 1) == 0)
128 return Yap_MkBigIntTerm(num);
129 if ((num->_mp_alloc + den->_mp_alloc) * (
sizeof(mp_limb_t) / CellSize) >
130 (ASP - ret) - 1024) {
133 HR[0] = (CELL)FunctorBigInt;
134 HR[1] = BIG_RATIONAL;
136 rat = (
MP_RAT *)(dst + 1);
137 rat->_mp_num._mp_size = num->_mp_size;
138 rat->_mp_num._mp_alloc = num->_mp_alloc;
139 nlimbs = (num->_mp_alloc) * (
sizeof(mp_limb_t) / CellSize);
140 memmove((
void *)(rat + 1), (
const void *)(num->_mp_d), nlimbs * CellSize);
141 rat->_mp_den._mp_size = den->_mp_size;
142 rat->_mp_den._mp_alloc = den->_mp_alloc;
143 HR = (CELL *)(rat + 1) + nlimbs;
144 nlimbs = (den->_mp_alloc) * (
sizeof(mp_limb_t) / CellSize);
145 memmove((
void *)(HR), (
const void *)(den->_mp_d), nlimbs * CellSize);
147 dst->_mp_alloc = (HR - (CELL *)(dst + 1));
148 HR[0] = CloseExtension(ret);
153MP_RAT *Yap_BigRatOfTerm(Term t) {
157 nt =
new->_mp_num._mp_d = (mp_limb_t *)(
new + 1);
158 nt +=
new->_mp_num._mp_alloc;
159 new->_mp_den._mp_d = nt;
163Term Yap_RatTermToApplTerm(Term t) {
165 MP_RAT *rat = Yap_BigRatOfTerm(t);
167 ts[0] = Yap_MkBigIntTerm(mpq_numref(rat));
168 ts[1] = Yap_MkBigIntTerm(mpq_denref(rat));
169 return Yap_MkApplTerm(FunctorRDiv, 2, ts);
174Term Yap_AllocExternalDataInStack(CELL tag,
size_t bytes, CELL* *pt) {
177 CELL *ret = HR, *tmp = HR;
181 ncells = (bytes+(CellSize-1)) / CellSize;
182 if (ncells > (ASP - ret) - 1024) {
186 ret[0] = (CELL)FunctorBlob;
192 HR[0] = CloseExtension((ret));
198int Yap_CleanOpaqueVariable(CELL d) {
199 CELL *pt = RepAppl(HeadOfTerm(d));
200 CELL blob_tag = pt[1];
205 if (pt[0] != (CELL)FunctorBlob) {
206 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"CleanOpaqueVariable bad call");
210 if (blob_tag < USER_BLOB_START || blob_tag >= USER_BLOB_END) {
211 Yap_Error(SYSTEM_ERROR_INTERNAL, AbsAppl(pt),
212 "clean opaque: bad blob with tag " UInt_FORMAT, blob_tag);
215Int blob_info = blob_tag;
216 if (!GLOBAL_OpaqueHandlers)
218 if (!GLOBAL_OpaqueHandlers[blob_info].fail_handler)
220 return (GLOBAL_OpaqueHandlers[blob_info].fail_handler)(d);
223YAP_Opaque_CallOnWrite Yap_blob_write_handler(Term t) {
224 CELL blob_info, blob_tag;
225 CELL *pt = RepAppl(t);
229 if (pt[0] != (CELL)FunctorBlob) {
230 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"CleanOpaqueVariable bad call");
235 if (blob_tag < USER_BLOB_START || blob_tag >= USER_BLOB_END) {
236 Yap_Error(SYSTEM_ERROR_INTERNAL, AbsAppl(pt),
237 "clean opaque: bad blob with tag " UInt_FORMAT, blob_tag);
240 blob_info = blob_tag;
241 if (!GLOBAL_OpaqueHandlers) {
244 return GLOBAL_OpaqueHandlers[blob_info].write_handler;
247YAP_Opaque_CallOnGCMark Yap_blob_gc_mark_handler(Term t) {
248 CELL blob_info, blob_tag;
249 CELL *pt = RepAppl(t);
253 if (pt[0] != (CELL)FunctorBigInt) {
254 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"CleanOpaqueVariable bad call");
259 if (blob_tag < USER_BLOB_START || blob_tag >= USER_BLOB_END) {
262 blob_info = blob_tag;
263 if (!GLOBAL_OpaqueHandlers)
265 return GLOBAL_OpaqueHandlers[blob_info].mark_handler;
268YAP_Opaque_CallOnGCRelocate Yap_blob_gc_relocate_handler(Term t) {
269 CELL blob_info, blob_tag;
270 CELL *pt = RepAppl(t);
274 if (pt[0] != (CELL)FunctorBlob) {
275 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"CleanOpaqueVariable bad call");
280 if (blob_tag < USER_BLOB_START || blob_tag >= USER_BLOB_END) {
281 Yap_Error(SYSTEM_ERROR_INTERNAL, AbsAppl(pt),
282 "clean opaque: bad blob with tag " UInt_FORMAT, blob_tag);
285 blob_info = blob_tag;
286 if (!GLOBAL_OpaqueHandlers)
288 return GLOBAL_OpaqueHandlers[blob_info].relocate_handler;
291extern Int Yap_blob_tag(Term t) {
292 CELL *pt = RepAppl(t);
296 if (pt[0] != (CELL)FunctorBlob) {
297 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"CleanOpaqueVariable bad call");
304void *Yap_blob_info(Term t) {
306 CELL *pt = RepAppl(t);
310 if (pt[0] != (CELL)FunctorBlob) {
311 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"CleanOpaqueVariable bad call");
315 if (!GLOBAL_OpaqueHandlers)
317 blobp = (
MP_INT *)(pt + 2);
318 return (
void *)(blobp + 1);
321Term Yap_MkULLIntTerm(YAP_ULONG_LONG n) {
328 snprintf(tmp, 256,
"%I64u", n);
330 snprintf(tmp, 256,
"%llu", n);
332 sprintf(tmp,
"%llu", n);
335 mpz_init_set_str(
new, tmp, 10);
336 if (mpz_fits_slong_p(
new)) {
338 return MkIntegerTerm(mpz_get_si(
new));
340 t = Yap_MkBigIntTerm(
new);
345 return MkIntegerTerm(n);
349CELL *Yap_HeapStoreOpaqueTerm(Term t) {
350 CELL *ptr = RepAppl(t);
354 sz = SizeOfOpaqueTerm(ptr,ptr[0]);
355 new = Yap_AllocCodeSpace(sz);
357 Yap_Error(RESOURCE_ERROR_HEAP, TermNil,
358 "subgoal_search_loop: no space for %s", StringOfTerm(t));
360 if (ptr[0] == (CELL)FunctorBlob) {
362 memmove(
new, ptr, sz);
368size_t Yap_OpaqueTermToString(Term t,
char *str,
size_t max) {
369 size_t str_index = 0;
370 CELL *li = RepAppl(t);
371 unsigned char *ptr = (
unsigned char *)StringOfTerm(AbsAppl(li));
372 if (li[0] == (CELL)FunctorString) {
373 str_index += sprintf(&str[str_index],
"\"");
375 utf8proc_int32_t chr;
376 ptr += get_utf8(ptr, -1, &chr);
379 str_index += sprintf(str + str_index,
"%C", chr);
381 str_index += sprintf(str + str_index,
"\"");
383 CELL big_tag = li[1];
385 if (big_tag == ARRAY_INT || big_tag == ARRAY_FLOAT) {
386 str_index += sprintf(&str[str_index],
"{...}");
388 }
else if (big_tag == BIG_INT) {
389 MP_INT *big = Yap_BigIntOfTerm(AbsAppl(li));
390 char *s = mpz_get_str(&str[str_index], 10, big);
391 str_index += strlen(&s[str_index]);
392 }
else if (big_tag == BIG_RATIONAL) {
393 MP_RAT *big = Yap_BigRatOfTerm(AbsAppl(li));
394 char *s = mpq_get_str(&str[str_index], 10, big);
395 str_index += strlen(&s[str_index]);
410 str_index += sprintf(&str[str_index],
"0");
415static Int p_is_bignum(USES_REGS1) {
417 Term t = Deref(ARG1);
418 return (IsNonVarTerm(t) && IsApplTerm(t) &&
419 FunctorOfTerm(t) == FunctorBigInt && RepAppl(t)[1] == BIG_INT);
425static Int p_is_string(USES_REGS1) {
426 Term t = Deref(ARG1);
427 return (IsNonVarTerm(t) && IsApplTerm(t) &&
428 FunctorOfTerm(t) == FunctorString);
431static Int p_nb_set_bit(USES_REGS1) {
433 Term t = Deref(ARG1);
434 Term ti = Deref(ARG2);
437 if (!(IsNonVarTerm(t) && IsApplTerm(t) && FunctorOfTerm(t) == FunctorBigInt &&
438 RepAppl(t)[1] == BIG_INT))
440 if (!IsIntegerTerm(ti)) {
443 if (!IsIntegerTerm(ti)) {
446 i = IntegerOfTerm(ti);
450 Yap_gmp_set_bit(i, t);
457static Int p_has_bignums(USES_REGS1) {
465static Int p_is_opaque(USES_REGS1) {
466 Term t = Deref(ARG1);
473 if (f != FunctorBigInt && f!= FunctorBlob)
476 return (pt[1] != BIG_RATIONAL && pt[1] != BIG_INT);
481static Int p_is_rational(USES_REGS1) {
482 Term t = Deref(ARG1);
491 if (f == FunctorLongInt)
493 if (f != FunctorBigInt)
496 return (pt[1] == BIG_RATIONAL || pt[1] == BIG_INT);
501static Int p_rational(USES_REGS1) {
503 Term t = Deref(ARG1);
513 f = FunctorOfTerm(t);
514 if (f != FunctorBigInt)
517 if (pt[1] != BIG_RATIONAL)
519 rat = Yap_BigRatOfTerm(t);
520 while ((t1 = Yap_MkBigIntTerm(mpq_numref(rat))) == TermNil ||
521 (t2 = Yap_MkBigIntTerm(mpq_denref(rat))) == TermNil) {
522 UInt size = (mpq_numref(rat)->_mp_alloc) * (
sizeof(mp_limb_t) / CellSize) +
523 (mpq_denref(rat)->_mp_alloc) * (
sizeof(mp_limb_t) / CellSize);
524 if (!Yap_dogcl(size PASS_REGS)) {
525 Yap_Error(RESOURCE_ERROR_STACK, t, LOCAL_ErrorMessage);
529 return Yap_unify(ARG2, t1) && Yap_unify(ARG3, t2);
535void Yap_InitBigNums(
void) {
536 Yap_InitCPred(
"$has_bignums", 0, p_has_bignums, SafePredFlag);
537 Yap_InitCPred(
"$bignum", 1, p_is_bignum, SafePredFlag);
538 Yap_InitCPred(
"rational", 3, p_rational, 0);
539 Yap_InitCPred(
"rational", 1, p_is_rational, SafePredFlag);
547 Yap_InitCPred(
"string", 1, p_is_string, SafePredFlag);
548 Yap_InitCPred(
"opaque", 1, p_is_opaque, SafePredFlag);
549 Yap_InitCPred(
"nb_set_bit", 2, p_nb_set_bit, SafePredFlag);