int immediate_depends_ptrlist(CTXTdeclc callnodeptr call1){ VariantSF subgoal; int count = 0; CPtr oldhreg = NULL; calllistptr cl; reg[4] = makelist(hreg); new_heap_free(hreg); new_heap_free(hreg); if(IsNonNULL(call1)){ /* This can be called from some non incremental predicate */ cl= call1->inedges; while(IsNonNULL(cl)){ subgoal = (VariantSF) cl->inedge_node->callnode->goal; if(IsNonNULL(subgoal)){/* fact check */ count++; check_glstack_overflow(4,pcreg,2); oldhreg = hreg-2; follow(oldhreg++) = makeint(subgoal); follow(oldhreg) = makelist(hreg); new_heap_free(hreg); new_heap_free(hreg); } cl=cl->next; } if (count>0) follow(oldhreg) = makenil; else reg[4] = makenil; } return unify(CTXTc reg_term(CTXTc 3),reg_term(CTXTc 4)); }
HashStats hash_statistics(CTXTdeclc Structure_Manager *sm) { HashStats ht_stats; counter num_used_hdrs; BTHTptr pBTHT; BTNptr *ppBTN; ht_stats.hdr = node_statistics(sm); num_used_hdrs = 0; HashStats_NumBuckets(ht_stats) = 0; HashStats_TotalOccupancy(ht_stats) = 0; HashStats_NonEmptyBuckets(ht_stats) = 0; HashStats_BucketSize(ht_stats) = sizeof(void *); pBTHT = (BTHTptr)SM_AllocList(*sm); while ( IsNonNULL(pBTHT) ) { #ifdef DEBUG_ASSERTIONS /* Counter for contents of current hash table ------------------------------------------ */ v counter num_contents = 0; #endif num_used_hdrs++; HashStats_NumBuckets(ht_stats) += BTHT_NumBuckets(pBTHT); HashStats_TotalOccupancy(ht_stats) += BTHT_NumContents(pBTHT); for ( ppBTN = BTHT_BucketArray(pBTHT); ppBTN < BTHT_BucketArray(pBTHT) + BTHT_NumBuckets(pBTHT); ppBTN++ ) if ( IsNonNULL(*ppBTN) ) { #ifdef DEBUG_ASSERTIONS /* Count the objects in each bucket -------------------------------- */ BTNptr pBTN = *ppBTN; do { num_contents++; pBTN = BTN_Sibling(pBTN); } while ( IsNonNULL(pBTN) ); #endif HashStats_NonEmptyBuckets(ht_stats)++; } #ifdef DEBUG_ASSERTIONS /* Compare counter and header values --------------------------------- */ if ( num_contents != BTHT_NumContents(pBTHT) ) xsb_warn(CTXTc "Inconsistent %s Usage Calculations:\n" "\tHash table occupancy mismatch.", SM_StructName(*sm)); #endif pBTHT = BTHT_NextBTHT(pBTHT); } if ( HashStats_NumAllocHeaders(ht_stats) != (num_used_hdrs + HashStats_NumFreeHeaders(ht_stats)) ) xsb_warn(CTXTc "Inconsistent %s Usage Calculations:\n" "\tHeader count mismatch: Alloc: %d Used: %d Free: %d", SM_StructName(*sm), HashStats_NumAllocHeaders(ht_stats), num_used_hdrs, HashStats_NumFreeHeaders(ht_stats)); return ht_stats; }
void addcalledge(callnodeptr fromcn, callnodeptr tocn){ KEY *k1; SM_AllocateStruct(smKey, k1); k1->goal = tocn->id; // #ifdef INCR_DEBUG // printf("%d-->%d",fromcn->id,tocn->id); // #endif if (NULL == search_some(fromcn->outedges->hasht,k1)) { insert_some(fromcn->outedges->hasht,k1,tocn); #ifdef INCR_DEBUG printf("Inedges of %d = ",tocn->id); temp=tocn->inedges; while(temp!=NULL){ printf("\t%d",temp->inedge_node->callnode->id); temp=temp->next; } printf("\n"); #endif add_calledge(&(tocn->inedges),fromcn->outedges); call_edge_count_gl++; fromcn->outcount++; #ifdef INCR_DEBUG if(IsNonNULL(fromcn->goal)){ sfPrintGoal(stdout,(VariantSF)fromcn->goal,NO);printf("(%d)",fromcn->id); }else printf("(%d)",fromcn->id); if(IsNonNULL(tocn->goal)){ printf("-->"); sfPrintGoal(stdout,(VariantSF)tocn->goal,NO);printf("(%d)",tocn->id); } printf("\n"); #endif } #ifdef INCR_DEBUG printf("Inedges of %d = ",tocn->id); temp=tocn->inedges; while(temp!=NULL){ printf("\t%d",temp->inedge_node->callnode->id); temp=temp->next; } printf("\n---------------------------------\n"); #endif }
/* For a callnode call1 returns a Prolog list of callnode on which call1 immediately depends. */ int immediate_inedges_list(CTXTdeclc callnodeptr call1){ VariantSF subgoal; TIFptr tif; int j, count = 0,arity; Psc psc; CPtr oldhreg = NULL; calllistptr cl; reg[4] = makelist(hreg); new_heap_free(hreg); new_heap_free(hreg); if(IsNonNULL(call1)){ /* This can be called from some non incremental predicate */ cl= call1->inedges; while(IsNonNULL(cl)){ subgoal = (VariantSF) cl->inedge_node->callnode->goal; if(IsNonNULL(subgoal)){/* fact check */ count++; tif = (TIFptr) subgoal->tif_ptr; psc = TIF_PSC(tif); arity = get_arity(psc); check_glstack_overflow(4,pcreg,2+arity*200); // don't know how much for build_subgoal_args... oldhreg = hreg-2; if(arity>0){ sreg = hreg; follow(oldhreg++) = makecs(hreg); hreg += arity + 1; new_heap_functor(sreg, psc); for (j = 1; j <= arity; j++) { new_heap_free(sreg); cell_array1[arity-j] = cell(sreg-1); } build_subgoal_args(subgoal); }else{ follow(oldhreg++) = makestring(get_name(psc)); } follow(oldhreg) = makelist(hreg); new_heap_free(hreg); new_heap_free(hreg); } cl=cl->next; } if (count>0) follow(oldhreg) = makenil; else reg[4] = makenil; }else{ xsb_warn("Called with non-incremental predicate\n"); reg[4] = makenil; } return unify(CTXTc reg_term(CTXTc 3),reg_term(CTXTc 4)); }
/* If ret != 0 (= CANNOT_UPDATE) then we'll use the old table, and we wont lazily update at all. */ int dfs_inedges(CTXTdeclc callnodeptr call1, calllistptr * lazy_affected, int flag ){ calllistptr inedge_list; VariantSF subgoal; int ret = 0; if(IsNonNULL(call1->goal)) { if (!subg_is_completed((VariantSF)call1->goal)){ deallocate_call_list(*lazy_affected); xsb_new_table_error(CTXTc "incremental_tabling", "Incremental tabling is trying to invalidate an incomplete table", get_name(TIF_PSC(subg_tif_ptr(call1->goal))), get_arity(TIF_PSC(subg_tif_ptr(call1->goal)))); } if (subg_visitors(call1->goal)) { #ifdef ISO_INCR_TABLING find_the_visitors(CTXTc call1->goal); #else dfs_inedges_warning(CTXTc call1,lazy_affected); return CANNOT_UPDATE; #endif } } // TLS: handles dags&cycles -- no need to traverse more than once. if (call1 -> recomputable == COMPUTE_DEPENDENCIES_FIRST) call1 -> recomputable = COMPUTE_DIRECTLY; else { // printf("found directly computable call \n"); return 0; } // printf(" dfs_i affected "); print_subgoal(stddbg,call1->goal);printf("\n"); inedge_list= call1-> inedges; while(IsNonNULL(inedge_list) && !ret){ subgoal = (VariantSF) inedge_list->inedge_node->callnode->goal; if(IsNonNULL(subgoal)){ /* fact check */ // count++; if (inedge_list->inedge_node->callnode->falsecount > 0) { ret = ret | dfs_inedges(CTXTc inedge_list->inedge_node->callnode, lazy_affected,flag); } else { ; // printf(" dfs_i non_affected "); print_subgoal(stddbg,subgoal);printf("\n"); } } inedge_list = inedge_list->next; } if(IsNonNULL(call1->goal) & !ret){ /* fact check */ // printf(" dfs_i adding "); print_subgoal(stddbg,call1->goal);printf("\n"); add_callnode(lazy_affected,call1); } return ret; }
void mark_for_incr_abol(callnodeptr c){ calllistptr in=c->inedges; call2listptr markedlistptr; callnodeptr c1; #ifdef INCR_DEBUG1 printf("marking ");printcall(c);printf("\n"); #endif c->deleted=1; markedlistptr=insert_cdbllist(marked_list_gl,c); if(c->outcount) ecall3(&assumption_list_gl,markedlistptr); while(IsNonNULL(in)){ c1=in->inedge_node->callnode; c1->outcount--; if(c1->deleted==0){ mark_for_incr_abol(c1); } in=in->next; } return; }
xsbBool smIsValidStructRef(Structure_Manager smRecord, void *ptr) { void *pBlock, *firstStruct, *lastStruct; size_t structSize; structSize = SM_StructSize(smRecord); for ( pBlock = SM_CurBlock(smRecord); IsNonNULL(pBlock); pBlock = SMBlk_NextBlock(pBlock) ) { firstStruct = SMBlk_FirstStruct(pBlock); lastStruct = SMBlk_LastStruct(pBlock,structSize,SM_StructsPerBlock(smRecord)); /* Determine whether pointer lies within block ------------------------------------------- */ if ( (firstStruct <= ptr) && (ptr <= lastStruct) ) { /* Determine whether pointer is a valid reference ---------------------------------------------- */ if ( (((char *)ptr - (char *)firstStruct) MOD structSize) == 0 ) return TRUE; else return FALSE; } } return FALSE; }
void printcall(callnodeptr c){ // printf("%d",c->id); if(IsNonNULL(c->goal)) sfPrintGoal(stdout,c->goal,NO); else printf("fact"); return; }
/* Printing Answers in an Answer List ---------------------------------- */ void printAnswerList(FILE *fp, ALNptr pALN) { fprintf(fp, "Answer List %p:\n", pALN); while ( IsNonNULL(pALN) ) { fprintf(fp, " "); printTriePath(fp, ALN_Answer(pALN), YES); fprintf(fp, "\n"); pALN = ALN_Next(pALN); } }
void delete_calls(CTXTdecl){ call2listptr n=marked_list_gl->next,temp; callnodeptr c; VariantSF goal; /* first iteration to delete inedges */ while(n!=marked_list_gl){ c=n->item; if(c->deleted){ /* facts are not deleted */ if(IsNonNULL(c->goal)){ deleteinedges(c); } } n=n->next; } /* second iteration is to delete outedges and callnode */ n=marked_list_gl->next; while(n!=marked_list_gl){ temp=n->next; c=n->item; if(c->deleted){ /* facts are not deleted */ if(IsNonNULL(c->goal)){ goal=c->goal; deletecallnode(c); abolish_table_call(CTXTc goal,ABOLISH_TABLES_DEFAULT); } } SM_DeallocateStruct(smCall2List,n); n=temp; } SM_DeallocateStruct(smCall2List,marked_list_gl); marked_list_gl=NULL; return; }
void smFreeBlocks(Structure_Manager *pSM) { void *pCurBlock, *pNextBlock; pCurBlock = SM_CurBlock(*pSM); while ( IsNonNULL(pCurBlock) ) { pNextBlock = SMBlk_NextBlock(pCurBlock); mem_dealloc(pCurBlock,SM_NewBlockSize(*pSM),TABLE_SPACE); pCurBlock = pNextBlock; } SM_CurBlock(*pSM) = SM_NextStruct(*pSM) = SM_LastStruct(*pSM) = NULL; SM_AllocList(*pSM) = SM_FreeList(*pSM) = NULL; }
int immediate_affects_ptrlist(CTXTdeclc callnodeptr call1){ VariantSF subgoal; int count = 0; CPtr oldhreg = NULL; struct hashtable *h; struct hashtable_itr *itr; callnodeptr cn; reg[4] = makelist(hreg); new_heap_free(hreg); new_heap_free(hreg); if(IsNonNULL(call1)){ /* This can be called from some non incremental predicate */ h=call1->outedges->hasht; itr = hashtable1_iterator(h); if (hashtable1_count(h) > 0){ do { cn = hashtable1_iterator_value(itr); if(IsNonNULL(cn->goal)){ count++; subgoal = (VariantSF) cn->goal; check_glstack_overflow(4,pcreg,2); oldhreg=hreg-2; follow(oldhreg++) = makeint(subgoal); follow(oldhreg) = makelist(hreg); new_heap_free(hreg); new_heap_free(hreg); } } while (hashtable1_iterator_advance(itr)); } if (count>0) follow(oldhreg) = makenil; else reg[4] = makenil; } return unify(CTXTc reg_term(CTXTc 3),reg_term(CTXTc 4)); }
void smFreeBlocks(Structure_Manager *pSM) { void *pCurBlock, *pNextBlock; pCurBlock = SM_CurBlock(*pSM); while ( IsNonNULL(pCurBlock) ) { pNextBlock = SMBlk_NextBlock(pCurBlock); free(pCurBlock); pCurBlock = pNextBlock; } SM_CurBlock(*pSM) = SM_NextStruct(*pSM) = SM_LastStruct(*pSM) = NULL; SM_AllocList(*pSM) = SM_FreeList(*pSM) = NULL; }
void dfs_outedges_check_non_completed(CTXTdeclc callnodeptr call1) { char bufferb[MAXTERMBUFSIZE]; if(IsNonNULL(call1->goal) && !subg_is_completed((VariantSF)call1->goal)){ deallocate_call_list(affected_gl); sprint_subgoal(CTXTc forest_log_buffer_1,0,(VariantSF)call1->goal); sprintf(bufferb,"Incremental tabling is trying to invalidate an incomplete table \n %s\n", forest_log_buffer_1->fl_buffer); xsb_new_table_error(CTXTc "incremental_tabling",bufferb, get_name(TIF_PSC(subg_tif_ptr(call1->goal))), get_arity(TIF_PSC(subg_tif_ptr(call1->goal)))); } }
void smPrintBlocks(Structure_Manager *pSM) { void *pCurBlock, *pNextBlock; printf("blocks for SM %p size %" UIntfmt "\n",pSM,(UInteger)SM_NewBlockSize(*pSM)); pCurBlock = SM_CurBlock(*pSM); while ( IsNonNULL(pCurBlock) ) { printf("Block %p\n",pCurBlock); pNextBlock = SMBlk_NextBlock(pCurBlock); // mem_dealloc(pCurBlock,SM_NewBlockSize(*pSM),TABLE_SPACE); pCurBlock = pNextBlock; } }
/* Printing Subsumed Calls ----------------------- */ void sfPrintConsGoals(FILE *fp, SubProdSF pProd) { SubConsSF pCons; fprintf(fp, "Producer:\n "); sfPrintGoal(fp, (VariantSF)pProd, YES); fprintf(fp, "\nConsumers:\n"); for ( pCons = subg_consumers(pProd); IsNonNULL(pCons); pCons = conssf_consumers(pCons) ) { fprintf(fp, " "); sfPrintGoal(fp, (VariantSF)pCons, YES); fprintf(fp, "\n"); } }
int sprintTriePath(CTXTdeclc char * buffer, BTNptr pLeaf) { BTNptr pRoot; int ctr = 0; if ( IsNULL(pLeaf) ) { return sprintf(buffer, "NULL"); } if ( ! IsLeafNode(pLeaf) ) { fprintf(stderr, "printTriePath() called with non-Leaf node!\n"); printTrieNode(stderr, pLeaf); return -1; } if (IsEscapeNode(pLeaf) ) { // printf("escape\n"); pRoot = BTN_Parent(pLeaf); if ( IsNonNULL(pRoot) ) { ctr = ctr + sprintTrieSymbol(buffer+ctr, BTN_Symbol(pRoot)); return ctr; } else { fprintf(stderr, "ESCAPE node"); return 0; } } SymbolStack_ResetTOS; SymbolStack_PushPathRoot(pLeaf,pRoot); if ( IsTrieFunctor(BTN_Symbol(pRoot)) ) { // printf("tf\n"); SymbolStack_Push(BTN_Symbol(pRoot)); ctr = ctr + symstkSPrintNextTerm(CTXTc buffer+ctr,FALSE); } else { // printf("nontf\n"); ctr = ctr + sprintTrieSymbol(buffer+ctr,BTN_Symbol(pRoot)); ctr = ctr + sprintf(buffer+ctr, "("); ctr = ctr + symstkSPrintNextTerm(CTXTc buffer+ctr,FALSE); while ( ! SymbolStack_IsEmpty ) { ctr = ctr + sprintf(buffer+ctr, ","); ctr = ctr + symstkSPrintNextTerm(CTXTc buffer+ctr,FALSE); } ctr = ctr + sprintf(buffer+ctr, ")"); } return ctr; }
NodeStats subgoal_statistics(CTXTdeclc Structure_Manager *sm) { NodeStats sg_stats; TIFptr tif; int nSubgoals; VariantSF pProdSF; SubConsSF pConsSF; sg_stats = node_statistics(sm); nSubgoals = 0; SYS_MUTEX_LOCK( MUTEX_TABLE ); if ( sm == &smVarSF ) { for ( tif = tif_list.first; IsNonNULL(tif); tif = TIF_NextTIF(tif) ) if ( IsVariantPredicate(tif) ) for ( pProdSF = TIF_Subgoals(tif); IsNonNULL(pProdSF); pProdSF = (VariantSF)subg_next_subgoal(pProdSF) ) nSubgoals++; } /* No shared smProdSF or smConsSF in MT engine */ else if ( sm == &smProdSF ) { for ( tif = tif_list.first; IsNonNULL(tif); tif = TIF_NextTIF(tif) ) if ( IsSubsumptivePredicate(tif) ) for ( pProdSF = TIF_Subgoals(tif); IsNonNULL(pProdSF); pProdSF = (VariantSF)subg_next_subgoal(pProdSF) ) nSubgoals++; } else if ( sm == &smConsSF ) { for ( tif = tif_list.first; IsNonNULL(tif); tif = TIF_NextTIF(tif) ) if ( IsSubsumptivePredicate(tif) ) for ( pProdSF = TIF_Subgoals(tif); IsNonNULL(pProdSF); pProdSF = (VariantSF)subg_next_subgoal(pProdSF) ) for ( pConsSF = subg_consumers(pProdSF); IsNonNULL(pConsSF); pConsSF = conssf_consumers(pConsSF) ) nSubgoals++; } else { SYS_MUTEX_UNLOCK( MUTEX_TABLE ); xsb_dbgmsg((LOG_DEBUG, "Incorrect use of subgoal_statistics()\n" "SM does not contain subgoal frames")); return sg_stats; } SYS_MUTEX_UNLOCK( MUTEX_TABLE ); if ( NodeStats_NumUsedNodes(sg_stats) != (counter) nSubgoals ) xsb_warn(CTXTc "Inconsistent Subgoal Frame Usage Calculations:\n" "\tSubgoal Frame count mismatch"); return sg_stats; }
void printTriePath(FILE *fp, BTNptr pLeaf, xsbBool printLeafAddr) { BTNptr pRoot; if ( IsNULL(pLeaf) ) { fprintf(fp, "NULL"); return; } if ( ! IsLeafNode(pLeaf) ) { fprintf(fp, "printTriePath() called with non-Leaf node!\n"); printTrieNode(fp, pLeaf); return; } if ( printLeafAddr ) fprintf(fp, "Leaf %p: ", pLeaf); if ( IsEscapeNode(pLeaf) ) { pRoot = BTN_Parent(pLeaf); if ( IsNonNULL(pRoot) ) printTrieSymbol(fp, BTN_Symbol(pRoot)); else fprintf(fp, "ESCAPE node"); return; } SymbolStack_ResetTOS; SymbolStack_PushPathRoot(pLeaf,pRoot); if ( IsTrieFunctor(BTN_Symbol(pRoot)) ) { SymbolStack_Push(BTN_Symbol(pRoot)); symstkPrintNextTerm(fp,FALSE); } else { printTrieSymbol(fp,BTN_Symbol(pRoot)); fprintf(fp, "("); symstkPrintNextTerm(fp,FALSE); while ( ! SymbolStack_IsEmpty ) { fprintf(fp, ","); symstkPrintNextTerm(fp,FALSE); } fprintf(fp, ")"); } }
xsbBool smIsAllocatedStruct(Structure_Manager smRecord, void *pStruct) { void *freeStruct; /* Determine whether struct lies w/i unallocated section of 1st block ------------------------------------------------------------------ */ if ( (SM_NextStruct(smRecord) <= pStruct) && (pStruct <= SM_LastStruct(smRecord)) ) return FALSE; /* Determine whether struct is on the free list -------------------------------------------- */ for ( freeStruct = SM_FreeList(smRecord); IsNonNULL(freeStruct); freeStruct = SMFL_NextFreeStruct(freeStruct) ) if ( freeStruct == pStruct ) return FALSE; return TRUE; }
void unmark(callnodeptr c){ callnodeptr c1; calllistptr in=c->inedges; #ifdef INCR_DEBUG1 printf("unmarking ");printcall(c);printf("\n"); #endif c->deleted=0; while(IsNonNULL(in)){ c1=in->inedge_node->callnode; c1->outcount++; if(c1->deleted) unmark(c1); in=in->next; } return; }
/* propagate_no_change(c) for c->c' if(c'.deleted=false) c'->falsecount>0 c'->falsecount-- if(c'->falsecount==0) propagate_no_change(c') When invalidation is done a parameter 'falsecount' is maintained with each call which signifies that these many predecessor calls have been affected. So if a call A has two pred node B and C and both of them are affected then A's falsecount is 2. Now when B is reevaluated and turns out it has not been changed (its old and new answer table is the same) completion of B calls propagate_no_change(B) which reduces the falsecount of A by 1. If for example turns out that C was also not changed the falsecount of A is going to be reduced to 0. Now when call A is executed it's just going to do answer clause resolution. */ void propagate_no_change(callnodeptr c){ callnodeptr cn; struct hashtable *h; struct hashtable_itr *itr; if(IsNonNULL(c)){ h=c->outedges->hasht; itr = hashtable1_iterator(h); if (hashtable1_count(h) > 0){ do { cn= hashtable1_iterator_value(itr); if(cn->falsecount>0){ /* this check is required for the new dependencies that can arise bcoz of the re-evaluation */ cn->falsecount--; if(cn->falsecount==0){ cn->deleted = 0; propagate_no_change(cn); } } } while (hashtable1_iterator_advance(itr)); } } }
void smPrint(Structure_Manager smRecord, char *string) { void *pBlock; counter nBlocks; nBlocks = 0; for ( pBlock = SM_CurBlock(smRecord); IsNonNULL(pBlock); pBlock = SMBlk_NextBlock(pBlock) ) nBlocks++; fprintf(stddbg, " Structure Manager for %s (%s)\n" "\tCurBlock: %p\t\tTotal Blocks: %u\n" "\tNextStr: %p\t\tFree List: %p\n" "\tLastStr: %p\t\tAlloc List: %p\n" "\tStructs per block: %u\t\tStruct size: %u bytes\n", SM_StructName(smRecord), string, SM_CurBlock(smRecord), nBlocks, SM_NextStruct(smRecord), SM_FreeList(smRecord), SM_LastStruct(smRecord), SM_AllocList(smRecord), SM_StructsPerBlock(smRecord), SM_StructSize(smRecord)); }
void deallocate_previous_call(callnodeptr callnode){ calllistptr tmpin,in; KEY *ownkey; /* callnodeptr inedge_node; */ struct hashtable* hasht; SM_AllocateStruct(smKey, ownkey); ownkey->goal=callnode->id; in = callnode->inedges; call_node_count_gl--; while(IsNonNULL(in)){ tmpin = in->next; hasht = in->inedge_node->hasht; if (remove_some(hasht,ownkey) == NULL) { /* prevnode=in->prevnode->callnode; if(IsNonNULL(prevnode->goal)){ sfPrintGoal(stdout,(VariantSF)prevnode->goal,NO); printf("(%d)",prevnode->id); } if(IsNonNULL(callnode->goal)){ sfPrintGoal(stdout,(VariantSF)callnode->goal,NO); printf("(%d)",callnode->id); } */ xsb_abort("BUG: key not found for removal\n"); } in->inedge_node->callnode->outcount--; call_edge_count_gl--; SM_DeallocateStruct(smCallList, in); in = tmpin; } SM_DeallocateStruct(smCallNode, callnode); SM_DeallocateStruct(smKey, ownkey); }
void deleteinedges(callnodeptr callnode){ calllistptr tmpin,in; KEY *ownkey; struct hashtable* hasht; SM_AllocateStruct(smKey, ownkey); ownkey->goal=callnode->id; in = callnode->inedges; while(IsNonNULL(in)){ tmpin = in->next; hasht = in->inedge_node->hasht; // printf("remove some callnode %x / ownkey %d\n",callnode,ownkey); if (remove_some(hasht,ownkey) == NULL) { xsb_abort("BUG: key not found for removal\n"); } call_edge_count_gl--; SM_DeallocateStruct(smCallList, in); in = tmpin; } SM_DeallocateStruct(smKey, ownkey); return; }
int immediate_outedges_list(CTXTdeclc callnodeptr call1){ VariantSF subgoal; TIFptr tif; int j, count = 0,arity; Psc psc; CPtr oldhreg = NULL; struct hashtable *h; struct hashtable_itr *itr; callnodeptr cn; reg[4] = makelist(hreg); new_heap_free(hreg); new_heap_free(hreg); if(IsNonNULL(call1)){ /* This can be called from some non incremental predicate */ h=call1->outedges->hasht; itr = hashtable1_iterator(h); if (hashtable1_count(h) > 0){ do { cn = hashtable1_iterator_value(itr); if(IsNonNULL(cn->goal)){ count++; subgoal = (VariantSF) cn->goal; tif = (TIFptr) subgoal->tif_ptr; psc = TIF_PSC(tif); arity = get_arity(psc); check_glstack_overflow(4,pcreg,2+arity*200); // don't know how much for build_subgoal_args... oldhreg=hreg-2; if(arity>0){ sreg = hreg; follow(oldhreg++) = makecs(sreg); hreg += arity + 1; new_heap_functor(sreg, psc); for (j = 1; j <= arity; j++) { new_heap_free(sreg); cell_array1[arity-j] = cell(sreg-1); } build_subgoal_args(subgoal); }else{ follow(oldhreg++) = makestring(get_name(psc)); } follow(oldhreg) = makelist(hreg); new_heap_free(hreg); new_heap_free(hreg); } } while (hashtable1_iterator_advance(itr)); } if (count>0) follow(oldhreg) = makenil; else reg[4] = makenil; }else{ xsb_warn("Called with non-incremental predicate\n"); reg[4] = makenil; } // printterm(stdout,call_list,100); return unify(CTXTc reg_term(CTXTc 3),reg_term(CTXTc 4)); }