Browse Source

Added min/max abstract over DD variables to CUDD (actual code taken from PRISM). Added more tests for DD layer. Fixed some bugs in the DD layer.

Former-commit-id: a4b7810137
tempestpy_adaptions
dehnert 11 years ago
parent
commit
88d9f36ef4
  1. 2
      resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h
  2. 261
      resources/3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c
  3. 2
      resources/3rdparty/cudd-2.5.0/src/cudd/cuddInt.h
  4. 17
      resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
  5. 2
      resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
  6. 34
      src/storage/dd/CuddDd.cpp
  7. 20
      src/storage/dd/CuddDd.h
  8. 169
      test/functional/storage/CuddDdTest.cpp

2
resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h

@ -767,6 +767,8 @@ extern int Cudd_bddVarIsBound (DdManager *dd, int index);
extern DdNode * Cudd_addExistAbstract (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * Cudd_addUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * Cudd_addOrAbstract (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * Cudd_addMinAbstract(DdManager * manager, DdNode * f, DdNode * cube);
extern DdNode * Cudd_addMaxAbstract(DdManager * manager, DdNode * f, DdNode * cube);
extern DdNode * Cudd_addApply (DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g);
extern DdNode * Cudd_addPlus (DdManager *dd, DdNode **f, DdNode **g);
extern DdNode * Cudd_addTimes (DdManager *dd, DdNode **f, DdNode **g);

261
resources/3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c

@ -11,12 +11,16 @@
<li> Cudd_addExistAbstract()
<li> Cudd_addUnivAbstract()
<li> Cudd_addOrAbstract()
<li> Cudd_addMinAbstract()
<li> Cudd_addMaxAbstract()
</ul>
Internal procedures included in this module:
<ul>
<li> cuddAddExistAbstractRecur()
<li> cuddAddUnivAbstractRecur()
<li> cuddAddOrAbstractRecur()
<li> cuddAddMinAbstractRecur()
<li> cuddAddMaxAbstractRecur()
</ul>
Static procedures included in this module:
<ul>
@ -229,6 +233,82 @@ Cudd_addOrAbstract(
} /* end of Cudd_addOrAbstract */
/**Function********************************************************************
Synopsis [Abstracts all the variables in cube from the
ADD f by taking the minimum.]
Description [Abstracts all the variables in cube from the ADD f
by taking the minimum over all possible values taken by the
variables. Returns the abstracted ADD if successful; NULL
otherwise.]
SideEffects [None]
SeeAlso [Cudd_addUnivAbstract Cudd_addExistAbstract]
Note: Added by Dave Parker 14/6/99
******************************************************************************/
DdNode *
Cudd_addMinAbstract(
DdManager * manager,
DdNode * f,
DdNode * cube)
{
DdNode *res;
if (addCheckPositiveCube(manager, cube) == 0) {
(void) fprintf(manager->err,"Error: Can only abstract cubes");
return(NULL);
}
do {
manager->reordered = 0;
res = cuddAddMinAbstractRecur(manager, f, cube);
} while (manager->reordered == 1);
return(res);
} /* end of Cudd_addMinAbstract */
/**Function********************************************************************
Synopsis [Abstracts all the variables in cube from the
ADD f by taking the maximum.]
Description [Abstracts all the variables in cube from the ADD f
by taking the maximum over all possible values taken by the
variables. Returns the abstracted ADD if successful; NULL
otherwise.]
SideEffects [None]
SeeAlso [Cudd_addUnivAbstract Cudd_addExistAbstract]
Note: Added by Dave Parker 14/6/99
******************************************************************************/
DdNode *
Cudd_addMaxAbstract(
DdManager * manager,
DdNode * f,
DdNode * cube)
{
DdNode *res;
if (addCheckPositiveCube(manager, cube) == 0) {
(void) fprintf(manager->err,"Error: Can only abstract cubes");
return(NULL);
}
do {
manager->reordered = 0;
res = cuddAddMaxAbstractRecur(manager, f, cube);
} while (manager->reordered == 1);
return(res);
} /* end of Cudd_addMaxAbstract */
/*---------------------------------------------------------------------------*/
/* Definition of internal functions */
@ -542,7 +622,188 @@ cuddAddOrAbstractRecur(
} /* end of cuddAddOrAbstractRecur */
/**Function********************************************************************
Synopsis [Performs the recursive step of Cudd_addMinAbstract.]
Description [Performs the recursive step of Cudd_addMinAbstract.
Returns the ADD obtained by abstracting the variables of cube from f,
if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
******************************************************************************/
DdNode *
cuddAddMinAbstractRecur(
DdManager * manager,
DdNode * f,
DdNode * cube)
{
DdNode *T, *E, *res, *res1, *res2, *zero;
zero = DD_ZERO(manager);
/* Cube is guaranteed to be a cube at this point. */
if (f == zero || cuddIsConstant(cube)) {
return(f);
}
/* Abstract a variable that does not appear in f. */
if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
res = cuddAddMinAbstractRecur(manager, f, cuddT(cube));
return(res);
}
if ((res = cuddCacheLookup2(manager, Cudd_addMinAbstract, f, cube)) != NULL) {
return(res);
}
T = cuddT(f);
E = cuddE(f);
/* If the two indices are the same, so are their levels. */
if (f->index == cube->index) {
res1 = cuddAddMinAbstractRecur(manager, T, cuddT(cube));
if (res1 == NULL) return(NULL);
cuddRef(res1);
res2 = cuddAddMinAbstractRecur(manager, E, cuddT(cube));
if (res2 == NULL) {
Cudd_RecursiveDeref(manager,res1);
return(NULL);
}
cuddRef(res2);
res = cuddAddApplyRecur(manager, Cudd_addMinimum, res1, res2);
if (res == NULL) {
Cudd_RecursiveDeref(manager,res1);
Cudd_RecursiveDeref(manager,res2);
return(NULL);
}
cuddRef(res);
Cudd_RecursiveDeref(manager,res1);
Cudd_RecursiveDeref(manager,res2);
cuddCacheInsert2(manager, Cudd_addMinAbstract, f, cube, res);
cuddDeref(res);
return(res);
}
else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
res1 = cuddAddMinAbstractRecur(manager, T, cube);
if (res1 == NULL) return(NULL);
cuddRef(res1);
res2 = cuddAddMinAbstractRecur(manager, E, cube);
if (res2 == NULL) {
Cudd_RecursiveDeref(manager,res1);
return(NULL);
}
cuddRef(res2);
res = (res1 == res2) ? res1 :
cuddUniqueInter(manager, (int) f->index, res1, res2);
if (res == NULL) {
Cudd_RecursiveDeref(manager,res1);
Cudd_RecursiveDeref(manager,res2);
return(NULL);
}
cuddDeref(res1);
cuddDeref(res2);
cuddCacheInsert2(manager, Cudd_addMinAbstract, f, cube, res);
return(res);
}
} /* end of cuddAddMinAbstractRecur */
/**Function********************************************************************
Synopsis [Performs the recursive step of Cudd_addMaxAbstract.]
Description [Performs the recursive step of Cudd_addMaxAbstract.
Returns the ADD obtained by abstracting the variables of cube from f,
if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
******************************************************************************/
DdNode *
cuddAddMaxAbstractRecur(
DdManager * manager,
DdNode * f,
DdNode * cube)
{
DdNode *T, *E, *res, *res1, *res2, *zero;
zero = DD_ZERO(manager);
/* Cube is guaranteed to be a cube at this point. */
if (f == zero || cuddIsConstant(cube)) {
return(f);
}
/* Abstract a variable that does not appear in f. */
if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
res = cuddAddMaxAbstractRecur(manager, f, cuddT(cube));
return(res);
}
if ((res = cuddCacheLookup2(manager, Cudd_addMaxAbstract, f, cube)) != NULL) {
return(res);
}
T = cuddT(f);
E = cuddE(f);
/* If the two indices are the same, so are their levels. */
if (f->index == cube->index) {
res1 = cuddAddMaxAbstractRecur(manager, T, cuddT(cube));
if (res1 == NULL) return(NULL);
cuddRef(res1);
res2 = cuddAddMaxAbstractRecur(manager, E, cuddT(cube));
if (res2 == NULL) {
Cudd_RecursiveDeref(manager,res1);
return(NULL);
}
cuddRef(res2);
res = cuddAddApplyRecur(manager, Cudd_addMaximum, res1, res2);
if (res == NULL) {
Cudd_RecursiveDeref(manager,res1);
Cudd_RecursiveDeref(manager,res2);
return(NULL);
}
cuddRef(res);
Cudd_RecursiveDeref(manager,res1);
Cudd_RecursiveDeref(manager,res2);
cuddCacheInsert2(manager, Cudd_addMaxAbstract, f, cube, res);
cuddDeref(res);
return(res);
}
else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
res1 = cuddAddMaxAbstractRecur(manager, T, cube);
if (res1 == NULL) return(NULL);
cuddRef(res1);
res2 = cuddAddMaxAbstractRecur(manager, E, cube);
if (res2 == NULL) {
Cudd_RecursiveDeref(manager,res1);
return(NULL);
}
cuddRef(res2);
res = (res1 == res2) ? res1 :
cuddUniqueInter(manager, (int) f->index, res1, res2);
if (res == NULL) {
Cudd_RecursiveDeref(manager,res1);
Cudd_RecursiveDeref(manager,res2);
return(NULL);
}
cuddDeref(res1);
cuddDeref(res2);
cuddCacheInsert2(manager, Cudd_addMaxAbstract, f, cube, res);
return(res);
}
} /* end of cuddAddMaxAbstractRecur */
/*---------------------------------------------------------------------------*/
/* Definition of static functions */

2
resources/3rdparty/cudd-2.5.0/src/cudd/cuddInt.h

@ -1000,6 +1000,8 @@ dd->nextSample += 250000;}
extern DdNode * cuddAddExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * cuddAddUnivAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * cuddAddOrAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * cuddAddMinAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * cuddAddMaxAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * cuddAddApplyRecur (DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g);
extern DdNode * cuddAddMonadicApplyRecur (DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f);
extern DdNode * cuddAddScalarInverseRecur (DdManager *dd, DdNode *f, DdNode *epsilon);

17
resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc

@ -2405,6 +2405,23 @@ ADD::OrAbstract(
} // ADD::OrAbstract
ADD
ADD::MinAbstract(const ADD& cube) const
{
DdManager *mgr = checkSameManager(cube);
DdNode *result = Cudd_addMinAbstract(mgr, node, cube.node);
checkReturnValue(result);
return ADD(p, result);
} // ADD::MinAbstract
ADD
ADD::MaxAbstract(const ADD& cube) const
{
DdManager *mgr = checkSameManager(cube);
DdNode *result = Cudd_addMaxAbstract(mgr, node, cube.node);
checkReturnValue(result);
return ADD(p, result);
} // ADD::MaxAbstract
ADD
ADD::Plus(

2
resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh

@ -373,6 +373,8 @@ public:
ADD ExistAbstract(const ADD& cube) const;
ADD UnivAbstract(const ADD& cube) const;
ADD OrAbstract(const ADD& cube) const;
ADD MinAbstract(const ADD& cube) const;
ADD MaxAbstract(const ADD& cube) const;
ADD Plus(const ADD& g) const;
ADD Times(const ADD& g) const;
ADD Threshold(const ADD& g) const;

34
src/storage/dd/CuddDd.cpp

@ -15,6 +15,10 @@ namespace storm {
return this->cuddAdd == other.getCuddAdd();
}
bool Dd<CUDD>::operator!=(Dd<CUDD> const& other) const {
return this->cuddAdd == other.getCuddAdd();
}
Dd<CUDD> Dd<CUDD>::operator+(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
result += other;
@ -67,7 +71,7 @@ namespace storm {
}
Dd<CUDD>& Dd<CUDD>::operator/=(Dd<CUDD> const& other) {
this->cuddAdd.Divide(other.getCuddAdd());
this->cuddAdd = this->cuddAdd.Divide(other.getCuddAdd());
// Join the variable sets of the two participating DDs.
this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
@ -88,37 +92,37 @@ namespace storm {
Dd<CUDD> Dd<CUDD>::equals(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
result.getCuddAdd().Equals(other.getCuddAdd());
result.cuddAdd = result.cuddAdd.Equals(other.getCuddAdd());
return result;
}
Dd<CUDD> Dd<CUDD>::notEquals(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
result.getCuddAdd().NotEquals(other.getCuddAdd());
result.cuddAdd = result.cuddAdd.NotEquals(other.getCuddAdd());
return result;
}
Dd<CUDD> Dd<CUDD>::less(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
result.getCuddAdd().LessThan(other.getCuddAdd());
result.cuddAdd = result.cuddAdd.LessThan(other.getCuddAdd());
return result;
}
Dd<CUDD> Dd<CUDD>::lessOrEqual(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
result.getCuddAdd().LessThanOrEqual(other.getCuddAdd());
result.cuddAdd = result.cuddAdd.LessThanOrEqual(other.getCuddAdd());
return result;
}
Dd<CUDD> Dd<CUDD>::greater(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
result.getCuddAdd().GreaterThan(other.getCuddAdd());
result.cuddAdd = result.cuddAdd.GreaterThan(other.getCuddAdd());
return result;
}
Dd<CUDD> Dd<CUDD>::greaterOrEqual(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
result.getCuddAdd().GreaterThanOrEqual(other.getCuddAdd());
result.cuddAdd = result.cuddAdd.GreaterThanOrEqual(other.getCuddAdd());
return result;
}
@ -136,7 +140,7 @@ namespace storm {
cubeDd *= metaVariable.getCube();
}
this->cuddAdd.OrAbstract(cubeDd.getCuddAdd());
this->cuddAdd = this->cuddAdd.OrAbstract(cubeDd.getCuddAdd());
}
void Dd<CUDD>::sumAbstract(std::set<std::string> const& metaVariableNames) {
@ -153,7 +157,7 @@ namespace storm {
cubeDd *= metaVariable.getCube();
}
this->cuddAdd.ExistAbstract(cubeDd.getCuddAdd());
this->cuddAdd = this->cuddAdd.ExistAbstract(cubeDd.getCuddAdd());
}
void Dd<CUDD>::minAbstract(std::set<std::string> const& metaVariableNames) {
@ -170,7 +174,7 @@ namespace storm {
cubeDd *= metaVariable.getCube();
}
this->cuddAdd.Minimum(cubeDd.getCuddAdd());
this->cuddAdd = this->cuddAdd.MinAbstract(cubeDd.getCuddAdd());
}
void Dd<CUDD>::maxAbstract(std::set<std::string> const& metaVariableNames) {
@ -187,7 +191,7 @@ namespace storm {
cubeDd *= metaVariable.getCube();
}
this->cuddAdd.Maximum(cubeDd.getCuddAdd());
this->cuddAdd = this->cuddAdd.MaxAbstract(cubeDd.getCuddAdd());
}
void Dd<CUDD>::swapVariables(std::vector<std::pair<std::string, std::string>> const& metaVariablePairs) {
@ -223,7 +227,7 @@ namespace storm {
}
// Finally, call CUDD to swap the variables.
this->cuddAdd.SwapVariables(from, to);
this->cuddAdd = this->cuddAdd.SwapVariables(from, to);
}
Dd<CUDD> Dd<CUDD>::multiplyMatrix(Dd<CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames) {
@ -243,7 +247,6 @@ namespace storm {
return Dd<CUDD>(this->getDdManager(), this->cuddAdd.MatrixMultiply(otherMatrix.getCuddAdd(), summationDdVariables), containedMetaVariableNames);
}
uint_fast64_t Dd<CUDD>::getNonZeroCount() const {
std::size_t numberOfDdVariables = 0;
@ -310,6 +313,7 @@ namespace storm {
}
Dd<CUDD> value = *this * valueEncoding;
value.sumAbstract(this->getContainedMetaVariableNames());
return static_cast<double>(Cudd_V(value.getCuddAdd().getNode()));
}
@ -321,6 +325,10 @@ namespace storm {
return *this == this->getDdManager()->getZero();
}
bool Dd<CUDD>::isConstant() const {
return Cudd_IsConstant(this->cuddAdd.getNode());
}
bool Dd<CUDD>::containsMetaVariable(std::string const& metaVariableName) const {
auto const& metaVariable = containedMetaVariableNames.find(metaVariableName);
return metaVariable != containedMetaVariableNames.end();

20
src/storage/dd/CuddDd.h

@ -36,9 +36,18 @@ namespace storm {
* Retrieves whether the two DDs represent the same function.
*
* @param other The DD that is to be compared with the current one.
* @return True if the DDs represent the same function.
*/
bool operator==(Dd<CUDD> const& other) const;
/*!
* Retrieves whether the two DDs represent different functions.
*
* @param other The DD that is to be compared with the current one.
* @return True if the DDs represent the different functions.
*/
bool operator!=(Dd<CUDD> const& other) const;
/*!
* Adds the two DDs.
*
@ -295,7 +304,7 @@ namespace storm {
* have. All values must be within the range of the respective meta variable.
* @param targetValue The new function value of the modified encodings.
*/
void setValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue);
void setValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap = std::map<std::string, int_fast64_t>(), double targetValue = 0);
/*!
* Retrieves the value of the function when all meta variables are assigned the values of the given mapping.
@ -304,7 +313,7 @@ namespace storm {
* @param metaVariableNameToValueMap A mapping of meta variable names to their values.
* @return The value of the function evaluated with the given input.
*/
double getValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap) const;
double getValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap = std::map<std::string, int_fast64_t>()) const;
/*!
* Retrieves whether this DD represents the constant one function.
@ -320,6 +329,13 @@ namespace storm {
*/
bool isZero() const;
/*!
* Retrieves whether this DD represents a constant function.
*
* @return True if this DD represents a constants function.
*/
bool isConstant() const;
/*!
* Retrieves whether the given meta variable is contained in the DD.
*

169
test/functional/storage/CuddDdTest.cpp

@ -7,7 +7,6 @@
TEST(CuddDdManager, Constants) {
std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
storm::dd::Dd<storm::dd::CUDD> zero;
ASSERT_NO_THROW(zero = manager->getZero());
@ -38,7 +37,6 @@ TEST(CuddDdManager, Constants) {
TEST(CuddDdManager, AddGetMetaVariableTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
EXPECT_EQ(1, manager->getNumberOfMetaVariables());
@ -64,8 +62,7 @@ TEST(CuddDdManager, AddGetMetaVariableTest) {
TEST(CuddDdManager, EncodingTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
manager->addMetaVariable("x", 1, 9);
storm::dd::Dd<storm::dd::CUDD> encoding;
ASSERT_THROW(encoding = manager->getEncoding("x", 0), storm::exceptions::InvalidArgumentException);
@ -78,7 +75,6 @@ TEST(CuddDdManager, EncodingTest) {
TEST(CuddDdManager, RangeTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
storm::dd::Dd<storm::dd::CUDD> range;
@ -92,8 +88,7 @@ TEST(CuddDdManager, RangeTest) {
TEST(CuddDdManager, IdentityTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
manager->addMetaVariable("x", 1, 9);
storm::dd::Dd<storm::dd::CUDD> range;
ASSERT_THROW(range = manager->getIdentity("y"), storm::exceptions::InvalidArgumentException);
@ -106,8 +101,7 @@ TEST(CuddDdManager, IdentityTest) {
TEST(CuddDdMetaVariable, AccessorTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
manager->addMetaVariable("x", 1, 9);
EXPECT_EQ(1, manager->getNumberOfMetaVariables());
ASSERT_NO_THROW(storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x"));
storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x");
@ -119,13 +113,150 @@ TEST(CuddDdMetaVariable, AccessorTest) {
EXPECT_EQ(4, metaVariableX.getNumberOfDdVariables());
}
//TEST(CuddDd, OperatorTest) {
// std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
//
// ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
// EXPECT_EQ(manager->getZero(), manager->getZero());
// EXPECT_NE(manager->getZero(), manager->getOne());
//
// storm::dd::Dd<storm::dd::CUDD> add;
//
//}
TEST(CuddDd, OperatorTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
manager->addMetaVariable("x", 1, 9);
EXPECT_TRUE(manager->getZero() == manager->getZero());
EXPECT_FALSE(manager->getZero() == manager->getOne());
storm::dd::Dd<storm::dd::CUDD> dd1 = manager->getOne();
storm::dd::Dd<storm::dd::CUDD> dd2 = manager->getOne();
storm::dd::Dd<storm::dd::CUDD> dd3 = dd1 + dd2;
EXPECT_TRUE(dd3 == manager->getConstant(2));
dd3 += manager->getZero();
EXPECT_TRUE(dd3 == manager->getConstant(2));
dd3 = dd1 * manager->getConstant(3);
EXPECT_TRUE(dd3 == manager->getConstant(3));
dd3 *= manager->getConstant(2);
EXPECT_TRUE(dd3 == manager->getConstant(6));
dd3 = dd1 - dd2;
EXPECT_TRUE(dd3 == manager->getZero());
dd3 -= manager->getConstant(-2);
EXPECT_TRUE(dd3 == manager->getConstant(2));
dd3 /= manager->getConstant(2);
EXPECT_TRUE(dd3 == manager->getOne());
dd3.complement();
EXPECT_TRUE(dd3 == manager->getZero());
dd1 = ~dd3;
EXPECT_TRUE(dd1 == manager->getOne());
dd1 = manager->getIdentity("x");
dd2 = manager->getConstant(5);
dd3 = dd1.equals(dd2);
EXPECT_EQ(1, dd3.getNonZeroCount());
storm::dd::Dd<storm::dd::CUDD> dd4 = dd1.notEquals(dd2);
EXPECT_TRUE(dd4 == ~dd3);
dd3 = dd1.less(dd2);
EXPECT_EQ(11, dd3.getNonZeroCount());
dd3 = dd1.lessOrEqual(dd2);
EXPECT_EQ(12, dd3.getNonZeroCount());
dd3 = dd1.greater(dd2);
EXPECT_EQ(4, dd3.getNonZeroCount());
dd3 = dd1.greaterOrEqual(dd2);
EXPECT_EQ(5, dd3.getNonZeroCount());
}
TEST(CuddDd, AbstractionTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
storm::dd::Dd<storm::dd::CUDD> dd1;
storm::dd::Dd<storm::dd::CUDD> dd2;
storm::dd::Dd<storm::dd::CUDD> dd3;
dd1 = manager->getIdentity("x");
dd2 = manager->getConstant(5);
dd3 = dd1.equals(dd2);
EXPECT_EQ(1, dd3.getNonZeroCount());
ASSERT_THROW(dd3.existsAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
ASSERT_NO_THROW(dd3.existsAbstract({"x"}));
EXPECT_EQ(1, dd3.getNonZeroCount());
EXPECT_EQ(1, dd3.getMax());
dd3 = dd1.equals(dd2);
dd3 *= manager->getConstant(3);
EXPECT_EQ(1, dd3.getNonZeroCount());
ASSERT_THROW(dd3.existsAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
ASSERT_NO_THROW(dd3.existsAbstract({"x"}));
EXPECT_TRUE(dd3 == manager->getZero());
dd3 = dd1.equals(dd2);
dd3 *= manager->getConstant(3);
ASSERT_THROW(dd3.sumAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
ASSERT_NO_THROW(dd3.sumAbstract({"x"}));
EXPECT_EQ(1, dd3.getNonZeroCount());
EXPECT_EQ(3, dd3.getMax());
dd3 = dd1.equals(dd2);
dd3 *= manager->getConstant(3);
ASSERT_THROW(dd3.minAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
ASSERT_NO_THROW(dd3.minAbstract({"x"}));
EXPECT_EQ(0, dd3.getNonZeroCount());
EXPECT_EQ(0, dd3.getMax());
dd3 = dd1.equals(dd2);
dd3 *= manager->getConstant(3);
ASSERT_THROW(dd3.maxAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
ASSERT_NO_THROW(dd3.maxAbstract({"x"}));
EXPECT_EQ(1, dd3.getNonZeroCount());
EXPECT_EQ(3, dd3.getMax());
}
TEST(CuddDd, SwapTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
manager->addMetaVariable("z", 2, 8);
storm::dd::Dd<storm::dd::CUDD> dd1;
storm::dd::Dd<storm::dd::CUDD> dd2;
dd1 = manager->getIdentity("x");
ASSERT_THROW(dd1.swapVariables({std::make_pair("x", "z")}), storm::exceptions::InvalidArgumentException);
ASSERT_NO_THROW(dd1.swapVariables({std::make_pair("x", "x'")}));
EXPECT_TRUE(dd1 == manager->getIdentity("x'"));
}
TEST(CuddDd, MultiplyMatrixTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
storm::dd::Dd<storm::dd::CUDD> dd1 = manager->getIdentity("x").equals(manager->getIdentity("x'"));
storm::dd::Dd<storm::dd::CUDD> dd2 = manager->getRange("x'");
storm::dd::Dd<storm::dd::CUDD> dd3;
dd1 *= manager->getConstant(2);
ASSERT_NO_THROW(dd3 = dd1.multiplyMatrix(dd2, {"x'"}));
ASSERT_NO_THROW(dd3.swapVariables({std::make_pair("x", "x'")}));
EXPECT_TRUE(dd3 == dd2 * manager->getConstant(2));
}
TEST(CuddDd, GetSetValueTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
manager->addMetaVariable("x", 1, 9);
storm::dd::Dd<storm::dd::CUDD> dd1 = manager->getOne();
ASSERT_NO_THROW(dd1.setValue("x", 4, 2));
EXPECT_EQ(2, dd1.getLeafCount());
dd1.exportToDot("dd1.dot");
std::map<std::string, int_fast64_t> metaVariableToValueMap;
metaVariableToValueMap.emplace("x", 1);
EXPECT_EQ(1, dd1.getValue(metaVariableToValueMap));
metaVariableToValueMap.clear();
metaVariableToValueMap.emplace("x", 4);
EXPECT_EQ(2, dd1.getValue(metaVariableToValueMap));
}
Loading…
Cancel
Save