1268 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			1268 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								EMBLEM and SLIPCASE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Copyright (c) 2011, Fabrizio Riguzzi and Elena Bellodi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This package uses the library cudd, see http://vlsi.colorado.edu/~fabio/CUDD/
							 | 
						||
| 
								 | 
							
								for the relative license.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <math.h>
							 | 
						||
| 
								 | 
							
								#include <stdlib.h>
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#include <string.h>
							 | 
						||
| 
								 | 
							
								#include "cuddInt.h"
							 | 
						||
| 
								 | 
							
								#include "YapInterface.h"
							 | 
						||
| 
								 | 
							
								#define LOGZERO log(0.000001)
							 | 
						||
| 
								 | 
							
								#define CACHE_SLOTS 1 
							 | 
						||
| 
								 | 
							
								#define UNIQUE_SLOTS 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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 variable * vars;
							 | 
						||
| 
								 | 
							
								static variable ** vars_ex;
							 | 
						||
| 
								 | 
							
								static int * bVar2mVar;
							 | 
						||
| 
								 | 
							
								static int ** bVar2mVar_ex;
							 | 
						||
| 
								 | 
							
								static double * sigma;
							 | 
						||
| 
								 | 
							
								static double ***eta;
							 | 
						||
| 
								 | 
							
								static double ***eta_temp;
							 | 
						||
| 
								 | 
							
								static double **arrayprob;
							 | 
						||
| 
								 | 
							
								static int *rules;
							 | 
						||
| 
								 | 
							
								static DdManager *mgr;
							 | 
						||
| 
								 | 
							
								static DdManager **mgr_ex;
							 | 
						||
| 
								 | 
							
								static int *nVars;
							 | 
						||
| 
								 | 
							
								static int *nVars_ex;
							 | 
						||
| 
								 | 
							
								static int nRules;
							 | 
						||
| 
								 | 
							
								double * probs;
							 | 
						||
| 
								 | 
							
								double * nodes_probs_ex;
							 | 
						||
| 
								 | 
							
								double ** probs_ex;
							 | 
						||
| 
								 | 
							
								static int * boolVars;
							 | 
						||
| 
								 | 
							
								static int * boolVars_ex; 
							 | 
						||
| 
								 | 
							
								tablerow * nodesB;
							 | 
						||
| 
								 | 
							
								tablerow * nodesF;
							 | 
						||
| 
								 | 
							
								int ex,cycle;
							 | 
						||
| 
								 | 
							
								DdNode *** nodesToVisit;
							 | 
						||
| 
								 | 
							
								int * NnodesToVisit;
							 | 
						||
| 
								 | 
							
								double * example_prob;
							 | 
						||
| 
								 | 
							
								static int ret_prob(void);
							 | 
						||
| 
								 | 
							
								double Prob(DdNode *node,int comp_par);
							 | 
						||
| 
								 | 
							
								static int end_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);
							 | 
						||
| 
								 | 
							
								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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int init(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int j,i;
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2,list;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ex=0;
							 | 
						||
| 
								 | 
							
								  cycle=0;
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								  nRules=YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  vars_ex=NULL;
							 | 
						||
| 
								 | 
							
								  nVars_ex=NULL;
							 | 
						||
| 
								 | 
							
								  eta= (double ***) malloc(nRules * sizeof(double **));
							 | 
						||
| 
								 | 
							
								  eta_temp= (double ***) malloc(nRules * sizeof(double **));
							 | 
						||
| 
								 | 
							
								  rules= (int *) malloc(nRules * sizeof(int));
							 | 
						||
| 
								 | 
							
								  arrayprob=(double **) malloc(nRules * sizeof(double *));
							 | 
						||
| 
								 | 
							
								  probs_ex=NULL;
							 | 
						||
| 
								 | 
							
								  bVar2mVar_ex=NULL;
							 | 
						||
| 
								 | 
							
								  boolVars_ex=NULL;
							 | 
						||
| 
								 | 
							
								  mgr_ex=NULL;
							 | 
						||
| 
								 | 
							
								  nodes_probs_ex=NULL;
							 | 
						||
| 
								 | 
							
								  list=arg2;
							 | 
						||
| 
								 | 
							
								  for (j=0;j<nRules;j++)  
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    rules[j]=YAP_IntOfTerm(YAP_HeadOfTerm(list));
							 | 
						||
| 
								 | 
							
								    list=YAP_TailOfTerm(list);
							 | 
						||
| 
								 | 
							
								    eta[j]= (double **) malloc((rules[j]-1)*sizeof(double *));
							 | 
						||
| 
								 | 
							
								    eta_temp[j]= (double **) malloc((rules[j]-1)*sizeof(double *));
							 | 
						||
| 
								 | 
							
								    arrayprob[j]= (double *) malloc((rules[j]-1)*sizeof(double));
							 | 
						||
| 
								 | 
							
								    for (i=0;i<rules[j]-1;i++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      eta[j][i]=(double *) malloc(2*sizeof(double));
							 | 
						||
| 
								 | 
							
								      eta_temp[j][i]=(double *) malloc(2*sizeof(double));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int init_bdd(void)  
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  mgr=Cudd_Init(0,0,UNIQUE_SLOTS,CACHE_SLOTS,5120);
							 | 
						||
| 
								 | 
							
								  Cudd_AutodynEnable(mgr, CUDD_REORDER_GROUP_SIFT);
							 | 
						||
| 
								 | 
							
								  Cudd_SetMaxCacheHard(mgr, 0);
							 | 
						||
| 
								 | 
							
								  Cudd_SetLooseUpTo(mgr, 0);
							 | 
						||
| 
								 | 
							
								  Cudd_SetMinHit(mgr, 15);
							 | 
						||
| 
								 | 
							
								  mgr_ex=(DdManager **) realloc(mgr_ex, (ex+1)* sizeof(DdManager *)); 
							 | 
						||
| 
								 | 
							
								  mgr_ex[ex]=mgr;
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  bVar2mVar_ex=(int **) realloc(bVar2mVar_ex, (ex+1)* sizeof(int *));
							 | 
						||
| 
								 | 
							
								  bVar2mVar_ex[ex]=NULL;
							 | 
						||
| 
								 | 
							
								  bVar2mVar=bVar2mVar_ex[ex];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  vars_ex=(variable **) realloc(vars_ex, (ex+1)* sizeof(variable *));
							 | 
						||
| 
								 | 
							
								  vars_ex[ex]=NULL;
							 | 
						||
| 
								 | 
							
								  vars=vars_ex[ex];
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  nVars_ex=(int *) realloc(nVars_ex, (ex+1)* sizeof(int ));
							 | 
						||
| 
								 | 
							
								  nVars=nVars_ex+ex;
							 | 
						||
| 
								 | 
							
								  *nVars=0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  probs_ex=(double **) realloc(probs_ex, (ex+1)* sizeof(double *)); 
							 | 
						||
| 
								 | 
							
								  probs_ex[ex]=NULL;
							 | 
						||
| 
								 | 
							
								  probs=probs_ex[ex];
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  boolVars_ex=(int *) realloc(boolVars_ex, (ex+1)* sizeof(int ));
							 | 
						||
| 
								 | 
							
								  boolVars=boolVars_ex+ex;
							 | 
						||
| 
								 | 
							
								  *boolVars=0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int end_bdd(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  bVar2mVar_ex[ex]=bVar2mVar;
							 | 
						||
| 
								 | 
							
								  probs_ex[ex]=probs;
							 | 
						||
| 
								 | 
							
								  vars_ex[ex]=vars;
							 | 
						||
| 
								 | 
							
								  ex=ex+1;
							 | 
						||
| 
								 | 
							
								  return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int init_test(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1;  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  nRules=YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  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);
							 | 
						||
| 
								 | 
							
								  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;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int end_test(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  free(bVar2mVar);
							 | 
						||
| 
								 | 
							
								  free(vars);
							 | 
						||
| 
								 | 
							
								  free(nVars);
							 | 
						||
| 
								 | 
							
								  free(boolVars);
							 | 
						||
| 
								 | 
							
								  Cudd_Quit(mgr);
							 | 
						||
| 
								 | 
							
								  free(probs);
							 | 
						||
| 
								 | 
							
								  free(rules);
							 | 
						||
| 
								 | 
							
								  return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static double Expectation(DdNode **nodes_ex,int lenNodes)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int i;
							 | 
						||
| 
								 | 
							
								  double rootProb,CLL=0;
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  for(i=0;i<lenNodes;i++)  
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    if (!Cudd_IsConstant(nodes_ex[i]))
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      mgr=mgr_ex[i];
							 | 
						||
| 
								 | 
							
								      probs=probs_ex[i];
							 | 
						||
| 
								 | 
							
								      boolVars=boolVars_ex+i;
							 | 
						||
| 
								 | 
							
								      nodesB=init_table(*boolVars);
							 | 
						||
| 
								 | 
							
								      nodesF=init_table(*boolVars);
							 | 
						||
| 
								 | 
							
								      bVar2mVar=bVar2mVar_ex[i];
							 | 
						||
| 
								 | 
							
								      vars=vars_ex[i];
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								      Forward(nodes_ex[i]);
							 | 
						||
| 
								 | 
							
								      rootProb=GetOutsideExpe(nodes_ex[i],example_prob[i]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (rootProb<=0.0)
							 | 
						||
| 
								 | 
							
								        CLL = CLL + LOGZERO*example_prob[i];
							 | 
						||
| 
								 | 
							
								      else
							 | 
						||
| 
								 | 
							
								        CLL = CLL + log(rootProb)*example_prob[i];
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								      nodes_probs_ex[i]=rootProb;
							 | 
						||
| 
								 | 
							
								      destroy_table(nodesB,*boolVars);
							 | 
						||
| 
								 | 
							
								      destroy_table(nodesF,*boolVars);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								      if (nodes_ex[i]==Cudd_ReadLogicZero(mgr_ex[i]))
							 | 
						||
| 
								 | 
							
								        CLL=CLL+LOGZERO*example_prob[i];
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return CLL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int end(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int r,i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (i=0;i<ex;i++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    Cudd_Quit(mgr_ex[i]);
							 | 
						||
| 
								 | 
							
								    free(bVar2mVar_ex[i]);
							 | 
						||
| 
								 | 
							
								    free(vars_ex[i]);
							 | 
						||
| 
								 | 
							
								    free(probs_ex[i]);
							 | 
						||
| 
								 | 
							
								    fflush(stdout);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  free(mgr_ex);
							 | 
						||
| 
								 | 
							
								  free(bVar2mVar_ex);
							 | 
						||
| 
								 | 
							
								  free(vars_ex);
							 | 
						||
| 
								 | 
							
								  free(probs_ex);
							 | 
						||
| 
								 | 
							
								  free(nVars_ex);
							 | 
						||
| 
								 | 
							
								  free(boolVars_ex);
							 | 
						||
| 
								 | 
							
								  free(nodes_probs_ex);
							 | 
						||
| 
								 | 
							
								  for (r=0;r<nRules;r++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    for (i=0;i<rules[r]-1;i++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      free(eta[r][i]);
							 | 
						||
| 
								 | 
							
								      free(eta_temp[r][i]);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    free(eta[r]);
							 | 
						||
| 
								 | 
							
								    free(eta_temp[r]);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  free(eta);
							 | 
						||
| 
								 | 
							
								  free(eta_temp);
							 | 
						||
| 
								 | 
							
								  for (r=0;r<nRules;r++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    free(arrayprob[r]);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  free(arrayprob);
							 | 
						||
| 
								 | 
							
								  free(rules);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int ret_prob(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2,out;
							 | 
						||
| 
								 | 
							
								  DdNode * node;
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								  node=(DdNode *)YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!Cudd_IsConstant(node))
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    table=init_table(*boolVars);
							 | 
						||
| 
								 | 
							
								    out=YAP_MkFloatTerm(Prob(node,0));
							 | 
						||
| 
								 | 
							
								    destroy_table(table,*boolVars);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    if (node==Cudd_ReadOne(mgr))
							 | 
						||
| 
								 | 
							
								      out=YAP_MkFloatTerm(1.0);
							 | 
						||
| 
								 | 
							
								    else  
							 | 
						||
| 
								 | 
							
								      out=YAP_MkFloatTerm(0.0);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return(YAP_Unify(out,arg2));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								double Prob(DdNode *node,int comp_par)
							 | 
						||
| 
								 | 
							
								/* compute the probability of the expression rooted at node.
							 | 
						||
| 
								 | 
							
								table is used to store nodeB for which the probability has alread been computed
							 | 
						||
| 
								 | 
							
								so that it is not recomputed
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int index,mVarIndex,comp,pos;
							 | 
						||
| 
								 | 
							
								  variable v;
							 | 
						||
| 
								 | 
							
								  double res;
							 | 
						||
| 
								 | 
							
								  double p,pt,pf,BChild0,BChild1;
							 | 
						||
| 
								 | 
							
								  double * value_p;
							 | 
						||
| 
								 | 
							
								  DdNode *nodekey,*T,*F;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  comp=Cudd_IsComplement(node);   
							 | 
						||
| 
								 | 
							
								  comp=(comp && !comp_par) ||(!comp && comp_par);
							 | 
						||
| 
								 | 
							
								  if (Cudd_IsConstant(node))
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    if (comp)
							 | 
						||
| 
								 | 
							
								      return 0.0;
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								      return 1.0;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    nodekey=Cudd_Regular(node);
							 | 
						||
| 
								 | 
							
								/*    if (comp)
							 | 
						||
| 
								 | 
							
								      nodekey=Cudd_Complement(nodefw);
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								      nodekey=nodefw;*/
							 | 
						||
| 
								 | 
							
								    value_p=get_value(table,nodekey);
							 | 
						||
| 
								 | 
							
								    if (value_p!=NULL)
							 | 
						||
| 
								 | 
							
								      return *value_p;
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      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.
							 | 
						||
| 
								 | 
							
								      p=probs[index];
							 | 
						||
| 
								 | 
							
								      T = Cudd_T(node);
							 | 
						||
| 
								 | 
							
								      F = Cudd_E(node);
							 | 
						||
| 
								 | 
							
								      pf=Prob(F,comp);
							 | 
						||
| 
								 | 
							
								      pt=Prob(T,comp);
							 | 
						||
| 
								 | 
							
								      BChild0=pf*(1-p);
							 | 
						||
| 
								 | 
							
								      BChild1=pt*p;
							 | 
						||
| 
								 | 
							
								      mVarIndex=bVar2mVar[index];
							 | 
						||
| 
								 | 
							
								      v=vars[mVarIndex];  
							 | 
						||
| 
								 | 
							
								      pos=index-v.firstBoolVar;
							 | 
						||
| 
								 | 
							
								      res=BChild0+BChild1;
							 | 
						||
| 
								 | 
							
								      add_node(table,nodekey,res);
							 | 
						||
| 
								 | 
							
								      return res;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int add_var(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2,arg3,arg4,out,probTerm,probTerm_temp;
							 | 
						||
| 
								 | 
							
								  variable * v;
							 | 
						||
| 
								 | 
							
								  int i;
							 | 
						||
| 
								 | 
							
								  DdNode * node;
							 | 
						||
| 
								 | 
							
								  double p,p0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								  arg3=YAP_ARG3; 
							 | 
						||
| 
								 | 
							
								  arg4=YAP_ARG4;
							 | 
						||
| 
								 | 
							
								  *nVars=*nVars+1;
							 | 
						||
| 
								 | 
							
								  vars=(variable *) realloc(vars,*nVars * sizeof(variable));
							 | 
						||
| 
								 | 
							
								  v=&vars[*nVars-1];
							 | 
						||
| 
								 | 
							
								  v->nVal=YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								  v->nRule=YAP_IntOfTerm(arg3);
							 | 
						||
| 
								 | 
							
								  v->firstBoolVar=*boolVars;
							 | 
						||
| 
								 | 
							
								  probs=(double *) realloc(probs,(((*boolVars+v->nVal-1)* sizeof(double))));
							 | 
						||
| 
								 | 
							
								  bVar2mVar=(int *) realloc(bVar2mVar,((*boolVars+v->nVal-1)* sizeof(int)));
							 | 
						||
| 
								 | 
							
								  probTerm=arg2; 
							 | 
						||
| 
								 | 
							
								  p0=1;
							 | 
						||
| 
								 | 
							
								  for (i=0;i<v->nVal-1;i++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    node=Cudd_bddIthVar(mgr,*boolVars+i);
							 | 
						||
| 
								 | 
							
								    p=YAP_FloatOfTerm(YAP_HeadOfTerm(probTerm));
							 | 
						||
| 
								 | 
							
								    bVar2mVar[*boolVars+i]=*nVars-1;
							 | 
						||
| 
								 | 
							
								    probs[*boolVars+i]=p/p0;
							 | 
						||
| 
								 | 
							
								    probTerm_temp=YAP_TailOfTerm(probTerm);
							 | 
						||
| 
								 | 
							
								    probTerm=probTerm_temp;
							 | 
						||
| 
								 | 
							
								    p0=p0*(1-p/p0);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  *boolVars=*boolVars+v->nVal-1;
							 | 
						||
| 
								 | 
							
								  rules[v->nRule]= v->nVal; 
							 | 
						||
| 
								 | 
							
								  out=YAP_MkIntTerm((YAP_Int)* nVars-1);
							 | 
						||
| 
								 | 
							
								  return YAP_Unify(out,arg4);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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);
							 | 
						||
| 
								 | 
							
								  v=vars[varIndex];
							 | 
						||
| 
								 | 
							
								  i=v.firstBoolVar;
							 | 
						||
| 
								 | 
							
								  tmp=Cudd_ReadOne(mgr);
							 | 
						||
| 
								 | 
							
								  Cudd_Ref(tmp);
							 | 
						||
| 
								 | 
							
								  node=NULL;
							 | 
						||
| 
								 | 
							
								  for (i=v.firstBoolVar;i<v.firstBoolVar+value;i++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    var=Cudd_bddIthVar(mgr,i);
							 | 
						||
| 
								 | 
							
								    node=Cudd_bddAnd(mgr,tmp,Cudd_Not(var));
							 | 
						||
| 
								 | 
							
								    Cudd_Ref(node);
							 | 
						||
| 
								 | 
							
								    Cudd_RecursiveDeref(mgr,tmp);
							 | 
						||
| 
								 | 
							
								    tmp=node;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  if (!(value==v.nVal-1))
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    var=Cudd_bddIthVar(mgr,v.firstBoolVar+value);
							 | 
						||
| 
								 | 
							
								    node=Cudd_bddAnd(mgr,tmp,var);
							 | 
						||
| 
								 | 
							
								    Cudd_Ref(node);
							 | 
						||
| 
								 | 
							
								    Cudd_RecursiveDeref(mgr,tmp);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  out=YAP_MkIntTerm((YAP_Int) node);
							 | 
						||
| 
								 | 
							
								  return(YAP_Unify(out,arg3));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int one(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_Term arg,out;
							 | 
						||
| 
								 | 
							
								  DdNode * node;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  node =  Cudd_ReadOne(mgr);
							 | 
						||
| 
								 | 
							
								  Cudd_Ref(node);
							 | 
						||
| 
								 | 
							
								  out=YAP_MkIntTerm((YAP_Int) node);
							 | 
						||
| 
								 | 
							
								  return(YAP_Unify(out,arg));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int zero(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_Term arg,out;
							 | 
						||
| 
								 | 
							
								  DdNode * node;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  node = Cudd_ReadLogicZero(mgr);
							 | 
						||
| 
								 | 
							
								  Cudd_Ref(node);
							 | 
						||
| 
								 | 
							
								  out=YAP_MkIntTerm((YAP_Int) node);
							 | 
						||
| 
								 | 
							
								  return(YAP_Unify(out,arg));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int bdd_not(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2,out;
							 | 
						||
| 
								 | 
							
								  DdNode * node;
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  node = (DdNode *)YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								  node=Cudd_Not(node);
							 | 
						||
| 
								 | 
							
								  out=YAP_MkIntTerm((YAP_Int) node);
							 | 
						||
| 
								 | 
							
								  return(YAP_Unify(out,arg2));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int and(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2,arg3,out;
							 | 
						||
| 
								 | 
							
								  DdNode * node1, *node2,*nodeout;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								  arg3=YAP_ARG3;
							 | 
						||
| 
								 | 
							
								  node1=(DdNode *)YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								  node2=(DdNode *)YAP_IntOfTerm(arg2);
							 | 
						||
| 
								 | 
							
								  nodeout=Cudd_bddAnd(mgr,node1,node2);
							 | 
						||
| 
								 | 
							
								  Cudd_Ref(nodeout);
							 | 
						||
| 
								 | 
							
								  out=YAP_MkIntTerm((YAP_Int) nodeout);
							 | 
						||
| 
								 | 
							
								  return(YAP_Unify(out,arg3));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int or(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2,arg3,out;
							 | 
						||
| 
								 | 
							
								  DdNode * node1,*node2,*nodeout;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								  arg3=YAP_ARG3;
							 | 
						||
| 
								 | 
							
								  node1=(DdNode *)YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								  node2=(DdNode *)YAP_IntOfTerm(arg2);
							 | 
						||
| 
								 | 
							
								  nodeout=Cudd_bddOr(mgr,node1,node2);
							 | 
						||
| 
								 | 
							
								  Cudd_Ref(nodeout);
							 | 
						||
| 
								 | 
							
								  out=YAP_MkIntTerm((YAP_Int) nodeout);
							 | 
						||
| 
								 | 
							
								  return(YAP_Unify(out,arg3));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int garbage_collect(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2,out;
							 | 
						||
| 
								 | 
							
								  YAP_Int nodes,clearCache;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								  clearCache=YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								  nodes=(YAP_Int)cuddGarbageCollect(mgr,clearCache);
							 | 
						||
| 
								 | 
							
								  out=YAP_MkIntTerm(nodes);
							 | 
						||
| 
								 | 
							
								  return(YAP_Unify(out,arg2));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int bdd_to_add(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2,out;
							 | 
						||
| 
								 | 
							
								  DdNode * node1,*node2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								  node1=(DdNode *)YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								  node2= Cudd_BddToAdd(mgr,node1);
							 | 
						||
| 
								 | 
							
								  out=YAP_MkIntTerm((YAP_Int) node2);
							 | 
						||
| 
								 | 
							
								  return(YAP_Unify(out,arg2));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int create_dot(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  char * onames[]={"Out"};
							 | 
						||
| 
								 | 
							
								  char ** inames;
							 | 
						||
| 
								 | 
							
								   DdNode * array[1];
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2;
							 | 
						||
| 
								 | 
							
								  int i,b,index;
							 | 
						||
| 
								 | 
							
								  variable v;
							 | 
						||
| 
								 | 
							
								  char numberVar[10],numberBit[10],filename[1000];
							 | 
						||
| 
								 | 
							
								  FILE * file;
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  YAP_StringToBuffer(arg2,filename,1000);
							 | 
						||
| 
								 | 
							
								  inames= (char **) malloc(sizeof(char *)*(*boolVars));
							 | 
						||
| 
								 | 
							
								  index=0;
							 | 
						||
| 
								 | 
							
								  for (i=0;i<*nVars;i++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    v=vars[i];
							 | 
						||
| 
								 | 
							
								    for (b=0;b<v.nVal-1;b++)
							 | 
						||
| 
								 | 
							
								    {  
							 | 
						||
| 
								 | 
							
								      inames[b+index]=(char *) malloc(sizeof(char)*20);
							 | 
						||
| 
								 | 
							
								      strcpy(inames[b+index],"X");
							 | 
						||
| 
								 | 
							
								      sprintf(numberVar,"%d",i);
							 | 
						||
| 
								 | 
							
								      strcat(inames[b+index],numberVar);
							 | 
						||
| 
								 | 
							
								      strcat(inames[b+index],"_");
							 | 
						||
| 
								 | 
							
								      sprintf(numberBit,"%d",b);
							 | 
						||
| 
								 | 
							
								      strcat(inames[b+index],numberBit);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    index=index+v.nVal-1;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  array[0]=(DdNode *)YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								  file = open_file(filename, "w");
							 | 
						||
| 
								 | 
							
								  Cudd_DumpDot(mgr,1,array,inames,onames,file);
							 | 
						||
| 
								 | 
							
								  fclose(file);
							 | 
						||
| 
								 | 
							
								  index=0;
							 | 
						||
| 
								 | 
							
								  for (i=0;i<*nVars;i++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    v=vars[i];
							 | 
						||
| 
								 | 
							
								    for (b=0;b<v.nVal-1;b++)
							 | 
						||
| 
								 | 
							
								    {  
							 | 
						||
| 
								 | 
							
								      free(inames[b+index]);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    index=index+v.nVal-1;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  free(inames);
							 | 
						||
| 
								 | 
							
								  return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int rec_deref(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1;
							 | 
						||
| 
								 | 
							
								  DdNode * node;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  node=(DdNode *) YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								  Cudd_RecursiveDeref(mgr, node);
							 | 
						||
| 
								 | 
							
								  return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								double ProbPath(DdNode *node,int comp_par)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int index,mVarIndex,comp,pos,position,boolVarIndex;
							 | 
						||
| 
								 | 
							
								  variable v;
							 | 
						||
| 
								 | 
							
								  double res;
							 | 
						||
| 
								 | 
							
								  double value,p,pt,pf,BChild0,BChild1,e0,e1;
							 | 
						||
| 
								 | 
							
								  double * value_p,** eta_rule;
							 | 
						||
| 
								 | 
							
								  DdNode *nodekey,*T,*F;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  comp=Cudd_IsComplement(node);   
							 | 
						||
| 
								 | 
							
								  comp=(comp && !comp_par) ||(!comp && comp_par);
							 | 
						||
| 
								 | 
							
								  if (Cudd_IsConstant(node))
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    value=Cudd_V(node);
							 | 
						||
| 
								 | 
							
								    if (comp)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      return 0.0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      return 1.0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    nodekey=Cudd_Regular(node);
							 | 
						||
| 
								 | 
							
								    value_p=get_value(nodesB,nodekey);
							 | 
						||
| 
								 | 
							
								    if (value_p!=NULL)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      return *value_p;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      index=Cudd_NodeReadIndex(node);
							 | 
						||
| 
								 | 
							
								      p=probs[index];
							 | 
						||
| 
								 | 
							
								      T = Cudd_T(node);
							 | 
						||
| 
								 | 
							
								      F = Cudd_E(node);
							 | 
						||
| 
								 | 
							
								      pf=ProbPath(F,comp);
							 | 
						||
| 
								 | 
							
								      pt=ProbPath(T,comp);
							 | 
						||
| 
								 | 
							
								      BChild0=pf*(1-p);
							 | 
						||
| 
								 | 
							
								      BChild1=pt*p;
							 | 
						||
| 
								 | 
							
								      value_p=get_value(nodesF,nodekey);
							 | 
						||
| 
								 | 
							
								      e0 = (*value_p)*BChild0; 
							 | 
						||
| 
								 | 
							
								      e1 = (*value_p)*BChild1; 
							 | 
						||
| 
								 | 
							
								      mVarIndex=bVar2mVar[index];
							 | 
						||
| 
								 | 
							
								      v=vars[mVarIndex];  
							 | 
						||
| 
								 | 
							
								      pos=index-v.firstBoolVar;
							 | 
						||
| 
								 | 
							
								      eta_rule=eta_temp[v.nRule];
							 | 
						||
| 
								 | 
							
								      eta_rule[pos][0]=eta_rule[pos][0]+e0;
							 | 
						||
| 
								 | 
							
								      eta_rule[pos][1]=eta_rule[pos][1]+e1;
							 | 
						||
| 
								 | 
							
								      res=BChild0+BChild1;
							 | 
						||
| 
								 | 
							
								      add_node(nodesB,nodekey,res);
							 | 
						||
| 
								 | 
							
								      position=Cudd_ReadPerm(mgr,index);
							 | 
						||
| 
								 | 
							
								      position=position+1;
							 | 
						||
| 
								 | 
							
								      boolVarIndex=Cudd_ReadInvPerm(mgr,position);  //Returns the index of the variable currently in the i-th position of the order. 
							 | 
						||
| 
								 | 
							
								      if (position<*boolVars)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        sigma[position]=sigma[position]+e0+e1;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if(!Cudd_IsConstant(T))
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        index=Cudd_NodeReadIndex(T);  
							 | 
						||
| 
								 | 
							
								        position=Cudd_ReadPerm(mgr,index);
							 | 
						||
| 
								 | 
							
								        sigma[position]=sigma[position]-e1;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								      if(!Cudd_IsConstant(F))
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        index=Cudd_NodeReadIndex(F);
							 | 
						||
| 
								 | 
							
								        position=Cudd_ReadPerm(mgr,index);
							 | 
						||
| 
								 | 
							
								        sigma[position]=sigma[position]-e0;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								      return res;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void Forward(DdNode *root)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int i,j;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  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;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    add_node(nodesF,Cudd_Regular(root),1);
							 | 
						||
| 
								 | 
							
								    for(i=0;i<*boolVars;i++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      for(j=0;j<NnodesToVisit[i];j++)
							 | 
						||
| 
								 | 
							
								      UpdateForward(nodesToVisit[i][j]);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    for(i=0;i<*boolVars;i++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      free(nodesToVisit[i]);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    free(nodesToVisit);
							 | 
						||
| 
								 | 
							
								    free(NnodesToVisit);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    add_node(nodesF,Cudd_Regular(root),1);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void UpdateForward(DdNode *node)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int index,position,mVarIndex;
							 | 
						||
| 
								 | 
							
								  DdNode *T,*E,*nodereg;
							 | 
						||
| 
								 | 
							
								  variable v;
							 | 
						||
| 
								 | 
							
								  double *value_p,*value_p_T,*value_p_F,p;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (Cudd_IsConstant(node)) 
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    index=Cudd_NodeReadIndex(node);
							 | 
						||
| 
								 | 
							
								    mVarIndex=bVar2mVar[index];
							 | 
						||
| 
								 | 
							
								    v=vars[mVarIndex];
							 | 
						||
| 
								 | 
							
								    p=probs[index];
							 | 
						||
| 
								 | 
							
								    nodereg=Cudd_Regular(node);
							 | 
						||
| 
								 | 
							
								    value_p=get_value(nodesF,nodereg);
							 | 
						||
| 
								 | 
							
								    if (value_p== NULL)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      printf("Error\n");
							 | 
						||
| 
								 | 
							
								      return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      T = Cudd_T(node);
							 | 
						||
| 
								 | 
							
								      E = Cudd_E(node);
							 | 
						||
| 
								 | 
							
								      if (!Cudd_IsConstant(T)) 
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        value_p_T=get_value(nodesF,T);
							 | 
						||
| 
								 | 
							
								        if (value_p_T!= NULL)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								           *value_p_T= *value_p_T+*value_p*p;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          add_or_replace_node(nodesF,Cudd_Regular(T),*value_p*p);
							 | 
						||
| 
								 | 
							
								          index=Cudd_NodeReadIndex(T);
							 | 
						||
| 
								 | 
							
								          position=Cudd_ReadPerm(mgr,index);
							 | 
						||
| 
								 | 
							
								          nodesToVisit[position]=(DdNode **)realloc(nodesToVisit[position],
							 | 
						||
| 
								 | 
							
									    (NnodesToVisit[position]+1)* sizeof(DdNode *));
							 | 
						||
| 
								 | 
							
								          nodesToVisit[position][NnodesToVisit[position]]=T;
							 | 
						||
| 
								 | 
							
								          NnodesToVisit[position]=NnodesToVisit[position]+1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if (!Cudd_IsConstant(E)) 
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        value_p_F=get_value(nodesF,Cudd_Regular(E));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (value_p_F!= NULL)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          *value_p_F= *value_p_F+*value_p*(1-p);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          add_or_replace_node(nodesF,Cudd_Regular(E),*value_p*(1-p));
							 | 
						||
| 
								 | 
							
								          index=Cudd_NodeReadIndex(E);
							 | 
						||
| 
								 | 
							
								          position=Cudd_ReadPerm(mgr,index);
							 | 
						||
| 
								 | 
							
								          nodesToVisit[position]=(DdNode **)realloc(nodesToVisit[position],
							 | 
						||
| 
								 | 
							
									    (NnodesToVisit[position]+1)* sizeof(DdNode *));
							 | 
						||
| 
								 | 
							
								          nodesToVisit[position][NnodesToVisit[position]]=E;
							 | 
						||
| 
								 | 
							
								          NnodesToVisit[position]=NnodesToVisit[position]+1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int indexMvar(DdNode * node)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int index,mVarIndex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  index=Cudd_NodeReadIndex(node);
							 | 
						||
| 
								 | 
							
								  mVarIndex=bVar2mVar[index];
							 | 
						||
| 
								 | 
							
								  return mVarIndex;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								double GetOutsideExpe(DdNode *root,double ex_prob)  
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int i,j,mVarIndex,bVarIndex;
							 | 
						||
| 
								 | 
							
								  double **eta_rule;
							 | 
						||
| 
								 | 
							
								  double theta,rootProb, T=0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  sigma=(double *)malloc(*boolVars * sizeof(double));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (j=0; j<*boolVars; j++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    sigma[j]=0;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  for (j=0; j<nRules; j++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    for (i=0; i<rules[j]-1; i++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      eta_temp[j][i][0]=0;
							 | 
						||
| 
								 | 
							
								      eta_temp[j][i][1]=0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  rootProb=ProbPath(root,0);
							 | 
						||
| 
								 | 
							
								  if (rootProb>0.0)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    for (j=0; j<*boolVars; j++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      T += sigma[j];
							 | 
						||
| 
								 | 
							
								      bVarIndex=Cudd_ReadInvPerm(mgr,j);
							 | 
						||
| 
								 | 
							
								      if (bVarIndex==-1)  
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        bVarIndex=j;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      mVarIndex=bVar2mVar[bVarIndex];
							 | 
						||
| 
								 | 
							
								      eta_rule=eta_temp[vars[mVarIndex].nRule];
							 | 
						||
| 
								 | 
							
								      for (i=0; i<vars[mVarIndex].nVal-1;i++)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        theta=probs[bVarIndex];
							 | 
						||
| 
								 | 
							
								        eta_rule[i][0]=eta_rule[i][0]+T*(1-theta);
							 | 
						||
| 
								 | 
							
								        eta_rule[i][1]=eta_rule[i][1]+T*theta;
							 | 
						||
| 
								 | 
							
								      }   
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (j=0; j<nRules; j++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      for (i=0; i<rules[j]-1; i++)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        eta[j][i][0]=eta[j][i][0]+eta_temp[j][i][0]*ex_prob/rootProb;
							 | 
						||
| 
								 | 
							
								        eta[j][i][1]=eta[j][i][1]+eta_temp[j][i][1]*ex_prob/rootProb;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  free(sigma);
							 | 
						||
| 
								 | 
							
								  return rootProb;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void Maximization(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int r,i,j,e;
							 | 
						||
| 
								 | 
							
								  double sum=0;
							 | 
						||
| 
								 | 
							
								  double *probs_rule,**eta_rule;  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (r=0;r<nRules;r++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    eta_rule=eta[r];
							 | 
						||
| 
								 | 
							
								    for (i=0;i<rules[r]-1;i++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      sum=(eta_rule[i][0]+eta_rule[i][1]);
							 | 
						||
| 
								 | 
							
								      if (sum==0.0)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        arrayprob[r][i]=0;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      else 
							 | 
						||
| 
								 | 
							
								        arrayprob[r][i]=eta_rule[i][1]/sum;    
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for(e=0;e<ex;e++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    nVars=nVars_ex+e;
							 | 
						||
| 
								 | 
							
								    probs=probs_ex[e];
							 | 
						||
| 
								 | 
							
								    vars=vars_ex[e];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (j=0;j<*nVars;j++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      r=vars[j].nRule;
							 | 
						||
| 
								 | 
							
								      probs_rule=arrayprob[r];
							 | 
						||
| 
								 | 
							
								      for(i=0;i<rules[r]-1;i++)
							 | 
						||
| 
								 | 
							
								      {    
							 | 
						||
| 
								 | 
							
								        probs[vars[j].firstBoolVar+i]=probs_rule[i];     
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int randomize(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int i,j,e,rule;
							 | 
						||
| 
								 | 
							
								  double * theta,p0;
							 | 
						||
| 
								 | 
							
								  double pmass,par;
							 | 
						||
| 
								 | 
							
								  double **Theta_rules;
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  Theta_rules=(double **)malloc(nRules *sizeof(double *));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (j=0;j<nRules;j++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    Theta_rules[j]=(double *)malloc(rules[j]*sizeof(double));
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (j=0;j<nRules;j++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    theta=Theta_rules[j];
							 | 
						||
| 
								 | 
							
								    pmass=0;
							 | 
						||
| 
								 | 
							
								    for (i=0;i<rules[j]-1;i++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      par=((double)rand())/RAND_MAX*(1-pmass);
							 | 
						||
| 
								 | 
							
								      pmass=pmass+par;
							 | 
						||
| 
								 | 
							
								      theta[i]=par;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    theta[rules[j]-1]=1-pmass;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  for(e=0;e<ex;e++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    nVars=nVars_ex+e;
							 | 
						||
| 
								 | 
							
								    probs=probs_ex[e];
							 | 
						||
| 
								 | 
							
								    vars=vars_ex[e];
							 | 
						||
| 
								 | 
							
								    for (j=0; j<*nVars; j++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      rule=vars[j].nRule;
							 | 
						||
| 
								 | 
							
								      theta=Theta_rules[rule];
							 | 
						||
| 
								 | 
							
								      p0=1;
							 | 
						||
| 
								 | 
							
								      for (i=0; i<vars[j].nVal-1;i++)  
							 | 
						||
| 
								 | 
							
								      {    
							 | 
						||
| 
								 | 
							
								        probs[vars[j].firstBoolVar+i]=theta[i]/p0;
							 | 
						||
| 
								 | 
							
								        p0=p0*(1-theta[i]/p0);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  for (j=0;j<nRules;j++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    free(Theta_rules[j]);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  free(Theta_rules);
							 | 
						||
| 
								 | 
							
								  return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int EM(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2,arg3,arg4,arg5,arg6,arg7,
							 | 
						||
| 
								 | 
							
								    out1,out2,nodesTerm,ruleTerm,tail,pair,compoundTerm;
							 | 
						||
| 
								 | 
							
								  DdNode * node1,**nodes_ex;
							 | 
						||
| 
								 | 
							
								  int r,lenNodes,i,iter;
							 | 
						||
| 
								 | 
							
								  long iter1;
							 | 
						||
| 
								 | 
							
								  double CLL0= -2.2*pow(10,10); //-inf
							 | 
						||
| 
								 | 
							
								  double CLL1= -1.7*pow(10,8);  //+inf   
							 | 
						||
| 
								 | 
							
								  double p,p0,**eta_rule,ea,er; 
							 | 
						||
| 
								 | 
							
								  double ratio,diff;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								  arg3=YAP_ARG3;
							 | 
						||
| 
								 | 
							
								  arg4=YAP_ARG4;
							 | 
						||
| 
								 | 
							
								  arg5=YAP_ARG5;
							 | 
						||
| 
								 | 
							
								  arg6=YAP_ARG6;
							 | 
						||
| 
								 | 
							
								  arg7=YAP_ARG7;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  nodesTerm=arg1; 
							 | 
						||
| 
								 | 
							
								  ea=YAP_FloatOfTerm(arg2);
							 | 
						||
| 
								 | 
							
								  er=YAP_FloatOfTerm(arg3);
							 | 
						||
| 
								 | 
							
								  lenNodes=YAP_IntOfTerm(arg4);  
							 | 
						||
| 
								 | 
							
								  iter=YAP_IntOfTerm(arg5);  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  nodes_ex=(DdNode **)malloc(lenNodes*sizeof(DdNode*));
							 | 
						||
| 
								 | 
							
								  nodes_probs_ex=(double *)malloc(lenNodes*sizeof(double));
							 | 
						||
| 
								 | 
							
								  example_prob=(double *)malloc(lenNodes*sizeof(double));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (i=0;i<lenNodes;i++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    pair=YAP_HeadOfTerm(nodesTerm);
							 | 
						||
| 
								 | 
							
								    node1=(DdNode *)YAP_IntOfTerm(YAP_HeadOfTerm(pair));
							 | 
						||
| 
								 | 
							
								    nodes_ex[i]=node1;
							 | 
						||
| 
								 | 
							
								    pair=YAP_TailOfTerm(pair);
							 | 
						||
| 
								 | 
							
								    example_prob[i]=YAP_FloatOfTerm(YAP_HeadOfTerm(pair));
							 | 
						||
| 
								 | 
							
								    nodesTerm=YAP_TailOfTerm(nodesTerm);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  diff=CLL1-CLL0;
							 | 
						||
| 
								 | 
							
								  ratio=diff/fabs(CLL0);
							 | 
						||
| 
								 | 
							
								  if (iter==-1)
							 | 
						||
| 
								 | 
							
								    iter1= 2147000000;
							 | 
						||
| 
								 | 
							
								  else iter1=iter;
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  while  ( (diff>ea) && (ratio>er) && (cycle<iter1) )
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    cycle++;
							 | 
						||
| 
								 | 
							
								    for (r=0;r<nRules;r++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      for (i=0;i<rules[r]-1;i++)  
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        eta_rule=eta[r];
							 | 
						||
| 
								 | 
							
								        eta_rule[i][0]=0;
							 | 
						||
| 
								 | 
							
								        eta_rule[i][1]=0;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    CLL0 = CLL1;
							 | 
						||
| 
								 | 
							
								    CLL1 = Expectation(nodes_ex,lenNodes);
							 | 
						||
| 
								 | 
							
								    Maximization();
							 | 
						||
| 
								 | 
							
								    diff=CLL1-CLL0;
							 | 
						||
| 
								 | 
							
								    ratio=diff/fabs(CLL0);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  out2= YAP_TermNil();
							 | 
						||
| 
								 | 
							
								  for (r=0; r<nRules; r++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    tail=YAP_TermNil();
							 | 
						||
| 
								 | 
							
								    p0=1;
							 | 
						||
| 
								 | 
							
								    for (i=0;i<rules[r]-1;i++)  
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      p=arrayprob[r][i]*p0;
							 | 
						||
| 
								 | 
							
								      tail=YAP_MkPairTerm(YAP_MkFloatTerm(p),tail);
							 | 
						||
| 
								 | 
							
								      p0=p0*(1-arrayprob[r][i]); 
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    tail=YAP_MkPairTerm(YAP_MkFloatTerm(p0),tail);  
							 | 
						||
| 
								 | 
							
								    ruleTerm=YAP_MkIntTerm(r);
							 | 
						||
| 
								 | 
							
								    compoundTerm=YAP_MkPairTerm(ruleTerm,YAP_MkPairTerm(tail,YAP_TermNil()));
							 | 
						||
| 
								 | 
							
								    out2=YAP_MkPairTerm(compoundTerm,out2);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  out1=YAP_MkFloatTerm(CLL1);
							 | 
						||
| 
								 | 
							
								  YAP_Unify(out1,arg6);
							 | 
						||
| 
								 | 
							
								  free(nodes_ex);
							 | 
						||
| 
								 | 
							
								  free(example_prob);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return (YAP_Unify(out2,arg7));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int Q(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2,arg3,arg4,out,out1,
							 | 
						||
| 
								 | 
							
								    term,nodesTerm,ruleTerm,tail,pair,compoundTerm;
							 | 
						||
| 
								 | 
							
								  DdNode * node1,**nodes_ex;
							 | 
						||
| 
								 | 
							
								  int r,lenNodes,i;
							 | 
						||
| 
								 | 
							
								  double p1,p0,**eta_rule,CLL; 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								  arg3=YAP_ARG3;
							 | 
						||
| 
								 | 
							
								  arg4=YAP_ARG4;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  nodesTerm=arg1; 
							 | 
						||
| 
								 | 
							
								  lenNodes=YAP_IntOfTerm(arg2);  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  nodes_ex=(DdNode **)malloc(lenNodes*sizeof(DdNode*));
							 | 
						||
| 
								 | 
							
								  example_prob=(double *)malloc(lenNodes*sizeof(double));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (i=0;i<lenNodes;i++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    pair=YAP_HeadOfTerm(nodesTerm);
							 | 
						||
| 
								 | 
							
								    node1=(DdNode *)YAP_IntOfTerm(YAP_HeadOfTerm(pair));
							 | 
						||
| 
								 | 
							
								    nodes_ex[i]=node1;
							 | 
						||
| 
								 | 
							
								    pair=YAP_TailOfTerm(pair);
							 | 
						||
| 
								 | 
							
								    example_prob[i]=YAP_FloatOfTerm(YAP_HeadOfTerm(pair));
							 | 
						||
| 
								 | 
							
								    nodesTerm=YAP_TailOfTerm(nodesTerm);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (r=0;r<nRules;r++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    for (i=0;i<rules[r]-1;i++)  
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      eta_rule=eta[r];
							 | 
						||
| 
								 | 
							
								      eta_rule[i][0]=0;
							 | 
						||
| 
								 | 
							
								      eta_rule[i][1]=0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  CLL=Expectation(nodes_ex,lenNodes);
							 | 
						||
| 
								 | 
							
								  out= YAP_TermNil();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (r=0; r<nRules; r++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    tail=YAP_TermNil();
							 | 
						||
| 
								 | 
							
								    eta_rule=eta[r];    
							 | 
						||
| 
								 | 
							
								    for (i=0;i<rules[r]-1;i++)  
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      p0=eta_rule[i][0];
							 | 
						||
| 
								 | 
							
								      p1=eta_rule[i][1];
							 | 
						||
| 
								 | 
							
								      term=YAP_MkPairTerm(YAP_MkFloatTerm(p0),
							 | 
						||
| 
								 | 
							
								        YAP_MkPairTerm(YAP_MkFloatTerm(p1),YAP_TermNil()));
							 | 
						||
| 
								 | 
							
								      tail=YAP_MkPairTerm(term,tail);    
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ruleTerm=YAP_MkIntTerm(r);
							 | 
						||
| 
								 | 
							
								    compoundTerm=YAP_MkPairTerm(ruleTerm,YAP_MkPairTerm(tail,YAP_TermNil()));
							 | 
						||
| 
								 | 
							
								    out=YAP_MkPairTerm(compoundTerm,out);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  free(nodes_ex);
							 | 
						||
| 
								 | 
							
								  free(example_prob);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  out1=YAP_MkFloatTerm(CLL);
							 | 
						||
| 
								 | 
							
								  YAP_Unify(out1,arg4);
							 | 
						||
| 
								 | 
							
								  return (YAP_Unify(out,arg3));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int paths_to_non_zero(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  double paths;
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2,out;
							 | 
						||
| 
								 | 
							
								  DdNode * node;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								  node=(DdNode *)YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								  paths=Cudd_CountPathsToNonZero(node);
							 | 
						||
| 
								 | 
							
								  out=YAP_MkFloatTerm(paths);
							 | 
						||
| 
								 | 
							
								  return(YAP_Unify(out,arg2));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int paths(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  double paths;
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2,out;
							 | 
						||
| 
								 | 
							
								  DdNode * node;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								  node=(DdNode *)YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								  paths=Cudd_CountPath(node);
							 | 
						||
| 
								 | 
							
								  out=YAP_MkFloatTerm(paths);
							 | 
						||
| 
								 | 
							
								  return(YAP_Unify(out,arg2));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int dag_size(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int size;
							 | 
						||
| 
								 | 
							
								  YAP_Term arg1,arg2,out;
							 | 
						||
| 
								 | 
							
								  DdNode * node;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  arg1=YAP_ARG1;
							 | 
						||
| 
								 | 
							
								  arg2=YAP_ARG2;
							 | 
						||
| 
								 | 
							
								  node=(DdNode *)YAP_IntOfTerm(arg1);
							 | 
						||
| 
								 | 
							
								  size=Cudd_DagSize(node);
							 | 
						||
| 
								 | 
							
								  out=YAP_MkIntTerm(size);
							 | 
						||
| 
								 | 
							
								  return(YAP_Unify(out,arg2));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void init_my_predicates()
							 | 
						||
| 
								 | 
							
								/* function required by YAP for intitializing the predicates defined by a C function*/
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("init",init,2);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("init_bdd",init_bdd,0);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("end",end,0);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("end_bdd",end_bdd,0);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("add_var",add_var,4);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("equality",equality,3);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("and",and,3);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("one",one,1);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("zero",zero,1);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("or",or,3);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("bdd_not",bdd_not,2);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("create_dot",create_dot,2);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("init_test",init_test,1);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("end_test",end_test,0);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("ret_prob",ret_prob,2);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("em",EM,7);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("q",Q,4);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("randomize",randomize,0);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("deref",rec_deref,1);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("garbage_collect",garbage_collect,2);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("bdd_to_add",bdd_to_add,2);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("paths_to_non_zero",paths_to_non_zero,2);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("paths",paths,2);
							 | 
						||
| 
								 | 
							
								  YAP_UserCPredicate("dag_size",dag_size,2);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								FILE * open_file(char *filename, const char *mode)
							 | 
						||
| 
								 | 
							
								/* opens a file */
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  FILE *fp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if ((fp = fopen(filename, mode)) == NULL) 
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    perror(filename);
							 | 
						||
| 
								 | 
							
								    exit(1);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return fp;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								tablerow* init_table(int varcnt) {
							 | 
						||
| 
								 | 
							
								  int i;
							 | 
						||
| 
								 | 
							
								  tablerow *tab;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  tab = (tablerow *) malloc(sizeof(rowel) * varcnt);
							 | 
						||
| 
								 | 
							
								  for (i = 0; i < varcnt; 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;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void add_or_replace_node(tablerow *tab, DdNode *node, double value)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int i;
							 | 
						||
| 
								 | 
							
								  int index = Cudd_NodeReadIndex(node);
							 | 
						||
| 
								 | 
							
								  for(i = 0; i < tab[index].cnt; i++) 
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    if (tab[index].row[i].key == node) 
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      tab[index].row[i].value=value;
							 | 
						||
| 
								 | 
							
								      return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  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;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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 varcnt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (i = 0; i < varcnt; i++) 
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    free(tab[i].row);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  free(tab);
							 | 
						||
| 
								 | 
							
								}
							 |