int get_outedges_num(CTXTdeclc callnodeptr call1) { struct hashtable *h; struct hashtable_itr *itr; h=call1->outedges->hasht; itr = hashtable1_iterator(h); return hashtable1_count(h); }
int get_outedges_num(CTXTdeclc callnodeptr call1) { struct hashtable *h; struct hashtable_itr *itr; h=call1->outedges->hasht; itr = hashtable1_iterator(h); SQUASH_LINUX_COMPILER_WARN(itr) ; return hashtable1_count(h); }
void xsb_compute_scc(SCCNode * nodes,int * dfn_stack,int node_from, int * dfn_top, struct hashtable* hasht,int * dfn,int * component ) { struct hashtable_itr *itr; struct hashtable* edges_hash; CPtr sf; Integer node_to; int j; // printf("xsb_compute_scc for %d %p %s/%d dfn %d dfn_top %d\n", // node_from,nodes[node_from].node, // get_name(TIF_PSC(subg_tif_ptr(nodes[node_from].node))), // get_arity(TIF_PSC(subg_tif_ptr(nodes[node_from].node))),*dfn,*dfn_top); nodes[node_from].low = nodes[node_from].dfn = (*dfn)++; dfn_stack[*dfn_top] = node_from; nodes[node_from].stack = *dfn_top; (*dfn_top)++; edges_hash = subg_callnode_ptr(nodes[node_from].node)->outedges->hasht; itr = hashtable1_iterator(edges_hash); if (hashtable1_count(edges_hash) > 0) { // printf("found %d edges\n",hashtable1_count(edges_hash)); do { sf = ((callnodeptr) hashtable1_iterator_value(itr))-> goal; node_to = (Integer) search_some(hasht, (void *)sf); // printf("edge from %p to %p (%d)\n",(void *)nodes[node_from].node,sf,node_to); if (nodes[node_to].dfn == 0) { xsb_compute_scc(nodes,dfn_stack,(int)node_to, dfn_top,hasht,dfn,component ); if (nodes[node_to].low < nodes[node_from].low) nodes[node_from].low = nodes[node_to].low; } else if (nodes[node_to].dfn < nodes[node_from].dfn && nodes[node_to].component == 0) { if (nodes[node_to].low < nodes[node_from].low) { nodes[node_from].low = nodes[node_to].low; } } } while (hashtable1_iterator_advance(itr)); // printf("nodes[%d] low %d dfn %d\n",node_from,nodes[node_from].low, nodes[node_from].dfn); if (nodes[node_from].low == nodes[node_from].dfn) { for (j = (*dfn_top)-1 ; j >= nodes[node_from].stack ; j--) { // printf(" pop %d and assign %d\n",j,*component); nodes[dfn_stack[j]].component = *component; } (*component)++; *dfn_top = j+1; } } else nodes[node_from].component = (*component)++; }
/* 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)); } } }
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)); }
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)); }
void dfs_outedges(CTXTdeclc callnodeptr call1){ callnodeptr cn; struct hashtable *h; struct hashtable_itr *itr; int ctr = 0; int incr_callgraph_dfs_top = -1; int incr_callgraph_dfs_size; IncrCallgraphDFSFrame *incr_callgraph_dfs; // printf("1) calling dfs %p; subgoal ",call1); print_callnode(stddbg,call1); printf("\n"); incr_callgraph_dfs = (IncrCallgraphDFSFrame *) mem_alloc(10000*sizeof(IncrCallgraphDFSFrame), TABLE_SPACE); incr_callgraph_dfs_size = 10000; dfs_outedges_check_non_completed(CTXTc call1); if (!is_fact_in_callgraph(call1)) call1->deleted = 1; h=call1->outedges->hasht; if (hashtable1_count(h) > 0){ // printf("1-call1: %p \n",call1); push_dfs_frame(call1,0); } while (incr_callgraph_dfs_top > -1) { itr = 0; do { if (incr_callgraph_dfs[incr_callgraph_dfs_top].itr) { itr = incr_callgraph_dfs[incr_callgraph_dfs_top].itr; // printf("1-top %d itr %p\n",incr_callgraph_dfs_top,itr); if (!hashtable1_iterator_advance(itr)) { // last element in the hash itr = 0; cn = incr_callgraph_dfs[incr_callgraph_dfs_top].cn; add_callnode(&affected_gl,cn); // printf("+ adding callnode %p\n",cn); pop_dfs_frame; } } else { h=incr_callgraph_dfs[incr_callgraph_dfs_top].cn->outedges->hasht; if (hashtable1_count(h) > 0) { itr = hashtable1_iterator(h); // initialize incr_callgraph_dfs[incr_callgraph_dfs_top].itr = itr; } else { cn = incr_callgraph_dfs[incr_callgraph_dfs_top].cn; add_callnode(&affected_gl,cn); // printf("+ adding callnode %p\n",cn); pop_dfs_frame; } } } while (itr == 0 && incr_callgraph_dfs_top > -1); if (incr_callgraph_dfs_top > -1) { cn = hashtable1_iterator_value(itr); // printf("top %d cn: %p itr: %p\n",incr_callgraph_dfs_top,cn,itr); // printf("2) recursive dfs %p; subgoal ",cn); print_callnode(stddbg,cn); printf("\n"); cn->falsecount++; if (cn->deleted==0) { dfs_outedges_check_non_completed(CTXTc cn); cn->deleted = 1; // h=cn->outedges->hasht; // if (hashtable1_count(h) > 0) { push_dfs_frame(cn,0); // } } } } mem_dealloc(incr_callgraph_dfs, incr_callgraph_dfs_size*sizeof(IncrCallgraphDFSFrame), TABLE_SPACE); }