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))));
  }
}
/* 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;
}
/* reg 1: tag for this call
   reg 2: filter list of goals to keep (keep all if [])
   reg 3: returned list of changed goals
   reg 4: used as temp (in case of heap expansion)
 */
int create_changed_call_list(CTXTdecl){
  callnodeptr call1;
  VariantSF subgoal;
  TIFptr tif;
  int j, count = 0,arity;
  Psc psc;
  CPtr oldhreg = NULL;

  reg[4] = makelist(hreg);
  new_heap_free(hreg);   // make heap consistent
  new_heap_free(hreg);
  while ((call1 = delete_calllist_elt(&changed_gl)) != EMPTY){
    subgoal = (VariantSF) call1->goal;      
    tif = (TIFptr) subgoal->tif_ptr;
    psc = TIF_PSC(tif);
    if (in_reg2_list(CTXTc psc)) {
      count++;
      arity = get_arity(psc);
      check_glstack_overflow(4,pcreg,2+arity*200); // guess 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);   // make heap consistent
      new_heap_free(hreg);
    }
  }
  if (count>0)
    follow(oldhreg) = makenil;
  else
    reg[4] = makenil;
    
 
  return unify(CTXTc reg_term(CTXTc 3),reg_term(CTXTc 4));

  /*
    int i;
    for(i=0; i<callqptr; i++){
      if(IsNonNULL(callq[i]) && (callq[i]->deleted==1)){
    sfPrintGoal(stdout,(VariantSF)callq[i]->goal,NO);
    printf(" %d %d\n",callq[i]->falsecount,callq[i]->deleted);
    }
    }
  printf("-----------------------------\n");
  */
}
/*
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));
}
コード例 #5
0
ファイル: tst_utils.c プロジェクト: eden/navajoverb
void printTabledCall(FILE *fp, TabledCallInfo callInfo) {

  int arity, i;
  Psc pPSC;
  
  pPSC = TIF_PSC(CallInfo_TableInfo(callInfo));
  fprintf(fp, "%s(", get_name(pPSC));
  arity = CallInfo_CallArity(callInfo);
  for (i = 0; i < arity; i++) {
    printterm( fp, (Cell)(CallInfo_Arguments(callInfo)+i), 25 );
    if (i+1 < arity)
      fprintf(fp, ",");
  }
  fprintf(fp, ")");
}
int return_scc_list(CTXTdeclc SCCNode * nodes, int num_nodes){
 
  VariantSF subgoal;
  TIFptr tif;

  int cur_node = 0,arity, j;
  Psc psc;
  CPtr oldhreg = NULL;

  reg[4] = makelist(hreg);
  new_heap_free(hreg);  new_heap_free(hreg);
  do {
    subgoal = (VariantSF) nodes[cur_node].node;
    tif = (TIFptr) subgoal->tif_ptr;
    psc = TIF_PSC(tif);
    arity = get_arity(psc);
    //    printf("subgoal %p, %s/%d\n",subgoal,get_name(psc),arity);
    check_glstack_overflow(4,pcreg,2+arity*200); // don't know how much for build_subgoal_args..
    oldhreg=hreg-2;                          // ptr to car
    if(arity>0){
      sreg = hreg;
      follow(oldhreg++) = makecs(sreg);      
      new_heap_functor(sreg,get_ret_psc(2)); //  car pts to ret/2  psc
      hreg += 3;                             //  hreg pts past ret/2
      sreg = hreg;
      follow(hreg-1) = makeint(nodes[cur_node].component);  // arg 2 of ret/2 pts to component
      follow(hreg-2) = makecs(sreg);         
      new_heap_functor(sreg, psc);           //  arg 1 of ret/2 pts to goal psc
      hreg += arity + 1;
      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);        // cdr points to next car
    new_heap_free(hreg); new_heap_free(hreg);
    cur_node++;
  } while (cur_node  < num_nodes);
  follow(oldhreg) = makenil;                // cdr points to next car
  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));
}
int create_lazy_call_list(CTXTdeclc  callnodeptr call1){
  VariantSF subgoal;
  TIFptr tif;
  int j,count=0,arity; 
  Psc psc;
  CPtr oldhreg=NULL;

  //  print_call_list(lazy_affected);

  reg[6] = reg[5] = makelist(hreg);  // reg 5 first not-used, use regs in case of stack expanson
  new_heap_free(hreg);   // make heap consistent
  new_heap_free(hreg);
  while((call1 = delete_calllist_elt(&lazy_affected)) != EMPTY){
    subgoal = (VariantSF) call1->goal;      
    //    fprintf(stddbg,"  considering ");print_subgoal(stdout,subgoal);printf("\n");
    if(IsNULL(subgoal)){ /* fact predicates */
      call1->deleted = 0; 
      continue;
    }
    if (subg_visitors(subgoal)) {
      sprint_subgoal(CTXTc forest_log_buffer_1,0,subgoal);
      #ifdef ISO_INCR_TABLING
      find_the_visitors(CTXTc subgoal);
      #else
      #ifdef WARN_ON_UNSAFE_UPDATE
            xsb_warn("%d Choice point(s) exist to the table for %s -- cannot incrementally update (create_lazy_call_list)\n",
      	       subg_visitors(subgoal),forest_log_buffer_1->fl_buffer);
      #else
            xsb_abort("%d Choice point(s) exist to the table for %s -- cannot incrementally update (create_lazy_call_list)\n",
      	       subg_visitors(subgoal),forest_log_buffer_1->fl_buffer);
      #endif
      #endif
      continue;
    }
    //    fprintf(stddbg,"adding dependency for ");print_subgoal(stdout,subgoal);printf("\n");

    count++;
    tif = (TIFptr) subgoal->tif_ptr;
    //    if (!(psc = TIF_PSC(tif)))
    //	xsb_table_error(CTXTc "Cannot access dynamic incremental table\n");	
    psc = TIF_PSC(tif);
    arity = get_arity(psc);
    check_glstack_overflow(6,pcreg,2+arity*200); // don't know how much for build_subgoal_args...
    oldhreg = clref_val(reg[6]);  // maybe updated by re-alloc
    if(arity>0){
      sreg = hreg;
      follow(oldhreg++) = makecs(sreg);
      hreg += arity + 1;  // had 10, why 10?  why not 3? 2 for list, 1 for functor (dsw)
      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));
    }
    reg[6] = follow(oldhreg) = makelist(hreg);
    new_heap_free(hreg);
    new_heap_free(hreg);
  }
  if(count > 0) {
    follow(oldhreg) = makenil;
    hreg -= 2;  /* take back the extra words allocated... */
  } else
    reg[5] = makenil;
    
  return unify(CTXTc reg_term(CTXTc 4),reg_term(CTXTc 5));

  /*int i;
    for(i=0;i<callqptr;i++){
      if(IsNonNULL(callq[i]) && (callq[i]->deleted==1)){
    sfPrintGoal(stdout,(VariantSF)callq[i]->goal,NO);
    printf(" %d %d\n",callq[i]->falsecount,callq[i]->deleted);
    }
    }
  printf("-----------------------------\n");   */
}