107#include "YapArenas.h"
124#define QUEUE_FUNCTOR_ARITY 4
131#define HEAP_FUNCTOR_MIN_ARITY
145 READ_LOCK(ae->ARWLock);
149 if (pe->KindOfPE == GlobalProperty
151 && pe->owner_id == worker_id
154 READ_UNLOCK(ae->ARWLock);
159 READ_UNLOCK(ae->ARWLock);
165static Int nb_create_accumulator(USES_REGS1) {
166 Term t = Deref(ARG1), acct, to, t2;
170 Yap_ThrowError(INSTANTIATION_ERROR, t,
"nb_create_accumulator");
173 if (!IsIntegerTerm(t) && !IsBigIntTerm(t) && !IsFloatTerm(t)) {
174 Yap_ThrowError(TYPE_ERROR_NUMBER, t,
"nb_create_accumulator");
177 acct = Yap_MkApplTerm(FunctorGNumber, 1, &t);
178 if (!Yap_unify(ARG2, acct)) {
182 to = CopyTermToArena(t, TRUE, TRUE, NULL, &LOCAL_GlobalArena, NULL PASS_REGS);
187 return Yap_unify(t2, Yap_MkApplTerm(FunctorGNumber, 1, &to));
189 destp = RepAppl(Deref(ARG2));
194static Int nb_add_to_accumulator(USES_REGS1) {
195 Term t = Deref(ARG1), t0, tadd;
200 Yap_ThrowError(INSTANTIATION_ERROR, t,
"nb_crate_accumulator");
203 if (!IsApplTerm(t)) {
204 Yap_ThrowError(TYPE_ERROR_NUMBER, t,
"nb_accumulator_value");
207 f = FunctorOfTerm(t);
208 if (f != FunctorGNumber) {
212 t0 = Deref(destp[1]);
214 if (IsVarTerm(tadd)) {
215 Yap_ThrowError(INSTANTIATION_ERROR, tadd,
"nb_create_accumulator");
218 if (IsIntegerTerm(t0) && IsIntegerTerm(tadd)) {
219 Int i0 = IntegerOfTerm(t0);
220 Int i1 = IntegerOfTerm(tadd);
221 Term
new = MkIntegerTerm(i0 + i1);
223 if (IsIntTerm(
new)) {
228 if (IsLongIntTerm(t0)) {
229 CELL *target = RepAppl(t0);
230 CELL *
source = RepAppl(
new);
235 new = CopyTermToArena(
new, TRUE, TRUE, NULL, &LOCAL_GlobalArena, NULL PASS_REGS);
236 destp = RepAppl(Deref(ARG1));
242 if (IsFloatTerm(t0) && IsFloatTerm(tadd)) {
243 Float f0 = FloatOfTerm(t0);
244 Float f1 = FloatOfTerm(tadd);
245 Term
new = MkFloatTerm(f0 + f1);
246 CELL *target = RepAppl(t0);
247 CELL *
source = RepAppl(
new);
249#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
255 if (IsNumTerm(t0) && IsNumTerm(tadd)) {
259 new = Yap_MkApplTerm(FunctorPlus, 2, t2);
263 new = CopyTermToArena(
new, TRUE, TRUE, NULL, &(LOCAL_GlobalArena), NULL PASS_REGS);
264 destp = RepAppl(Deref(ARG1));
272static Int nb_accumulator_value(USES_REGS1) {
273 Term t = Deref(ARG1);
277 Yap_ThrowError(INSTANTIATION_ERROR, t,
"nb_accumulator_value");
280 if (!IsApplTerm(t)) {
281 Yap_ThrowError(TYPE_ERROR_NUMBER, t,
"nb_accumulator_value");
284 f = FunctorOfTerm(t);
285 if (f != FunctorGNumber) {
288 return Yap_unify(ArgOfTerm(1, t), ARG2);
291Term Yap_SetGlobalVal(
Atom at, Term t0) {
295 ge = GetGlobalEntry(at PASS_REGS);
297 to = CopyTermToArena(t0, FALSE, TRUE, NULL, &(LOCAL_GlobalArena), NULL PASS_REGS);
300 WRITE_LOCK(ge->GRWLock);
302 WRITE_UNLOCK(ge->GRWLock);
306Term Yap_CopyTermToArena(Term inp, Term *arenap) {
308 return CopyTermToArena(inp,
false,
true, NULL, arenap, NULL PASS_REGS);
311Term Yap_SaveTerm(Term t0) {
314 to = CopyTermToArena(Deref(t0),
false,
true, NULL, &LOCAL_GlobalArena, NULL PASS_REGS);
329static Int nb_setval(USES_REGS1) {
330 Term t = Deref(ARG1);
332 Yap_ThrowError(INSTANTIATION_ERROR, t,
"nb_setval");
334 }
else if (!IsAtomTerm(t)) {
335 Yap_ThrowError(TYPE_ERROR_ATOM, t,
"nb_setval");
338 return Yap_SetGlobalVal(AtomOfTerm(t), ARG2) != 0;
367static Int nb_set_shared_val(USES_REGS1) {
368 Term t = Deref(ARG1), to;
371 Yap_ThrowError(INSTANTIATION_ERROR, t,
"nb_setval");
373 }
else if (!IsAtomTerm(t)) {
374 Yap_ThrowError(TYPE_ERROR_ATOM, t,
"nb_setval");
377 ge = GetGlobalEntry(AtomOfTerm(t) PASS_REGS);
379 to = CopyTermToArena(ARG2, TRUE, TRUE, NULL, &LOCAL_GlobalArena, NULL PASS_REGS);
382 WRITE_LOCK(ge->GRWLock);
384 WRITE_UNLOCK(ge->GRWLock);
388static Int p_b_setval(USES_REGS1) {
389 Term t = Deref(ARG1);
393 Yap_ThrowError(INSTANTIATION_ERROR, t,
"b_setval");
395 }
else if (!IsAtomTerm(t)) {
396 Yap_ThrowError(TYPE_ERROR_ATOM, t,
"b_setval");
399 ge = GetGlobalEntry(AtomOfTerm(t) PASS_REGS);
400 WRITE_LOCK(ge->GRWLock);
401#ifdef MULTI_ASSIGNMENT_VARIABLES
406 Term t = Deref(ARG2);
407 if (IsVarTerm(t) && VarOfTerm(t) > HR && VarOfTerm(t) < LCL0) {
408 Term tn = MkVarTerm();
409 Bind_Local(VarOfTerm(t), tn);
412 MaBind(&ge->global, t);
414 WRITE_UNLOCK(ge->GRWLock);
417 WRITE_UNLOCK(ge->GRWLock);
418 Yap_ThrowError(SYSTEM_ERROR_INTERNAL, t,
"update_array");
423static int undefined_global(USES_REGS1) {
424 Term t3 = Deref(ARG3);
426 if (IsApplTerm(t3)) {
427 if (FunctorOfTerm(t3) == FunctorEq)
428 return Yap_unify(ArgOfTerm(1, t3), ArgOfTerm(2, t3));
431 return Yap_unify(t3, TermNil);
434static Int nb_getval(USES_REGS1) {
435 Term t = Deref(ARG1), to;
439 Yap_ThrowError(INSTANTIATION_ERROR, t,
"nb_getval");
441 }
else if (!IsAtomTerm(t)) {
442 Yap_ThrowError(TYPE_ERROR_ATOM, t,
"nb_getval");
445 ge = FindGlobalEntry(AtomOfTerm(t) PASS_REGS);
447 return undefined_global(PASS_REGS1);
448 READ_LOCK(ge->GRWLock);
451 Yap_ThrowError(INSTANTIATION_ERROR, ARG1,
"nb_getval");
452 READ_UNLOCK(ge->GRWLock);
453 if (to == TermFoundVar) {
456 return Yap_unify(ARG2, to);
459Term Yap_GetGlobal(
Atom at) {
464 ge = FindGlobalEntry(at PASS_REGS);
467 READ_LOCK(ge->GRWLock);
469 if (IsVarTerm(to) && IsUnboundVar(VarOfTerm(to))) {
470 Term t = MkVarTerm();
471 Bind_and_Trail(VarOfTerm(to), t);
474 READ_UNLOCK(ge->GRWLock);
475 if (to == TermFoundVar) {
498static Int nbdelete(
Atom at USES_REGS) {
503 ge = FindGlobalEntry(at PASS_REGS);
505 Yap_ThrowError(EXISTENCE_ERROR_VARIABLE, MkAtomTerm(at),
"nb_delete");
508 WRITE_LOCK(ge->GRWLock);
510 if (LOCAL_GlobalVariables == ge) {
511 LOCAL_GlobalVariables = ge->NextGE;
513 g = LOCAL_GlobalVariables;
514 while (g->NextGE != ge)
516 g->NextGE = ge->NextGE;
518 gp = AbsGlobalProp(ge);
519 WRITE_LOCK(ae->ARWLock);
520 if (ae->PropsOfAE == gp) {
521 ae->PropsOfAE = ge->NextOfPE;
524 while (g0->NextOfPE != gp)
526 g0->NextOfPE = ge->NextOfPE;
528 WRITE_UNLOCK(ae->ARWLock);
529 WRITE_UNLOCK(ge->GRWLock);
530 Yap_FreeCodeSpace((
char *) ge);
534Int Yap_DeleteGlobal(
Atom at) {
536 return nbdelete(at PASS_REGS);
539static Int nb_delete(USES_REGS1) {
540 Term t = Deref(ARG1);
543 Yap_ThrowError(INSTANTIATION_ERROR, t,
"nb_delete");
545 }
else if (!IsAtomTerm(t)) {
546 Yap_ThrowError(TYPE_ERROR_ATOM, t,
"nb_delete");
549 return nbdelete(AtomOfTerm(t) PASS_REGS);
552static Int nb_create(USES_REGS1) {
553 Term t = Deref(ARG1);
554 Term tname = Deref(ARG2);
555 Term tarity = Deref(ARG3);
560 Yap_ThrowError(INSTANTIATION_ERROR, t,
"nb_create");
562 }
else if (!IsAtomTerm(t)) {
563 Yap_ThrowError(TYPE_ERROR_ATOM, t,
"nb_create");
566 ge = GetGlobalEntry(AtomOfTerm(t) PASS_REGS);
568 Yap_ThrowError(EXISTENCE_ERROR_VARIABLE, t,
"nb_create");
571 if (IsVarTerm(tarity)) {
572 Yap_ThrowError(INSTANTIATION_ERROR, tarity,
"nb_create");
574 }
else if (!IsIntegerTerm(tarity)) {
575 Yap_ThrowError(TYPE_ERROR_INTEGER, tarity,
"nb_create");
578 if (IsVarTerm(tname)) {
579 Yap_ThrowError(INSTANTIATION_ERROR, tname,
"nb_create");
581 }
else if (!IsAtomTerm(tname)) {
582 Yap_ThrowError(TYPE_ERROR_ATOM, tname,
"nb_create");
585 to = CopyTermToArena(t,
false, TRUE, NULL, &LOCAL_GlobalArena, NULL PASS_REGS);
591 WRITE_LOCK(ge->GRWLock);
593 WRITE_UNLOCK(ge->GRWLock);
597static Int nb_create2(USES_REGS1) {
598 Term t = Deref(ARG1);
599 Term tname = Deref(ARG2);
600 Term tarity = Deref(ARG3);
601 Term tinit = Deref(ARG4);
606 Yap_ThrowError(INSTANTIATION_ERROR, t,
"nb_create");
608 }
else if (!IsAtomTerm(t)) {
609 Yap_ThrowError(TYPE_ERROR_ATOM, t,
"nb_create");
612 ge = GetGlobalEntry(AtomOfTerm(t) PASS_REGS);
614 Yap_ThrowError(EXISTENCE_ERROR_VARIABLE, t,
"nb_create");
617 if (IsVarTerm(tarity)) {
618 Yap_ThrowError(INSTANTIATION_ERROR, tarity,
"nb_create");
620 }
else if (!IsIntegerTerm(tarity)) {
621 Yap_ThrowError(TYPE_ERROR_INTEGER, tarity,
"nb_create");
624 if (IsVarTerm(tname)) {
625 Yap_ThrowError(INSTANTIATION_ERROR, tname,
"nb_create");
627 }
else if (!IsAtomTerm(tname)) {
628 Yap_ThrowError(TYPE_ERROR_ATOM, tname,
"nb_create");
631 if (IsVarTerm(tinit)) {
632 Yap_ThrowError(INSTANTIATION_ERROR, tname,
"nb_create");
634 }
else if (!IsAtomTerm(tinit)) {
635 Yap_ThrowError(TYPE_ERROR_ATOM, tname,
"nb_create");
638 to = CopyTermToArena(tinit,
false,
false, NULL, &LOCAL_GlobalArena, NULL PASS_REGS);
641 WRITE_LOCK(ge->GRWLock);
643 WRITE_UNLOCK(ge->GRWLock);
651static Int nb_queue_sized(
size_t arena_sz USES_REGS) {
653 Term t = Deref(ARG1);
656 if (!IsApplTerm(t)) {
659 return (FunctorOfTerm(t) == FunctorNBQueue);
661 if (arena_sz < 32 * MIN_ARENA_SIZE)
662 arena_sz = 32 * MIN_ARENA_SIZE;
665 HR += QUEUE_FUNCTOR_ARITY + 1;
669 ar[0] = (CELL) FunctorNBQueue;
671 RESET_VARIABLE(ar + QUEUE_TAIL);
672 ar[QUEUE_HEAD] = ar[QUEUE_TAIL];
673 ar[QUEUE_SIZE] = MkIntTerm(0);
674 ar[QUEUE_ARENA] = Yap_MkArena(HR, HR + arena_sz);
675 HR = ArenaLimit(ar[QUEUE_ARENA]);
676 return Yap_unify(queue, ARG1);
679static Int nb_queue(USES_REGS1) {
680 UInt arena_sz = (ASP - HR) / 16;
681 if (LOCAL_DepthArenas > 1)
682 arena_sz /= LOCAL_DepthArenas;
683 if (arena_sz < MIN_ARENA_SIZE)
684 arena_sz = MIN_ARENA_SIZE;
685 if (arena_sz > MAX_ARENA_SIZE)
686 arena_sz = MAX_ARENA_SIZE;
687 return nb_queue_sized(arena_sz PASS_REGS);
690static Int nb_queue2(USES_REGS1) {
691 Term t = Deref(ARG2);
693 Yap_ThrowError(INSTANTIATION_ERROR, t,
"nb_queue");
696 if (!IsIntegerTerm(t)) {
697 Yap_ThrowError(TYPE_ERROR_INTEGER, t,
"nb_queue");
700 return nb_queue_sized((UInt) IntegerOfTerm(t) PASS_REGS);
703static CELL *GetQueue(Term t,
char *caller) {
707 Yap_ThrowError(INSTANTIATION_ERROR, t, caller);
710 if (!IsApplTerm(t)) {
711 Yap_ThrowError(TYPE_ERROR_COMPOUND, t, caller);
714 if (FunctorOfTerm(t) != FunctorNBQueue) {
715 Yap_ThrowError(DOMAIN_ERROR_ARRAY_TYPE, t, caller);
718 return RepAppl(t) + 1;
721static Term GetQueueArena(CELL *qd,
char *caller) {
722 Term t = Deref(qd[QUEUE_ARENA]);
725 Yap_ThrowError(INSTANTIATION_ERROR, t, caller);
728 if (!IsApplTerm(t)) {
729 Yap_ThrowError(TYPE_ERROR_COMPOUND, t, caller);
732 if (FunctorOfTerm(t) != FunctorBlob) {
733 Yap_ThrowError(DOMAIN_ERROR_ARRAY_TYPE, t, caller);
739static void RecoverArena(Term arena USES_REGS) {
740 CELL *pt = ArenaPt(arena), *a_max = ArenaLimit(arena);
746 while (bb && bb->cp_h > HR) {
758static void RecoverQueue(Term *qp USES_REGS) {
759 Term arena = qp[QUEUE_ARENA];
760 RecoverArena(arena PASS_REGS);
761 qp[QUEUE_ARENA] = MkIntTerm(0);
764static Int nb_queue_close(USES_REGS1) {
765 Term t = Deref(ARG1);
771 qp = GetQueue(t,
"queue/3");
773 return Yap_unify(ARG3, ARG2);
775 if (qp[QUEUE_ARENA] != MkIntTerm(0))
776 RecoverQueue(qp PASS_REGS);
777 if (qp[QUEUE_SIZE] == MkIntTerm(0)) {
778 return Yap_unify(ARG3, ARG2);
780 out = Yap_unify(ARG3, qp[QUEUE_TAIL]) && Yap_unify(ARG2, qp[QUEUE_HEAD]);
781 RESET_VARIABLE(qp + QUEUE_TAIL);
782 qp[QUEUE_HEAD] = qp[QUEUE_TAIL];
783 RESET_VARIABLE(qp + QUEUE_TAIL);
784 qp[QUEUE_SIZE] = MkIntTerm(0);
787 Yap_ThrowError(INSTANTIATION_ERROR, t,
"queue/3");
791static Int nb_queue_enqueue(USES_REGS1) {
794 qd = GetQueue(ARG1,
"enqueue");
797 Term arena = GetQueueArena(qd,
"enqueue");
801 Term to = CopyTermToArena(MkPairTerm(Deref(ARG2),TermNil),
false,
true, NULL, &arena, NULL PASS_REGS);
802 qd = GetQueue(ARG1,
"enqueue");
805 Int qsize = IntegerOfTerm(qd[QUEUE_SIZE]);
809 VarOfTerm(qd[QUEUE_TAIL])[0] = to;
811 qd[QUEUE_SIZE] = MkIntTerm(qsize + 1);
812 RESET_VARIABLE(RepPair(to)+1);
813 qd[QUEUE_TAIL] = RepPair(to)[1];
814 qd[QUEUE_ARENA] = arena;
819static Int nb_queue_dequeue(USES_REGS1) {
820 CELL *qd = GetQueue(ARG1,
"dequeue");
826 qsz = IntegerOfTerm(qd[QUEUE_SIZE]);
829 arena = GetQueueArena(qd,
"dequeue");
832 out = HeadOfTerm(qd[QUEUE_HEAD]);
833 qd[QUEUE_HEAD] = TailOfTerm(qd[QUEUE_HEAD]);
834 qd[QUEUE_SIZE] = Global_MkIntegerTerm(qsz - 1);
835 qd[QUEUE_ARENA] = arena;
836 return Yap_unify(out, ARG2);
840static Int nb_queue_replace(USES_REGS1) {
841 CELL *qd = GetQueue(ARG1,
"dequeue");
843 Term queue, t = Deref(ARG2);
847 qsz = IntegerOfTerm(qd[QUEUE_SIZE]);
851 queue = qd[QUEUE_HEAD];
852 for (; qsz > 0; qsz--) {
853 if (Yap_eq(HeadOfTerm(queue), t)) {
854 *RepPair(Deref(queue)) = Deref(ARG3);
857 queue = TailOfTerm(queue);
862static Int nb_queue_peek(USES_REGS1) {
863 CELL *qd = GetQueue(ARG1,
"queue_peek");
868 qsz = IntegerOfTerm(qd[QUEUE_SIZE]);
871 return Yap_unify(HeadOfTerm(qd[QUEUE_HEAD]), ARG2);
874static Int nb_queue_empty(USES_REGS1) {
875 CELL *qd = GetQueue(ARG1,
"queue_empty");
879 return (IntegerOfTerm(qd[QUEUE_SIZE]) == 0);
882static Int nb_queue_size(USES_REGS1) {
883 CELL *qd = GetQueue(ARG1,
"queue_size");
887 return Yap_unify(ARG2, qd[QUEUE_SIZE]);
890static Int nb_queue_show(USES_REGS1) {
891 CELL *qd = GetQueue(ARG1,
"queue_size");
895 return Yap_unify(ARG2, qd[QUEUE_HEAD]);
898static CELL *GetHeap(Term t,
char *caller) {
902 Yap_ThrowError(INSTANTIATION_ERROR, t, caller);
905 if (!IsApplTerm(t)) {
906 Yap_ThrowError(TYPE_ERROR_COMPOUND, t, caller);
909 return RepAppl(t) + 1;
912static Term MkZeroApplTerm(
Atom f, UInt sz) {
917 Functor fsz = Yap_MkFunctor(f, sz);
925 return Yap_MkArena(pt0, HR);
928static Int nb_heap(USES_REGS1) {
934 if (IsVarTerm(tsize)) {
935 Yap_ThrowError(INSTANTIATION_ERROR, tsize,
"nb_heap");
938 if (!IsIntegerTerm(tsize)) {
939 Yap_ThrowError(TYPE_ERROR_INTEGER, tsize,
"nb_heap");
942 arena_sz = hsize = IntegerOfTerm(tsize);
944 if (arena_sz < 1024) {
947 size_t sz = (8 * hsize * 2 + 16);
948 if (HR + sz > ASP - 1024) {
950 Yap_growstack(sz * CellSize);
951 }
else if (!Yap_dogcl(sz * CellSize)) {
952 Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil,
953 "No Stack Space for Non-Backtrackable terms");
958 Term heap = MkZeroApplTerm(AtomHeapData, 8 * hsize + HEAP_START + 1);
959 if (heap != TermNil) {
961 CELL *ar = RepAppl(heap) + 1;
962 ar[HEAP_ARENA] = Yap_MkArena(ar + 2 * hsize + HEAP_START,
963 ar + 8 * hsize + HEAP_START);
964 ar[HEAP_SIZE] = MkIntTerm(0);
965 ar[HEAP_MAX] = MkIntegerTerm(hsize);
970 return Yap_unify(heap, ARG2);
975static Int nb_heap_close(USES_REGS1) {
976 Term t = Deref(ARG1);
981 if (qp[HEAP_ARENA] != MkIntTerm(0))
982 RecoverArena(qp[HEAP_ARENA] PASS_REGS);
983 qp[-1] = (CELL) Yap_MkFunctor(AtomHeapData, 1);
984 qp[0] = MkIntegerTerm(0);
987 Yap_ThrowError(INSTANTIATION_ERROR, t,
"heap_close/1");
991static Int nb_heap_clear(USES_REGS1) {
992 Term t = Deref(ARG1);
997 qp[HEAP_SIZE] = MkIntTerm(0);
998 CELL *p = qp + HEAP_START;
1000 for (i = 0; i < IntOfTerm(qp[HEAP_MAX]) * 2; i += 2, p += 2) {
1002 RESET_VARIABLE(p + 1);
1006 Yap_ThrowError(INSTANTIATION_ERROR, t,
"heap_close/1");
1029static void DelHeapRoot(CELL *pt, UInt sz) {
1035 tv = pt[2 * sz + 1];
1036 pt[2 * sz] = TermNil;
1037 pt[2 * sz + 1] = TermNil;
1039 if (sz < 2 * indx + 3 ||
1040 Yap_compare_terms(pt[4 * indx + 2], pt[4 * indx + 4]) < 0) {
1041 if (sz < 2 * indx + 2 || Yap_compare_terms(tk, pt[4 * indx + 2]) < 0) {
1043 pt[2 * indx + 1] = tv;
1046 pt[2 * indx] = pt[4 * indx + 2];
1047 pt[2 * indx + 1] = pt[4 * indx + 3];
1048 indx = 2 * indx + 1;
1051 if (Yap_compare_terms(tk, pt[4 * indx + 4]) < 0) {
1053 pt[2 * indx + 1] = tv;
1056 pt[2 * indx] = pt[4 * indx + 4];
1057 pt[2 * indx + 1] = pt[4 * indx + 5];
1058 indx = 2 * indx + 2;
1064CELL *new_heap_entry(CELL *qd) {
1065 size_t size = HEAP_START + 2 * IntOfTerm(qd[HEAP_MAX]);
1066 size_t indx = HEAP_START + 2 * IntOfTerm(qd[HEAP_SIZE]);
1067 size_t extra = 8 * MIN_ARENA_SIZE + 2 * size;
1068 size_t howmany = extra;
1069 CELL *a_max = qd + size;
1070 if (size < indx + 10) {
1072 CELL *new_max = a_max;
1074 if ((nsize = Yap_InsertInGlobal(a_max, howmany * CellSize, &new_max) /
1075 CellSize) >= howmany) {
1080 if (!Yap_dogcl(extra * CellSize)) {
1081 Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil,
1082 "No Stack Space for Non-Backtrackable terms");
1086 qd[HEAP_MAX] = MkIntTerm((size + extra) / 2 - HEAP_START);
1089 CELL *top = a_max + extra;
1090 qd[-1] = (CELL) Yap_MkFunctor(AtomHeapData, size + extra);
1091 while (a_max < top) {
1092 a_max[0] = a_max[1] = TermNil;
1099static Int nb_heap_add_to_heap(USES_REGS1) {
1104 qd = new_heap_entry(GetHeap(ARG1,
"add_to_heap"));
1106 arena = qd[HEAP_ARENA];
1112 Term l = MkPairTerm(ARG2, ARG3);
1113 to = CopyTermToArena(l,
false,
true, NULL, &arena, NULL PASS_REGS);
1114 qd = GetHeap(Deref(ARG1),
"add_to_heap)");
1115 hsize = IntegerOfTerm(qd[HEAP_SIZE]);
1116 pt = qd + HEAP_START;
1117 pt[2 * hsize] = HeadOfTerm(to);
1119 pt[2 * hsize + 1] = TailOfTerm(to);
1120 Term thsz = Global_MkIntegerTerm(hsize + 1);
1122 qd[HEAP_ARENA] = arena;
1123 qd[HEAP_SIZE] = thsz;
1127static Int nb_heap_del(USES_REGS1) {
1128 CELL *qd = GetHeap(ARG1,
"deheap");
1135 qsz = IntegerOfTerm(qd[HEAP_SIZE]);
1138 arena = qd[HEAP_ARENA];
1142 qd[HEAP_SIZE] = MkIntTerm(qsz - 1);
1143 tk = qd[HEAP_START];
1144 tv = qd[HEAP_START + 1];
1145 DelHeapRoot(qd + HEAP_START, qsz);
1146 return Yap_unify(tk, ARG2) && Yap_unify(tv, ARG3);
1149static Int nb_heap_peek(USES_REGS1) {
1150 CELL *qd = GetHeap(ARG1,
"heap_peek");
1156 qsz = IntegerOfTerm(qd[HEAP_SIZE]);
1159 tk = qd[HEAP_START];
1160 tv = qd[HEAP_START + 1];
1161 return Yap_unify(tk, ARG2) && Yap_unify(tv, ARG3);
1164static Int nb_heap_empty(USES_REGS1) {
1165 CELL *qd = GetHeap(ARG1,
"heap_empty");
1169 return (IntegerOfTerm(qd[HEAP_SIZE]) == 0);
1172static Int nb_heap_size(USES_REGS1) {
1173 CELL *qd = GetHeap(ARG1,
"heap_size");
1177 return Yap_unify(ARG2, qd[HEAP_SIZE]);
1180static Int nb_beam(USES_REGS1) {
1183 Term tsize = Deref(ARG1);
1184 UInt arena_sz = (HR - H0) / 16;
1186 if (IsVarTerm(tsize)) {
1187 Yap_ThrowError(INSTANTIATION_ERROR, tsize,
"nb_beam");
1190 if (!IsIntegerTerm(tsize)) {
1191 Yap_ThrowError(TYPE_ERROR_INTEGER, tsize,
"nb_beam");
1194 hsize = IntegerOfTerm(tsize);
1196 if (arena_sz < 1024)
1198 while (HR + (3 * hsize + arena_sz + 16) > ASP - 1024) {
1199 CreepFlag = EventFlag =
1200 StackGap(PASS_REGS1) + (5 * hsize + HEAP_START + 1 + arena_sz);
1203 Yap_track_cpred(0, P, 0, &info);
1205 if (!Yap_gc(&info)) {
1206 Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil,
1207 "stack overflow: gc failed");
1210 beam = MkZeroApplTerm(AtomHeapData, 5 * hsize + HEAP_START + 1);
1211 if (beam == TermNil) {
1214 if (!Yap_unify(beam, ARG2))
1216 ar = RepAppl(beam) + 1;
1217 ar[HEAP_ARENA] = ar[HEAP_SIZE] = MkIntTerm(0);
1218 ar[HEAP_MAX] = tsize;
1223static Int nb_beam_close(USES_REGS1) {
return nb_heap_close(PASS_REGS1); }
1230static void PushBeam(CELL *pt, CELL *npt, UInt hsize, Term key, Term to) {
1232 UInt off = hsize, off2 = hsize;
1237 UInt noff = (off + 1) / 2 - 1;
1238 if (Yap_compare_terms(key, pt[2 * noff]) < 0) {
1239 UInt i2 = IntegerOfTerm(pt[2 * noff + 1]);
1241 pt[2 * off] = pt[2 * noff];
1242 pt[2 * off + 1] = pt[2 * noff + 1];
1243 npt[3 * i2 + 1] = Global_MkIntegerTerm(off);
1249 toff = Global_MkIntegerTerm(off);
1253 UInt noff = (off2 + 1) / 2 - 1;
1254 if (Yap_compare_terms(key, npt[3 * noff]) > 0) {
1255 UInt i1 = IntegerOfTerm(npt[3 * noff + 1]);
1257 npt[3 * off2] = npt[3 * noff];
1258 npt[3 * off2 + 1] = npt[3 * noff + 1];
1259 npt[3 * off2 + 2] = npt[3 * noff + 2];
1260 pt[2 * i1 + 1] = Global_MkIntegerTerm(off2);
1266 toff2 = Global_MkIntegerTerm(off2);
1268 npt[3 * off2] = pt[2 * off] = key;
1269 pt[2 * off + 1] = toff2;
1270 npt[3 * off2 + 1] = toff;
1271 npt[3 * off2 + 2] = to;
1274static void DelBeamMax(CELL *pt, CELL *pt2, UInt sz) {
1276 UInt off = IntegerOfTerm(pt2[1]);
1283 ti = pt2[3 * sz + 1];
1284 tv = pt2[3 * sz + 2];
1286 if (sz < 2 * indx + 3 ||
1287 Yap_compare_terms(pt2[6 * indx + 3], pt2[6 * indx + 6]) > 0) {
1288 if (sz < 2 * indx + 2 || Yap_compare_terms(tk, pt2[6 * indx + 3]) > 0) {
1291 UInt off = IntegerOfTerm(pt2[6 * indx + 4]);
1293 pt2[3 * indx] = pt2[6 * indx + 3];
1294 pt2[3 * indx + 1] = pt2[6 * indx + 4];
1295 pt2[3 * indx + 2] = pt2[6 * indx + 5];
1296 pt[2 * off + 1] = Global_MkIntegerTerm(indx);
1297 indx = 2 * indx + 1;
1300 if (Yap_compare_terms(tk, pt2[6 * indx + 6]) > 0) {
1303 UInt off = IntegerOfTerm(pt2[6 * indx + 7]);
1305 pt2[3 * indx] = pt2[6 * indx + 6];
1306 pt2[3 * indx + 1] = pt2[6 * indx + 7];
1307 pt2[3 * indx + 2] = pt2[6 * indx + 8];
1308 pt[2 * off + 1] = Global_MkIntegerTerm(indx);
1309 indx = 2 * indx + 2;
1313 pt[2 * IntegerOfTerm(ti) + 1] = Global_MkIntegerTerm(indx);
1315 pt2[3 * indx + 1] = ti;
1316 pt2[3 * indx + 2] = tv;
1319 Term toff, toff2, key;
1323 toff2 = pt[2 * sz + 1];
1324 off2 = IntegerOfTerm(toff2);
1328 UInt noff = (off + 1) / 2 - 1;
1329 if (Yap_compare_terms(key, pt[2 * noff]) < 0) {
1330 UInt i1 = IntegerOfTerm(pt[2 * noff + 1]);
1332 pt[2 * off] = pt[2 * noff];
1333 pt[2 * off + 1] = pt[2 * noff + 1];
1334 pt2[3 * i1 + 1] = Global_MkIntegerTerm(off);
1340 toff = Global_MkIntegerTerm(off);
1343 pt2[3 * off2 + 1] = toff;
1344 pt[2 * off + 1] = toff2;
1348static Term DelBeamMin(CELL *pt, CELL *pt2, UInt sz) {
1350 UInt off2 = IntegerOfTerm(pt[1]);
1351 Term ov = pt2[3 * off2 + 2];
1358 tv = pt[2 * sz + 1];
1360 if (sz < 2 * indx + 3 ||
1361 Yap_compare_terms(pt[4 * indx + 2], pt[4 * indx + 4]) < 0) {
1362 if (sz < 2 * indx + 2 || Yap_compare_terms(tk, pt[4 * indx + 2]) < 0) {
1365 UInt off2 = IntegerOfTerm(pt[4 * indx + 3]);
1366 pt[2 * indx] = pt[4 * indx + 2];
1367 pt[2 * indx + 1] = pt[4 * indx + 3];
1368 pt2[3 * off2 + 1] = Global_MkIntegerTerm(indx);
1369 indx = 2 * indx + 1;
1372 if (Yap_compare_terms(tk, pt[4 * indx + 4]) < 0) {
1375 UInt off2 = IntegerOfTerm(pt[4 * indx + 5]);
1377 pt[2 * indx] = pt[4 * indx + 4];
1378 pt[2 * indx + 1] = pt[4 * indx + 5];
1379 pt2[3 * off2 + 1] = Global_MkIntegerTerm(indx);
1380 indx = 2 * indx + 2;
1385 pt[2 * indx + 1] = tv;
1386 pt2[3 * IntegerOfTerm(tv) + 1] = Global_MkIntegerTerm(indx);
1389 Term to, toff, toff2, key;
1393 toff = pt2[3 * sz + 1];
1394 to = pt2[3 * sz + 2];
1395 off = IntegerOfTerm(toff);
1399 UInt noff = (off2 + 1) / 2 - 1;
1400 if (Yap_compare_terms(key, pt2[3 * noff]) > 0) {
1401 UInt i1 = IntegerOfTerm(pt2[3 * noff + 1]);
1403 pt2[3 * off2] = pt2[3 * noff];
1404 pt2[3 * off2 + 1] = pt2[3 * noff + 1];
1405 pt2[3 * off2 + 2] = pt2[3 * noff + 2];
1406 pt[2 * i1 + 1] = Global_MkIntegerTerm(off2);
1412 toff2 = Global_MkIntegerTerm(off2);
1414 pt2[3 * off2] = key;
1415 pt[2 * off + 1] = toff2;
1416 pt2[3 * off2 + 1] = toff;
1417 pt2[3 * off2 + 2] = to;
1422static size_t new_beam_entry(CELL **qdp) {
1423 size_t hsize, hmsize;
1425 hsize = IntegerOfTerm(qd[HEAP_SIZE]);
1426 hmsize = IntegerOfTerm(qd[HEAP_MAX]);
1430 if (hsize >= hmsize - 10) {
1433 size_t sz = 2 * hsize + HEAP_START, ex = 2 * sz;
1435 CELL *new_max = qd + sz, *a_max = qd + sz;
1436 if ((nsize = Yap_InsertInGlobal(a_max, ex * CellSize, &new_max) /
1443 if (!Yap_dogcl(ex * CellSize)) {
1444 Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil,
1445 "No Stack Space for Non-Backtrackable terms");
1448 qd[HEAP_MAX] = MkIntTerm(3 * hmsize);
1451 pt = qd + HEAP_START;
1453 if (Yap_compare_terms(pt[2 * hmsize], Deref(ARG2)) > 0) {
1455 DelBeamMax(pt, pt + 2 * hmsize, hmsize);
1462static Int nb_beam_add_to_beam(USES_REGS1) {
1463 CELL *qd = GetHeap(ARG1,
"add_to_beam"), *pt;
1464 size_t hsize, hmsize = qd[HEAP_SIZE];
1467 hsize = new_beam_entry(&qd);
1468 arena = qd[HEAP_ARENA];
1471 CELL *arenap = &arena;
1472 Term l = MkPairTerm(ARG2, ARG3);
1473 to = CopyTermToArena(l, FALSE, TRUE, NULL, &arena, NULL PASS_REGS);
1476 qd = GetHeap(ARG1,
"add_to_beam");
1478 qd[HEAP_ARENA] = arena;
1479 pt = qd + HEAP_START;
1480 PushBeam(pt, pt + 2 * hmsize, hsize, HeadOfTerm(to), TailOfTerm(to));
1481 qd[HEAP_SIZE] = Global_MkIntegerTerm(hsize + 1);
1485static Int nb_beam_del(USES_REGS1) {
1486 CELL *qd = GetHeap(ARG1,
"debeam");
1492 qsz = IntegerOfTerm(qd[HEAP_SIZE]);
1496 qd[HEAP_SIZE] = Global_MkIntegerTerm(qsz - 1);
1497 tk = qd[HEAP_START];
1498 tv = DelBeamMin(qd + HEAP_START,
1499 qd + (HEAP_START + 2 * IntegerOfTerm(qd[HEAP_MAX])), qsz);
1500 return Yap_unify(tk, ARG2) && Yap_unify(tv, ARG3);
1505static Int nb_beam_check(USES_REGS1) {
1506 CELL *qd = GetHeap(ARG1,
"debeam");
1513 qsz = IntegerOfTerm(qd[HEAP_SIZE]);
1514 qmax = IntegerOfTerm(qd[HEAP_MAX]);
1517 pt = qd + HEAP_START;
1518 pt2 = pt + 2 * qmax;
1519 for (i = 1; i < qsz; i++) {
1521 if (Yap_compare_terms(pt[2 * ((i + 1) / 2 - 1)], pt[2 * i]) > 0) {
1522 Yap_DebugPlWrite(pt[2 * ((i + 1) / 2 - 1)]);
1523 fprintf(stderr,
"\n");
1524 Yap_DebugPlWrite(pt[2 * i]);
1525 fprintf(stderr,
"\n");
1526 fprintf(stderr,
"Error at %ld\n", (
unsigned long int) i);
1529 back = IntegerOfTerm(pt[2 * i + 1]);
1530 if (IntegerOfTerm(pt2[3 * back + 1]) != i) {
1531 fprintf(stderr,
"Link error at %ld\n", (
unsigned long int) i);
1535 for (i = 1; i < qsz; i++) {
1536 if (Yap_compare_terms(pt2[3 * ((i + 1) / 2 - 1)], pt2[3 * i]) < 0) {
1537 fprintf(stderr,
"Error at sec %ld\n", (
unsigned long int) i);
1538 Yap_DebugPlWrite(pt2[3 * ((i + 1) / 2 - 1)]);
1539 fprintf(stderr,
"\n");
1540 Yap_DebugPlWrite(pt2[3 * i]);
1541 fprintf(stderr,
"\n");
1550static Int nb_beam_keys(USES_REGS1) {
1557 qd = GetHeap(ARG1,
"beam_keys");
1560 qsz = IntegerOfTerm(qd[HEAP_SIZE]);
1562 pt = qd + HEAP_START;
1564 return Yap_unify(ARG2, TermNil);
1565 for (i = 0; i < qsz; i++) {
1566 if (HR > ASP - 1024) {
1568 Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage);
1575 *HR = AbsPair(HR + 1);
1580 return Yap_unify(ARG2, AbsPair(ho));
1583static Int nb_beam_peek(USES_REGS1) {
1584 CELL *qd = GetHeap(ARG1,
"beam_peek"), *pt, *pt2;
1590 qsz = IntegerOfTerm(qd[HEAP_SIZE]);
1591 qbsize = IntegerOfTerm(qd[HEAP_MAX]);
1594 pt = qd + HEAP_START;
1595 pt2 = pt + 2 * qbsize;
1598 return Yap_unify(tk, ARG2) && Yap_unify(tv, ARG3);
1601static Int nb_beam_empty(USES_REGS1) {
1602 CELL *qd = GetHeap(ARG1,
"beam_empty");
1606 return (IntegerOfTerm(qd[HEAP_SIZE]) == 0);
1609static Int nb_beam_size(USES_REGS1) {
1610 CELL *qd = GetHeap(ARG1,
"beam_size");
1614 return Yap_unify(ARG2, qd[HEAP_SIZE]);
1617static Int cont_current_nb(USES_REGS1) {
1621 unif = Yap_unify(MkAtomTerm(AbsAtom(ge->AtomOfGE)), ARG1);
1629 EXTRA_CBACK_ARG(1, 1) = MkIntegerTerm((Int) ge);
1634static Int init_current_nb(USES_REGS1) {
1636 Term t1 = Deref(ARG1);
1637 if (!IsVarTerm(t1)) {
1638 if (IsAtomTerm(t1)) {
1639 if (!FindGlobalEntry(AtomOfTerm(t1) PASS_REGS)) {
1645 Yap_ThrowError(TYPE_ERROR_ATOM, t1,
"nb_current");
1649 READ_LOCK(HashChain[0].AERWLock);
1650 EXTRA_CBACK_ARG(1, 1) = MkIntegerTerm((Int) LOCAL_GlobalVariables);
1651 return cont_current_nb(PASS_REGS1);
1655void Yap_InitGlobals(
void) {
1657 Term cm = CurrentModule;
1658 Yap_InitCPred(
"b_setval", 2, p_b_setval, SafePredFlag);
1659 Yap_InitCPred(
"__B_setval__", 2, p_b_setval, HiddenPredFlag | SafePredFlag);
1660 Yap_InitCPred(
"nb_setval", 2, nb_setval, 0L);
1661 Yap_InitCPred(
"__NB_setval__", 2, nb_setval, HiddenPredFlag);
1662 Yap_InitCPred(
"nb_set_shared_val", 2, nb_set_shared_val, 0L);
1663 Yap_InitCPred(
"$nb_getval", 3, nb_getval, SafePredFlag);
1664 Yap_InitCPred(
"__NB_getval__", 3, nb_getval, HiddenPredFlag);
1665 Yap_InitCPred(
"__B_getval__", 3, nb_getval, HiddenPredFlag);
1666 Yap_InitCPred(
"nb_delete", 1, nb_delete, 0L);
1667 Yap_InitCPred(
"nb_create", 3, nb_create, 0L);
1668 Yap_InitCPred(
"nb_create", 4, nb_create2, 0L);
1669 Yap_InitCPredBack(
"$nb_current", 1, 1, init_current_nb, cont_current_nb,
1671 CurrentModule = GLOBALS_MODULE;
1672 Yap_InitCPred(
"nb_queue", 1, nb_queue, 0L);
1673 Yap_InitCPred(
"nb_queue", 2, nb_queue2, 0L);
1674 Yap_InitCPred(
"nb_queue_close", 3, nb_queue_close, SafePredFlag);
1675 Yap_InitCPred(
"nb_queue_enqueue", 2, nb_queue_enqueue, 0L);
1676 Yap_InitCPred(
"nb_queue_dequeue", 2, nb_queue_dequeue, SafePredFlag);
1677 Yap_InitCPred(
"nb_queue_peek", 2, nb_queue_peek, SafePredFlag);
1678 Yap_InitCPred(
"nb_queue_empty", 1, nb_queue_empty, SafePredFlag);
1679 Yap_InitCPred(
"nb_queue_replace", 3, nb_queue_replace, SafePredFlag);
1680 Yap_InitCPred(
"nb_queue_size", 2, nb_queue_size, SafePredFlag);
1681 Yap_InitCPred(
"nb_queue_show", 2, nb_queue_show, SafePredFlag);
1682 Yap_InitCPred(
"nb_heap", 2, nb_heap, 0);
1683 Yap_InitCPred(
"nb_heap_close", 1, nb_heap_close, SafePredFlag);
1684 Yap_InitCPred(
"nb_heap_clear", 1, nb_heap_clear, SafePredFlag);
1685 Yap_InitCPred(
"nb_heap_add", 3, nb_heap_add_to_heap, 0L);
1686 Yap_InitCPred(
"nb_heap_del", 3, nb_heap_del, SafePredFlag);
1687 Yap_InitCPred(
"nb_heap_peek", 3, nb_heap_peek, SafePredFlag);
1688 Yap_InitCPred(
"nb_heap_empty", 1, nb_heap_empty, SafePredFlag);
1689 Yap_InitCPred(
"nb_heap_size", 2, nb_heap_size, SafePredFlag);
1690 Yap_InitCPred(
"nb_beam", 2, nb_beam, 0L);
1691 Yap_InitCPred(
"nb_beam_close", 1, nb_beam_close, SafePredFlag);
1692 Yap_InitCPred(
"nb_beam_add", 3, nb_beam_add_to_beam, 0L);
1693 Yap_InitCPred(
"nb_beam_del", 3, nb_beam_del, SafePredFlag);
1694 Yap_InitCPred(
"nb_beam_peek", 3, nb_beam_peek, SafePredFlag);
1695 Yap_InitCPred(
"nb_beam_empty", 1, nb_beam_empty, SafePredFlag);
1696 Yap_InitCPred(
"nb_beam_keys", 2, nb_beam_keys, 0L);
1698 Yap_InitCPred(
"nb_create_accumulator", 2, nb_create_accumulator, 0L);
1699 Yap_InitCPred(
"nb_add_to_accumulator", 2, nb_add_to_accumulator, 0L);
1700 Yap_InitCPred(
"nb_accumulator_value", 2, nb_accumulator_value, 0L);
1702 Yap_InitCPred(
"nb_beam_check", 1, nb_beam_check, SafePredFlag);
1704 Yap_InitCPred(
"nb_beam_size", 2, nb_beam_size, SafePredFlag);
@ source
If true maintain the source for all clauses.