diff --git a/prism/include/odd.h b/prism/include/odd.h index ce9a60c9..36844323 100644 --- a/prism/include/odd.h +++ b/prism/include/odd.h @@ -33,6 +33,13 @@ #include #include +// Flags for building Windows DLLs +#ifdef __MINGW32__ + #define EXPORT __declspec(dllexport) +#else + #define EXPORT +#endif + // odd definitions typedef struct ODDNode ODDNode; @@ -52,6 +59,7 @@ struct ODDNode ODDNode *build_odd(DdManager *ddman, DdNode *dd, DdNode **vars, int num_vars); int get_index_of_first_from_bdd(DdManager *ddman, DdNode *dd, DdNode **vars, int num_vars, ODDNode *odd); +EXPORT DdNode *single_index_to_bdd(DdManager *ddman, int i, DdNode **vars, int num_vars, ODDNode *odd); int get_num_odd_nodes(); //------------------------------------------------------------------------------ diff --git a/prism/src/odd/odd.cc b/prism/src/odd/odd.cc index 6614cf0f..187e1b7e 100644 --- a/prism/src/odd/odd.cc +++ b/prism/src/odd/odd.cc @@ -32,6 +32,7 @@ static int num_odd_nodes = 0; // local prototypes static ODDNode *build_odd_rec(DdManager *ddman, DdNode *dd, int level, DdNode **vars, int num_vars, ODDNode **tables); static long add_offsets(DdManager *ddman, ODDNode *dd, int level, int num_vars); +static DdNode *single_index_to_bdd_rec(DdManager *ddman, int i, DdNode **vars, int num_vars, int level, ODDNode *odd, long o); //------------------------------------------------------------------------------ @@ -162,6 +163,34 @@ int get_index_of_first_from_bdd(DdManager *ddman, DdNode *dd, DdNode **vars, int return index; } +// Get a BDD for a single state given its index and the accompanying ODD. + +EXPORT DdNode *single_index_to_bdd(DdManager *ddman, int i, DdNode **vars, int num_vars, ODDNode *odd) +{ + return single_index_to_bdd_rec(ddman, i, vars, num_vars, 0, odd, 0); +} + +DdNode *single_index_to_bdd_rec(DdManager *ddman, int i, DdNode **vars, int num_vars, int level, ODDNode *odd, long o) +{ + DdNode *dd; + + if (level == num_vars) { + return DD_Constant(ddman, 1); + } + else { + if (odd->eoff > i - o) { + dd = single_index_to_bdd_rec(ddman, i, vars, num_vars, level+1, odd->e, o); + Cudd_Ref(vars[level]); + return DD_And(ddman, DD_Not(ddman, vars[level]), dd); + } + else { + dd = single_index_to_bdd_rec(ddman, i, vars, num_vars, level+1, odd->t, o+odd->eoff); + Cudd_Ref(vars[level]); + return DD_And(ddman, vars[level], dd); + } + } +} + //------------------------------------------------------------------------------ int get_num_odd_nodes()