RL-Trees module.
git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@2169 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
446
library/rltree/yap_rl.c
Normal file
446
library/rltree/yap_rl.c
Normal file
@@ -0,0 +1,446 @@
|
||||
/*******************************************************************************************
|
||||
|
||||
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),t2=YAP_Deref(YAP_ARG2),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_Deref(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);
|
||||
}
|
||||
/*
|
||||
*
|
||||
*
|
||||
*/
|
||||
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);
|
||||
}
|
||||
/*
|
||||
*
|
||||
*
|
||||
*/
|
||||
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);
|
||||
YAP_Term t2=YAP_Deref(YAP_ARG2);
|
||||
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(){
|
||||
|
||||
|
||||
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);
|
||||
}
|
Reference in New Issue
Block a user