/* LPAD and CP-Logic interpreter Copyright (c) 2007, Fabrizio Riguzzi This package uses the library cudd, see http://vlsi.colorado.edu/~fabio/CUDD/ for the relative license. This file contains the functions for interfacing Yap and C The arguments of the predicate compute_prob are parsed and translated into C data structures NOTE: 1. le variabili Value e Bit in ProbPathBool (algoritmo 6) corrispondono a bits e posBvar risp. nel codice 2. Per eta^value (Rule) userei un array di puntatori, in cui gli elementi puntano ad un'area di memoria allocata dinamicamente (con malloc) che contiene un array con un elemento per ogni possibile value. L'array di puntatori è lungo quante sono le regole. 3. Per sigma(var) puoi usare un array che indicizzi con il valore di var che e' un intero.Per "valore di var" intende l'indice della variabile multivalore. 4. Per e userei una hash table, dato che deve memorizzare valori in corrispondenza dei nodi che non sono in sequenza. Nella hash table, memorizza un puntatore ad un array con tanti elementi quanti i valori della variabile multivalore associata a VarRootNode 5. L'indice 65535 indica un nodo foglia */ #include "util.h" #include "cuddInt.h" //#include "dddmp.h" #include "dddmp.h" //#include "array.h" #include "mtr.h" //#include "avl.h" #include "YapInterface.h" #include #include #include #include #include #include //#include "memwatch.h" #define ArrayElements( array ) ( sizeof( array ) / sizeof( array[0] ) ) #define LOGZERO log(0.000001) #define CACHE_SLOTS 1 #define UNIQUE_SLOTS 1//8192 //con questo numero arriva al max num di esempi processati, aumentandolo cala di nuovo il num di esempi //default:CUDD_UNIQUE_SLOTS typedef struct { int nVal,nRule; int firstBoolVar; } variable; typedef struct { DdNode *key; double value; } rowel; typedef struct { int cnt; rowel *row; } tablerow; tablerow * table; //static int array; static unsigned long memuseT=0,memuse,maxmem; static variable * vars; static variable ** vars_ex; static int * bVar2mVar; //per ogni var. booleana contiene l'indice della var. multivalore nell'array vars:bVar2mVar[indice var.booleana]=ind.var.mult. static int ** bVar2mVar_ex; static double * sigma; //sigma(V) static double ***eta; //eta^value(Rule) static double ***eta_temp; //eta^value(Rule) static double **arrayprob; static int *rules; //array indicizzato dalle regole //double *e_temp; static DdManager *mgr; static DdManager **mgr_ex; static int *nVars; static int *nVars_ex; static int nRules; // num. variabili multivalore;num regole double * probs; double * nodes_probs_ex; double ** probs_ex; static int * boolVars; // numero totale di variabili booleane per 1 gruppo di esempi;e' globale e viene incrementata ogni volta che viene aggiunta una variabile static int * boolVars_ex; //GHashTable * nodesB; /* hash table that associates nodes with their probability Backward if already computed, it is defined in glib */ //GHashTable * nodesF; /* hash table that associates nodes with their probability Forward*/ tablerow * nodesB; tablerow * nodesF; //GHashTable * eTable; int ex,cycle,esempio; DdNode *** nodesToVisit; int * NnodesToVisit; double * example_prob; static int ret_prob(void); static int expec(void); double Prob(DdNode *node,int comp_par); static int end_bdd(void); static int dump_bdd(void); static int init_test(void); static int add_var(void); static int init(void); static int end(void); static int EM(void); static int Q(void); double ProbPath(DdNode *node, int comp_par); static int rec_deref(void); int indexMvar(DdNode *node); void Forward(DdNode *node); void GetForward(DdNode *node, double ForwProbPath); void UpdateForward(DdNode * node); double GetOutsideExpe(DdNode *root,double ex_prob); void Maximization(void); static double Expectation(DdNode **nodes_ex, int lenNodes); void init_my_predicates(void); FILE *open_file(char *filename, const char *mode); void reverse(char s[]); tablerow* init_table(int varcnt); double * get_value(tablerow *tab, DdNode *node); void add_or_replace_node(tablerow *tab, DdNode *node, double value); void add_node(tablerow *tab, DdNode *node, double value); void destroy_table(tablerow *tab,int varcnt); gint my_equal(gconstpointer v,gconstpointer v2); guint my_hash(gconstpointer key); void dealloc(gpointer key,gpointer value,gpointer user_data); static int init(void) //riceve in ingresso il numero di regole e il num. di atomi testa per ogni regola { int j,i; YAP_Term arg1,arg2,list; //num.regole //printf("init\n"); //nbVars=0 //////printf("nbvar %d\n",nbVars); //////printf("nvar %d\n",nVars); ex=0; cycle=0; arg1=YAP_ARG1; arg2=YAP_ARG2; nRules=YAP_IntOfTerm(arg1); //numero di regole //srand ( time(NULL) ); //Cudd_AutodynEnable(mgr,CUDD_REORDER_SAME); vars_ex=NULL; //array indicizzato dalle var. multivalue nVars_ex=NULL;//array indicizzato dagli esempi,per ogni esempio tiene il numero delle variabili booleane //printf("nRules = %d \n",nRules); eta= (double ***) malloc(nRules * sizeof(double **)); //array indicizzato dalle regole eta_temp= (double ***) malloc(nRules * sizeof(double **)); rules= (int *) malloc(nRules * sizeof(int)); //array indicizzato dalle regole arrayprob=(double **) malloc(nRules * sizeof(double *)); probs_ex=NULL; bVar2mVar_ex=NULL; boolVars_ex=NULL; mgr_ex=NULL; nodes_probs_ex=NULL; /* dividend is a global variable used by my_hash it is equal to an unsigned int with binary representation 11..1 */ list=arg2; //lista di interi, rappresentati il n° di atomi nella testa, per tutte le regole for (j=0;j creo manager per ex=%d\n\n",ex); //printf("\n ex=%d \n",ex); //printf("mgr %d %d\n",mgr_ex,mgr); //printf("size %d %d\n",sizeof(mgr_ex),(ex+1)* sizeof(DdManager *)); //fflush(stdout); mgr_ex_temp=(DdManager **) realloc(mgr_ex, (ex+1)* sizeof(DdManager *)); if (mgr_ex_temp==NULL) { printf("mgr_ex_temp==NULL\n"); } else mgr_ex=mgr_ex_temp; mgr_ex[ex]=mgr; //printf("bvar2mvar\n"); //fflush(stdout); bVar2mVar_ex_temp=(int **) realloc(bVar2mVar_ex, (ex+1)* sizeof(int *)); if (bVar2mVar_ex_temp==NULL) printf("bVar2mVar_ex_temp==NULL\n"); else bVar2mVar_ex=bVar2mVar_ex_temp; bVar2mVar_ex[ex]=NULL; bVar2mVar=bVar2mVar_ex[ex]; //printf("vars\n"); //fflush(stdout); vars_ex_temp=(variable **) realloc(vars_ex, (ex+1)* sizeof(variable *)); if (vars_ex_temp==NULL) printf("vars_ex_temp==NULL\n"); else vars_ex=vars_ex_temp; vars_ex[ex]=NULL; vars=vars_ex[ex]; //printf("nVars\n"); //fflush(stdout); nVars_ex_temp=(int *) realloc(nVars_ex, (ex+1)* sizeof(int )); if (nVars_ex_temp==NULL) printf("nVars_ex_temp==NULL\n"); else nVars_ex=nVars_ex_temp; nVars=nVars_ex+ex; *nVars=0; // printf("nVars %d nVars_ex[ex] %d\n",nVars,&nVars_ex[ex]); //printf("probs_ex\n"); //fflush(stdout); probs_ex_temp=(double **) realloc(probs_ex, (ex+1)* sizeof(double *)); if (probs_ex_temp==NULL) printf("probs_ex_temp==NULL\n"); else probs_ex=probs_ex_temp; //printf("probs_ex1 %d\n",probs_ex); probs_ex[ex]=NULL; probs=probs_ex[ex]; // printf("boolvars\n"); fflush(stdout); boolVars_ex_temp=(int *) realloc(boolVars_ex, (ex+1)* sizeof(int )); if (boolVars_ex_temp==NULL) printf("boolVars_ex_temp==NULL\n"); else boolVars_ex=boolVars_ex_temp; boolVars=boolVars_ex+ex; *boolVars=0; // printf("*boolvars %d boolVars_ex[ex] %d\n",boolVars,&boolVars_ex[ex]); return 1; //out=YAP_MkIntTerm((YAP_Int) mgr); //return(YAP_Unify(out,arg1)); } static int end_bdd(void) { // printf("***************end_bdd\n"); bVar2mVar_ex[ex]=bVar2mVar; probs_ex[ex]=probs; vars_ex[ex]=vars; // printf("Boolvars ex %d\n",boolVars_ex[ex]); ex=ex+1; memuse=Cudd_ReadMemoryInUse(mgr);//Returns the memory in use by the manager measured in bytes. // printf("Memoria in uso dopo dump=%lu\n",memuse); memuseT=memuseT+memuse; // printf("Memoria dal primo esempio=%lu\n\n",memuseT); maxmem=Cudd_ReadMaxMemory(mgr); // printf("Memoria max=%lu\n\n",maxmem); // Cudd_PrintInfo(mgr,stdout); return 1; } static int dump_bdd(void) { FILE *fdump; char fname[100],fname1[100]; int retValue1; //unsigned long maxmem; DdNode *node,*bdd_reloaded; YAP_Term arg1,arg2,out; arg1=YAP_ARG1; arg2=YAP_ARG2; node = (DdNode *)YAP_IntOfTerm(arg1); strcpy(fname,"BDD_mem.txt"); strcpy(fname1,"BDD1_mem.txt"); fdump=fopen(fname,"w"); memuse=Cudd_ReadMemoryInUse(mgr);//INCREMENTO -Returns the memory in use by the manager measured in bytes. //printf("\nMemoria in uso corrente(prima dump)=%lu\n",memuse); /*memuseT=memuseT+memuse; printf("Memoria dal primo esempio=%u\n\n",memuseT);i*/ /* f=fopen("bVar2mVar_mem.txt","a"); fprintf(f,"ex=%d, BoolVars= %d\n\n",ex,*boolVars); fclose(f);*/ //printf("\n NVARS= %d\t",*nVars); //printf("NVARS_Ex= %d - ex=%d\n",nVars_ex[ex],ex); /*for (i=0;i<*boolVars;i++) { printf("posizione corrente della variabile %d nell'ordine: %d\n",i,Cudd_ReadPerm(mgr,i));} */ //printf("prima di bdd_store\n"); //salvataggio su file /* Dddmp_cuddBddStore( DdManager * ddMgr, IN: DD Manager char * ddname, IN: DD name (or NULL) DdNode * f, IN: BDD root to be stored char ** varnames, IN: array of variable names (or NULL) int * auxids, IN: array of converted var ids int mode, IN: storing mode selector Dddmp_VarInfoType varinfo, IN: extra info for variables in text mode char * fname, IN: File name FILE * fp IN: File pointer to the store file ) */ retValue1 = Dddmp_cuddBddStore(mgr,NULL,node,NULL,NULL,DDDMP_MODE_TEXT,4,fname,fdump); fclose(fdump); //Deletes resources associated with a DD manager and resets the global statistical counters. Cudd_Quit(mgr); //printf("*********Quit mgr per ex=%d\n\n",ex); //Creates a new DD manager mgr=Cudd_Init(0,0,UNIQUE_SLOTS,CACHE_SLOTS,512000/*=500K,1048576=1M,33554432=32M,4294967295=4096M,8737678950*/); Cudd_AutodynEnable(mgr, CUDD_REORDER_GROUP_SIFT); Cudd_SetMaxCacheHard(mgr,0/*1024*1024*1024*/); Cudd_SetLooseUpTo(mgr, 0/*1024*1024*512*/); // Cudd_EnableReorderingReporting(mgr); // Cudd_SetMinHit(mgr, 15); mgr_ex[ex]=mgr; //printf("**********Init new mgr \n"); /*for (i=0;i<*boolVars;i++) { printf("posizione corrente della variabile %d nell'ordine: %d\n",i,Cudd_ReadPerm(mgr,i));} */ fdump=fopen(fname,"r"); /* DdNode * Dddmp_cuddBddLoad( DdManager * ddMgr, IN: DD Manager Dddmp_VarMatchType varMatchMode, IN: storing mode selector char ** varmatchnames, IN: array of variable names - by IDs int * varmatchauxids, IN: array of variable auxids - by IDs int * varcomposeids, IN: array of new ids accessed - by IDs int mode, IN: requested input file format char * file, IN: file name FILE * fp IN: file pointer ) Retrieve the BDD root*/ bdd_reloaded= Dddmp_cuddBddLoad(mgr,DDDMP_VAR_MATCHIDS,NULL,NULL,NULL,DDDMP_MODE_TEXT,fname,fdump); //printf("dopo bdd_load,bdd=%d\n",(int)bdd_reloaded); fclose(fdump); //Cudd_PrintInfo(mgr,stdout); /*for (j=0; j<*boolVars; j++) { printf("\nj = %d \n",j); bVarIndex=Cudd_ReadInvPerm(mgr,j); printf("bVarIndex=%d\n",bVarIndex); if (bVarIndex==-1) { fprintf(f,"\nbVarIndex=%d esempio %d\n",bVarIndex,esempio); bVarIndex=j; } mVarIndex=bVar2mVar[bVarIndex]; printf("mVarIndex=%d\n",mVarIndex); } */ /*fdump=fopen(fname1,"w"); Dddmp_cuddBddStore(mgr,NULL,bdd_reloaded,NULL,NULL,DDDMP_MODE_TEXT,4,fname1,fdump); fclose(fdump); */ out=YAP_MkIntTerm((YAP_Int)bdd_reloaded); //printf("DUMP per ex=%d\n",ex); //maxmem=Cudd_ReadMaxMemory(mgr); //memuse=Cudd_ReadMemoryInUse(mgr); //printf("maxmem=%u memuse=%u\n\n",maxmem,memuse); //Cudd_PrintInfo(mgr,stdout); return(YAP_Unify(out,arg2)); } static int init_test(void) //riceve in ingresso il numero di regole e la lista di probabilità { YAP_Term arg1; //num.regole //printf("init\n"); //nbVars=0 //////printf("nbvar %d\n",nbVars); //////printf("nvar %d\n",nVars); //printf("nRules = %d \n",nRules); /* dividend is a global variable used by my_hash it is equal to an unsigned int with binary representation 11..1 */ ////printf("letta lista prob.\n"); arg1=YAP_ARG1; nRules=YAP_IntOfTerm(arg1); //numero di regole mgr=Cudd_Init(0,0,UNIQUE_SLOTS,CACHE_SLOTS,0); Cudd_AutodynEnable(mgr, CUDD_REORDER_GROUP_SIFT); Cudd_SetMaxCacheHard(mgr, 1024*1024*1024); Cudd_SetLooseUpTo(mgr, 1024*1024*512); // Cudd_EnableReorderingReporting(mgr); rules= (int *) malloc(nRules * sizeof(int)); bVar2mVar=NULL; probs=NULL; vars=NULL; nVars=(int *) malloc(sizeof(int )); *nVars=0; boolVars=(int *) malloc(sizeof(int )); *boolVars=0; return 1; //out=YAP_MkIntTerm((YAP_Int) mgr); //return(YAP_Unify(out,arg1)); } static int end_test(void) { //Cudd_PrintInfo(mgr,stdout); //printf("end_bdd\n"); free(bVar2mVar); free(vars); free(nVars); free(boolVars); Cudd_Quit(mgr); free(probs); free(rules); //free(eta); return 1; } static double Expectation(DdNode **nodes_ex,int lenNodes) { int i; double rootProb,CLL=0; // printf("\n EXPECTATION \n"); // printf("nVars %d\n",*nVars); /* for(i=0;iindex; //printf("ProbPath \t node %d\n",node); index=Cudd_NodeReadIndex(node); ////printf("Prob INdex %d\n",index);*/ //printf("\nPROBPATH - nodo in input %x con indice %d \n",(unsigned int)node,Cudd_NodeReadIndex(node)); comp=Cudd_IsComplement(node); comp=(comp && !comp_par) ||(!comp && comp_par); ////printf("complementato=%d \n",comp); if (Cudd_IsConstant(node)) //********NODO FOGLIA-Returns 1 if the node is a constant node (rather than an internal node). { //printf("Nodo foglia %x \t",(unsigned int)node); //printf("valore %f comp %d\n",value,comp); if (comp) //Cudd_IsComplement(node)):restituisce 1 se il puntatore node è complementato (in pratica se e' pari) //return (1.0-value); //if (value>0) { //////printf("return 0"); return 0.0; } else { //////printf("return 1"); return 1.0; } /*else if (value>0) return 1.0; else return 0.0; */ //return value; } else { ////printf("dentro else \n"); nodefw=Cudd_Regular(node); if (comp) nodekey=Cudd_Complement(nodefw); else nodekey=nodefw; //printf("nodekey=%x\t comp=%d",(unsigned int)nodekey,comp); // value_p=g_hash_table_lookup(nodesB,nodekey); //probabilità del nodo node value_p=get_value(table,nodekey); //value_p=NULL; //printf("value_p=%f\n",*value_p); if (value_p!=NULL) { // printf("value_p found %e\n",*value_p); /* if (comp) return 1-*value_p; else */ return *value_p; } else {// printf("value_p null \n"); index=Cudd_NodeReadIndex(node); //Returns the index of the node. The node pointer can be either regular or complemented. //The index field holds the name of the variable that labels the node. The index of a variable is a permanent attribute that reflects the order of creation. //////printf("node absent %d comp %d\n",node,comp); //mVarIndex=array_fetch(int,bVar2mVar,index); ////printf("\n\n*******************PROBPATH- root node %x index %d \n",(unsigned int)node,index); p=probs[index]; T = Cudd_T(node);//node->type.kids.T; //figlio 1 F = Cudd_E(node);//node->type.kids.E; //figlio 0 //printf("FIGLI: T %x index %d F %x index %d \n",(int) T,Cudd_NodeReadIndex(T),(int)F,Cudd_NodeReadIndex(F)); pf=Prob(F,comp); pt=Prob(T,comp); BChild0=pf*(1-p); //printf("node %x F %x ProbPath(F)=%f p=%f 1-p=%f \n",(int)node,(int)F,pf,p,1-p); BChild1=pt*p; //printf("node %x T %x ProbPath(T)=%f p=%f \n",(int)node,(int)T,pt,p); // printf("prima di value_p da hash_table, node=%x nodefw=%x \n", node,nodefw); mVarIndex=bVar2mVar[index]; v=vars[mVarIndex]; //eta ////printf("vRN.nRule = %d \n",vRN.nRule); pos=index-v.firstBoolVar; //printf("pos=%d v.nRule=%d\n",pos,v.nRule); // *key=nodekey; // rp=(double *)malloc(sizeof(double)); res=BChild0+BChild1; // *rp=res; // printf("\n RES=Bchild0+Bchild1 = %f\n",*rp); // g_hash_table_insert(nodesB, nodekey, rp); //Inserts a new key and value into a GHashTable. Inserisce nella tabella il nodo key e la prob. rp add_node(table,nodekey,res); //printf("T %x index %d\n",(int)T,Cudd_NodeReadIndex(T)); return res; //} } } } static int add_var(void) //chiamata dentro a dir.pl { YAP_Term arg1,arg2,arg3,arg4,out,probTerm,probTerm_temp; variable * v,*vars_temp; //variabile multivalore; puntatore ad array di var. multiv. int i; DdNode * node; double p,p0; double * probs_temp; int * bVar2mVar_temp; arg1=YAP_ARG1; //num. di valori della variabile mult. arg2=YAP_ARG2; //lista di probabilità arg3=YAP_ARG3; //numero della regola a cui si riferisce la variabile mult. arg4=YAP_ARG4; //output *nVars=*nVars+1; vars_temp=(variable *) realloc(vars,*nVars * sizeof(variable)); //vars=array delle var. multivalore, realloc estende l'array; nVars è incrementato quindi rialloco lo spazio if (vars_temp==NULL) printf("add_var vars_temp null\n"); else vars=vars_temp; v=&vars[*nVars-1]; //puntatore a nuova variabile v->nVal=YAP_IntOfTerm(arg1); v->nRule=YAP_IntOfTerm(arg3); v->firstBoolVar=*boolVars; //////printf("varIndex %d nbit %d\n",varIndex,v.nBit); //////printf("boolVars %d ",boolVars); // printf("\n ADDED VAR %d\n",*nVars-1); //printf("Rule %d\n",v->nRule); probs_temp=(double *) realloc(probs,(((*boolVars+v->nVal-1)* sizeof(double)))); probs=probs_temp; //printf("dopo probs\n"); bVar2mVar_temp=(int *) realloc(bVar2mVar,((*boolVars+v->nVal-1)* sizeof(int))); bVar2mVar=bVar2mVar_temp; //printf("n b var %d\n",*boolVars+v->nVal-1); probTerm=arg2; p0=1; // printf("nVal=%d\n\n", v->nVal); for (i=0;inVal-1;i++) { // printf("i=%d \n",i); node=Cudd_bddIthVar(mgr,*boolVars+i); // printf("nodo %x\t",(int) node); p=YAP_FloatOfTerm(YAP_HeadOfTerm(probTerm)); //p=YAP_IntOfTerm(YAP_HeadOfTerm(probTerm)); //printf("p=%f \n\n",p); // printf("Index=%d\n",Cudd_NodeReadIndex(node)); ////printf("add_var - booleanNode= %x \n",(unsigned int)node); bVar2mVar[*boolVars+i]=*nVars-1; //printf("add_var - bVar2mVar[%d]=%d \n",*boolVars+i,*nVars-1); //////printf("node %d\n",node); //array_insert(DdNode *,v.booleanVars,i,node); //array_insert(int,bVar2mVar,b+i,varIndex); probs[*boolVars+i]=p/p0; //printf("probs[%d]=%f \n",*boolVars+i,probs[*boolVars+i]); probTerm_temp=YAP_TailOfTerm(probTerm); //free(probTerm); probTerm=probTerm_temp; p0=p0*(1-p/p0); } *boolVars=*boolVars+v->nVal-1; //printf("bVar2mVar %x\n",(int)bVar2mVar); // printf("BoolVars= %d\n\n",*boolVars); rules[v->nRule]= v->nVal; //quando si chiama add_var, ad esempio add_var(2,[0.3,0.7],0,V1),prendi il numero dei valori e lo memorizzi in un array globale indicizzato con il numero della regola // eta[v->nRule]= (double **) malloc(v->nVal*sizeof(double)); // eta[v->nRule][v->nVal]=(double *) malloc(2*sizeof(double)); out=YAP_MkIntTerm((YAP_Int)* nVars-1); //crea un integer term //printf("prima di return\n\n"); return YAP_Unify(out,arg4); //YAP_Unify(YAP_Term, YAP_Term) which in turn returns an integer denoting success or failure of the unification //restituisce l'ultima var. multivalore } static int equality(void) { YAP_Term arg1,arg2,arg3,out; int varIndex; int value; int i; variable v; DdNode * node, * tmp,*var; arg1=YAP_ARG1; //var arg2=YAP_ARG2; //value arg3=YAP_ARG3; //node varIndex=YAP_IntOfTerm(arg1); value=YAP_IntOfTerm(arg2); //////printf("index %d value %d\n",varIndex,value); //v=array_fetch(variable, vars, varIndex); v=vars[varIndex]; i=v.firstBoolVar; //////printf("var obtained\n"); tmp=Cudd_ReadOne(mgr); Cudd_Ref(tmp); node=NULL; for (i=v.firstBoolVar;iindex; //printf("ProbPath \t node %x\n",node); //index=Cudd_NodeReadIndex(node); ////printf("Prob INdex %d\n",index); //printf("\nPROBPATH - nodo in input %x con indice %d \n",(unsigned int)node,Cudd_NodeReadIndex(node)); comp=Cudd_IsComplement(node); comp=(comp && !comp_par) ||(!comp && comp_par); //printf("complementato=%d \n",comp); if (Cudd_IsConstant(node)) //********NODO FOGLIA-Returns 1 if the node is a constant node (rather than an internal node). { //printf("Nodo foglia %x \n",(unsigned int)node); value=Cudd_V(node);//node->type.value; //********NON SERVE: Returns the value of a constant node. //printf("valore %f comp %d\n",value,comp); if (comp) //Cudd_IsComplement(node)):restituisce 1 se il puntatore node è complementato (in pratica se e' pari) //return (1.0-value); //if (value>0) { // printf("return 0\n"); return 0.0; } else { //////printf("return 1"); return 1.0; } /*else if (value>0) return 1.0; else return 0.0; */ //return value; } else { ////printf("dentro else \n"); nodefw=Cudd_Regular(node); if (comp) nodekey=Cudd_Complement(nodefw); else nodekey=nodefw; //printf("nodekey=%x\t comp=%d",(unsigned int)nodekey,comp); //value_p=g_hash_table_lookup(nodesB,nodekey); //probabilità del nodo node value_p=get_value(nodesB,nodefw); //printf("value_p=%f\n",*value_p); if (value_p!=NULL) { // printf("value_p found %e\n",*value_p); /* if (comp) return 1-*value_p; else */ return *value_p; } else {// printf("value_p null \n"); index=Cudd_NodeReadIndex(node); //Returns the index of the node. The node pointer can be either regular or complemented. //The index field holds the name of the variable that labels the node. The index of a variable is a permanent attribute that reflects the order of creation. //////printf("node absent %d comp %d\n",node,comp); //mVarIndex=array_fetch(int,bVar2mVar,index); ////printf("\n\n*******************PROBPATH- root node %x index %d \n",(unsigned int)node,index); p=probs[index]; T = Cudd_T(node);//node->type.kids.T; //figlio 1 F = Cudd_E(node);//node->type.kids.E; //figlio 0 //printf("FIGLI: T %x index %d F %x index %d \n",(int) T,Cudd_NodeReadIndex(T),(int)F,Cudd_NodeReadIndex(F)); pf=ProbPath(F,comp); //printf("pf\n"); pt=ProbPath(T,comp); //printf("pt\n"); BChild0=pf*(1-p); //printf("node %x F %x ProbPath(F)=%f p=%f 1-p=%f \n",(int)node,(int)F,pf,p,1-p); BChild1=pt*p; //printf("BChild1=pt*p= %f=%f*%f\n", BChild1,pt,p); //printf("node %x T %x ProbPath(T)=%f p=%f \n",(int)node,(int)T,pt,p); // printf("prima di value_p da hash_table, node=%x nodefw=%x \n", node,nodefw); //value_p=g_hash_table_lookup(nodesF,nodefw); value_p=get_value(nodesF,nodefw); //printf("\n value_p(da nodesF) = %x associato al nodo %x\n BChild0=%f \t Bchild1=%f\n",value_p,(int)nodefw,BChild0,BChild1); e0 = (*value_p)*BChild0; //if (e0<0.0) printf("e0 %lf\n",e0); e1 = (*value_p)*BChild1; //printf("e1-valuep= %f\n", *value_p); //if (e1<0.0) printf("e1 %lf\n",e1); // printf("e0=value_p*B0=%f e1=value_p*B1=%f \n",e0,e1); mVarIndex=bVar2mVar[index]; v=vars[mVarIndex]; //eta ////printf("vRN.nRule = %d \n",vRN.nRule); pos=index-v.firstBoolVar; //printf("pos=%d v.nRule=%d\n",pos,v.nRule); eta_rule=eta_temp[v.nRule]; //printf("\n ####### prima dell'aggiornamento: eta_rule[%d][0] = %f \t eta_rule[%d][1] = %f\n", pos,eta_rule[pos][0],pos,eta_rule[pos][1]); eta_rule[pos][0]=eta_rule[pos][0]+e0; eta_rule[pos][1]=eta_rule[pos][1]+e1; // printf("dopo l'aggiornamento: eta_rule[%d][0] = %f \t eta_rule[%d][1] = %f\n", pos,eta_rule[pos][0],pos,eta_rule[pos][1]); // key=(DdNode **)malloc(sizeof(DdNode *)); // *key=nodekey; //rp=(double *)malloc(sizeof(double)); res=BChild0+BChild1; //*rp=res; // printf("\n RES=Bchild0+Bchild1 = %f\n",*rp); add_node(nodesB,nodefw,res); //g_hash_table_insert(nodesB, nodekey, rp); //Inserts a new key and value into a GHashTable. Inserisce nella tabella il nodo key e la prob. rp position=Cudd_ReadPerm(mgr,index); // printf("POS: %d",pos); position=position+1; boolVarIndex=Cudd_ReadInvPerm(mgr,position); //Returns the index of the variable currently in the i-th position of the order. // if(boolVarIndex!=-1) if (position<*boolVars) { //Vsucc //printf("\nprima - sigma[%d] = %f\n ",boolVarIndex,sigma[boolVarIndex]); sigma[position]=sigma[position]+e0+e1; //printf("dopo - sigma[%d] = %f\n ",boolVarIndex,sigma[boolVarIndex]); } // scandire l'ordine fino a che non trovi una variabile booleana che fa parte di una variabile multivalore successiva ////printf("\n \n 2^ chiamata a indexMVar"); //printf("T %x index %d\n",(int)T,Cudd_NodeReadIndex(T)); if(!Cudd_IsConstant(T)){ index=Cudd_NodeReadIndex(T); position=Cudd_ReadPerm(mgr,index); //printf("prima - per nodo(T) %x - sigma[%d] = %f\n ",(unsigned int)T,index,sigma[index]); sigma[position]=sigma[position]-e1; // if (sigma[index]<0) printf("sigma[%d]=%lf\n",index,sigma[index]); //printf("dopo - per nodo(T) %x - sigma[%d] = %f\n ",(unsigned int)T,index,sigma[index]); } if(!Cudd_IsConstant(F)){ index=Cudd_NodeReadIndex(F); position=Cudd_ReadPerm(mgr,index); //printf("prima - per nodo(F) %x - sigma[%d] = %f\n ",(unsigned int)F,index,sigma[index]); sigma[position]=sigma[position]-e0; // if (sigma[index]<0) printf("sigma[%d]=%lf\n",index,sigma[index]); //printf("dopo - per nodo(F) %x - sigma[%d] = %f\n ",(unsigned int)F,index,sigma[index]); } /* if (comp) { //printf("ProbPath 1-res = %f, comp = %d\n",1-res, comp); return 1-res; } else { */ //printf("\n ProbPath-res= %f \n",res); return res; //} } } } /*******************************************************************************FORWARD******************************************************************/ void Forward(DdNode *root) //tiene in conto una nuova variabile multivalore /* compute the probability of the expression rooted at node. nodesB is used to store nodesB for which the probability has alread been computed so that it is not recomputed */ { int i,j; //DdNode **key; //double *rp; //////printf("lungh. bVar2mVar= %d",ArrayElements(bVar2mVar)); //printf("********************************FORWARD \t root %x \n",(unsigned int)root); /*key=(DdNode **)malloc(sizeof(DdNode *)); *key=root; rp=(double *)malloc(sizeof(double)); *rp=1; g_hash_table_insert(nodesF, key, rp);*/ if (*boolVars) { nodesToVisit= (DdNode ***)malloc(sizeof(DdNode **)* *boolVars); NnodesToVisit= (int *)malloc(sizeof(int)* *boolVars); nodesToVisit[0]=(DdNode **)malloc(sizeof(DdNode *)); nodesToVisit[0][0]=root; NnodesToVisit[0]=1; for(i=1;i<*boolVars;i++) { nodesToVisit[i]=NULL; NnodesToVisit[i]=0; } //rp=(double *)malloc(sizeof(double)); //*rp=1; //value //printf("prima di hash table insert\n"); add_node(nodesF,Cudd_Regular(root),1); //printf("dopo hash table insert\n"); //printf("boolvars %d\n",*boolVars); for(i=0;i<*boolVars;i++) { // printf("Level %d node %d\n",i,NnodesToVisit[i]); for(j=0;jtype.kids.T; //figlio 1 E = Cudd_E(node);//node->type.kids.E; //figlio 0 // printf("node %x T %x E %x index_T %d pos_T %d index_E=%d pos_E %d \n",(int)node,(int)T,(int)E,Cudd_NodeReadIndex(T),Cudd_ReadPerm(mgr,Cudd_NodeReadIndex(T)),Cudd_NodeReadIndex(E),Cudd_ReadPerm(mgr,Cudd_NodeReadIndex(E))); if (!Cudd_IsConstant(T)) { // value_p_T=g_hash_table_lookup(nodesF,T); value_p_T=get_value(nodesF,T); if (value_p_T!= NULL) { // printf("ForwProbPath=%f\n",ForwProbPath); // // printf("1\t"); // *value_p_T= *value_p_T+*value_p*p; } else { //rp=(double *)malloc(sizeof(double)); //*rp=*value_p*p; //value // g_hash_table_insert(nodesF, T, rp); add_or_replace_node(nodesF,Cudd_Regular(T),*value_p*p); index=Cudd_NodeReadIndex(T); position=Cudd_ReadPerm(mgr,index); array_temp=(DdNode **)realloc(nodesToVisit[position], (NnodesToVisit[position]+1)* sizeof(DdNode *)); nodesToVisit[position]=array_temp; //printf("mprobe %d\n",mprobe(nodesToVisit[position])); nodesToVisit[position][NnodesToVisit[position]]=T; NnodesToVisit[position]=NnodesToVisit[position]+1; } } if (!Cudd_IsConstant(E)) { // value_p_F=g_hash_table_lookup(nodesF,Cudd_Regular(E)); value_p_F=get_value(nodesF,Cudd_Regular(E)); if (value_p_F!= NULL) { // printf("ForwProbPath=%f\n",ForwProbPath); // // printf("1\t"); // *value_p_F= *value_p_F+*value_p*(1-p); } else { // rp=(double *)malloc(sizeof(double)); // *rp= *value_p*(1-p); //value // g_hash_table_insert(nodesF, Cudd_Regular(E), rp); add_or_replace_node(nodesF,Cudd_Regular(E),*value_p*(1-p)); index=Cudd_NodeReadIndex(E); position=Cudd_ReadPerm(mgr,index); array_temp=(DdNode **)realloc(nodesToVisit[position], (NnodesToVisit[position]+1)* sizeof(DdNode *)); nodesToVisit[position]=array_temp; //printf("mprobe %d\n",mprobe(nodesToVisit[position])); nodesToVisit[position][NnodesToVisit[position]]=E; NnodesToVisit[position]=NnodesToVisit[position]+1; } } //printf("end fw\n"); return; } } } int indexMvar(DdNode * node) //dato un nodo restituisce l'indice della variabile multivalore ad essa associato. { int index,mVarIndex; ////printf("\n *FUNZ. INDEXMVAR \n"); index=Cudd_NodeReadIndex(node); //indice della variabile booleana associata al nodo ////printf("node %x index_node_bool=%d \n",node,index); ////printf("lungh. bVar2mVar: %d \n", ArrayElements(bVar2mVar)); //////printf("bVar2mVar[0]=%d \t",bVar2mVar[0]); //////printf("bVar2mVar[1]=%d \n",bVar2mVar[1]); mVarIndex=bVar2mVar[index]; ////printf("IndexmVar= %d \n",mVarIndex); return mVarIndex; } /**************************************************************GETOUTSIDEXPE***************************************************************************/ double GetOutsideExpe(DdNode *root,double ex_prob) { int i,j,mVarIndex,bVarIndex; double **eta_rule; double theta,rootProb, T=0; //f=fopen("bVar2mVar.txt","a"); sigma=(double *)malloc(*boolVars * sizeof(double)); for (j=0; j<*boolVars; j++) { sigma[j]=0; } //printf("\n GETOUTSIDEXPE - prima di ProbPath \n"); for (j=0; j0.0) { //printf("GETOUTSIDEXPE - dopo ProbPath, rootProb=%f\n",rootProb); //Cudd_PrintInfo(mgr,stdout); //printf("\nboolVars=%d\n",*boolVars); for (j=0; j<*boolVars; j++) { // printf("\n CICLO ESTERNO, j = %d \n",j); T += sigma[j]; // if (T<-0.00000000000001) // printf("j %d T %30.28lf \n",j,T); // printf("\nT = %f \t sigma[%d] = %f\n",T,j,sigma[j]); bVarIndex=Cudd_ReadInvPerm(mgr,j); // printf("bVarIndex=%d\n",bVarIndex); if (bVarIndex==-1) { // fprintf(f,"\nbVarIndex=%d esempio %d\n",bVarIndex,esempio); bVarIndex=j; } /* if (esempio==29) create_dot(root);*/ mVarIndex=bVar2mVar[bVarIndex]; // printf("mVarIndex=%d\n",mVarIndex); eta_rule=eta_temp[vars[mVarIndex].nRule]; //Vj.nRule // printf("rule %d\n",vars[mVarIndex].nRule); // printf("vars[mVarIndex].nVal=%d\n",vars[mVarIndex].nVal); for (i=0; iea) && (ratio>er) && (cycle