diff --git a/resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h b/resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h
index 8e3686170..5a2c2f952 100644
--- a/resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h
+++ b/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);
diff --git a/resources/3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c b/resources/3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c
index 5e809c134..7d774586c 100644
--- a/resources/3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c
+++ b/resources/3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c
@@ -11,12 +11,16 @@
Cudd_addExistAbstract()
Cudd_addUnivAbstract()
Cudd_addOrAbstract()
+ Cudd_addMinAbstract()
+ Cudd_addMaxAbstract()
Internal procedures included in this module:
- cuddAddExistAbstractRecur()
- cuddAddUnivAbstractRecur()
- cuddAddOrAbstractRecur()
+
- cuddAddMinAbstractRecur()
+
- cuddAddMaxAbstractRecur()
Static procedures included in this module:
@@ -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 */
diff --git a/resources/3rdparty/cudd-2.5.0/src/cudd/cuddInt.h b/resources/3rdparty/cudd-2.5.0/src/cudd/cuddInt.h
index 398b057f7..313a56586 100644
--- a/resources/3rdparty/cudd-2.5.0/src/cudd/cuddInt.h
+++ b/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);
diff --git a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
index ffbaaf826..c9fcf7b11 100644
--- a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
+++ b/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(
diff --git a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
index 0dce65989..a1a859490 100644
--- a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
+++ b/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;
diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 6fbf38a11..d2c69c3c5 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -15,6 +15,10 @@ namespace storm {
return this->cuddAdd == other.getCuddAdd();
}
+ bool Dd::operator!=(Dd const& other) const {
+ return this->cuddAdd == other.getCuddAdd();
+ }
+
Dd Dd::operator+(Dd const& other) const {
Dd result(*this);
result += other;
@@ -67,7 +71,7 @@ namespace storm {
}
Dd& Dd::operator/=(Dd 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 Dd::equals(Dd const& other) const {
Dd result(*this);
- result.getCuddAdd().Equals(other.getCuddAdd());
+ result.cuddAdd = result.cuddAdd.Equals(other.getCuddAdd());
return result;
}
Dd Dd::notEquals(Dd const& other) const {
Dd result(*this);
- result.getCuddAdd().NotEquals(other.getCuddAdd());
+ result.cuddAdd = result.cuddAdd.NotEquals(other.getCuddAdd());
return result;
}
Dd Dd::less(Dd const& other) const {
Dd result(*this);
- result.getCuddAdd().LessThan(other.getCuddAdd());
+ result.cuddAdd = result.cuddAdd.LessThan(other.getCuddAdd());
return result;
}
Dd Dd::lessOrEqual(Dd const& other) const {
Dd result(*this);
- result.getCuddAdd().LessThanOrEqual(other.getCuddAdd());
+ result.cuddAdd = result.cuddAdd.LessThanOrEqual(other.getCuddAdd());
return result;
}
Dd Dd::greater(Dd const& other) const {
Dd result(*this);
- result.getCuddAdd().GreaterThan(other.getCuddAdd());
+ result.cuddAdd = result.cuddAdd.GreaterThan(other.getCuddAdd());
return result;
}
Dd Dd::greaterOrEqual(Dd const& other) const {
Dd 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::sumAbstract(std::set 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::minAbstract(std::set 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::maxAbstract(std::set 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::swapVariables(std::vector> 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 Dd::multiplyMatrix(Dd const& otherMatrix, std::set const& summationMetaVariableNames) {
@@ -243,7 +247,6 @@ namespace storm {
return Dd(this->getDdManager(), this->cuddAdd.MatrixMultiply(otherMatrix.getCuddAdd(), summationDdVariables), containedMetaVariableNames);
}
-
uint_fast64_t Dd::getNonZeroCount() const {
std::size_t numberOfDdVariables = 0;
@@ -310,6 +313,7 @@ namespace storm {
}
Dd value = *this * valueEncoding;
+ value.sumAbstract(this->getContainedMetaVariableNames());
return static_cast(Cudd_V(value.getCuddAdd().getNode()));
}
@@ -321,6 +325,10 @@ namespace storm {
return *this == this->getDdManager()->getZero();
}
+ bool Dd::isConstant() const {
+ return Cudd_IsConstant(this->cuddAdd.getNode());
+ }
+
bool Dd::containsMetaVariable(std::string const& metaVariableName) const {
auto const& metaVariable = containedMetaVariableNames.find(metaVariableName);
return metaVariable != containedMetaVariableNames.end();
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 0a665108e..80cf88f3a 100644
--- a/src/storage/dd/CuddDd.h
+++ b/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 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 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 const& metaVariableNameToValueMap, double targetValue);
+ void setValue(std::map const& metaVariableNameToValueMap = std::map(), 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 const& metaVariableNameToValueMap) const;
+ double getValue(std::map const& metaVariableNameToValueMap = std::map()) 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.
*
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 245b1f283..959bc5db0 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -7,7 +7,6 @@
TEST(CuddDdManager, Constants) {
std::shared_ptr> manager(new storm::dd::DdManager());
-
storm::dd::Dd zero;
ASSERT_NO_THROW(zero = manager->getZero());
@@ -38,7 +37,6 @@ TEST(CuddDdManager, Constants) {
TEST(CuddDdManager, AddGetMetaVariableTest) {
std::shared_ptr> manager(new storm::dd::DdManager());
-
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> manager(new storm::dd::DdManager());
-
- ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
+ manager->addMetaVariable("x", 1, 9);
storm::dd::Dd encoding;
ASSERT_THROW(encoding = manager->getEncoding("x", 0), storm::exceptions::InvalidArgumentException);
@@ -78,7 +75,6 @@ TEST(CuddDdManager, EncodingTest) {
TEST(CuddDdManager, RangeTest) {
std::shared_ptr> manager(new storm::dd::DdManager());
-
ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
storm::dd::Dd range;
@@ -92,8 +88,7 @@ TEST(CuddDdManager, RangeTest) {
TEST(CuddDdManager, IdentityTest) {
std::shared_ptr> manager(new storm::dd::DdManager());
-
- ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
+ manager->addMetaVariable("x", 1, 9);
storm::dd::Dd range;
ASSERT_THROW(range = manager->getIdentity("y"), storm::exceptions::InvalidArgumentException);
@@ -106,8 +101,7 @@ TEST(CuddDdManager, IdentityTest) {
TEST(CuddDdMetaVariable, AccessorTest) {
std::shared_ptr> manager(new storm::dd::DdManager());
-
- ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
+ manager->addMetaVariable("x", 1, 9);
EXPECT_EQ(1, manager->getNumberOfMetaVariables());
ASSERT_NO_THROW(storm::dd::DdMetaVariable const& metaVariableX = manager->getMetaVariable("x"));
storm::dd::DdMetaVariable const& metaVariableX = manager->getMetaVariable("x");
@@ -119,13 +113,150 @@ TEST(CuddDdMetaVariable, AccessorTest) {
EXPECT_EQ(4, metaVariableX.getNumberOfDdVariables());
}
-//TEST(CuddDd, OperatorTest) {
-// std::shared_ptr> manager(new storm::dd::DdManager());
-//
-// ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
-// EXPECT_EQ(manager->getZero(), manager->getZero());
-// EXPECT_NE(manager->getZero(), manager->getOne());
-//
-// storm::dd::Dd add;
-//
-//}
+TEST(CuddDd, OperatorTest) {
+ std::shared_ptr> manager(new storm::dd::DdManager());
+ manager->addMetaVariable("x", 1, 9);
+ EXPECT_TRUE(manager->getZero() == manager->getZero());
+ EXPECT_FALSE(manager->getZero() == manager->getOne());
+
+ storm::dd::Dd dd1 = manager->getOne();
+ storm::dd::Dd dd2 = manager->getOne();
+ storm::dd::Dd 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 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> manager(new storm::dd::DdManager());
+ manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
+ storm::dd::Dd dd1;
+ storm::dd::Dd dd2;
+ storm::dd::Dd 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> manager(new storm::dd::DdManager());
+
+ manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
+ manager->addMetaVariable("z", 2, 8);
+ storm::dd::Dd dd1;
+ storm::dd::Dd 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> manager(new storm::dd::DdManager());
+ manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
+
+ storm::dd::Dd dd1 = manager->getIdentity("x").equals(manager->getIdentity("x'"));
+ storm::dd::Dd dd2 = manager->getRange("x'");
+ storm::dd::Dd 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> manager(new storm::dd::DdManager());
+ manager->addMetaVariable("x", 1, 9);
+
+ storm::dd::Dd dd1 = manager->getOne();
+ ASSERT_NO_THROW(dd1.setValue("x", 4, 2));
+ EXPECT_EQ(2, dd1.getLeafCount());
+ dd1.exportToDot("dd1.dot");
+
+ std::map metaVariableToValueMap;
+ metaVariableToValueMap.emplace("x", 1);
+ EXPECT_EQ(1, dd1.getValue(metaVariableToValueMap));
+
+ metaVariableToValueMap.clear();
+ metaVariableToValueMap.emplace("x", 4);
+ EXPECT_EQ(2, dd1.getValue(metaVariableToValueMap));
+}