removed dependency on array_t

This commit is contained in:
Fabrizio Riguzzi 2010-07-27 16:53:47 +02:00
parent 25d1fac007
commit 5a19dd372a
3 changed files with 123 additions and 72 deletions

View File

@ -10,9 +10,7 @@ for the relative license.
#include "util.h" #include "util.h"
#include "cuddInt.h" #include "cuddInt.h"
#include "array.h"
#include "mtr.h" #include "mtr.h"
#include "avl.h"
#include "YapInterface.h" #include "YapInterface.h"
#include <glib.h> #include <glib.h>
@ -21,16 +19,35 @@ typedef struct
int var,value; int var,value;
} factor; } factor;
typedef struct
{
int nFact;
factor * factors;
} term;
typedef struct
{
int nTerms;
term * terms;
} expr;
typedef struct typedef struct
{ {
int nVal,nBit; int nVal,nBit;
array_t * probabilities; double * probabilities;
array_t * booleanVars; DdNode * * booleanVars;
} variable; } variable;
typedef struct
{
int nVar;
int nBVar;
variable * varar;
int * bVar2mVar;
} variables;
void createVars(array_t * vars, YAP_Term t,DdManager * mgr, array_t * bVar2mVar,int create_dot, char inames[1000][20]); variables createVars(YAP_Term t,DdManager * mgr, int create_dot, char inames[1000][20]);
void createExpression(array_t * expression, YAP_Term t); expr createExpression(YAP_Term t);
void init_my_predicates(void); void init_my_predicates(void);
int compare(char *a, char *b); int compare(char *a, char *b);
gint my_equal(gconstpointer v,gconstpointer v2); gint my_equal(gconstpointer v,gconstpointer v2);
@ -39,11 +56,11 @@ void dealloc(gpointer key,gpointer value,gpointer user_data);
DdNode * retFunction(DdManager * mgr, array_t * expression,array_t * v); DdNode * retFunction(DdManager * mgr, expr expression,variables v);
DdNode * retTerm(DdManager * mgr,array_t *factors,array_t * v); DdNode * retTerm(DdManager * mgr,term t,variables v);
DdNode * retFactor(DdManager * mgr, factor f, array_t * v); DdNode * retFactor(DdManager * mgr, factor f, variables v);
double Prob(DdNode *node, array_t * vars,array_t * bVar2mVar, GHashTable * nodes); double Prob(DdNode *node, variables vars,GHashTable * nodes);
double ProbBool(DdNode *node, int bits, int nBit,int posBVar,variable v, double ProbBool(DdNode *node, int bits, int nBit,int posBVar,variable v,
array_t * vars,array_t * bVar2mVar, GHashTable * nodes); variables vars,GHashTable * nodes);

View File

@ -19,20 +19,20 @@ int correctPosition(int index,variable v, DdNode * node,int posBVar);
DdNode * retFunction(DdManager * mgr,array_t *expression, array_t *v) DdNode * retFunction(DdManager * mgr,expr expression, variables v)
/* given an expression term1+term2+...+termn, returns the BDD that implements that function */ /* given an expression term1+term2+...+termn, returns the BDD that implements that function */
{ {
array_t * term; term term1;
DdNode * tNode, * tmp, *tmp1; DdNode * tNode, * tmp, *tmp1;
int i; int i;
i=0; i=0;
tNode=Cudd_ReadLogicZero(mgr); tNode=Cudd_ReadLogicZero(mgr);
Cudd_Ref(tNode); Cudd_Ref(tNode);
while(i<array_n(expression)) while(i<expression.nTerms)
{ {
term=array_fetch(array_t * ,expression,i); term1=expression.terms[i];
tmp=retTerm(mgr,term,v); tmp=retTerm(mgr,term1,v);
Cudd_Ref(tmp); Cudd_Ref(tmp);
tmp1=Cudd_bddOr(mgr,tNode,tmp); tmp1=Cudd_bddOr(mgr,tNode,tmp);
Cudd_Ref(tmp1); Cudd_Ref(tmp1);
@ -43,7 +43,7 @@ DdNode * retFunction(DdManager * mgr,array_t *expression, array_t *v)
return tNode; return tNode;
} }
DdNode * retTerm(DdManager * mgr,array_t *term, array_t * v) DdNode * retTerm(DdManager * mgr,term t, variables v)
/* given a term V1=v1 and V2=v2 ... Vn=vn, returns the BDD that implements that function */ /* given a term V1=v1 and V2=v2 ... Vn=vn, returns the BDD that implements that function */
{ {
factor f; factor f;
@ -53,9 +53,9 @@ DdNode * retTerm(DdManager * mgr,array_t *term, array_t * v)
i=0; i=0;
fNode=Cudd_ReadOne(mgr); fNode=Cudd_ReadOne(mgr);
Cudd_Ref(fNode); Cudd_Ref(fNode);
while (i<array_n(term)) while (i<t.nFact)
{ {
f=array_fetch(factor, term, i); f=t.factors[i];
tmp=retFactor(mgr,f,v); tmp=retFactor(mgr,f,v);
Cudd_Ref(tmp); Cudd_Ref(tmp);
tmp1= Cudd_bddAnd(mgr,fNode,tmp); tmp1= Cudd_bddAnd(mgr,fNode,tmp);
@ -67,7 +67,7 @@ DdNode * retTerm(DdManager * mgr,array_t *term, array_t * v)
return fNode; return fNode;
} }
DdNode * retFactor(DdManager * mgr, factor f, array_t * vars) DdNode * retFactor(DdManager * mgr, factor f, variables vars)
/* given a factor V=v, returns the BDD that implements that function */ /* given a factor V=v, returns the BDD that implements that function */
{ {
int varIndex; int varIndex;
@ -76,19 +76,19 @@ DdNode * retFactor(DdManager * mgr, factor f, array_t * vars)
int bit; int bit;
variable v; variable v;
DdNode * node, *booleanVar, * tmp; DdNode * node, *booleanVar, * tmp;
array_t * booleanVars; DdNode ** booleanVars;
varIndex=f.var; varIndex=f.var;
value=f.value; value=f.value;
v=array_fetch(variable, vars, varIndex); v=vars.varar[varIndex];
booleanVars=v.booleanVars; booleanVars=v.booleanVars;
i=v.nBit-1; i=v.nBit-1;
node=Cudd_ReadOne(mgr); node=Cudd_ReadOne(mgr);
Cudd_Ref(node); Cudd_Ref(node);
/* booelan var with index 0 in v.booleanVars is the most significant */ /* booelan var with index 0 in v.booleanVars is the most significant */
do { do {
booleanVar=array_fetch(DdNode *,booleanVars,i); booleanVar=booleanVars[i];
bit=value & 01; bit=value & 01;
if (bit) if (bit)
{ {
@ -111,7 +111,7 @@ DdNode * retFactor(DdManager * mgr, factor f, array_t * vars)
double Prob(DdNode *node, array_t * vars,array_t * bVar2mVar, GHashTable * nodes) double Prob(DdNode *node, variables vars, GHashTable * nodes)
/* compute the probability of the expression rooted at node /* compute the probability of the expression rooted at node
nodes is used to store nodes for which the probability has alread been computed nodes is used to store nodes for which the probability has alread been computed
so that it is not recomputed so that it is not recomputed
@ -141,10 +141,10 @@ so that it is not recomputed
} }
else else
{ {
mVarIndex=array_fetch(int,bVar2mVar,index); mVarIndex=vars.bVar2mVar[index];
v=array_fetch(variable,vars,mVarIndex); v=vars.varar[mVarIndex];
nBit=v.nBit; nBit=v.nBit;
res=ProbBool(node,0,nBit,0,v,vars,bVar2mVar,nodes); res=ProbBool(node,0,nBit,0,v,vars,nodes);
key=(DdNode **)malloc(sizeof(DdNode *)); key=(DdNode **)malloc(sizeof(DdNode *));
*key=node; *key=node;
rp=(double *)malloc(sizeof(double)); rp=(double *)malloc(sizeof(double));
@ -156,22 +156,22 @@ so that it is not recomputed
} }
double ProbBool(DdNode *node, int bits, int nBit,int posBVar,variable v, double ProbBool(DdNode *node, int bits, int nBit,int posBVar,variable v,
array_t * vars,array_t * bVar2mVar, GHashTable * nodes) variables vars, GHashTable * nodes)
/* explores a group of binary variables making up the multivalued variable v */ /* explores a group of binary variables making up the multivalued variable v */
{ {
DdNode *T,*F; DdNode *T,*F;
double p,res; double p,res;
array_t * probs; double * probs;
probs=v.probabilities; probs=v.probabilities;
if (nBit==0) if (nBit==0)
{ {
if (bits>=array_n(probs)) if (bits>=v.nVal)
return 0; return 0;
else else
{ {
p=array_fetch(double,probs,bits); p=probs[bits];
res=p*Prob(node,vars,bVar2mVar,nodes); res=p*Prob(node,vars,nodes);
return res; return res;
} }
} }
@ -183,16 +183,16 @@ array_t * vars,array_t * bVar2mVar, GHashTable * nodes)
F = node->type.kids.E; F = node->type.kids.E;
bits=bits<<1; bits=bits<<1;
res=ProbBool(T,bits+1,nBit-1,posBVar+1,v,vars,bVar2mVar,nodes)+ res=ProbBool(T,bits+1,nBit-1,posBVar+1,v,vars,nodes)+
ProbBool(F,bits,nBit-1,posBVar+1,v,vars,bVar2mVar,nodes); ProbBool(F,bits,nBit-1,posBVar+1,v,vars,nodes);
return res; return res;
} }
else else
{ {
bits=bits<<1; bits=bits<<1;
res=ProbBool(node,bits+1,nBit-1,posBVar+1,v,vars,bVar2mVar,nodes)+ res=ProbBool(node,bits+1,nBit-1,posBVar+1,v,vars,nodes)+
ProbBool(node,bits,nBit-1,posBVar+1,v,vars,bVar2mVar,nodes); ProbBool(node,bits,nBit-1,posBVar+1,v,vars,nodes);
return res; return res;
} }
} }
@ -204,6 +204,6 @@ currently explored by ProbBool */
{ {
DdNode * bvar; DdNode * bvar;
bvar=array_fetch(DdNode *,v.booleanVars,posBVar); bvar=v.booleanVars[posBVar];
return bvar->index==index; return bvar->index==index;
} }

View File

@ -24,9 +24,9 @@ FILE *open_file (char *filename, const char *mode);
void reverse(char s[]); void reverse(char s[]);
static int compute_prob(void); static int compute_prob(void);
void createVars(array_t * vars, YAP_Term t,DdManager * mgr, array_t * bVar2mVar,int create_dot, char inames[1000][20]) variables createVars(YAP_Term t,DdManager * mgr, int create_dot, char inames[1000][20])
/* adds the boolean variables to the BDD and returns /* adds the boolean variables to the BDD and returns
an array_t containing them (array_t is defined in the util library of glu) the array vars containing them
returns also the names of the variables to be used to save the ADD in dot format returns also the names of the variables to be used to save the ADD in dot format
*/ */
{ {
@ -35,10 +35,16 @@ returns also the names of the variables to be used to save the ADD in dot format
variable v; variable v;
char numberVar[10],numberBit[10]; char numberVar[10],numberBit[10];
double p; double p;
b=0; variables vars;
vars.varar= (variable *) malloc(0* sizeof(variable));
vars.bVar2mVar=(int *) malloc(0* sizeof(int));
b=0;
vars.nVar=0;
while(YAP_IsPairTerm(t)) while(YAP_IsPairTerm(t))
{ {
varTerm=YAP_HeadOfTerm(t); varTerm=YAP_HeadOfTerm(t);
varIndex=YAP_IntOfTerm(YAP_HeadOfTerm(varTerm)); varIndex=YAP_IntOfTerm(YAP_HeadOfTerm(varTerm));
@ -48,10 +54,18 @@ returns also the names of the variables to be used to save the ADD in dot format
probTerm=YAP_HeadOfTerm(varTerm); probTerm=YAP_HeadOfTerm(varTerm);
v.nVal=nVal; v.nVal=nVal;
v.nBit=(int)ceil(log(nVal)/log(2)); v.nBit=(int)ceil(log(nVal)/log(2));
v.probabilities=array_alloc(double,0); v.probabilities=(double *) malloc(nVal* sizeof(double));
v.booleanVars=array_alloc(DdNode *,0); v.booleanVars=(DdNode * *) malloc(v.nBit* sizeof(DdNode *));
for (i=0;i<nVal;i++) for (i=0;i<nVal;i++)
{ {
p=YAP_FloatOfTerm(YAP_HeadOfTerm(probTerm));
v.probabilities[i]=p;
probTerm=YAP_TailOfTerm(probTerm);
}
for (i=0;i<v.nBit;i++)
{
if (create_dot) if (create_dot)
{ {
strcpy(inames[b+i],"X"); strcpy(inames[b+i],"X");
@ -61,20 +75,24 @@ returns also the names of the variables to be used to save the ADD in dot format
sprintf(numberBit,"%d",i); sprintf(numberBit,"%d",i);
strcat(inames[b+i],numberBit); strcat(inames[b+i],numberBit);
} }
p=YAP_FloatOfTerm(YAP_HeadOfTerm(probTerm)); v.booleanVars[i]=Cudd_bddIthVar(mgr,b+i);
array_insert(double,v.probabilities,i,p); vars.bVar2mVar=(int *)realloc(vars.bVar2mVar,(b+i+1)*sizeof(int));
probTerm=YAP_TailOfTerm(probTerm); vars.bVar2mVar[b+i]=varIndex;
array_insert(DdNode *,v.booleanVars,i,Cudd_bddIthVar(mgr,b+i));
array_insert(int,bVar2mVar,b+i,varIndex);
} }
Cudd_MakeTreeNode(mgr,b,nVal,MTR_FIXED); Cudd_MakeTreeNode(mgr,b,v.nBit,MTR_FIXED);
b=b+nVal; b=b+v.nBit;
array_insert(variable,vars,varIndex,v); vars.varar=(variable *) realloc(vars.varar,(varIndex+1)* sizeof(variable));
vars.varar[varIndex]=v;
t=YAP_TailOfTerm(t); t=YAP_TailOfTerm(t);
} }
vars.nVar=varIndex+1;
vars.nBVar=b;
return vars;
} }
void createExpression(array_t * expression, YAP_Term t) expr createExpression(YAP_Term t)
/* returns the expression as an array_t of terms (cubes) starting from the prolog lists of terms /* returns the expression as an array_t of terms (cubes) starting from the prolog lists of terms
each term is an array_t of factors obtained from a prolog list of factors each term is an array_t of factors obtained from a prolog list of factors
each factor is a couple (index of variable, index of value) obtained from a prolog list containing each factor is a couple (index of variable, index of value) obtained from a prolog list containing
@ -84,12 +102,13 @@ two integers
YAP_Term termTerm,factorTerm; YAP_Term termTerm,factorTerm;
factor f; factor f;
int i,j; int i,j;
array_t * term; term term1;
expr expression;
expression.terms=(term *)malloc(0 *sizeof(term));
i=0; i=0;
while(YAP_IsPairTerm(t)) while(YAP_IsPairTerm(t))
{ {
term=array_alloc(factor,0); term1.factors=(factor *)malloc(0 *sizeof(factor));
termTerm=YAP_HeadOfTerm(t); termTerm=YAP_HeadOfTerm(t);
j=0; j=0;
while(YAP_IsPairTerm(termTerm)) while(YAP_IsPairTerm(termTerm))
@ -97,14 +116,19 @@ two integers
factorTerm=YAP_HeadOfTerm(termTerm); factorTerm=YAP_HeadOfTerm(termTerm);
f.var=YAP_IntOfTerm(YAP_HeadOfTerm(factorTerm)); f.var=YAP_IntOfTerm(YAP_HeadOfTerm(factorTerm));
f.value=YAP_IntOfTerm(YAP_HeadOfTerm(YAP_TailOfTerm(factorTerm))); f.value=YAP_IntOfTerm(YAP_HeadOfTerm(YAP_TailOfTerm(factorTerm)));
array_insert(factor,term,j,f); term1.factors=(factor *)realloc(term1.factors,(j+1)* sizeof(factor));
term1.factors[j]=f;
termTerm=YAP_TailOfTerm(termTerm); termTerm=YAP_TailOfTerm(termTerm);
j++; j++;
} }
array_insert(array_t *,expression,i,term); term1.nFact=j;
expression.terms=(term *)realloc(expression.terms,(i+1)* sizeof(term));
expression.terms[i]=term1;
t=YAP_TailOfTerm(t); t=YAP_TailOfTerm(t);
i++; i++;
} }
expression.nTerms=i;
return(expression);
} }
static int compute_prob(void) static int compute_prob(void)
@ -112,28 +136,28 @@ static int compute_prob(void)
*/ */
{ {
YAP_Term out,arg1,arg2,arg3,arg4; YAP_Term out,arg1,arg2,arg3,arg4;
array_t * variables,* expression, * bVar2mVar; variables vars;
expr expression;
DdNode * function, * add; DdNode * function, * add;
DdManager * mgr; DdManager * mgr;
int nBVar,i,j,intBits,create_dot; int nBVar,i,j,intBits,create_dot;
FILE * file; FILE * file;
DdNode * array[1]; DdNode * array[1];
double prob;
char * onames[1]; char * onames[1];
char inames[1000][20]; char inames[1000][20];
char * names[1000]; char * names[1000];
GHashTable * nodes; /* hash table that associates nodes with their probability if already GHashTable * nodes; /* hash table that associates nodes with their probability if already
computed, it is defined in glib */ computed, it is defined in glib */
//Cudd_ReorderingType order;
arg1=YAP_ARG1; arg1=YAP_ARG1;
arg2=YAP_ARG2; arg2=YAP_ARG2;
arg3=YAP_ARG3; arg3=YAP_ARG3;
arg4=YAP_ARG4; arg4=YAP_ARG4;
mgr=Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); mgr=Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0);
variables=array_alloc(variable,0);
bVar2mVar=array_alloc(int,0);
create_dot=YAP_IntOfTerm(arg4); create_dot=YAP_IntOfTerm(arg4);
createVars(variables,arg1,mgr,bVar2mVar,create_dot,inames); vars=createVars(arg1,mgr,create_dot,inames);
//Cudd_PrintInfo(mgr,stderr); //Cudd_PrintInfo(mgr,stderr);
/* automatic variable reordering, default method CUDD_REORDER_SIFT used */ /* automatic variable reordering, default method CUDD_REORDER_SIFT used */
@ -148,10 +172,10 @@ static int compute_prob(void)
*/ */
expression=array_alloc(array_t *,0); expression=createExpression(arg2);
createExpression(expression,arg2);
function=retFunction(mgr,expression,vars);
function=retFunction(mgr,expression,variables);
/* the BDD build by retFunction is converted to an ADD (algebraic decision diagram) /* the BDD build by retFunction is converted to an ADD (algebraic decision diagram)
because it is easier to interpret and to print */ because it is easier to interpret and to print */
add=Cudd_BddToAdd(mgr,function); add=Cudd_BddToAdd(mgr,function);
@ -160,7 +184,7 @@ static int compute_prob(void)
if (create_dot) if (create_dot)
/* if specified by the user, a dot file for the BDD is written to cpl.dot */ /* if specified by the user, a dot file for the BDD is written to cpl.dot */
{ {
nBVar=array_n(bVar2mVar); nBVar=vars.nBVar;
for(i=0;i<nBVar;i++) for(i=0;i<nBVar;i++)
names[i]=inames[i]; names[i]=inames[i];
array[0]=add; array[0]=add;
@ -179,13 +203,23 @@ static int compute_prob(void)
{ {
dividend=(dividend<<1)+1; dividend=(dividend<<1)+1;
} }
out=YAP_MkFloatTerm(Prob(add,variables,bVar2mVar,nodes)); prob=Prob(add,vars,nodes);
out=YAP_MkFloatTerm(prob);
g_hash_table_foreach (nodes,dealloc,NULL); g_hash_table_foreach (nodes,dealloc,NULL);
g_hash_table_destroy(nodes); g_hash_table_destroy(nodes);
Cudd_Quit(mgr); Cudd_Quit(mgr);
array_free(variables); for(i=0;i<vars.nVar;i++)
array_free(bVar2mVar); {
array_free(expression); free(vars.varar[i].probabilities);
free(vars.varar[i].booleanVars);
}
free(vars.varar);
free(vars.bVar2mVar);
for(i=0;i<expression.nTerms;i++)
{
free(expression.terms[i].factors);
}
free(expression.terms);
return(YAP_Unify(out,arg3)); return(YAP_Unify(out,arg3));
} }
/* /*