| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  |   LPAD and CP-Logic interpreter | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  | Copyright (c) 2007, Fabrizio Riguzzi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This package uses the library cudd, see http://vlsi.colorado.edu/~fabio/CUDD/
 | 
					
						
							|  |  |  | for the relative license. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  | This file contains the definition of Prob and ProbBool plus the functions | 
					
						
							|  |  |  | for building the BDD | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "cplint.h"
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  | int correctPosition(int index,variable v, DdNode * node,int posBVar); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  | DdNode * retFunction(DdManager * mgr,expr expression, variables v) | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  | /* given an expression term1+term2+...+termn, returns the BDD that implements that function */   | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  |   term term1; | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |   DdNode * tNode, * tmp, *tmp1; | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   i=0; | 
					
						
							|  |  |  |   tNode=Cudd_ReadLogicZero(mgr); | 
					
						
							|  |  |  |   Cudd_Ref(tNode); | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  |   while(i<expression.nTerms) | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  |     term1=expression.terms[i]; | 
					
						
							|  |  |  |     tmp=retTerm(mgr,term1,v); | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |     Cudd_Ref(tmp); | 
					
						
							|  |  |  |     tmp1=Cudd_bddOr(mgr,tNode,tmp); | 
					
						
							|  |  |  |     Cudd_Ref(tmp1); | 
					
						
							|  |  |  |     Cudd_RecursiveDeref(mgr,tNode); | 
					
						
							|  |  |  |     tNode=tmp1; | 
					
						
							|  |  |  |     i++;     | 
					
						
							|  |  |  |   }  | 
					
						
							|  |  |  |   return tNode; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  | DdNode * retTerm(DdManager * mgr,term t, variables v) | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  | /* given a term V1=v1 and V2=v2 ... Vn=vn, returns the BDD that implements that function */   | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   factor f; | 
					
						
							|  |  |  |   DdNode * fNode, * tmp, *tmp1; | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   i=0; | 
					
						
							|  |  |  |   fNode=Cudd_ReadOne(mgr); | 
					
						
							|  |  |  |   Cudd_Ref(fNode); | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  |   while (i<t.nFact) | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  |     f=t.factors[i]; | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |     tmp=retFactor(mgr,f,v); | 
					
						
							|  |  |  |     Cudd_Ref(tmp); | 
					
						
							|  |  |  |     tmp1= Cudd_bddAnd(mgr,fNode,tmp); | 
					
						
							|  |  |  |     Cudd_Ref(tmp1); | 
					
						
							|  |  |  |     Cudd_RecursiveDeref(mgr,fNode); | 
					
						
							|  |  |  |     fNode=tmp1; | 
					
						
							|  |  |  |     i++; | 
					
						
							|  |  |  |   }  | 
					
						
							|  |  |  |   return fNode; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  | DdNode * retFactor(DdManager * mgr, factor f, variables vars) | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  | /* given a factor V=v, returns the BDD that implements that function */   | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int varIndex; | 
					
						
							|  |  |  |   int value; | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  |   int bit; | 
					
						
							|  |  |  |   variable v; | 
					
						
							|  |  |  |   DdNode * node, *booleanVar, * tmp; | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  |   DdNode  ** booleanVars; | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |    | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   varIndex=f.var; | 
					
						
							|  |  |  |   value=f.value; | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  |   v=vars.varar[varIndex]; | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |   booleanVars=v.booleanVars; | 
					
						
							|  |  |  |   i=v.nBit-1; | 
					
						
							|  |  |  |   node=Cudd_ReadOne(mgr); | 
					
						
							|  |  |  |   Cudd_Ref(node); | 
					
						
							|  |  |  |   /* booelan var with index 0 in v.booleanVars is the most significant */ | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  |   do  | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  |     booleanVar=booleanVars[i]; | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |     bit=value & 01; | 
					
						
							|  |  |  |     if (bit) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       tmp=Cudd_bddAnd(mgr,node,booleanVar); | 
					
						
							|  |  |  |       Cudd_Ref(tmp); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |       tmp=Cudd_bddAnd(mgr,node,Cudd_Not(booleanVar)); | 
					
						
							|  |  |  |       Cudd_Ref(tmp); | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |     value=value>>1; | 
					
						
							|  |  |  |     i--; | 
					
						
							|  |  |  |     Cudd_RecursiveDeref(mgr,node); | 
					
						
							|  |  |  |     node=tmp; | 
					
						
							|  |  |  |   } while (i>=0); | 
					
						
							|  |  |  |   return node; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  | double Prob(DdNode *node, variables vars, tablerow * nodes) | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  | /* compute the probability of the expression rooted at node
 | 
					
						
							|  |  |  | nodes is used to store nodes for which the probability has alread been computed | 
					
						
							|  |  |  | so that it is not recomputed | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-27 22:51:05 +02:00
										 |  |  |   int index,mVarIndex,nBit,comp; | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |   variable v; | 
					
						
							|  |  |  |   double res; | 
					
						
							|  |  |  |   double * value_p; | 
					
						
							| 
									
										
										
										
											2010-07-27 23:03:06 +02:00
										 |  |  |   DdNode *nodereg; | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-27 22:51:05 +02:00
										 |  |  |   index=Cudd_NodeReadIndex(node); | 
					
						
							|  |  |  |   comp=Cudd_IsComplement(node); | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |   if (Cudd_IsConstant(node)) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  |     if (comp) | 
					
						
							|  |  |  |       return 0.0; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       return 1.0; | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     nodereg=Cudd_Regular(node); | 
					
						
							|  |  |  |     value_p=get_value(nodes,nodereg); | 
					
						
							|  |  |  |     if (value_p!=NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (comp) | 
					
						
							|  |  |  |         return 1-*value_p; | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         return *value_p; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       mVarIndex=vars.bVar2mVar[index]; | 
					
						
							|  |  |  |       v=vars.varar[mVarIndex]; | 
					
						
							|  |  |  |       nBit=v.nBit; | 
					
						
							|  |  |  |       res=ProbBool(node,0,nBit,0,v,mVarIndex,vars,nodes,0); | 
					
						
							|  |  |  |       add_node(nodes,nodereg,res); | 
					
						
							|  |  |  |       if (comp) | 
					
						
							|  |  |  |         return 1-res; | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         return res; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | double ProbBool(DdNode *node, int bits, int nBit,int posBVar,variable v, | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  |   int mVarIndex, | 
					
						
							|  |  |  |   variables vars, tablerow * nodes,int comp) | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  | /* explores a group of binary variables making up the multivalued variable v */ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   DdNode *T,*F; | 
					
						
							|  |  |  |   double p,res; | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  |   double * probs; | 
					
						
							| 
									
										
										
										
											2010-07-27 22:51:05 +02:00
										 |  |  |   int comp1,comp2,index,indexF,mVarIndexF; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |   probs=v.probabilities; | 
					
						
							|  |  |  |   if (nBit==0) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  |     if (bits>=v.nVal) | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |       return 0; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  |       p=probs[bits]; | 
					
						
							| 
									
										
										
										
											2010-07-27 22:51:05 +02:00
										 |  |  |       if (comp) | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  |         res=p*(1-Prob(node,vars,nodes)); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         res=p*Prob(node,vars,nodes); | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |       return res; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  |     index=Cudd_NodeReadIndex(node); | 
					
						
							| 
									
										
										
										
											2010-07-27 22:51:05 +02:00
										 |  |  |     if (correctPosition(index,v,node,posBVar)) | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-07-27 22:51:05 +02:00
										 |  |  |       T = Cudd_T(node); | 
					
						
							|  |  |  |       F = Cudd_E(node); | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |       bits=bits<<1; | 
					
						
							| 
									
										
										
										
											2010-07-27 22:51:05 +02:00
										 |  |  |       comp1=Cudd_IsComplement(F); | 
					
						
							|  |  |  |       res=ProbBool(T,bits+1,nBit-1,posBVar+1,v,mVarIndex,vars,nodes,comp); | 
					
						
							|  |  |  |       indexF=Cudd_NodeReadIndex(F); | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  |       if (Cudd_IsConstant(F)) | 
					
						
							|  |  |  |         mVarIndexF=-1; | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         mVarIndexF=vars.bVar2mVar[indexF];   | 
					
						
							|  |  |  |       if (mVarIndexF==mVarIndex) | 
					
						
							|  |  |  |         comp2=(comp1 && !comp) || (!comp1 && comp); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         comp2=comp; | 
					
						
							|  |  |  |       res=res+ ProbBool(F,bits,nBit-1,posBVar+1,v,mVarIndex,vars,nodes,comp2); | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |       return res; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       bits=bits<<1; | 
					
						
							| 
									
										
										
										
											2010-07-27 22:51:05 +02:00
										 |  |  |       res=ProbBool(node,bits+1,nBit-1,posBVar+1,v,mVarIndex,vars,nodes,comp)+  | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  |       ProbBool(node,bits,nBit-1,posBVar+1,v,mVarIndex,vars,nodes,comp); | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  |       return res; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int correctPosition(int index,variable v, DdNode * node,int posBVar) | 
					
						
							|  |  |  | /* returns 1 is the boolean variable with index posBVar is in the correct position 
 | 
					
						
							|  |  |  | currently explored by ProbBool */ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   DdNode * bvar; | 
					
						
							| 
									
										
										
										
											2010-07-27 22:51:05 +02:00
										 |  |  |   int ind; | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-27 16:53:47 +02:00
										 |  |  |   bvar=v.booleanVars[posBVar]; | 
					
						
							| 
									
										
										
										
											2010-07-27 22:51:05 +02:00
										 |  |  |   ind=Cudd_NodeReadIndex(bvar); | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  |   return ind==index; | 
					
						
							| 
									
										
										
										
											2009-02-16 12:23:29 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-10-22 16:33:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | double * get_value(tablerow *tab,  DdNode *node) { | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  |   int index = Cudd_NodeReadIndex(node); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for(i = 0; i < tab[index].cnt; i++)  | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (tab[index].row[i].key == node) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       return &tab[index].row[i].value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void destroy_table(tablerow *tab, int boolVars) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  |   for (i = 0; i < boolVars; i++)  | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     free(tab[i].row); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   free(tab); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | tablerow* init_table(int boolVars) { | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   tablerow *tab; | 
					
						
							|  |  |  |   tab = (tablerow *) malloc(sizeof(rowel) * boolVars); | 
					
						
							|  |  |  |   for (i = 0; i < boolVars; i++)  | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     tab[i].row = NULL; | 
					
						
							|  |  |  |     tab[i].cnt = 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return tab; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void add_node(tablerow *tab, DdNode *node, double value)  | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int index = Cudd_NodeReadIndex(node); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   tab[index].row = (rowel *) realloc(tab[index].row,  | 
					
						
							|  |  |  |     (tab[index].cnt + 1) * sizeof(rowel)); | 
					
						
							|  |  |  |   tab[index].row[tab[index].cnt].key = node; | 
					
						
							|  |  |  |   tab[index].row[tab[index].cnt].value = value; | 
					
						
							|  |  |  |   tab[index].cnt += 1;                                         | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |