- fix quoted characters output - fix line position in read_term and friends - make messages look a bit better - CLP(BN) EM improvements.
		
			
				
	
	
		
			450 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			450 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*******************************************************************************************
 | |
| 
 | |
| Copyright (C) 2004,2005,2006,2007,2008 (Nuno A. Fonseca) <nuno.fonseca@gmail.com>
 | |
| 
 | |
| This program is free software; you can redistribute it and/or 
 | |
| modify it under the terms of the GNU General Public License 
 | |
| as published by the Free Software Foundation; either 
 | |
| version 2 of the License, or (at your option) any later 
 | |
| version.
 | |
| 
 | |
| This program is distributed in the hope that it will be useful,
 | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| GNU General Public License for more details.
 | |
| 
 | |
| You should have received a copy of the GNU General Public License
 | |
| along with this program; if not, write to the Free Software
 | |
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | |
| 
 | |
| 
 | |
| Last rev: $Id: yap_rl.c,v 1.1 2008-03-26 23:05:22 nunofonseca Exp $
 | |
| **************************************************************************/
 | |
| 
 | |
| #include <time.h>
 | |
| #include <stdio.h>
 | |
| 
 | |
| #include "range_list.h"
 | |
| #include <YapInterface.h>
 | |
| 
 | |
| #define  IDTYPE long
 | |
| #define  PTR2ID(ptr) (IDTYPE)ptr
 | |
| #define  ID2PTR(id)  (RL_Tree*)id
 | |
| 
 | |
| 
 | |
| /* ############################################################ */
 | |
| unsigned long int memory_usage=0;
 | |
| unsigned long int tree_mem=0;
 | |
| 
 | |
| #define STORE_TREE_SIZE(tree) tree_mem=tree->mem_alloc
 | |
| #define UPDATE_MEM_USAGE(tree) memory_usage+=(tree->mem_alloc>0?tree->mem_alloc-tree_mem:0)
 | |
| #define FREE_MEM_USAGE(tree) (memory_usage-=tree->mem_alloc)
 | |
| #define ADD_MEM_USAGE(tree) (memory_usage+=tree->mem_alloc)
 | |
| 
 | |
| /*
 | |
|  */
 | |
| static
 | |
| int 
 | |
| p_rl_new(void) {
 | |
|   YAP_Term t1=YAP_Deref(YAP_ARG1);
 | |
|   YAP_Term t2=YAP_Deref(YAP_ARG2);
 | |
|   RL_Tree* new_tree;
 | |
|   IDTYPE  newid;
 | |
| 
 | |
|   // Check args
 | |
|   if (!YAP_IsIntTerm(t1) || !YAP_IsVarTerm(t2)) {
 | |
|     fprintf(stderr,"Error in rl_new arguments\n");
 | |
|     return(FALSE);
 | |
|   }
 | |
|   //
 | |
|   new_tree=new_rl(YAP_IntOfTerm(t1));
 | |
|   if(new_tree==NULL) {
 | |
|     fprintf(stderr,"Error creating new rl.");
 | |
|     return (FALSE);
 | |
|   }
 | |
|   //printf("New rl %d %p--%u\n",PTR2ID(new_tree),new_tree,(int)new_tree,YAP_IntOfTerm(t1));
 | |
|   // return reference
 | |
|   newid=YAP_MkIntTerm(PTR2ID(new_tree));
 | |
|   if(!YAP_Unify(YAP_Deref(YAP_ARG2),newid)) 
 | |
|     return (FALSE);
 | |
|   
 | |
|   return(TRUE);
 | |
| }
 | |
| /*
 | |
|  *
 | |
|  *
 | |
|  */
 | |
| static
 | |
| int 
 | |
| p_rl_copy(void) {
 | |
|   YAP_Term t1=YAP_Deref(YAP_ARG1); // src
 | |
|   YAP_Term t2=YAP_Deref(YAP_ARG2); // dest
 | |
|   RL_Tree* new_tree;
 | |
|   IDTYPE  id1,newid;
 | |
|   RL_Tree* tree;
 | |
| 
 | |
|   // Check args
 | |
|   if (!YAP_IsIntTerm(t1))
 | |
|     return(FALSE);
 | |
|   if (!YAP_IsVarTerm(t2)) 
 | |
|     return(FALSE);
 | |
|   //
 | |
|   id1=YAP_IntOfTerm(t1);
 | |
|   tree=ID2PTR(id1);
 | |
|   new_tree=copy_rl(tree);
 | |
| 
 | |
|   if(new_tree==NULL) {
 | |
|     fprintf(stderr,"Error creating new rl.");
 | |
|     return (FALSE);
 | |
|   }
 | |
|   //
 | |
| #ifdef STATS
 | |
|   ADD_MEM_USAGE(new_tree);
 | |
| #endif
 | |
| 
 | |
|   // return list reference
 | |
|   newid=YAP_MkIntTerm(PTR2ID(new_tree));
 | |
|   if(!YAP_Unify(YAP_Deref(YAP_ARG2),newid)) 
 | |
|     return (FALSE);  
 | |
|   return(TRUE);
 | |
| }
 | |
| /*
 | |
|  *
 | |
|  *
 | |
|  */
 | |
| static
 | |
| int 
 | |
| p_rl_size(void) {
 | |
| 
 | |
|   YAP_Term t1=YAP_Deref(YAP_ARG1),t_size;
 | |
|   IDTYPE id;
 | |
|   RL_Tree* tree;
 | |
|   unsigned int size;
 | |
| 
 | |
|   if (YAP_IsVarTerm(t1))
 | |
|     return(FALSE);
 | |
| 
 | |
|   id = YAP_IntOfTerm(t1);
 | |
|   tree=ID2PTR(id);
 | |
|   
 | |
|   size=tree->size*sizeof(RL_Node)+sizeof(RL_Tree);
 | |
|   t_size=YAP_MkIntTerm(size);
 | |
|   if(!YAP_Unify(YAP_ARG2,t_size) )   
 | |
|     return (FALSE);
 | |
|   
 | |
|   return(TRUE);
 | |
| }
 | |
| /*
 | |
|  *
 | |
|  *
 | |
|  */
 | |
| static
 | |
| int 
 | |
| p_rl_mem_usage(void) {
 | |
| 
 | |
|   YAP_Term t1=YAP_Deref(YAP_ARG1);
 | |
| 
 | |
|   if(!YAP_Unify(t1,YAP_MkIntTerm(memory_usage)) )   
 | |
|     return (FALSE);
 | |
|   
 | |
|   return(TRUE);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  */
 | |
| static
 | |
| int 
 | |
| p_rl_free(void) {
 | |
| 
 | |
|   YAP_Term t1=YAP_Deref(YAP_ARG1);
 | |
|   IDTYPE id;
 | |
|   RL_Tree* tree;
 | |
|   
 | |
|   // Check args
 | |
|   if (YAP_IsVarTerm(t1)) 
 | |
|     return(FALSE);
 | |
| 
 | |
|   id=YAP_IntOfTerm(t1);
 | |
|   tree=ID2PTR(id);
 | |
| #ifdef STATS  
 | |
|   FREE_MEM_USAGE(tree);
 | |
| #endif
 | |
| 
 | |
|   free_rl(tree);
 | |
| 
 | |
|   return (TRUE);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  *
 | |
|  *
 | |
|  */
 | |
| static
 | |
| int 
 | |
| p_rl_set_in(void) {
 | |
| 
 | |
|   YAP_Term t1=YAP_Deref(YAP_ARG1);
 | |
|   YAP_Term t2=YAP_Deref(YAP_ARG2);
 | |
|   IDTYPE id;
 | |
|   NUM val;
 | |
|   RL_Tree *tree;
 | |
| 
 | |
|   // Check args
 | |
|   if (YAP_IsVarTerm(t1) || YAP_IsVarTerm(t2) )
 | |
|     return(FALSE);
 | |
| 
 | |
|   id = YAP_IntOfTerm(t1);
 | |
|   val = YAP_IntOfTerm(t2);
 | |
| 
 | |
|   tree=ID2PTR(id);
 | |
| 
 | |
| #ifdef STATS
 | |
|   STORE_TREE_SIZE(tree);
 | |
|   set_in_rl(tree,val,IN);
 | |
|   UPDATE_MEM_USAGE(tree);
 | |
| #else
 | |
|   set_in_rl(tree,val,IN);
 | |
| #endif
 | |
|   return (TRUE);
 | |
| }
 | |
| 
 | |
| #ifdef UNUSED
 | |
|  /*
 | |
|  *
 | |
|  *
 | |
|  */
 | |
| static
 | |
| int 
 | |
| p_rl_in(void) {
 | |
| 
 | |
|   YAP_Term t1=YAP_Deref(YAP_ARG1);
 | |
|   YAP_Term t2=YAP_Deref(YAP_ARG2);
 | |
|   IDTYPE id;
 | |
|   NUM val;
 | |
|   RL_Tree *tree;
 | |
| 
 | |
|   // Check args
 | |
|   if (YAP_IsVarTerm(t1) || YAP_IsVarTerm(t2) )
 | |
|     return(FALSE);
 | |
| 
 | |
|   id = YAP_IntOfTerm(t1);
 | |
|   val = YAP_IntOfTerm(t2);
 | |
| 
 | |
|   tree=ID2PTR(id);
 | |
| 
 | |
|   if ( in_rl(tree,val) ) 
 | |
|     return (TRUE);
 | |
|   return (FALSE);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|  *
 | |
|  *
 | |
|  */
 | |
| static
 | |
| int 
 | |
| p_rl_set_out(void) {
 | |
| 
 | |
|   YAP_Term t1=YAP_Deref(YAP_ARG1);
 | |
|   YAP_Term t2=YAP_Deref(YAP_ARG2);
 | |
|   IDTYPE id;
 | |
|   NUM val;
 | |
|   RL_Tree *tree;
 | |
| 
 | |
|   // Check args
 | |
|   if (YAP_IsVarTerm(t1) || YAP_IsVarTerm(t2) )
 | |
|     return(FALSE);
 | |
| 
 | |
|   id = YAP_IntOfTerm(t1);
 | |
|   val = YAP_IntOfTerm(t2);
 | |
| 
 | |
|   tree=ID2PTR(id);
 | |
| #ifdef STATS
 | |
|   STORE_TREE_SIZE(tree);
 | |
|   set_in_rl(tree,val,OUT);
 | |
|   UPDATE_MEM_USAGE(tree);
 | |
| #else
 | |
|   set_in_rl(tree,val,OUT);
 | |
| #endif
 | |
|   return (TRUE);
 | |
| }
 | |
| /*
 | |
|  *
 | |
|  *
 | |
|  */
 | |
| static
 | |
| int 
 | |
| p_rl_freeze(void) {
 | |
| 
 | |
|   YAP_Term t1=YAP_Deref(YAP_ARG1);
 | |
|   IDTYPE id;
 | |
|   RL_Tree *tree;
 | |
| 
 | |
|   // Check args
 | |
|   if (YAP_IsVarTerm(t1) )
 | |
|     return(FALSE);
 | |
| 
 | |
|   id = YAP_IntOfTerm(t1);
 | |
|   tree=ID2PTR(id);
 | |
|   
 | |
| 
 | |
| #ifdef STATS
 | |
|   STORE_TREE_SIZE(tree);
 | |
|   freeze_rl(tree);
 | |
|   UPDATE_MEM_USAGE(tree);
 | |
| #else
 | |
|   freeze_rl(tree);
 | |
| #endif
 | |
| 
 | |
|   return (TRUE);
 | |
| }
 | |
| /*
 | |
|  *
 | |
|  *
 | |
|  */
 | |
| static
 | |
| int 
 | |
| p_rl_set_all_in(void) {
 | |
| 
 | |
|   YAP_Term t1=YAP_Deref(YAP_ARG1);
 | |
|   IDTYPE id;
 | |
|   RL_Tree *tree;
 | |
| 
 | |
|   // Check args
 | |
|   if (YAP_IsVarTerm(t1) )
 | |
|     return(FALSE);
 | |
| 
 | |
|   id = YAP_IntOfTerm(t1);
 | |
|   tree=ID2PTR(id);
 | |
|   
 | |
|   
 | |
| #ifdef STATS
 | |
|   STORE_TREE_SIZE(tree);
 | |
|   rl_all(tree,IN);
 | |
|   freeze_rl(tree);
 | |
|   UPDATE_MEM_USAGE(tree);
 | |
| #else
 | |
|   rl_all(tree,IN);
 | |
|   freeze_rl(tree);
 | |
| #endif
 | |
| 
 | |
|   return (TRUE);
 | |
| }
 | |
| /*
 | |
|  *
 | |
|  *
 | |
|  */
 | |
| static
 | |
| int 
 | |
| p_rl_print(void) {
 | |
| 
 | |
|   YAP_Term t1=YAP_Deref(YAP_ARG1);
 | |
|   IDTYPE id;
 | |
|   RL_Tree *tree;
 | |
| 
 | |
|   // Check args
 | |
|   if (YAP_IsVarTerm(t1) ) {
 | |
|     fprintf(stderr,"Error printing tree..");
 | |
|     return(FALSE);
 | |
|   }
 | |
|   id = YAP_IntOfTerm(t1);
 | |
|   tree=ID2PTR(id);
 | |
|   
 | |
|   display_tree(tree);
 | |
|   
 | |
|   return (TRUE);
 | |
| }
 | |
| 
 | |
| 
 | |
| /* ==============================================================================
 | |
|  *
 | |
|  *
 | |
|  */
 | |
| typedef struct {
 | |
|     YAP_Term last_solution;  /* the last solution */
 | |
| } yap_back_data_type;
 | |
| 
 | |
| yap_back_data_type *back_data;
 | |
| 
 | |
| /*
 | |
|  *
 | |
|  *
 | |
|  */
 | |
| static
 | |
| int 
 | |
| p_rl_b_in2(void) {
 | |
| 
 | |
|   YAP_Term t1=YAP_Deref(YAP_ARG1);
 | |
|   IDTYPE id;
 | |
|   NUM val;
 | |
|   RL_Tree *tree;
 | |
| 
 | |
|   YAP_PRESERVED_DATA(back_data,yap_back_data_type);
 | |
|   id = YAP_IntOfTerm(t1);
 | |
|   tree=ID2PTR(id);
 | |
|   val=YAP_IntOfTerm(back_data->last_solution);
 | |
|   val=rl_next_in_bigger(tree,val);
 | |
|   if ( val > 0 && YAP_Unify(YAP_Deref(YAP_ARG2),YAP_MkIntTerm(val))) {
 | |
|     back_data->last_solution=YAP_MkIntTerm(val);
 | |
|     return TRUE;
 | |
|   }
 | |
|   YAP_cut_fail();
 | |
|   return (FALSE); 
 | |
| }
 | |
| static
 | |
| int 
 | |
| p_rl_b_in1(void) {
 | |
| 
 | |
|   YAP_Term t1=YAP_Deref(YAP_ARG1);
 | |
|   YAP_Term t2=YAP_Deref(YAP_ARG2);
 | |
|   IDTYPE id;
 | |
|   NUM val;
 | |
|   RL_Tree *tree;
 | |
| 
 | |
|   // Check args
 | |
|   if (!YAP_IsIntTerm(t1)) {
 | |
|     YAP_cut_fail();
 | |
|     return(FALSE);
 | |
|   }
 | |
|   if ( YAP_IsVarTerm(t2) ) {
 | |
|     // return all in through backtracking
 | |
|     YAP_PRESERVE_DATA(back_data,yap_back_data_type);
 | |
|     back_data->last_solution = YAP_MkIntTerm(0);
 | |
|     return p_rl_b_in2();
 | |
|   } else {
 | |
|     id = YAP_IntOfTerm(t1);
 | |
|     tree=ID2PTR(id);
 | |
|     val = YAP_IntOfTerm(t2);
 | |
|     if ( in_rl(tree,val) ) {
 | |
|       YAP_cut_succeed();
 | |
|       return (TRUE);
 | |
|     }
 | |
|     YAP_cut_fail();
 | |
|     return (FALSE);
 | |
|   }
 | |
| }
 | |
| /* ******************************************************* */
 | |
| void init_rl(void){
 | |
| 
 | |
|      
 | |
|  YAP_UserCPredicate("rl_new", p_rl_new,2);        //  Maximum -> RangeID
 | |
|  YAP_UserCPredicate("rl_free", p_rl_free,1);      //  RangeId ->
 | |
|  YAP_UserCPredicate("rl_size", p_rl_size,2);      //  RangeId -> Size (in bytes)
 | |
|  YAP_UserCPredicate("rl_mem", p_rl_mem_usage,1);  //  -> TotalMemory (in bytes)
 | |
| 
 | |
|  YAP_UserCPredicate("rl_copy", p_rl_copy,2);      //  RangeId  -> NewRangeId
 | |
|  YAP_UserCPredicate("rl_set_out", p_rl_set_out,2);//  RangeId x Number  ->
 | |
|  YAP_UserBackCPredicate("rl_in", p_rl_b_in1,p_rl_b_in2,2,sizeof(yap_back_data_type));   //  +RangeId x ?Number 
 | |
|  //YAP_UserCPredicate("rl_in", p_rl_in,2);        //  RangeId x Number  ->
 | |
|  YAP_UserCPredicate("rl_set_in", p_rl_set_in,2);  //  RangeIdxNumber  -> 
 | |
|  YAP_UserCPredicate("rl_set_all_in", p_rl_set_all_in,1); //  RangeId -> 
 | |
| 
 | |
|  YAP_UserCPredicate("rl_print", p_rl_print,1);    //  RangeId ->
 | |
| 
 | |
|  YAP_UserCPredicate("rl_freeze", p_rl_freeze,1);  //  RangeId
 | |
|  
 | |
|  // fprintf(stderr,"Range list  module succesfully loaded.");
 | |
|  //fflush(stderr);
 | |
| }
 |