/******************************************************************************************* Copyright (C) 2004,2005,2006,2007,2008 (Nuno A. Fonseca) 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 #include #include "range_list.h" #include #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); }