From a73c48880c0d27d97d3fedb17405af3945d1bed1 Mon Sep 17 00:00:00 2001 From: PBerger Date: Wed, 13 Jul 2016 15:21:53 +0200 Subject: [PATCH 01/49] Initial commit. The basic Implementation compiles. No tests yet. Former-commit-id: 60b6d0f892ce4ca16aa197483194b025f7526504 --- resources/3rdparty/CMakeLists.txt | 2 +- resources/3rdparty/sylvan/CMakeLists.txt | 18 ++ .../3rdparty/sylvan/examples/CMakeLists.txt | 6 + resources/3rdparty/sylvan/examples/storm.cpp | 127 +++++++++ resources/3rdparty/sylvan/src/CMakeLists.txt | 9 + .../sylvan/src/storm_function_wrapper.cpp | 116 +++++++++ .../sylvan/src/storm_function_wrapper.h | 33 +++ .../src/sylvan_storm_rational_function.c | 240 ++++++++++++++++++ .../src/sylvan_storm_rational_function.h | 87 +++++++ 9 files changed, 637 insertions(+), 1 deletion(-) create mode 100644 resources/3rdparty/sylvan/examples/storm.cpp create mode 100644 resources/3rdparty/sylvan/src/storm_function_wrapper.cpp create mode 100644 resources/3rdparty/sylvan/src/storm_function_wrapper.h create mode 100644 resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c create mode 100644 resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h diff --git a/resources/3rdparty/CMakeLists.txt b/resources/3rdparty/CMakeLists.txt index 9b30445f3..faf6e2663 100644 --- a/resources/3rdparty/CMakeLists.txt +++ b/resources/3rdparty/CMakeLists.txt @@ -47,7 +47,7 @@ ExternalProject_Add( DOWNLOAD_COMMAND "" PREFIX "sylvan" SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sylvan - CMAKE_ARGS -DSYLVAN_BUILD_TEST=Off -DSYLVAN_BUILD_EXAMPLES=Off -DCMAKE_BUILD_TYPE=Release + CMAKE_ARGS -DSYLVAN_BUILD_TEST=Off -DSYLVAN_BUILD_EXAMPLES=On -DCMAKE_BUILD_TYPE=Release BINARY_DIR "${PROJECT_BINARY_DIR}/sylvan" INSTALL_COMMAND "" INSTALL_DIR "${PROJECT_BINARY_DIR}/sylvan" diff --git a/resources/3rdparty/sylvan/CMakeLists.txt b/resources/3rdparty/sylvan/CMakeLists.txt index d9999a0f3..1007c5917 100644 --- a/resources/3rdparty/sylvan/CMakeLists.txt +++ b/resources/3rdparty/sylvan/CMakeLists.txt @@ -5,6 +5,7 @@ enable_testing() set(CMAKE_C_FLAGS "-O3 -Wextra -Wall -Werror -fno-strict-aliasing -std=gnu11 -fPIC") set(CMAKE_CXX_FLAGS "-O3 -Wextra -Wall -Werror -fno-strict-aliasing -Wno-deprecated-register -std=gnu++11 -fPIC") +option(USE_CARL "Sets whether carl should be included." ON) option(WITH_COVERAGE "Add generation of test coverage" OFF) if(WITH_COVERAGE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g -coverage") @@ -28,9 +29,26 @@ if(WITH_COVERAGE) ) endif() +if(USE_CARL) + find_package(carl QUIET REQUIRED) + if(carl_FOUND) + add_definitions(-DSYLVAN_HAVE_CARL) + include_directories("${carl_INCLUDE_DIR}") + list(APPEND STORM_LINK_LIBRARIES ${carl_LIBRARIES}) + message(STATUS "Sylvan - using CARL.") + else() + message(FATAL_ERROR "Sylvan - CARL was requested but not found") + endif() +else() + message(STATUS "Sylvan - not using CARL.") +endif() + + set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) find_package(GMP REQUIRED) include_directories(${GMP_INCLUDE_DIR}) +include_directories("${PROJECT_SOURCE_DIR}/../../../") +include_directories("${PROJECT_BINARY_DIR}/../include") include_directories(src) include_directories(src) diff --git a/resources/3rdparty/sylvan/examples/CMakeLists.txt b/resources/3rdparty/sylvan/examples/CMakeLists.txt index bb335935d..ce2d0d740 100644 --- a/resources/3rdparty/sylvan/examples/CMakeLists.txt +++ b/resources/3rdparty/sylvan/examples/CMakeLists.txt @@ -12,6 +12,12 @@ target_link_libraries(lddmc sylvan) add_executable(simple simple.cpp) target_link_libraries(simple sylvan stdc++) +if(USE_CARL) + message(STATUS "Sylvan - Example for Storm enabled.") + add_executable(storm-rf storm.cpp) + target_link_libraries(storm-rf sylvan stdc++ ${carl_LIBRARIES}) +endif(USE_CARL) + include(CheckIncludeFiles) check_include_files("gperftools/profiler.h" HAVE_PROFILER) diff --git a/resources/3rdparty/sylvan/examples/storm.cpp b/resources/3rdparty/sylvan/examples/storm.cpp new file mode 100644 index 000000000..c9bcfb032 --- /dev/null +++ b/resources/3rdparty/sylvan/examples/storm.cpp @@ -0,0 +1,127 @@ +#ifdef NDEBUG +#undef NDEBUG +#endif + +#include +#include +#include + +#include +#include +#include +#include + +using namespace sylvan; + +VOID_TASK_0(storm_rf) +{ + Bdd one = Bdd::bddOne(); // the True terminal + Bdd zero = Bdd::bddZero(); // the False terminal + + // check if they really are the True/False terminal + assert(one.GetBDD() == sylvan_true); + assert(zero.GetBDD() == sylvan_false); + + Bdd a = Bdd::bddVar(0); // create a BDD variable x_0 + Bdd b = Bdd::bddVar(1); // create a BDD variable x_1 + + // check if a really is the Boolean formula "x_0" + assert(!a.isConstant()); + assert(a.TopVar() == 0); + assert(a.Then() == one); + assert(a.Else() == zero); + + // check if b really is the Boolean formula "x_1" + assert(!b.isConstant()); + assert(b.TopVar() == 1); + assert(b.Then() == one); + assert(b.Else() == zero); + + // compute !a + Bdd not_a = !a; + + // check if !!a is really a + assert((!not_a) == a); + + // compute a * b and !(!a + !b) and check if they are equivalent + Bdd a_and_b = a * b; + Bdd not_not_a_or_not_b = !(!a + !b); + assert(a_and_b == not_not_a_or_not_b); + + // perform some simple quantification and check the results + Bdd ex = a_and_b.ExistAbstract(a); // \exists a . a * b + assert(ex == b); + Bdd andabs = a.AndAbstract(b, a); // \exists a . a * b using AndAbstract + assert(ex == andabs); + Bdd univ = a_and_b.UnivAbstract(a); // \forall a . a * b + assert(univ == zero); + + // alternative method to get the cube "ab" using bddCube + BddSet variables = a * b; + std::vector vec = {1, 1}; + assert(a_and_b == Bdd::bddCube(variables, vec)); + + // test the bddCube method for all combinations + assert((!a * !b) == Bdd::bddCube(variables, std::vector({0, 0}))); + assert((!a * b) == Bdd::bddCube(variables, std::vector({0, 1}))); + assert((!a) == Bdd::bddCube(variables, std::vector({0, 2}))); + assert((a * !b) == Bdd::bddCube(variables, std::vector({1, 0}))); + assert((a * b) == Bdd::bddCube(variables, std::vector({1, 1}))); + assert((a) == Bdd::bddCube(variables, std::vector({1, 2}))); + assert((!b) == Bdd::bddCube(variables, std::vector({2, 0}))); + assert((b) == Bdd::bddCube(variables, std::vector({2, 1}))); + assert(one == Bdd::bddCube(variables, std::vector({2, 2}))); +} + +VOID_TASK_1(_main, void*, arg) +{ + // Initialize Sylvan + // With starting size of the nodes table 1 << 21, and maximum size 1 << 27. + // With starting size of the cache table 1 << 20, and maximum size 1 << 20. + // Memory usage: 24 bytes per node, and 36 bytes per cache bucket + // - 1<<24 nodes: 384 MB + // - 1<<25 nodes: 768 MB + // - 1<<26 nodes: 1536 MB + // - 1<<27 nodes: 3072 MB + // - 1<<24 cache: 576 MB + // - 1<<25 cache: 1152 MB + // - 1<<26 cache: 2304 MB + // - 1<<27 cache: 4608 MB + sylvan_init_package(1LL<<22, 1LL<<26, 1LL<<22, 1LL<<26); + + // Initialize the BDD module with granularity 1 (cache every operation) + // A higher granularity (e.g. 6) often results in better performance in practice + sylvan_init_bdd(1); + + // Now we can do some simple stuff using the C++ objects. + CALL(storm_rf); + + // Report statistics (if SYLVAN_STATS is 1 in the configuration) + sylvan_stats_report(stdout, 1); + + // And quit, freeing memory + sylvan_quit(); + + // We didn't use arg + (void)arg; +} + +int +main (int argc, char *argv[]) +{ + int n_workers = 0; // automatically detect number of workers + size_t deque_size = 0; // default value for the size of task deques for the workers + size_t program_stack_size = 0; // default value for the program stack of each pthread + + // Initialize the Lace framework for workers. + lace_init(n_workers, deque_size); + + // Spawn and start all worker pthreads; suspends current thread until done. + lace_startup(program_stack_size, TASK(_main), NULL); + + // The lace_startup command also exits Lace after _main is completed. + + return 0; + (void)argc; // unused variable + (void)argv; // unused variable +} diff --git a/resources/3rdparty/sylvan/src/CMakeLists.txt b/resources/3rdparty/sylvan/src/CMakeLists.txt index 50a645f22..eb27a6fc4 100644 --- a/resources/3rdparty/sylvan/src/CMakeLists.txt +++ b/resources/3rdparty/sylvan/src/CMakeLists.txt @@ -13,6 +13,8 @@ add_library(sylvan sha2.c stats.h stats.c + storm_function_wrapper.h + storm_function_wrapper.cpp sylvan.h sylvan_bdd.h sylvan_bdd.c @@ -30,6 +32,8 @@ add_library(sylvan sylvan_mtbdd_int.h sylvan_obj.hpp sylvan_obj.cpp + sylvan_storm_rational_function.h + sylvan_storm_rational_function.c tls.h ) @@ -42,6 +46,11 @@ set_target_properties(sylvan PROPERTIES target_link_libraries(sylvan m pthread) +if(USE_CARL) + message(STATUS "Sylvan - linking CARL.") + target_link_libraries(sylvan ${carl_LIBRARIES}) +endif(USE_CARL) + if(UNIX AND NOT APPLE) target_link_libraries(sylvan rt) endif() diff --git a/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp b/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp new file mode 100644 index 000000000..3b9c19679 --- /dev/null +++ b/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp @@ -0,0 +1,116 @@ +#include "storm_function_wrapper.h" + +#include +#include "src/adapters/CarlAdapter.h" + +void storm_rational_function_init(storm_rational_function_ptr* a) { + storm_rational_function_ptr srf_ptr = static_cast(malloc(sizeof(storm_rational_function_ptr_struct))); + + if (srf_ptr == nullptr) { + return; + } + + srf_ptr->storm_rational_function = new storm::RationalFunction(*(storm::RationalFunction*)((*a)->storm_rational_function)); + + *a = srf_ptr; +} + +void storm_rational_function_destroy(storm_rational_function_ptr a) { + delete (storm::RationalFunction*)a->storm_rational_function; + a->storm_rational_function = nullptr; + free((void*)a); +} + +int storm_rational_function_equals(storm_rational_function_ptr a, storm_rational_function_ptr b) { + storm::RationalFunction* srf_a = (storm::RationalFunction*)a->storm_rational_function; + storm::RationalFunction* srf_b = (storm::RationalFunction*)b->storm_rational_function; + + if (*srf_a == *srf_b) { + return 0; + } + + return -1; +} + +storm_rational_function_ptr storm_rational_function_plus(storm_rational_function_ptr a, storm_rational_function_ptr b) { + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; + storm::RationalFunction& srf_b = *(storm::RationalFunction*)b->storm_rational_function; + + storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); + *result_srf += srf_b; + + storm_rational_function_ptr result = (storm_rational_function_ptr)malloc(sizeof(storm_rational_function_ptr_struct)); + result->storm_rational_function = (void*)result_srf; + + return result; +} + +storm_rational_function_ptr storm_rational_function_minus(storm_rational_function_ptr a, storm_rational_function_ptr b) { + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; + storm::RationalFunction& srf_b = *(storm::RationalFunction*)b->storm_rational_function; + + storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); + *result_srf -= srf_b; + + storm_rational_function_ptr result = (storm_rational_function_ptr)malloc(sizeof(storm_rational_function_ptr_struct)); + result->storm_rational_function = (void*)result_srf; + + return result; +} + +storm_rational_function_ptr storm_rational_function_times(storm_rational_function_ptr a, storm_rational_function_ptr b) { + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; + storm::RationalFunction& srf_b = *(storm::RationalFunction*)b->storm_rational_function; + + storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); + *result_srf *= srf_b; + + storm_rational_function_ptr result = (storm_rational_function_ptr)malloc(sizeof(storm_rational_function_ptr_struct)); + result->storm_rational_function = (void*)result_srf; + + return result; +} + +storm_rational_function_ptr storm_rational_function_divide(storm_rational_function_ptr a, storm_rational_function_ptr b) { + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; + storm::RationalFunction& srf_b = *(storm::RationalFunction*)b->storm_rational_function; + + storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); + *result_srf /= srf_b; + + storm_rational_function_ptr result = (storm_rational_function_ptr)malloc(sizeof(storm_rational_function_ptr_struct)); + result->storm_rational_function = (void*)result_srf; + + return result; +} + +uint64_t storm_rational_function_hash(storm_rational_function_ptr const a, uint64_t const seed) { + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; + + size_t hash = carl::hash_value(srf_a); + uint64_t result = hash ^ seed; + + return result; +} + +storm_rational_function_ptr storm_rational_function_negate(storm_rational_function_ptr a) { + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; + + storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); + *result_srf = -srf_a; + + storm_rational_function_ptr result = (storm_rational_function_ptr)malloc(sizeof(storm_rational_function_ptr_struct)); + result->storm_rational_function = (void*)result_srf; + + return result; +} + +int storm_rational_function_is_zero(storm_rational_function_ptr a) { + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; + + if (srf_a.isZero()) { + return 1; + } else { + return 0; + } +} diff --git a/resources/3rdparty/sylvan/src/storm_function_wrapper.h b/resources/3rdparty/sylvan/src/storm_function_wrapper.h new file mode 100644 index 000000000..3feeafec5 --- /dev/null +++ b/resources/3rdparty/sylvan/src/storm_function_wrapper.h @@ -0,0 +1,33 @@ +#ifndef SYLVAN_STORM_FUNCTION_WRAPPER_H +#define SYLVAN_STORM_FUNCTION_WRAPPER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + void* storm_rational_function; +} storm_rational_function_ptr_struct; +typedef storm_rational_function_ptr_struct storm_rational_function_t[1]; +typedef storm_rational_function_ptr_struct* storm_rational_function_ptr; + + +// equals, plus, minus, divide, times, create, destroy +void storm_rational_function_init(storm_rational_function_ptr* a); +void storm_rational_function_destroy(storm_rational_function_ptr a); +int storm_rational_function_equals(storm_rational_function_ptr a, storm_rational_function_ptr b); +storm_rational_function_ptr storm_rational_function_plus(storm_rational_function_ptr a, storm_rational_function_ptr b); +storm_rational_function_ptr storm_rational_function_minus(storm_rational_function_ptr a, storm_rational_function_ptr b); +storm_rational_function_ptr storm_rational_function_times(storm_rational_function_ptr a, storm_rational_function_ptr b); +storm_rational_function_ptr storm_rational_function_divide(storm_rational_function_ptr a, storm_rational_function_ptr b); +storm_rational_function_ptr storm_rational_function_negate(storm_rational_function_ptr a); +uint64_t storm_rational_function_hash(storm_rational_function_ptr const a, uint64_t const seed); +int storm_rational_function_is_zero(storm_rational_function_ptr a); + +#ifdef __cplusplus +} +#endif + +#endif // SYLVAN_STORM_FUNCTION_WRAPPER_H \ No newline at end of file diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c new file mode 100644 index 000000000..fcbd1f911 --- /dev/null +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c @@ -0,0 +1,240 @@ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +/*#include */ +#include + +#include + +/** + * helper function for hash + */ +#ifndef rotl64 +static inline uint64_t +rotl64(uint64_t x, int8_t r) +{ + return ((x<>(64-r))); +} +#endif + +static uint64_t +sylvan_storm_rational_function_hash(const uint64_t v, const uint64_t seed) +{ + /* Hash the storm::RationalFunction in pointer v */ + + storm_rational_function_ptr x = (storm_rational_function_ptr)(size_t)v; + + return storm_rational_function_hash(x, seed); +} + +static int +sylvan_storm_rational_function_equals(const uint64_t left, const uint64_t right) +{ + /* This function is called by the unique table when comparing a new + leaf with an existing leaf */ + storm_rational_function_ptr a = (storm_rational_function_ptr)(size_t)left; + storm_rational_function_ptr b = (storm_rational_function_ptr)(size_t)right; + + /* Just compare x and y */ + return (storm_rational_function_equals(a, b) == 0) ? 1 : 0; +} + +static void +sylvan_storm_rational_function_create(uint64_t *val) +{ + /* This function is called by the unique table when a leaf does not yet exist. + We make a copy, which will be stored in the hash table. */ + storm_rational_function_ptr* x = (storm_rational_function_ptr*)(size_t)val; + storm_rational_function_init(x); +} + +static void +sylvan_storm_rational_function_destroy(uint64_t val) +{ + /* This function is called by the unique table + when a leaf is removed during garbage collection. */ + storm_rational_function_ptr x = (storm_rational_function_ptr)(size_t)val; + storm_rational_function_destroy(x); +} + +static uint32_t sylvan_storm_rational_function_type; +static uint64_t CACHE_STORM_RATIONAL_FUNCTION_AND_EXISTS; + +/** + * Initialize storm::RationalFunction custom leaves + */ +void +sylvan_storm_rational_function_init() +{ + /* Register custom leaf 3 */ + sylvan_storm_rational_function_type = mtbdd_register_custom_leaf(sylvan_storm_rational_function_hash, sylvan_storm_rational_function_equals, sylvan_storm_rational_function_create, sylvan_storm_rational_function_destroy); + CACHE_STORM_RATIONAL_FUNCTION_AND_EXISTS = cache_next_opid(); +} + +/** + * Create storm::RationalFunction leaf + */ +MTBDD +mtbdd_storm_rational_function(storm_rational_function_t val) +{ + return mtbdd_makeleaf(sylvan_storm_rational_function_type, (size_t)val); +} + +/** + * Operation "plus" for two storm::RationalFunction MTBDDs + * Interpret partial function as "0" + */ +TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_plus, MTBDD*, pa, MTBDD*, pb) +{ + MTBDD a = *pa, b = *pb; + + /* Check for partial functions */ + if (a == mtbdd_false) return b; + if (b == mtbdd_false) return a; + + /* If both leaves, compute plus */ + if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { + storm_rational_function_ptr ma = (storm_rational_function_ptr)mtbdd_getvalue(a); + storm_rational_function_ptr mb = (storm_rational_function_ptr)mtbdd_getvalue(b); + + storm_rational_function_ptr mres = storm_rational_function_plus(ma, mb); + MTBDD res = mtbdd_storm_rational_function(mres); + + // TODO: Delete mres? + + return res; + } + + /* Commutative, so swap a,b for better cache performance */ + if (a < b) { + *pa = b; + *pb = a; + } + + return mtbdd_invalid; +} + +/** + * Operation "minus" for two storm::RationalFunction MTBDDs + * Interpret partial function as "0" + */ +TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_minus, MTBDD*, pa, MTBDD*, pb) +{ + MTBDD a = *pa, b = *pb; + + /* Check for partial functions */ + if (a == mtbdd_false) return sylvan_storm_rational_function_neg(b); + if (b == mtbdd_false) return a; + + /* If both leaves, compute plus */ + if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { + storm_rational_function_ptr ma = (storm_rational_function_ptr)mtbdd_getvalue(a); + storm_rational_function_ptr mb = (storm_rational_function_ptr)mtbdd_getvalue(b); + + storm_rational_function_ptr mres = storm_rational_function_minus(ma, mb); + MTBDD res = mtbdd_storm_rational_function(mres); + + // TODO: Delete mres? + + return res; + } + + return mtbdd_invalid; +} + +/** + * Operation "times" for two storm::RationalFunction MTBDDs. + * One of the parameters can be a BDD, then it is interpreted as a filter. + * For partial functions, domain is intersection + */ +TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_times, MTBDD*, pa, MTBDD*, pb) +{ + MTBDD a = *pa, b = *pb; + + /* Check for partial functions and for Boolean (filter) */ + if (a == mtbdd_false || b == mtbdd_false) return mtbdd_false; + + /* If one of Boolean, interpret as filter */ + if (a == mtbdd_true) return b; + if (b == mtbdd_true) return a; + + /* Handle multiplication of leaves */ + if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { + storm_rational_function_ptr ma = (storm_rational_function_ptr)mtbdd_getvalue(a); + storm_rational_function_ptr mb = (storm_rational_function_ptr)mtbdd_getvalue(b); + + storm_rational_function_ptr mres = storm_rational_function_times(ma, mb); + MTBDD res = mtbdd_storm_rational_function(mres); + + // TODO: Delete mres? + + return res; + } + + /* Commutative, so make "a" the lowest for better cache performance */ + if (a < b) { + *pa = b; + *pb = a; + } + + return mtbdd_invalid; +} + +/** + * Operation "divide" for two storm::RationalFunction MTBDDs. + * For partial functions, domain is intersection + */ +TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_divide, MTBDD*, pa, MTBDD*, pb) +{ + MTBDD a = *pa, b = *pb; + + /* Check for partial functions */ + if (a == mtbdd_false || b == mtbdd_false) return mtbdd_false; + + /* Handle division of leaves */ + if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { + storm_rational_function_ptr ma = (storm_rational_function_ptr)mtbdd_getvalue(a); + storm_rational_function_ptr mb = (storm_rational_function_ptr)mtbdd_getvalue(b); + + storm_rational_function_ptr mres = storm_rational_function_divide(ma, mb); + MTBDD res = mtbdd_storm_rational_function(mres); + + // TODO: Delete mres? + + return res; + } + + return mtbdd_invalid; +} + +/** + * Operation "neg" for one storm::RationalFunction MTBDD + */ +TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_neg, MTBDD, dd, size_t, p) +{ + /* Handle partial functions */ + if (dd == mtbdd_false) return mtbdd_false; + + /* Compute result for leaf */ + if (mtbdd_isleaf(dd)) { + storm_rational_function_ptr mdd = (storm_rational_function_ptr)mtbdd_getvalue(dd); + + storm_rational_function_ptr mres = storm_rational_function_negate(mdd); + MTBDD res = mtbdd_storm_rational_function(mres); + + // TODO: Delete mres? + return res; + } + + return mtbdd_invalid; + (void)p; +} diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h new file mode 100644 index 000000000..2080ca11c --- /dev/null +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h @@ -0,0 +1,87 @@ +/** + * This is an implementation of storm::RationalFunction custom leaves of MTBDDs + */ + +#ifndef SYLVAN_STORM_RATIONAL_FUNCTION_H +#define SYLVAN_STORM_RATIONAL_FUNCTION_H + +#include +#include + +#define SYLVAN_HAVE_CARL 1 + +#ifdef SYLVAN_HAVE_CARL + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * Initialize storm::RationalFunction custom leaves + */ +void sylvan_storm_rational_function_init(); + +/** + * Create storm::RationalFunction leaf + */ +MTBDD mtbdd_storm_rational_function(storm_rational_function_t val); + +/** + * Operation "plus" for two storm::RationalFunction MTBDDs + */ +TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_plus, MTBDD*, MTBDD*); +TASK_DECL_3(MTBDD, sylvan_storm_rational_function_abstract_op_plus, MTBDD, MTBDD, int); + +/** + * Operation "minus" for two storm::RationalFunction MTBDDs + */ +TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_minus, MTBDD*, MTBDD*); + +/** + * Operation "times" for two storm::RationalFunction MTBDDs + */ +TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_times, MTBDD*, MTBDD*); +TASK_DECL_3(MTBDD, sylvan_storm_rational_function_abstract_op_times, MTBDD, MTBDD, int); + +/** + * Operation "divide" for two storm::RationalFunction MTBDDs + */ +TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_divide, MTBDD*, MTBDD*); + +/** + * Operation "negate" for one storm::RationalFunction MTBDD + */ +TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_neg, MTBDD, size_t); + +/** + * Compute a + b + */ +#define sylvan_storm_rational_function_plus(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_function_op_plus)) + +/** + * Compute a - b + */ +#define sylvan_storm_rational_function_minus(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_function_op_minus)) + +/** + * Compute a * b + */ +#define sylvan_storm_rational_function_times(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_function_op_times)) + +/** + * Compute a / b + */ +#define sylvan_storm_rational_function_divide(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_function_op_divide)) + +/** + * Compute -a + */ +#define sylvan_storm_rational_function_neg(a) mtbdd_uapply(a, TASK(sylvan_storm_rational_function_op_neg), 0); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // SYLVAN_HAVE_CARL + +#endif // SYLVAN_STORM_RATIONAL_FUNCTION_H From a0dd2064c1a68bba38b9487115e24d20e9d24793 Mon Sep 17 00:00:00 2001 From: PBerger Date: Thu, 14 Jul 2016 21:40:39 +0200 Subject: [PATCH 02/49] Started adding stuff to src/storage/dd/sylvan/InternalSylvanDdManager. Former-commit-id: cf8adfc43f0557c9785af0f123337be817fbd95e --- .../dd/sylvan/InternalSylvanDdManager.cpp | 273 +++++++++-------- .../dd/sylvan/InternalSylvanDdManager.h | 278 +++++++++--------- src/utility/sylvan.h | 29 +- 3 files changed, 309 insertions(+), 271 deletions(-) diff --git a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp index f79e62277..06fcd57bb 100644 --- a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp +++ b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp @@ -1,127 +1,148 @@ -#include "src/storage/dd/sylvan/InternalSylvanDdManager.h" - -#include - -#include "src/settings/SettingsManager.h" -#include "src/settings/modules/SylvanSettings.h" - -#include "src/utility/constants.h" -#include "src/utility/macros.h" -#include "src/exceptions/NotSupportedException.h" - -namespace storm { - namespace dd { - uint_fast64_t InternalDdManager::numberOfInstances = 0; - - // It is important that the variable pairs start at an even offset, because sylvan assumes this to be true for - // some operations. - uint_fast64_t InternalDdManager::nextFreeVariableIndex = 0; - - uint_fast64_t findLargestPowerOfTwoFitting(uint_fast64_t number) { - for (uint_fast64_t index = 0; index < 64; ++index) { - if ((number & (1ull << (63 - index))) != 0) { - return 63 - index; - } - } - return 0; - } - - InternalDdManager::InternalDdManager() { - if (numberOfInstances == 0) { - // Initialize lace: auto-detect number of workers. - lace_init(storm::settings::getModule().getNumberOfThreads(), 1000000); - lace_startup(0, 0, 0); - - // Each node takes 24 bytes and the maximal memory is specified in megabytes. - uint_fast64_t totalNodesToStore = storm::settings::getModule().getMaximalMemory() * 1024 * 1024 / 24; - - // Compute the power of two that still fits within the total numbers to store. - uint_fast64_t powerOfTwo = findLargestPowerOfTwoFitting(totalNodesToStore); - - sylvan::Sylvan::initPackage(1ull << std::max(16ull, powerOfTwo > 24 ? powerOfTwo - 8 : 0ull), 1ull << (powerOfTwo - 1), 1ull << std::max(16ull, powerOfTwo > 24 ? powerOfTwo - 12 : 0ull), 1ull << (powerOfTwo - 1)); - sylvan::Sylvan::initBdd(1); - sylvan::Sylvan::initMtbdd(); - } - ++numberOfInstances; - } - - InternalDdManager::~InternalDdManager() { - --numberOfInstances; - if (numberOfInstances == 0) { - // Enable this to print the sylvan statistics to a file. -// FILE* filePointer = fopen("sylvan.stats", "w"); -// sylvan_stats_report(filePointer, 0); -// fclose(filePointer); - - sylvan::Sylvan::quitPackage(); - lace_exit(); - } - } - - InternalBdd InternalDdManager::getBddOne() const { - return InternalBdd(this, sylvan::Bdd::bddOne()); - } - - template<> - InternalAdd InternalDdManager::getAddOne() const { - return InternalAdd(this, sylvan::Mtbdd::doubleTerminal(storm::utility::one())); - } - - template<> - InternalAdd InternalDdManager::getAddOne() const { - return InternalAdd(this, sylvan::Mtbdd::int64Terminal(storm::utility::one())); - } - - InternalBdd InternalDdManager::getBddZero() const { - return InternalBdd(this, sylvan::Bdd::bddZero()); - } - - template<> - InternalAdd InternalDdManager::getAddZero() const { - return InternalAdd(this, sylvan::Mtbdd::doubleTerminal(storm::utility::zero())); - } - - template<> - InternalAdd InternalDdManager::getAddZero() const { - return InternalAdd(this, sylvan::Mtbdd::int64Terminal(storm::utility::zero())); - } - - template<> - InternalAdd InternalDdManager::getConstant(double const& value) const { - return InternalAdd(this, sylvan::Mtbdd::doubleTerminal(value)); - } - - template<> - InternalAdd InternalDdManager::getConstant(uint_fast64_t const& value) const { - return InternalAdd(this, sylvan::Mtbdd::int64Terminal(value)); - } - - std::pair, InternalBdd> InternalDdManager::createNewDdVariablePair() { - InternalBdd first = InternalBdd(this, sylvan::Bdd::bddVar(nextFreeVariableIndex)); - InternalBdd second = InternalBdd(this, sylvan::Bdd::bddVar(nextFreeVariableIndex + 1)); - nextFreeVariableIndex += 2; - return std::make_pair(first, second); - } - - void InternalDdManager::allowDynamicReordering(bool value) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation is not supported by sylvan."); - } - - bool InternalDdManager::isDynamicReorderingAllowed() const { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation is not supported by sylvan."); - } - - void InternalDdManager::triggerReordering() { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation is not supported by sylvan."); - } - - template InternalAdd InternalDdManager::getAddOne() const; - template InternalAdd InternalDdManager::getAddOne() const; - - template InternalAdd InternalDdManager::getAddZero() const; - template InternalAdd InternalDdManager::getAddZero() const; - - template InternalAdd InternalDdManager::getConstant(double const& value) const; - template InternalAdd InternalDdManager::getConstant(uint_fast64_t const& value) const; - } +#include "src/storage/dd/sylvan/InternalSylvanDdManager.h" + +#include + +#include "src/settings/SettingsManager.h" +#include "src/settings/modules/SylvanSettings.h" + +#include "src/utility/constants.h" +#include "src/utility/macros.h" +#include "src/exceptions/NotSupportedException.h" + +namespace storm { + namespace dd { + uint_fast64_t InternalDdManager::numberOfInstances = 0; + + // It is important that the variable pairs start at an even offset, because sylvan assumes this to be true for + // some operations. + uint_fast64_t InternalDdManager::nextFreeVariableIndex = 0; + + uint_fast64_t findLargestPowerOfTwoFitting(uint_fast64_t number) { + for (uint_fast64_t index = 0; index < 64; ++index) { + if ((number & (1ull << (63 - index))) != 0) { + return 63 - index; + } + } + return 0; + } + + InternalDdManager::InternalDdManager() { + if (numberOfInstances == 0) { + // Initialize lace: auto-detect number of workers. + lace_init(storm::settings::getModule().getNumberOfThreads(), 1000000); + lace_startup(0, 0, 0); + + // Each node takes 24 bytes and the maximal memory is specified in megabytes. + uint_fast64_t totalNodesToStore = storm::settings::getModule().getMaximalMemory() * 1024 * 1024 / 24; + + // Compute the power of two that still fits within the total numbers to store. + uint_fast64_t powerOfTwo = findLargestPowerOfTwoFitting(totalNodesToStore); + + sylvan::Sylvan::initPackage(1ull << std::max(16ull, powerOfTwo > 24 ? powerOfTwo - 8 : 0ull), 1ull << (powerOfTwo - 1), 1ull << std::max(16ull, powerOfTwo > 24 ? powerOfTwo - 12 : 0ull), 1ull << (powerOfTwo - 1)); + sylvan::Sylvan::initBdd(1); + sylvan::Sylvan::initMtbdd(); + } + ++numberOfInstances; + } + + InternalDdManager::~InternalDdManager() { + --numberOfInstances; + if (numberOfInstances == 0) { + // Enable this to print the sylvan statistics to a file. +// FILE* filePointer = fopen("sylvan.stats", "w"); +// sylvan_stats_report(filePointer, 0); +// fclose(filePointer); + + sylvan::Sylvan::quitPackage(); + lace_exit(); + } + } + + InternalBdd InternalDdManager::getBddOne() const { + return InternalBdd(this, sylvan::Bdd::bddOne()); + } + + template<> + InternalAdd InternalDdManager::getAddOne() const { + return InternalAdd(this, sylvan::Mtbdd::doubleTerminal(storm::utility::one())); + } + + template<> + InternalAdd InternalDdManager::getAddOne() const { + return InternalAdd(this, sylvan::Mtbdd::int64Terminal(storm::utility::one())); + } + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalDdManager::getAddOne() const { + return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), storm::utility::one())); + } +#endif + + InternalBdd InternalDdManager::getBddZero() const { + return InternalBdd(this, sylvan::Bdd::bddZero()); + } + + template<> + InternalAdd InternalDdManager::getAddZero() const { + return InternalAdd(this, sylvan::Mtbdd::doubleTerminal(storm::utility::zero())); + } + + template<> + InternalAdd InternalDdManager::getAddZero() const { + return InternalAdd(this, sylvan::Mtbdd::int64Terminal(storm::utility::zero())); + } + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalDdManager::getAddZero() const { + return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), storm::utility::zero())); + } +#endif + + template<> + InternalAdd InternalDdManager::getConstant(double const& value) const { + return InternalAdd(this, sylvan::Mtbdd::doubleTerminal(value)); + } + + template<> + InternalAdd InternalDdManager::getConstant(uint_fast64_t const& value) const { + return InternalAdd(this, sylvan::Mtbdd::int64Terminal(value)); + } + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalDdManager::getConstant(storm::RationalFunction const& value) const { + return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), storm::utility::zero())); + } +#endif + + std::pair, InternalBdd> InternalDdManager::createNewDdVariablePair() { + InternalBdd first = InternalBdd(this, sylvan::Bdd::bddVar(nextFreeVariableIndex)); + InternalBdd second = InternalBdd(this, sylvan::Bdd::bddVar(nextFreeVariableIndex + 1)); + nextFreeVariableIndex += 2; + return std::make_pair(first, second); + } + + void InternalDdManager::allowDynamicReordering(bool value) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation is not supported by sylvan."); + } + + bool InternalDdManager::isDynamicReorderingAllowed() const { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation is not supported by sylvan."); + } + + void InternalDdManager::triggerReordering() { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation is not supported by sylvan."); + } + + template InternalAdd InternalDdManager::getAddOne() const; + template InternalAdd InternalDdManager::getAddOne() const; + + template InternalAdd InternalDdManager::getAddZero() const; + template InternalAdd InternalDdManager::getAddZero() const; + + template InternalAdd InternalDdManager::getConstant(double const& value) const; + template InternalAdd InternalDdManager::getConstant(uint_fast64_t const& value) const; + } } \ No newline at end of file diff --git a/src/storage/dd/sylvan/InternalSylvanDdManager.h b/src/storage/dd/sylvan/InternalSylvanDdManager.h index 55be0581f..0618b0dbe 100644 --- a/src/storage/dd/sylvan/InternalSylvanDdManager.h +++ b/src/storage/dd/sylvan/InternalSylvanDdManager.h @@ -1,132 +1,148 @@ -#ifndef STORM_STORAGE_DD_SYLVAN_INTERNALSYLVANDDMANAGER_H_ -#define STORM_STORAGE_DD_SYLVAN_INTERNALSYLVANDDMANAGER_H_ - -#include "src/storage/dd/DdType.h" -#include "src/storage/dd/InternalDdManager.h" - -#include "src/storage/dd/sylvan/InternalSylvanBdd.h" -#include "src/storage/dd/sylvan/InternalSylvanAdd.h" - -namespace storm { - namespace dd { - template - class InternalAdd; - - template - class InternalBdd; - - template<> - class InternalDdManager { - public: - friend class InternalBdd; - - template - friend class InternalAdd; - - /*! - * Creates a new internal manager for Sylvan DDs. - */ - InternalDdManager(); - - /*! - * Destroys the internal manager. - */ - ~InternalDdManager(); - - /*! - * Retrieves a BDD representing the constant one function. - * - * @return A BDD representing the constant one function. - */ - InternalBdd getBddOne() const; - - /*! - * Retrieves an ADD representing the constant one function. - * - * @return An ADD representing the constant one function. - */ - template - InternalAdd getAddOne() const; - - /*! - * Retrieves a BDD representing the constant zero function. - * - * @return A BDD representing the constant zero function. - */ - InternalBdd getBddZero() const; - - /*! - * Retrieves an ADD representing the constant zero function. - * - * @return An ADD representing the constant zero function. - */ - template - InternalAdd getAddZero() const; - - /*! - * Retrieves an ADD representing the constant function with the given value. - * - * @return An ADD representing the constant function with the given value. - */ - template - InternalAdd getConstant(ValueType const& value) const; - - /*! - * Creates a new pair of DD variables and returns the two cubes as a result. - * - * @return The two cubes belonging to the DD variables. - */ - std::pair, InternalBdd> createNewDdVariablePair(); - - /*! - * Sets whether or not dynamic reordering is allowed for the DDs managed by this manager. - * - * @param value If set to true, dynamic reordering is allowed and forbidden otherwise. - */ - void allowDynamicReordering(bool value); - - /*! - * Retrieves whether dynamic reordering is currently allowed. - * - * @return True iff dynamic reordering is currently allowed. - */ - bool isDynamicReorderingAllowed() const; - - /*! - * Triggers a reordering of the DDs managed by this manager. - */ - void triggerReordering(); - - private: - // A counter for the number of instances of this class. This is used to determine when to initialize and - // quit the sylvan. This is because Sylvan does not know the concept of managers but implicitly has a - // 'global' manager. - static uint_fast64_t numberOfInstances; - - // The index of the next free variable index. This needs to be shared across all instances since the sylvan - // manager is implicitly 'global'. - static uint_fast64_t nextFreeVariableIndex; - }; - - template<> - InternalAdd InternalDdManager::getAddOne() const; - - template<> - InternalAdd InternalDdManager::getAddOne() const; - - template<> - InternalAdd InternalDdManager::getAddZero() const; - - template<> - InternalAdd InternalDdManager::getAddZero() const; - - template<> - InternalAdd InternalDdManager::getConstant(double const& value) const; - - template<> - InternalAdd InternalDdManager::getConstant(uint_fast64_t const& value) const; - - } -} - +#ifndef STORM_STORAGE_DD_SYLVAN_INTERNALSYLVANDDMANAGER_H_ +#define STORM_STORAGE_DD_SYLVAN_INTERNALSYLVANDDMANAGER_H_ + +#include "src/storage/dd/DdType.h" +#include "src/storage/dd/InternalDdManager.h" + +#include "src/storage/dd/sylvan/InternalSylvanBdd.h" +#include "src/storage/dd/sylvan/InternalSylvanAdd.h" + +#include "src/adapters/CarlAdapter.h" + +namespace storm { + namespace dd { + template + class InternalAdd; + + template + class InternalBdd; + + template<> + class InternalDdManager { + public: + friend class InternalBdd; + + template + friend class InternalAdd; + + /*! + * Creates a new internal manager for Sylvan DDs. + */ + InternalDdManager(); + + /*! + * Destroys the internal manager. + */ + ~InternalDdManager(); + + /*! + * Retrieves a BDD representing the constant one function. + * + * @return A BDD representing the constant one function. + */ + InternalBdd getBddOne() const; + + /*! + * Retrieves an ADD representing the constant one function. + * + * @return An ADD representing the constant one function. + */ + template + InternalAdd getAddOne() const; + + /*! + * Retrieves a BDD representing the constant zero function. + * + * @return A BDD representing the constant zero function. + */ + InternalBdd getBddZero() const; + + /*! + * Retrieves an ADD representing the constant zero function. + * + * @return An ADD representing the constant zero function. + */ + template + InternalAdd getAddZero() const; + + /*! + * Retrieves an ADD representing the constant function with the given value. + * + * @return An ADD representing the constant function with the given value. + */ + template + InternalAdd getConstant(ValueType const& value) const; + + /*! + * Creates a new pair of DD variables and returns the two cubes as a result. + * + * @return The two cubes belonging to the DD variables. + */ + std::pair, InternalBdd> createNewDdVariablePair(); + + /*! + * Sets whether or not dynamic reordering is allowed for the DDs managed by this manager. + * + * @param value If set to true, dynamic reordering is allowed and forbidden otherwise. + */ + void allowDynamicReordering(bool value); + + /*! + * Retrieves whether dynamic reordering is currently allowed. + * + * @return True iff dynamic reordering is currently allowed. + */ + bool isDynamicReorderingAllowed() const; + + /*! + * Triggers a reordering of the DDs managed by this manager. + */ + void triggerReordering(); + + private: + // A counter for the number of instances of this class. This is used to determine when to initialize and + // quit the sylvan. This is because Sylvan does not know the concept of managers but implicitly has a + // 'global' manager. + static uint_fast64_t numberOfInstances; + + // The index of the next free variable index. This needs to be shared across all instances since the sylvan + // manager is implicitly 'global'. + static uint_fast64_t nextFreeVariableIndex; + }; + + template<> + InternalAdd InternalDdManager::getAddOne() const; + + template<> + InternalAdd InternalDdManager::getAddOne() const; + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalDdManager::getAddOne() const; +#endif + + template<> + InternalAdd InternalDdManager::getAddZero() const; + + template<> + InternalAdd InternalDdManager::getAddZero() const; + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalDdManager::getAddZero() const; +#endif + + template<> + InternalAdd InternalDdManager::getConstant(double const& value) const; + + template<> + InternalAdd InternalDdManager::getConstant(uint_fast64_t const& value) const; + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalDdManager::getConstant(storm::RationalNumber const& value) const; +#endif + } +} + #endif /* STORM_STORAGE_DD_SYLVAN_INTERNALSYLVANDDMANAGER_H_ */ \ No newline at end of file diff --git a/src/utility/sylvan.h b/src/utility/sylvan.h index ccaffe097..1dd236609 100644 --- a/src/utility/sylvan.h +++ b/src/utility/sylvan.h @@ -1,15 +1,16 @@ -#ifndef STORM_STORAGE_DD_SYLVAN_SYLVAN_H_ -#define STORM_STORAGE_DD_SYLVAN_SYLVAN_H_ - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wextra-semi" -#pragma clang diagnostic ignored "-Wzero-length-array" -#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" -#pragma clang diagnostic ignored "-Wdeprecated-register" -#pragma clang diagnostic ignored "-Wc99-extensions" - -#include "sylvan_obj.hpp" - -#pragma clang diagnostic pop - +#ifndef STORM_STORAGE_DD_SYLVAN_SYLVAN_H_ +#define STORM_STORAGE_DD_SYLVAN_SYLVAN_H_ + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wextra-semi" +#pragma clang diagnostic ignored "-Wzero-length-array" +#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" +#pragma clang diagnostic ignored "-Wdeprecated-register" +#pragma clang diagnostic ignored "-Wc99-extensions" + +#include "sylvan_obj.hpp" +#include "sylvan_storm_rational_function.h" + +#pragma clang diagnostic pop + #endif /* STORM_STORAGE_DD_SYLVAN_SYLVAN_H_ */ \ No newline at end of file From 252879f0bff86ae8e459f5a3bb2fc1ecc1769509 Mon Sep 17 00:00:00 2001 From: PBerger Date: Thu, 14 Jul 2016 21:44:28 +0200 Subject: [PATCH 03/49] Removed unnecessary semicolons. Former-commit-id: 4d9f9c265aeded0ee992e17b09c068328e3b5b4d --- src/models/sparse/NondeterministicModel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/models/sparse/NondeterministicModel.cpp b/src/models/sparse/NondeterministicModel.cpp index 3a4af6664..5dfaea955 100644 --- a/src/models/sparse/NondeterministicModel.cpp +++ b/src/models/sparse/NondeterministicModel.cpp @@ -72,7 +72,7 @@ namespace storm { std::cout << i++ << "/" << modifications.size() << std::endl; rewardModel.setStateActionReward(mod.first, mod.second); } - }; + } template template @@ -81,7 +81,7 @@ namespace storm { for(auto const& mod : modifications) { rewardModel.setStateReward(mod.first, mod.second); } - }; + } template void NondeterministicModel::reduceToStateBasedRewards() { From c8262a3022f26f1cf266285461a4694354daa8f0 Mon Sep 17 00:00:00 2001 From: PBerger Date: Thu, 14 Jul 2016 21:44:58 +0200 Subject: [PATCH 04/49] Added function for retrieving the ID of the custom leaves. Former-commit-id: 615cacf3b9a16075338eb59229d82de33a5c6b74 --- .../3rdparty/sylvan/src/sylvan_storm_rational_function.c | 4 ++++ .../3rdparty/sylvan/src/sylvan_storm_rational_function.h | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c index fcbd1f911..ebb5f7062 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c @@ -80,6 +80,10 @@ sylvan_storm_rational_function_init() CACHE_STORM_RATIONAL_FUNCTION_AND_EXISTS = cache_next_opid(); } +uint32_t sylvan_storm_rational_function_get_type() { + return sylvan_storm_rational_function_type; +} + /** * Create storm::RationalFunction leaf */ diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h index 2080ca11c..f97347690 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h @@ -10,7 +10,7 @@ #define SYLVAN_HAVE_CARL 1 -#ifdef SYLVAN_HAVE_CARL +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) #ifdef __cplusplus extern "C" { @@ -21,6 +21,11 @@ extern "C" { */ void sylvan_storm_rational_function_init(); +/** + * Returns the identifier necessary to use these custom leaves. + */ +uint32_t sylvan_storm_rational_function_get_type(); + /** * Create storm::RationalFunction leaf */ From 807aa90fa6d8e0bb32262c1d0113f0181171b1ea Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 18 Jul 2016 17:02:14 +0200 Subject: [PATCH 05/49] Added missing instantiations. Former-commit-id: 875e2b94d0d55df7b8001e789e757af072a26545 --- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 23 ++++++++++++- .../dd/sylvan/InternalSylvanDdManager.cpp | 32 +++++++++++++++++-- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index fb9834aaa..a244cc198 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -10,6 +10,12 @@ #include "src/utility/constants.h" #include "src/exceptions/NotImplementedException.h" +#include "storm-config.h" +// TODO: Remove this later on. +#ifndef STORM_HAVE_CARL +#define STORM_HAVE_CARL 1 +#endif + namespace storm { namespace dd { template @@ -614,7 +620,19 @@ namespace storm { } else if (std::is_same::value) { STORM_LOG_ASSERT(mtbdd_gettype(node) == 0, "Expected an unsigned value."); return negated ? -mtbdd_getint64(node) : mtbdd_getint64(node); - } else { + } +#ifdef STORM_HAVE_CARL + else if (std::is_same::value) { + STORM_LOG_ASSERT(mtbdd_gettype(node) == sylvan_storm_rational_function_get_type(), "Expected a storm::RationalFunction value."); + uint64_t value = mtbdd_getvalue(leaf); + storm_rational_function_ptr_struct* helperStructPtr = (storm_rational_function_ptr_struct*) value; + + storm::RationalFunction* rationalFunction = (storm::RationalFunction*)(helperStructPtr->storm_rational_function); + + return negated ? -(*rationalFunction) : (*rationalFunction); + } +#endif + else { STORM_LOG_ASSERT(false, "Illegal or unknown type in MTBDD."); } } @@ -626,5 +644,8 @@ namespace storm { template class InternalAdd; template class InternalAdd; +#ifdef STORM_HAVE_CARL + template class InternalAdd; +#endif } } \ No newline at end of file diff --git a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp index 06fcd57bb..93445387f 100644 --- a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp +++ b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp @@ -9,6 +9,14 @@ #include "src/utility/macros.h" #include "src/exceptions/NotSupportedException.h" +#include "src/utility/sylvan.h" + +#include "storm-config.h" +// TODO: Remove this later on. +#ifndef STORM_HAVE_CARL +#define STORM_HAVE_CARL 1 +#endif + namespace storm { namespace dd { uint_fast64_t InternalDdManager::numberOfInstances = 0; @@ -75,7 +83,10 @@ namespace storm { #ifdef STORM_HAVE_CARL template<> InternalAdd InternalDdManager::getAddOne() const { - return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), storm::utility::one())); + storm::RationalFunction rationalFunction = storm::utility::one(); + storm_rational_function_ptr_struct helperStruct; + helperStruct.storm_rational_function = static_cast(&rationalFunction); + return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), helperStruct)); } #endif @@ -96,7 +107,10 @@ namespace storm { #ifdef STORM_HAVE_CARL template<> InternalAdd InternalDdManager::getAddZero() const { - return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), storm::utility::zero())); + storm::RationalFunction rationalFunction = storm::utility::zero(); + storm_rational_function_ptr_struct helperStruct; + helperStruct.storm_rational_function = static_cast(&rationalFunction); + return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), helperStruct)); } #endif @@ -113,7 +127,10 @@ namespace storm { #ifdef STORM_HAVE_CARL template<> InternalAdd InternalDdManager::getConstant(storm::RationalFunction const& value) const { - return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), storm::utility::zero())); + storm::RationalFunction rationalFunction = value; + storm_rational_function_ptr_struct helperStruct; + helperStruct.storm_rational_function = static_cast(&rationalFunction); + return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), helperStruct)); } #endif @@ -138,11 +155,20 @@ namespace storm { template InternalAdd InternalDdManager::getAddOne() const; template InternalAdd InternalDdManager::getAddOne() const; +#ifdef STORM_HAVE_CARL + template InternalAdd InternalDdManager::getAddOne() const; +#endif template InternalAdd InternalDdManager::getAddZero() const; template InternalAdd InternalDdManager::getAddZero() const; +#ifdef STORM_HAVE_CARL + template InternalAdd InternalDdManager::getAddZero() const; +#endif template InternalAdd InternalDdManager::getConstant(double const& value) const; template InternalAdd InternalDdManager::getConstant(uint_fast64_t const& value) const; +#ifdef STORM_HAVE_CARL + template InternalAdd InternalDdManager::getConstant(storm::RationalFunction const& value) const; +#endif } } \ No newline at end of file From 16e287ca8fe312ce9023dd8f9c7e2bc97183c16a Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 18 Jul 2016 17:42:20 +0200 Subject: [PATCH 06/49] Fixes. Former-commit-id: 267bf081c4e2ed36a8a71bd09d43bfc44bf44e99 --- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 7 +++++++ src/storage/dd/sylvan/InternalSylvanAdd.h | 9 +++++++++ src/storage/dd/sylvan/InternalSylvanDdManager.h | 6 ++++++ 3 files changed, 22 insertions(+) diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index a244cc198..fe8eafec4 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -606,6 +606,13 @@ namespace storm { MTBDD InternalAdd::getLeaf(uint_fast64_t value) { return mtbdd_int64(value); } + + template + MTBDD InternalAdd::getLeaf(storm::RationalFunction const& value) { + storm_rational_function_ptr_struct helperStruct; + helperStruct.storm_rational_function = static_cast(&value); + return sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), helperStruct); + } template ValueType InternalAdd::getValue(MTBDD const& node) { diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.h b/src/storage/dd/sylvan/InternalSylvanAdd.h index e02e0107e..4c4859332 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.h +++ b/src/storage/dd/sylvan/InternalSylvanAdd.h @@ -13,6 +13,8 @@ #include "src/storage/expressions/Variable.h" +#include "src/adapters/CarlAdapter.h" + namespace storm { namespace storage { template @@ -655,6 +657,13 @@ namespace storm { * @return The sylvan node for the given value. */ static MTBDD getLeaf(uint_fast64_t value); + + /*! + * Retrieves the sylvan representation of the given storm::RatíonalFunction value. + * + * @return The sylvan node for the given value. + */ + static MTBDD getLeaf(storm::RationalFunction const& value); /*! * Retrieves the value of the given node (that must be a leaf). diff --git a/src/storage/dd/sylvan/InternalSylvanDdManager.h b/src/storage/dd/sylvan/InternalSylvanDdManager.h index 0618b0dbe..79182a1ae 100644 --- a/src/storage/dd/sylvan/InternalSylvanDdManager.h +++ b/src/storage/dd/sylvan/InternalSylvanDdManager.h @@ -9,6 +9,12 @@ #include "src/adapters/CarlAdapter.h" +#include "storm-config.h" +// TODO: Remove this later on. +#ifndef STORM_HAVE_CARL +#define STORM_HAVE_CARL 1 +#endif + namespace storm { namespace dd { template From 542fcb8e8c6416dede18a5624a03a617494e1a5a Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 18 Jul 2016 18:50:16 +0200 Subject: [PATCH 07/49] More fixes. Former-commit-id: 4f62760e4b68ebe57337fca2886657718f28890b --- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 6 ------ src/storage/dd/sylvan/InternalSylvanAdd.h | 10 +++++++++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index fe8eafec4..693252db8 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -10,12 +10,6 @@ #include "src/utility/constants.h" #include "src/exceptions/NotImplementedException.h" -#include "storm-config.h" -// TODO: Remove this later on. -#ifndef STORM_HAVE_CARL -#define STORM_HAVE_CARL 1 -#endif - namespace storm { namespace dd { template diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.h b/src/storage/dd/sylvan/InternalSylvanAdd.h index 4c4859332..e070faa7a 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.h +++ b/src/storage/dd/sylvan/InternalSylvanAdd.h @@ -15,6 +15,12 @@ #include "src/adapters/CarlAdapter.h" +#include "storm-config.h" +// TODO: Remove this later on. +#ifndef STORM_HAVE_CARL +#define STORM_HAVE_CARL 1 +#endif + namespace storm { namespace storage { template @@ -658,12 +664,14 @@ namespace storm { */ static MTBDD getLeaf(uint_fast64_t value); +#ifdef STORM_HAVE_CARL /*! * Retrieves the sylvan representation of the given storm::RatíonalFunction value. * * @return The sylvan node for the given value. */ static MTBDD getLeaf(storm::RationalFunction const& value); +#endif /*! * Retrieves the value of the given node (that must be a leaf). @@ -688,4 +696,4 @@ namespace storm { } } -#endif /* STORM_STORAGE_DD_SYLVAN_INTERNALSYLVANADD_H_ */ \ No newline at end of file +#endif /* STORM_STORAGE_DD_SYLVAN_INTERNALSYLVANADD_H_ */ From 310fe8ecf94d2608915048c24035e456a00c5453 Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 18 Jul 2016 18:52:15 +0200 Subject: [PATCH 08/49] Meh. Fix. Former-commit-id: 45bab235507ce3c13a527b6fba50d4d44dbf5125 --- src/storage/dd/sylvan/InternalSylvanDdManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/dd/sylvan/InternalSylvanDdManager.h b/src/storage/dd/sylvan/InternalSylvanDdManager.h index 79182a1ae..e7a089fd0 100644 --- a/src/storage/dd/sylvan/InternalSylvanDdManager.h +++ b/src/storage/dd/sylvan/InternalSylvanDdManager.h @@ -146,7 +146,7 @@ namespace storm { #ifdef STORM_HAVE_CARL template<> - InternalAdd InternalDdManager::getConstant(storm::RationalNumber const& value) const; + InternalAdd InternalDdManager::getConstant(storm::RationalFunction const& value) const; #endif } } From a8fa45b89c9cb68ebe4b6dc82d55b9637198acac Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 18 Jul 2016 18:56:08 +0200 Subject: [PATCH 09/49] Fixed call to terminal(type, valPtr) Former-commit-id: dde588ba1412b4a04d5e841ae3524dfb81ff3fd9 --- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 4 +++- src/storage/dd/sylvan/InternalSylvanDdManager.cpp | 12 +++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index 693252db8..ff59c2e39 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -605,7 +605,9 @@ namespace storm { MTBDD InternalAdd::getLeaf(storm::RationalFunction const& value) { storm_rational_function_ptr_struct helperStruct; helperStruct.storm_rational_function = static_cast(&value); - return sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), helperStruct); + uint64_t terminalValue = (uint64_t)&helperStruct; + + return sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), terminalValue); } template diff --git a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp index 93445387f..1d0642048 100644 --- a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp +++ b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp @@ -86,7 +86,9 @@ namespace storm { storm::RationalFunction rationalFunction = storm::utility::one(); storm_rational_function_ptr_struct helperStruct; helperStruct.storm_rational_function = static_cast(&rationalFunction); - return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), helperStruct)); + uint64_t value = (uint64_t)&helperStruct; + + return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), value)); } #endif @@ -110,7 +112,9 @@ namespace storm { storm::RationalFunction rationalFunction = storm::utility::zero(); storm_rational_function_ptr_struct helperStruct; helperStruct.storm_rational_function = static_cast(&rationalFunction); - return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), helperStruct)); + uint64_t value = (uint64_t)&helperStruct; + + return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), value)); } #endif @@ -130,7 +134,9 @@ namespace storm { storm::RationalFunction rationalFunction = value; storm_rational_function_ptr_struct helperStruct; helperStruct.storm_rational_function = static_cast(&rationalFunction); - return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), helperStruct)); + uint64_t terminalValue = (uint64_t)&helperStruct; + + return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), terminalValue)); } #endif From 912ad98cbb12ba3775bcd72391d7c66e890554b5 Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 18 Jul 2016 19:18:02 +0200 Subject: [PATCH 10/49] Copy&Paste fixed. Former-commit-id: 745ec5503738b6d3729d5d42fd4bc939125ab466 --- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index ff59c2e39..730038763 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -627,7 +627,7 @@ namespace storm { #ifdef STORM_HAVE_CARL else if (std::is_same::value) { STORM_LOG_ASSERT(mtbdd_gettype(node) == sylvan_storm_rational_function_get_type(), "Expected a storm::RationalFunction value."); - uint64_t value = mtbdd_getvalue(leaf); + uint64_t value = mtbdd_getvalue(node); storm_rational_function_ptr_struct* helperStructPtr = (storm_rational_function_ptr_struct*) value; storm::RationalFunction* rationalFunction = (storm::RationalFunction*)(helperStructPtr->storm_rational_function); From 4cb70c8093d525b955f72ef261748d3e04d4b615 Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 18 Jul 2016 19:19:34 +0200 Subject: [PATCH 11/49] Fall back on C-style casts. Former-commit-id: 80df36b395cdb12549795d23d18fdc76a00fe35c --- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 2 +- src/storage/dd/sylvan/InternalSylvanDdManager.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index 730038763..55dd24c79 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -604,7 +604,7 @@ namespace storm { template MTBDD InternalAdd::getLeaf(storm::RationalFunction const& value) { storm_rational_function_ptr_struct helperStruct; - helperStruct.storm_rational_function = static_cast(&value); + helperStruct.storm_rational_function = (void*)(&value); uint64_t terminalValue = (uint64_t)&helperStruct; return sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), terminalValue); diff --git a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp index 1d0642048..c10235ca8 100644 --- a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp +++ b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp @@ -85,7 +85,7 @@ namespace storm { InternalAdd InternalDdManager::getAddOne() const { storm::RationalFunction rationalFunction = storm::utility::one(); storm_rational_function_ptr_struct helperStruct; - helperStruct.storm_rational_function = static_cast(&rationalFunction); + helperStruct.storm_rational_function = (void*)(&rationalFunction); uint64_t value = (uint64_t)&helperStruct; return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), value)); @@ -111,7 +111,7 @@ namespace storm { InternalAdd InternalDdManager::getAddZero() const { storm::RationalFunction rationalFunction = storm::utility::zero(); storm_rational_function_ptr_struct helperStruct; - helperStruct.storm_rational_function = static_cast(&rationalFunction); + helperStruct.storm_rational_function = (void*)(&rationalFunction); uint64_t value = (uint64_t)&helperStruct; return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), value)); @@ -133,7 +133,7 @@ namespace storm { InternalAdd InternalDdManager::getConstant(storm::RationalFunction const& value) const { storm::RationalFunction rationalFunction = value; storm_rational_function_ptr_struct helperStruct; - helperStruct.storm_rational_function = static_cast(&rationalFunction); + helperStruct.storm_rational_function = (void*)(&rationalFunction); uint64_t terminalValue = (uint64_t)&helperStruct; return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), terminalValue)); From 810e4bbbb0bede7b0954ca9b1f23dc4bcb008b82 Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 18 Jul 2016 19:22:13 +0200 Subject: [PATCH 12/49] Added call to GetMTBDD(). Former-commit-id: 6e19166ca4f3d3b714656e2ba361d766284fecff --- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index 55dd24c79..1ceb02b01 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -607,7 +607,7 @@ namespace storm { helperStruct.storm_rational_function = (void*)(&value); uint64_t terminalValue = (uint64_t)&helperStruct; - return sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), terminalValue); + return sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), terminalValue).GetMTBDD(); } template From 4de8d6c1213eda84ec9a36480c1426d17f2c9f80 Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 18 Jul 2016 19:29:33 +0200 Subject: [PATCH 13/49] Moved code to template specialization because of return type conversion. Former-commit-id: cc2e57a22ecaf7f388c415a1d9dbefb9dd5d4d66 --- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 26 +++++++++++++++------ 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index 1ceb02b01..560592c57 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -626,13 +626,7 @@ namespace storm { } #ifdef STORM_HAVE_CARL else if (std::is_same::value) { - STORM_LOG_ASSERT(mtbdd_gettype(node) == sylvan_storm_rational_function_get_type(), "Expected a storm::RationalFunction value."); - uint64_t value = mtbdd_getvalue(node); - storm_rational_function_ptr_struct* helperStructPtr = (storm_rational_function_ptr_struct*) value; - - storm::RationalFunction* rationalFunction = (storm::RationalFunction*)(helperStructPtr->storm_rational_function); - - return negated ? -(*rationalFunction) : (*rationalFunction); + STORM_LOG_ASSERT(false, "Non-specialized version of getValue() called for storm::RationalFunction value."); } #endif else { @@ -640,6 +634,24 @@ namespace storm { } } +#ifdef STORM_HAVE_CARL + template<> + storm::RationalFunction InternalAdd::getValue(MTBDD const& node) { + STORM_LOG_ASSERT(mtbdd_isleaf(node), "Expected leaf, but got variable " << mtbdd_getvar(node) << "."); + + bool negated = mtbdd_hascomp(node); + MTBDD n = mtbdd_regular(node); + + STORM_LOG_ASSERT(mtbdd_gettype(node) == sylvan_storm_rational_function_get_type(), "Expected a storm::RationalFunction value."); + uint64_t value = mtbdd_getvalue(node); + storm_rational_function_ptr_struct* helperStructPtr = (storm_rational_function_ptr_struct*)value; + + storm::RationalFunction* rationalFunction = (storm::RationalFunction*)(helperStructPtr->storm_rational_function); + + return negated ? -(*rationalFunction) : (*rationalFunction); + } +#endif + template sylvan::Mtbdd InternalAdd::getSylvanMtbdd() const { return sylvanMtbdd; From 40e40a19b12e38a0fe54cd5a8cf38cebe9a504c7 Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 18 Jul 2016 19:30:45 +0200 Subject: [PATCH 14/49] Missing template argument replacement. Former-commit-id: 5bebdda1488ff74da4a94959bbdef11ac6ea5cd4 --- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index 560592c57..25320babd 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -636,7 +636,7 @@ namespace storm { #ifdef STORM_HAVE_CARL template<> - storm::RationalFunction InternalAdd::getValue(MTBDD const& node) { + storm::RationalFunction InternalAdd::getValue(MTBDD const& node) { STORM_LOG_ASSERT(mtbdd_isleaf(node), "Expected leaf, but got variable " << mtbdd_getvar(node) << "."); bool negated = mtbdd_hascomp(node); From cdb57ed47b05ec6747e987f3754237a039c6473a Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 18 Jul 2016 19:37:01 +0200 Subject: [PATCH 15/49] Moooore templates. Former-commit-id: 050bebd7713c69e5102d2f7aa9f502d69462e4b5 --- src/storage/dd/sylvan/InternalSylvanBdd.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/storage/dd/sylvan/InternalSylvanBdd.cpp b/src/storage/dd/sylvan/InternalSylvanBdd.cpp index 4d580cfeb..0ad6cfa47 100644 --- a/src/storage/dd/sylvan/InternalSylvanBdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanBdd.cpp @@ -11,6 +11,14 @@ #include "src/utility/macros.h" #include "src/exceptions/InvalidOperationException.h" +#include "src/adapters/CarlAdapter.h" + +#include "storm-config.h" +// TODO: Remove this later on. +#ifndef STORM_HAVE_CARL +#define STORM_HAVE_CARL 1 +#endif + namespace storm { namespace dd { InternalBdd::InternalBdd(InternalDdManager const* ddManager, sylvan::Bdd const& sylvanBdd) : ddManager(ddManager), sylvanBdd(sylvanBdd) { @@ -237,7 +245,13 @@ namespace storm { return InternalAdd(ddManager, this->sylvanBdd.toDoubleMtbdd()); } else if (std::is_same::value) { return InternalAdd(ddManager, this->sylvanBdd.toInt64Mtbdd()); - } else { + } +#ifdef STORM_HAVE_CARL + else if (std::is_same::value) { + STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Conversion to ADD is currently unsupported for storm::RationalFunction."); + } +#endif + else { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Illegal ADD type."); } } @@ -381,15 +395,18 @@ namespace storm { template InternalBdd InternalBdd::fromVector(InternalDdManager const* ddManager, std::vector const& values, Odd const& odd, std::vector const& sortedDdVariableIndices, std::function const& filter); template InternalBdd InternalBdd::fromVector(InternalDdManager const* ddManager, std::vector const& values, Odd const& odd, std::vector const& sortedDdVariableIndices, std::function const& filter); + template InternalBdd InternalBdd::fromVector(InternalDdManager const* ddManager, std::vector const& values, Odd const& odd, std::vector const& sortedDdVariableIndices, std::function const& filter); template InternalAdd InternalBdd::toAdd() const; template InternalAdd InternalBdd::toAdd() const; + template InternalAdd InternalBdd::toAdd() const; template void InternalBdd::filterExplicitVector(Odd const& odd, std::vector const& ddVariableIndices, std::vector const& sourceValues, std::vector& targetValues) const; template void InternalBdd::filterExplicitVector(Odd const& odd, std::vector const& ddVariableIndices, std::vector const& sourceValues, std::vector& targetValues) const; + template void InternalBdd::filterExplicitVector(Odd const& odd, std::vector const& ddVariableIndices, std::vector const& sourceValues, std::vector& targetValues) const; template InternalAdd InternalBdd::ite(InternalAdd const& thenAdd, InternalAdd const& elseAdd) const; template InternalAdd InternalBdd::ite(InternalAdd const& thenAdd, InternalAdd const& elseAdd) const; - + template InternalAdd InternalBdd::ite(InternalAdd const& thenAdd, InternalAdd const& elseAdd) const; } } \ No newline at end of file From d81f4ca5a823c9e6ef57d16238dbf09d55bb3a8f Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 18 Jul 2016 19:43:39 +0200 Subject: [PATCH 16/49] Code around features that are not available. Former-commit-id: 45a0752daad271ad04f013773c4a13ed859ccb97 --- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index 25320babd..9b6303f54 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -187,12 +187,22 @@ namespace storm { InternalBdd InternalAdd::greater(ValueType const& value) const { return InternalBdd(ddManager, this->sylvanMtbdd.BddStrictThreshold(value)); } + + template<> + InternalBdd InternalAdd::greater(storm::RationalFunction const& value) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented."); + } template InternalBdd InternalAdd::greaterOrEqual(ValueType const& value) const { return InternalBdd(ddManager, this->sylvanMtbdd.BddThreshold(value)); } + template<> + InternalBdd InternalAdd::greaterOrEqual(storm::RationalFunction const& value) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented."); + } + template InternalBdd InternalAdd::less(ValueType const& value) const { return !this->greaterOrEqual(value); From e0647f34eb937a0702cbe8a6c1d6b4ffca257b87 Mon Sep 17 00:00:00 2001 From: PBerger Date: Tue, 19 Jul 2016 17:32:00 +0200 Subject: [PATCH 17/49] Added missing template instantiation. Added missing function implementation for sylvan OPs. Former-commit-id: fb10555ca3c2e791533cf0b7da960e86dc348a65 --- .../src/sylvan_storm_rational_function.c | 36 +++++++++++++++++++ src/storage/dd/sylvan/SylvanAddIterator.cpp | 11 ++++++ 2 files changed, 47 insertions(+) diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c index ebb5f7062..c2fb73016 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c @@ -220,6 +220,42 @@ TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_divide, MTBDD*, pa, MTBDD*, return mtbdd_invalid; } +/** + * The abstraction operators are called in either of two ways: + * - with k=0, then just calculate "a op b" + * - with k<>0, then just calculate "a := a op a", k times + */ + +TASK_IMPL_3(MTBDD, sylvan_storm_rational_function_abstract_op_plus, MTBDD, a, MTBDD, b, int, k) +{ + if (k==0) { + return mtbdd_apply(a, b, TASK(sylvan_storm_rational_function_op_plus)); + } else { + MTBDD res = a; + for (int i=0; i +#include "src/adapters/CarlAdapter.h" + +#include "storm-config.h" +// TODO: Remove this later on. +#ifndef STORM_HAVE_CARL +#define STORM_HAVE_CARL 1 +#endif + namespace storm { namespace dd { template @@ -187,5 +195,8 @@ namespace storm { template class AddIterator; template class AddIterator; +#ifdef STORM_HAVE_CARL + template class AddIterator; +#endif } } From 291fa3171414ea9f2cab45a84fcebe3c1be73038 Mon Sep 17 00:00:00 2001 From: PBerger Date: Wed, 20 Jul 2016 19:44:45 +0200 Subject: [PATCH 18/49] Fixes for old GCC versions. Former-commit-id: 8b97eab10285a75ee806d35c5f869ed9fc6d5c36 --- CMakeLists.txt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6775e3fff..f6e0e467f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,7 +114,20 @@ if(CMAKE_COMPILER_IS_GNUCC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -funroll-loops") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -funroll-loops") add_definitions(-DBOOST_RESULT_OF_USE_DECLTYPE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -pedantic -Wno-deprecated-declarations -Wno-unused-local-typedefs -Wno-unknown-pragmas") + + set(STORM_CXX_STD_COMMAND "-std=c++14") + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.1) + message(STATUS "GCC Version is greater then 5.1, using -std=c++14") + set(STORM_CXX_STD_COMMAND "-std=c++14") + elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9.2) + message(WARNING "GCC Version is less then 4.9.2 - your compiler is probably too old for StoRM!") + set(STORM_CXX_STD_COMMAND "-std=c++1y") + else() + message(STATUS "GCC Version is between 4.9.2 and 5.1, using -std=c++1y") + set(STORM_CXX_STD_COMMAND "-std=c++1y") + endif() + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${STORM_CXX_STD_COMMAND} -Wall -pedantic -Wno-deprecated-declarations -Wno-unused-local-typedefs -Wno-unknown-pragmas") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -Wno-deprecated-declarations") # Turn on popcnt instruction if desired (yes by default) @@ -362,6 +375,7 @@ find_package(CLN QUIET) if(CLN_FOUND) set(STORM_HAVE_CLN ON) + add_definitions(-DUSE_CLN_NUMBERS) message(STATUS "StoRM - Linking with CLN ${CLN_VERSION_STRING}") include_directories("${CLN_INCLUDE_DIR}") list(APPEND STORM_LINK_LIBRARIES ${CLN_LIBRARIES}) From ec3b5d2aac41b6750e047394c2b1598e68e316b0 Mon Sep 17 00:00:00 2001 From: PBerger Date: Wed, 20 Jul 2016 22:35:34 +0200 Subject: [PATCH 19/49] Removed useless piece of code. Former-commit-id: 8012cd58dea6b6c78e612c2a1d33731c21aca509 --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6e0e467f..50b0e1500 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -375,7 +375,6 @@ find_package(CLN QUIET) if(CLN_FOUND) set(STORM_HAVE_CLN ON) - add_definitions(-DUSE_CLN_NUMBERS) message(STATUS "StoRM - Linking with CLN ${CLN_VERSION_STRING}") include_directories("${CLN_INCLUDE_DIR}") list(APPEND STORM_LINK_LIBRARIES ${CLN_LIBRARIES}) From ca65cecbfdec9deb4e3ef8f01e57f61483abf52d Mon Sep 17 00:00:00 2001 From: PBerger Date: Thu, 21 Jul 2016 19:39:51 +0200 Subject: [PATCH 20/49] Fixed a few of Sylvans nasty habits. Former-commit-id: e965a8f613a5677a5a9726f7d18e2c6fcafb045a --- resources/3rdparty/sylvan/src/lace.h | 49 ++++++++++++------- .../3rdparty/sylvan/src/sylvan_mtbdd_storm.h | 16 +++--- .../src/sylvan_storm_rational_function.h | 14 +++--- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/resources/3rdparty/sylvan/src/lace.h b/resources/3rdparty/sylvan/src/lace.h index 419cd222a..7933d98d7 100644 --- a/resources/3rdparty/sylvan/src/lace.h +++ b/resources/3rdparty/sylvan/src/lace.h @@ -66,6 +66,7 @@ extern "C" { #define PAD(x,b) ( ( (b) - ((x)%(b)) ) & ((b)-1) ) /* b must be power of 2 */ #define ROUND(x,b) ( (x) + PAD( (x), (b) ) ) +#define MINONE(x) ((x < 1) ? (1) : (x)) /* The size is in bytes. Note that this is without the extra overhead from Lace. The value must be greater than or equal to the maximum size of your tasks. @@ -183,7 +184,7 @@ struct __lace_common_fields_only { TASK_COMMON_FIELDS(_Task) }; typedef struct _Task { TASK_COMMON_FIELDS(_Task); - char p1[PAD(LACE_COMMON_FIELD_SIZE, P_SZ)]; + char p1[MINONE(PAD(LACE_COMMON_FIELD_SIZE, P_SZ))]; char d[LACE_TASKSIZE]; char p2[PAD(ROUND(LACE_COMMON_FIELD_SIZE, P_SZ) + LACE_TASKSIZE, LINE_SIZE)]; } Task; @@ -226,7 +227,7 @@ typedef struct _WorkerP { uint32_t seed; // my random seed (for lace_steal_random) } WorkerP; -#define LACE_TYPEDEF_CB(t, f, ...) typedef t (*f)(WorkerP *, Task *, ##__VA_ARGS__); +#define LACE_TYPEDEF_CB(t, f, ...) typedef t (*f)(WorkerP *, Task *, ##__VA_ARGS__) LACE_TYPEDEF_CB(void, lace_startup_cb, void*); /** @@ -648,7 +649,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head ) if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head+1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -760,7 +762,7 @@ RTYPE NAME##_CALL(WorkerP *w, Task *__dq_head ) static inline __attribute__((always_inline)) \ RTYPE NAME##_WORK(WorkerP *__lace_worker __attribute__((unused)), Task *__lace_dq_head __attribute__((unused)) )\ -#define TASK_0(RTYPE, NAME) TASK_DECL_0(RTYPE, NAME) TASK_IMPL_0(RTYPE, NAME) +#define TASK_0(RTYPE, NAME) TASK_DECL_0(RTYPE, NAME); TASK_IMPL_0(RTYPE, NAME) #define VOID_TASK_DECL_0(NAME) \ \ @@ -798,7 +800,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head ) if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head + 1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -951,7 +954,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1) if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head + 1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -1101,7 +1105,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1) if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head + 1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -1254,7 +1259,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2) if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head + 1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -1404,7 +1410,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2) if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head + 1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -1557,7 +1564,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head + 1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -1707,7 +1715,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head + 1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -1860,7 +1869,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head + 1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -2010,7 +2020,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head + 1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -2163,7 +2174,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head + 1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -2313,7 +2325,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head + 1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -2466,7 +2479,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head + 1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -2616,7 +2630,8 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts = (TailSplit){{head,head+1}}; \ + ts.ts.tail = head; \ + ts.ts.split = head + 1; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ diff --git a/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.h b/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.h index 38fa6668b..a35fd8398 100644 --- a/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.h +++ b/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.h @@ -6,7 +6,7 @@ void mtbdd_getsha(MTBDD mtbdd, char *target); // target must be at least 65 byte * If either operand is mtbdd_false (not defined), * then the result is mtbdd_false (i.e. not defined). */ -TASK_DECL_2(MTBDD, mtbdd_op_divide, MTBDD*, MTBDD*); +TASK_DECL_2(MTBDD, mtbdd_op_divide, MTBDD*, MTBDD*) #define mtbdd_divide(a, b) mtbdd_apply(a, b, TASK(mtbdd_op_divide)) /** @@ -15,7 +15,7 @@ TASK_DECL_2(MTBDD, mtbdd_op_divide, MTBDD*, MTBDD*); * For Integer/Double MTBDD, if either operand is mtbdd_false (not defined), * then the result is the other operand. */ -TASK_DECL_2(MTBDD, mtbdd_op_equals, MTBDD*, MTBDD*); +TASK_DECL_2(MTBDD, mtbdd_op_equals, MTBDD*, MTBDD*) #define mtbdd_equals(a, b) mtbdd_apply(a, b, TASK(mtbdd_op_equals)) /** @@ -24,7 +24,7 @@ TASK_DECL_2(MTBDD, mtbdd_op_equals, MTBDD*, MTBDD*); * For Integer/Double MTBDD, if either operand is mtbdd_false (not defined), * then the result is the other operand. */ -TASK_DECL_2(MTBDD, mtbdd_op_less, MTBDD*, MTBDD*); +TASK_DECL_2(MTBDD, mtbdd_op_less, MTBDD*, MTBDD*) #define mtbdd_less_as_bdd(a, b) mtbdd_apply(a, b, TASK(mtbdd_op_less)) /** @@ -33,7 +33,7 @@ TASK_DECL_2(MTBDD, mtbdd_op_less, MTBDD*, MTBDD*); * For Integer/Double MTBDD, if either operand is mtbdd_false (not defined), * then the result is the other operand. */ -TASK_DECL_2(MTBDD, mtbdd_op_less_or_equal, MTBDD*, MTBDD*); +TASK_DECL_2(MTBDD, mtbdd_op_less_or_equal, MTBDD*, MTBDD*) #define mtbdd_less_or_equal_as_bdd(a, b) mtbdd_apply(a, b, TASK(mtbdd_op_less_or_equal)) /** @@ -42,7 +42,7 @@ TASK_DECL_2(MTBDD, mtbdd_op_less_or_equal, MTBDD*, MTBDD*); * For Integer/Double MTBDD, if either operand is mtbdd_false (not defined), * then the result is the other operand. */ -TASK_DECL_2(MTBDD, mtbdd_op_pow, MTBDD*, MTBDD*); +TASK_DECL_2(MTBDD, mtbdd_op_pow, MTBDD*, MTBDD*) #define mtbdd_pow(a, b) mtbdd_apply(a, b, TASK(mtbdd_op_pow)) /** @@ -51,7 +51,7 @@ TASK_DECL_2(MTBDD, mtbdd_op_pow, MTBDD*, MTBDD*); * For Integer/Double MTBDD, if either operand is mtbdd_false (not defined), * then the result is the other operand. */ -TASK_DECL_2(MTBDD, mtbdd_op_mod, MTBDD*, MTBDD*); +TASK_DECL_2(MTBDD, mtbdd_op_mod, MTBDD*, MTBDD*) #define mtbdd_mod(a, b) mtbdd_apply(a, b, TASK(mtbdd_op_mod)) /** @@ -60,7 +60,7 @@ TASK_DECL_2(MTBDD, mtbdd_op_mod, MTBDD*, MTBDD*); * For Integer/Double MTBDD, if either operand is mtbdd_false (not defined), * then the result is the other operand. */ -TASK_DECL_2(MTBDD, mtbdd_op_logxy, MTBDD*, MTBDD*); +TASK_DECL_2(MTBDD, mtbdd_op_logxy, MTBDD*, MTBDD*) #define mtbdd_logxy(a, b) mtbdd_apply(a, b, TASK(mtbdd_op_logxy)) /** @@ -101,7 +101,7 @@ TASK_DECL_1(MTBDD, mtbdd_bool_to_int64, MTBDD) /** * Count the number of assignments (minterms) leading to a non-zero */ -TASK_DECL_2(double, mtbdd_non_zero_count, MTBDD, size_t); +TASK_DECL_2(double, mtbdd_non_zero_count, MTBDD, size_t) #define mtbdd_non_zero_count(dd, nvars) CALL(mtbdd_non_zero_count, dd, nvars) // Checks whether the given MTBDD (does represents a zero leaf. diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h index f97347690..6cdb142a5 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h @@ -34,29 +34,29 @@ MTBDD mtbdd_storm_rational_function(storm_rational_function_t val); /** * Operation "plus" for two storm::RationalFunction MTBDDs */ -TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_plus, MTBDD*, MTBDD*); -TASK_DECL_3(MTBDD, sylvan_storm_rational_function_abstract_op_plus, MTBDD, MTBDD, int); +TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_plus, MTBDD*, MTBDD*) +TASK_DECL_3(MTBDD, sylvan_storm_rational_function_abstract_op_plus, MTBDD, MTBDD, int) /** * Operation "minus" for two storm::RationalFunction MTBDDs */ -TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_minus, MTBDD*, MTBDD*); +TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_minus, MTBDD*, MTBDD*) /** * Operation "times" for two storm::RationalFunction MTBDDs */ -TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_times, MTBDD*, MTBDD*); -TASK_DECL_3(MTBDD, sylvan_storm_rational_function_abstract_op_times, MTBDD, MTBDD, int); +TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_times, MTBDD*, MTBDD*) +TASK_DECL_3(MTBDD, sylvan_storm_rational_function_abstract_op_times, MTBDD, MTBDD, int) /** * Operation "divide" for two storm::RationalFunction MTBDDs */ -TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_divide, MTBDD*, MTBDD*); +TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_divide, MTBDD*, MTBDD*) /** * Operation "negate" for one storm::RationalFunction MTBDD */ -TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_neg, MTBDD, size_t); +TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_neg, MTBDD, size_t) /** * Compute a + b From 07d4848f55d0b46d4dc83df2b07a3e2d677fe537 Mon Sep 17 00:00:00 2001 From: PBerger Date: Thu, 21 Jul 2016 19:56:32 +0200 Subject: [PATCH 21/49] Fixed missing include in InternalSylvanAdd.cpp Added simple test for Sylvan + RationalFunctions. Former-commit-id: ffb747a861f06422bebc1e5a1146f9150c55e710 --- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 2 ++ test/functional/storage/SylvanDdTest.cpp | 29 +++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index 9b6303f54..92c6ca642 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -10,6 +10,8 @@ #include "src/utility/constants.h" #include "src/exceptions/NotImplementedException.h" +#include "storm-config.h" + namespace storm { namespace dd { template diff --git a/test/functional/storage/SylvanDdTest.cpp b/test/functional/storage/SylvanDdTest.cpp index fdb60e5c0..75a2c8947 100644 --- a/test/functional/storage/SylvanDdTest.cpp +++ b/test/functional/storage/SylvanDdTest.cpp @@ -1,6 +1,7 @@ #include "gtest/gtest.h" #include "storm-config.h" +#include "src/adapters/CarlAdapter.h" #include "src/exceptions/InvalidArgumentException.h" #include "src/storage/dd/DdManager.h" #include "src/storage/dd/Add.h" @@ -40,6 +41,34 @@ TEST(SylvanDd, Constants) { EXPECT_EQ(2, two.getMax()); } +#ifdef STORM_HAVE_CARL +TEST(SylvanDd, RationalFunctionConstants) { + std::shared_ptr> manager(new storm::dd::DdManager()); + storm::dd::Add zero; + ASSERT_NO_THROW(zero = manager->template getAddZero()); + + EXPECT_EQ(0ul, zero.getNonZeroCount()); + EXPECT_EQ(1ul, zero.getLeafCount()); + EXPECT_EQ(1ul, zero.getNodeCount()); + + storm::dd::Add one; + ASSERT_NO_THROW(one = manager->template getAddOne()); + + EXPECT_EQ(0ul, one.getNonZeroCount()); + EXPECT_EQ(1ul, one.getLeafCount()); + EXPECT_EQ(1ul, one.getNodeCount()); + + storm::dd::Add two; + storm::RationalFunction constantTwo(2); + + ASSERT_NO_THROW(two = manager->template getConstant(constantTwo)); + + EXPECT_EQ(0ul, two.getNonZeroCount()); + EXPECT_EQ(1ul, two.getLeafCount()); + EXPECT_EQ(1ul, two.getNodeCount()); +} +#endif + TEST(SylvanDd, AddGetMetaVariableTest) { std::shared_ptr> manager(new storm::dd::DdManager()); ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9)); From 1eb3335f220b3fe9e688651ebbd4f08f7e4469c9 Mon Sep 17 00:00:00 2001 From: PBerger Date: Thu, 21 Jul 2016 20:11:56 +0200 Subject: [PATCH 22/49] Mooooore template instances! Former-commit-id: 6da42f16c528c9911ca3ba0c79812be6294098d8 --- src/storage/dd/Add.cpp | 6 ++++++ src/storage/dd/Bdd.cpp | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/storage/dd/Add.cpp b/src/storage/dd/Add.cpp index bcff0e3da..53074bbb6 100644 --- a/src/storage/dd/Add.cpp +++ b/src/storage/dd/Add.cpp @@ -12,6 +12,9 @@ #include "src/utility/macros.h" #include "src/exceptions/InvalidArgumentException.h" +#include "storm-config.h" +#include "src/adapters/CarlAdapter.h" + namespace storm { namespace dd { template @@ -766,5 +769,8 @@ namespace storm { template class Add; template class Add; +#ifdef STORM_HAVE_CARL + template class InternalAdd; +#endif } } \ No newline at end of file diff --git a/src/storage/dd/Bdd.cpp b/src/storage/dd/Bdd.cpp index f8bf6b368..c1e72cf09 100644 --- a/src/storage/dd/Bdd.cpp +++ b/src/storage/dd/Bdd.cpp @@ -15,6 +15,9 @@ #include "src/utility/macros.h" #include "src/exceptions/InvalidArgumentException.h" +#include "storm-config.h" +#include "src/adapters/CarlAdapter.h" + namespace storm { namespace dd { @@ -352,14 +355,27 @@ namespace storm { template Bdd Bdd::fromVector(DdManager const& ddManager, std::vector const& values, Odd const& odd, std::set const& metaVariables, std::function const& filter); template Bdd Bdd::fromVector(DdManager const& ddManager, std::vector const& values, Odd const& odd, std::set const& metaVariables, std::function const& filter); +#ifdef STORM_HAVE_CARL + template Bdd Bdd::fromVector(DdManager const& ddManager, std::vector const& values, Odd const& odd, std::set const& metaVariables, std::function const& filter); +#endif template Add Bdd::toAdd() const; template Add Bdd::toAdd() const; +#ifdef STORM_HAVE_CARL + template Add Bdd::toAdd() const; +#endif template std::vector Bdd::filterExplicitVector(Odd const& odd, std::vector const& values) const; template std::vector Bdd::filterExplicitVector(Odd const& odd, std::vector const& values) const; +#ifdef STORM_HAVE_CARL + template std::vector Bdd::filterExplicitVector(Odd const& odd, std::vector const& values) const; +#endif + template Add Bdd::ite(Add const& thenAdd, Add const& elseAdd) const; template Add Bdd::ite(Add const& thenAdd, Add const& elseAdd) const; +#ifdef STORM_HAVE_CARL + template Add Bdd::ite(Add const& thenAdd, Add const& elseAdd) const; +#endif } } From 53ca0f190a87b2fea13225d69494e97e744ac09d Mon Sep 17 00:00:00 2001 From: PBerger Date: Sun, 24 Jul 2016 17:21:46 +0200 Subject: [PATCH 23/49] More template instances. Former-commit-id: c019bad31b7e789800ec3036d8942de860055343 --- src/storage/dd/DdManager.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/storage/dd/DdManager.cpp b/src/storage/dd/DdManager.cpp index 195565e8f..caeedd2fa 100644 --- a/src/storage/dd/DdManager.cpp +++ b/src/storage/dd/DdManager.cpp @@ -6,6 +6,9 @@ #include "src/utility/constants.h" #include "src/exceptions/InvalidArgumentException.h" +#include "storm-config.h" +#include "src/adapters/CarlAdapter.h" + #include namespace storm { @@ -343,17 +346,32 @@ namespace storm { template Add DdManager::getAddZero() const; template Add DdManager::getAddZero() const; +#ifdef STORM_HAVE_CARL + template Add DdManager::getAddZero() const; +#endif template Add DdManager::getAddOne() const; template Add DdManager::getAddOne() const; - +#ifdef STORM_HAVE_CARL + template Add DdManager::getAddOne() const; +#endif + template Add DdManager::getInfinity() const; template Add DdManager::getInfinity() const; +#ifdef STORM_HAVE_CARL + template Add DdManager::getInfinity() const; +#endif template Add DdManager::getConstant(double const& value) const; template Add DdManager::getConstant(uint_fast64_t const& value) const; - +#ifdef STORM_HAVE_CARL + template Add DdManager::getConstant(uint_fast64_t const& value) const; +#endif + template Add DdManager::getIdentity(storm::expressions::Variable const& variable) const; template Add DdManager::getIdentity(storm::expressions::Variable const& variable) const; +#ifdef STORM_HAVE_CARL + template Add DdManager::getIdentity(storm::expressions::Variable const& variable) const; +#endif } } From 74f8efb0f938ba7919178e86a3109c9c82b1301f Mon Sep 17 00:00:00 2001 From: PBerger Date: Sun, 24 Jul 2016 17:26:14 +0200 Subject: [PATCH 24/49] Fixed Copy&Paste errors. Former-commit-id: 5e503a0ae4a2f8ca66d6a4094cff3db545929b45 --- src/storage/dd/DdManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storage/dd/DdManager.cpp b/src/storage/dd/DdManager.cpp index caeedd2fa..5ad46ac53 100644 --- a/src/storage/dd/DdManager.cpp +++ b/src/storage/dd/DdManager.cpp @@ -359,13 +359,13 @@ namespace storm { template Add DdManager::getInfinity() const; template Add DdManager::getInfinity() const; #ifdef STORM_HAVE_CARL - template Add DdManager::getInfinity() const; + template Add DdManager::getInfinity() const; #endif template Add DdManager::getConstant(double const& value) const; template Add DdManager::getConstant(uint_fast64_t const& value) const; #ifdef STORM_HAVE_CARL - template Add DdManager::getConstant(uint_fast64_t const& value) const; + template Add DdManager::getConstant(storm::RationalFunction const& value) const; #endif template Add DdManager::getIdentity(storm::expressions::Variable const& variable) const; From 9511ecc9e47b40b7478dd866897d6437a965c20d Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 25 Jul 2016 14:57:36 +0200 Subject: [PATCH 25/49] Fixed Copy&Paste Error. Former-commit-id: 3b06dc0ba4a63698ff269a630d3d085871e1cbaf --- src/storage/dd/Add.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/dd/Add.cpp b/src/storage/dd/Add.cpp index 618adee92..97809049d 100644 --- a/src/storage/dd/Add.cpp +++ b/src/storage/dd/Add.cpp @@ -770,7 +770,7 @@ namespace storm { template class Add; template class Add; #ifdef STORM_HAVE_CARL - template class InternalAdd; + template class Add; #endif } } From fb4bfd724dc7078f6646a52199983b28fed8a1c5 Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 25 Jul 2016 17:32:20 +0200 Subject: [PATCH 26/49] Reverted lace.h back to find the regression. Former-commit-id: 03d4d796f3d42b003a15d5f0b69ea9d21a562a11 --- resources/3rdparty/sylvan/src/lace.h | 49 ++++++++++------------------ 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/resources/3rdparty/sylvan/src/lace.h b/resources/3rdparty/sylvan/src/lace.h index 7933d98d7..419cd222a 100644 --- a/resources/3rdparty/sylvan/src/lace.h +++ b/resources/3rdparty/sylvan/src/lace.h @@ -66,7 +66,6 @@ extern "C" { #define PAD(x,b) ( ( (b) - ((x)%(b)) ) & ((b)-1) ) /* b must be power of 2 */ #define ROUND(x,b) ( (x) + PAD( (x), (b) ) ) -#define MINONE(x) ((x < 1) ? (1) : (x)) /* The size is in bytes. Note that this is without the extra overhead from Lace. The value must be greater than or equal to the maximum size of your tasks. @@ -184,7 +183,7 @@ struct __lace_common_fields_only { TASK_COMMON_FIELDS(_Task) }; typedef struct _Task { TASK_COMMON_FIELDS(_Task); - char p1[MINONE(PAD(LACE_COMMON_FIELD_SIZE, P_SZ))]; + char p1[PAD(LACE_COMMON_FIELD_SIZE, P_SZ)]; char d[LACE_TASKSIZE]; char p2[PAD(ROUND(LACE_COMMON_FIELD_SIZE, P_SZ) + LACE_TASKSIZE, LINE_SIZE)]; } Task; @@ -227,7 +226,7 @@ typedef struct _WorkerP { uint32_t seed; // my random seed (for lace_steal_random) } WorkerP; -#define LACE_TYPEDEF_CB(t, f, ...) typedef t (*f)(WorkerP *, Task *, ##__VA_ARGS__) +#define LACE_TYPEDEF_CB(t, f, ...) typedef t (*f)(WorkerP *, Task *, ##__VA_ARGS__); LACE_TYPEDEF_CB(void, lace_startup_cb, void*); /** @@ -649,8 +648,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head ) if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head+1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -762,7 +760,7 @@ RTYPE NAME##_CALL(WorkerP *w, Task *__dq_head ) static inline __attribute__((always_inline)) \ RTYPE NAME##_WORK(WorkerP *__lace_worker __attribute__((unused)), Task *__lace_dq_head __attribute__((unused)) )\ -#define TASK_0(RTYPE, NAME) TASK_DECL_0(RTYPE, NAME); TASK_IMPL_0(RTYPE, NAME) +#define TASK_0(RTYPE, NAME) TASK_DECL_0(RTYPE, NAME) TASK_IMPL_0(RTYPE, NAME) #define VOID_TASK_DECL_0(NAME) \ \ @@ -800,8 +798,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head ) if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head + 1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -954,8 +951,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1) if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head + 1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -1105,8 +1101,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1) if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head + 1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -1259,8 +1254,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2) if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head + 1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -1410,8 +1404,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2) if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head + 1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -1564,8 +1557,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head + 1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -1715,8 +1707,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head + 1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -1869,8 +1860,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head + 1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -2020,8 +2010,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head + 1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -2174,8 +2163,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head + 1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -2325,8 +2313,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head + 1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -2479,8 +2466,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head + 1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ @@ -2630,8 +2616,7 @@ void NAME##_SPAWN(WorkerP *w, Task *__dq_head , ATYPE_1 arg_1, ATYPE_2 arg_2, AT if (unlikely(w->allstolen)) { \ if (wt->movesplit) wt->movesplit = 0; \ head = __dq_head - w->dq; \ - ts.ts.tail = head; \ - ts.ts.split = head + 1; \ + ts = (TailSplit){{head,head+1}}; \ wt->ts.v = ts.v; \ compiler_barrier(); \ wt->allstolen = 0; \ From c4b7d778f30edc4cd77eb254286ea6d05a9c6dad Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 25 Jul 2016 22:58:00 +0200 Subject: [PATCH 27/49] Add MINONE macro back into lace.h Former-commit-id: 8eb55b63c2709aeca810810856de7d67aef5738f --- resources/3rdparty/sylvan/src/lace.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/3rdparty/sylvan/src/lace.h b/resources/3rdparty/sylvan/src/lace.h index 419cd222a..60f8d8fdf 100644 --- a/resources/3rdparty/sylvan/src/lace.h +++ b/resources/3rdparty/sylvan/src/lace.h @@ -66,6 +66,7 @@ extern "C" { #define PAD(x,b) ( ( (b) - ((x)%(b)) ) & ((b)-1) ) /* b must be power of 2 */ #define ROUND(x,b) ( (x) + PAD( (x), (b) ) ) +#define MINONE(x) ((x < 1) ? (1) : (x)) /* The size is in bytes. Note that this is without the extra overhead from Lace. The value must be greater than or equal to the maximum size of your tasks. @@ -183,7 +184,7 @@ struct __lace_common_fields_only { TASK_COMMON_FIELDS(_Task) }; typedef struct _Task { TASK_COMMON_FIELDS(_Task); - char p1[PAD(LACE_COMMON_FIELD_SIZE, P_SZ)]; + char p1[MINONE(PAD(LACE_COMMON_FIELD_SIZE, P_SZ))]; char d[LACE_TASKSIZE]; char p2[PAD(ROUND(LACE_COMMON_FIELD_SIZE, P_SZ) + LACE_TASKSIZE, LINE_SIZE)]; } Task; From 157c9f4f5a32e1464dcedaa9b2856cc9bf3697f6 Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 25 Jul 2016 23:10:19 +0200 Subject: [PATCH 28/49] Reverted MINONE change. Former-commit-id: 047c8175aa310d98d7f9fc07d8984761bae39c10 --- resources/3rdparty/sylvan/src/lace.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/3rdparty/sylvan/src/lace.h b/resources/3rdparty/sylvan/src/lace.h index 60f8d8fdf..419cd222a 100644 --- a/resources/3rdparty/sylvan/src/lace.h +++ b/resources/3rdparty/sylvan/src/lace.h @@ -66,7 +66,6 @@ extern "C" { #define PAD(x,b) ( ( (b) - ((x)%(b)) ) & ((b)-1) ) /* b must be power of 2 */ #define ROUND(x,b) ( (x) + PAD( (x), (b) ) ) -#define MINONE(x) ((x < 1) ? (1) : (x)) /* The size is in bytes. Note that this is without the extra overhead from Lace. The value must be greater than or equal to the maximum size of your tasks. @@ -184,7 +183,7 @@ struct __lace_common_fields_only { TASK_COMMON_FIELDS(_Task) }; typedef struct _Task { TASK_COMMON_FIELDS(_Task); - char p1[MINONE(PAD(LACE_COMMON_FIELD_SIZE, P_SZ))]; + char p1[PAD(LACE_COMMON_FIELD_SIZE, P_SZ)]; char d[LACE_TASKSIZE]; char p2[PAD(ROUND(LACE_COMMON_FIELD_SIZE, P_SZ) + LACE_TASKSIZE, LINE_SIZE)]; } Task; From 291f120cc0cc802aa01a9969aa39e05d4255829d Mon Sep 17 00:00:00 2001 From: PBerger Date: Tue, 26 Jul 2016 14:20:09 +0200 Subject: [PATCH 29/49] Added the encoding and identity test for Rational Functions. Former-commit-id: ed9695a5e235196e67158d4b1051b85ef374afda --- test/functional/storage/SylvanDdTest.cpp | 80 +++++++++++++++++------- 1 file changed, 58 insertions(+), 22 deletions(-) diff --git a/test/functional/storage/SylvanDdTest.cpp b/test/functional/storage/SylvanDdTest.cpp index 75a2c8947..ad5566050 100644 --- a/test/functional/storage/SylvanDdTest.cpp +++ b/test/functional/storage/SylvanDdTest.cpp @@ -41,6 +41,46 @@ TEST(SylvanDd, Constants) { EXPECT_EQ(2, two.getMax()); } +TEST(SylvanDd, AddGetMetaVariableTest) { + std::shared_ptr> manager(new storm::dd::DdManager()); + ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9)); + EXPECT_EQ(2ul, manager->getNumberOfMetaVariables()); + + ASSERT_THROW(manager->addMetaVariable("x", 0, 3), storm::exceptions::InvalidArgumentException); + + ASSERT_NO_THROW(manager->addMetaVariable("y", 0, 3)); + EXPECT_EQ(4ul, manager->getNumberOfMetaVariables()); + + EXPECT_TRUE(manager->hasMetaVariable("x'")); + EXPECT_TRUE(manager->hasMetaVariable("y'")); + + std::set metaVariableSet = {"x", "x'", "y", "y'"}; + EXPECT_EQ(metaVariableSet, manager->getAllMetaVariableNames()); +} + +TEST(SylvanDd, EncodingTest) { + std::shared_ptr> manager(new storm::dd::DdManager()); + std::pair x = manager->addMetaVariable("x", 1, 9); + + storm::dd::Bdd encoding; + ASSERT_THROW(encoding = manager->getEncoding(x.first, 0), storm::exceptions::InvalidArgumentException); + ASSERT_THROW(encoding = manager->getEncoding(x.first, 10), storm::exceptions::InvalidArgumentException); + ASSERT_NO_THROW(encoding = manager->getEncoding(x.first, 4)); + EXPECT_EQ(1ul, encoding.getNonZeroCount()); + + // As a BDD, this DD has one only leaf, because there does not exist a 0-leaf, and (consequently) one node less + // than the MTBDD. + EXPECT_EQ(5ul, encoding.getNodeCount()); + EXPECT_EQ(1ul, encoding.getLeafCount()); + + storm::dd::Add add; + ASSERT_NO_THROW(add = encoding.template toAdd()); + + // As an MTBDD, the 0-leaf is there, so the count is actually 2 and the node count is 6. + EXPECT_EQ(6ul, add.getNodeCount()); + EXPECT_EQ(2ul, add.getLeafCount()); +} + #ifdef STORM_HAVE_CARL TEST(SylvanDd, RationalFunctionConstants) { std::shared_ptr> manager(new storm::dd::DdManager()); @@ -67,26 +107,8 @@ TEST(SylvanDd, RationalFunctionConstants) { EXPECT_EQ(1ul, two.getLeafCount()); EXPECT_EQ(1ul, two.getNodeCount()); } -#endif - -TEST(SylvanDd, AddGetMetaVariableTest) { - std::shared_ptr> manager(new storm::dd::DdManager()); - ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9)); - EXPECT_EQ(2ul, manager->getNumberOfMetaVariables()); - - ASSERT_THROW(manager->addMetaVariable("x", 0, 3), storm::exceptions::InvalidArgumentException); - - ASSERT_NO_THROW(manager->addMetaVariable("y", 0, 3)); - EXPECT_EQ(4ul, manager->getNumberOfMetaVariables()); - - EXPECT_TRUE(manager->hasMetaVariable("x'")); - EXPECT_TRUE(manager->hasMetaVariable("y'")); - - std::set metaVariableSet = {"x", "x'", "y", "y'"}; - EXPECT_EQ(metaVariableSet, manager->getAllMetaVariableNames()); -} -TEST(SylvanDd, EncodingTest) { +TEST(SylvanDd, RationalFunctionEncodingTest) { std::shared_ptr> manager(new storm::dd::DdManager()); std::pair x = manager->addMetaVariable("x", 1, 9); @@ -101,14 +123,28 @@ TEST(SylvanDd, EncodingTest) { EXPECT_EQ(5ul, encoding.getNodeCount()); EXPECT_EQ(1ul, encoding.getLeafCount()); - storm::dd::Add add; - ASSERT_NO_THROW(add = encoding.template toAdd()); + storm::dd::Add add; + ASSERT_NO_THROW(add = encoding.template toAdd()); // As an MTBDD, the 0-leaf is there, so the count is actually 2 and the node count is 6. EXPECT_EQ(6ul, add.getNodeCount()); EXPECT_EQ(2ul, add.getLeafCount()); } +TEST(SylvanDd, RationalFunctionIdentityTest) { + std::shared_ptr> manager(new storm::dd::DdManager()); + std::pair x = manager->addMetaVariable("x", 1, 9); + + storm::dd::Add identity; + ASSERT_NO_THROW(identity = manager->getIdentity(x.first)); + + EXPECT_EQ(9ul, identity.getNonZeroCount()); + EXPECT_EQ(10ul, identity.getLeafCount()); + EXPECT_EQ(21ul, identity.getNodeCount()); +} + +#endif + TEST(SylvanDd, RangeTest) { std::shared_ptr> manager(new storm::dd::DdManager()); std::pair x; @@ -440,4 +476,4 @@ TEST(SylvanDd, BddOddTest) { EXPECT_EQ(9ul, matrix.getRowGroupCount()); EXPECT_EQ(9ul, matrix.getColumnCount()); EXPECT_EQ(106ul, matrix.getNonzeroEntryCount()); -} \ No newline at end of file +} From 9e90f416080ea41b72bc36504cf724e260929b59 Mon Sep 17 00:00:00 2001 From: PBerger Date: Wed, 27 Jul 2016 16:18:34 +0200 Subject: [PATCH 30/49] Implemented functions for BDD -> ADD conversion and some helpers. Former-commit-id: 78c9003366339d6a48f4740250d0b98365aabbd7 --- .../sylvan/src/storm_function_wrapper.cpp | 16 ++++++++++++ .../sylvan/src/storm_function_wrapper.h | 3 +++ resources/3rdparty/sylvan/src/sylvan_obj.cpp | 11 ++++++++ resources/3rdparty/sylvan/src/sylvan_obj.hpp | 9 +++++++ .../sylvan/src/sylvan_obj_bdd_storm.hpp | 3 +++ .../3rdparty/sylvan/src/sylvan_obj_storm.cpp | 8 ++++++ .../src/sylvan_storm_rational_function.c | 26 ++++++++++++++++++- .../src/sylvan_storm_rational_function.h | 7 +++++ src/storage/dd/sylvan/InternalSylvanAdd.cpp | 3 +-- src/storage/dd/sylvan/InternalSylvanBdd.cpp | 2 +- 10 files changed, 84 insertions(+), 4 deletions(-) diff --git a/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp b/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp index 3b9c19679..15d2cdc66 100644 --- a/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp +++ b/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp @@ -114,3 +114,19 @@ int storm_rational_function_is_zero(storm_rational_function_ptr a) { return 0; } } + +storm_rational_function_ptr storm_rational_function_get_zero() { + static storm::RationalFunction zeroFunction(0); + static storm_rational_function_ptr_struct functionStruct; + functionStruct.storm_rational_function = (void*)&zeroFunction; + + return &functionStruct; +} + +storm_rational_function_ptr storm_rational_function_get_one() { + static storm::RationalFunction oneFunction(1); + static storm_rational_function_ptr_struct functionStruct; + functionStruct.storm_rational_function = (void*)&oneFunction; + + return &functionStruct; +} diff --git a/resources/3rdparty/sylvan/src/storm_function_wrapper.h b/resources/3rdparty/sylvan/src/storm_function_wrapper.h index 3feeafec5..08b9f9471 100644 --- a/resources/3rdparty/sylvan/src/storm_function_wrapper.h +++ b/resources/3rdparty/sylvan/src/storm_function_wrapper.h @@ -26,6 +26,9 @@ storm_rational_function_ptr storm_rational_function_negate(storm_rational_functi uint64_t storm_rational_function_hash(storm_rational_function_ptr const a, uint64_t const seed); int storm_rational_function_is_zero(storm_rational_function_ptr a); +storm_rational_function_ptr storm_rational_function_get_zero(); +storm_rational_function_ptr storm_rational_function_get_one(); + #ifdef __cplusplus } #endif diff --git a/resources/3rdparty/sylvan/src/sylvan_obj.cpp b/resources/3rdparty/sylvan/src/sylvan_obj.cpp index a573c7a49..068c9a57f 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj.cpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj.cpp @@ -15,6 +15,7 @@ */ #include +#include using namespace sylvan; @@ -604,6 +605,16 @@ Mtbdd::doubleTerminal(double value) return mtbdd_double(value); } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) +Mtbdd +Mtbdd::stormRationalFunctionTerminal(storm::RationalFunction const& value) +{ + storm_rational_function_t functionStruct; + functionStruct.storm_rational_function = (void*)(&value); + return mtbdd_storm_rational_function(functionStruct); +} +#endif + Mtbdd Mtbdd::fractionTerminal(int64_t nominator, uint64_t denominator) { diff --git a/resources/3rdparty/sylvan/src/sylvan_obj.hpp b/resources/3rdparty/sylvan/src/sylvan_obj.hpp index e7f77f6ca..6cd81a2fb 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj.hpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj.hpp @@ -23,6 +23,8 @@ #include #include +#include "src/adapters/CarlAdapter.h" + namespace sylvan { class BddSet; @@ -542,6 +544,13 @@ public: */ static Mtbdd doubleTerminal(double value); +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + /** + * @brief Creates a Mtbdd leaf representing the rational function value + */ + static Mtbdd stormRationalFunctionTerminal(storm::RationalFunction const& value); +#endif + /** * @brief Creates a Mtbdd leaf representing the fraction value / * Internally, Sylvan uses 32-bit values and reports overflows to stderr. diff --git a/resources/3rdparty/sylvan/src/sylvan_obj_bdd_storm.hpp b/resources/3rdparty/sylvan/src/sylvan_obj_bdd_storm.hpp index 393ce988c..172bcf5c6 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj_bdd_storm.hpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj_bdd_storm.hpp @@ -1,3 +1,6 @@ Mtbdd toDoubleMtbdd() const; Mtbdd toInt64Mtbdd() const; +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + Mtbdd toStormRationalFunctionMtbdd() const; +#endif Mtbdd Ite(Mtbdd const& thenDd, Mtbdd const& elseDd) const; diff --git a/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp b/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp index 27706dcdd..f64ffeaa2 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp @@ -10,6 +10,14 @@ Bdd::toInt64Mtbdd() const { return mtbdd_bool_to_int64(bdd); } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) +Mtbdd +Bdd::toStormRationalFunctionMtbdd() const { + LACE_ME; + return mtbdd_bool_to_storm_rational_function(bdd); +} +#endif + Mtbdd Bdd::Ite(Mtbdd const& thenDd, Mtbdd const& elseDd) const { LACE_ME; diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c index c2fb73016..2991f322c 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c @@ -90,7 +90,31 @@ uint32_t sylvan_storm_rational_function_get_type() { MTBDD mtbdd_storm_rational_function(storm_rational_function_t val) { - return mtbdd_makeleaf(sylvan_storm_rational_function_type, (size_t)val); + uint64_t terminalValue = (uint64_t)&val; + return mtbdd_makeleaf(sylvan_storm_rational_function_type, terminalValue); +} + +/** + * Converts a BDD to a MTBDD with storm::RationalFunction leaves + */ +TASK_IMPL_2(MTBDD, mtbdd_op_bool_to_storm_rational_function, MTBDD, a, size_t, v) +{ + if (a == mtbdd_false) { + return mtbdd_storm_rational_function(*storm_rational_function_get_zero()); + } + if (a == mtbdd_true) { + return mtbdd_storm_rational_function(*storm_rational_function_get_one()); + } + + // Ugly hack to get rid of the error "unused variable v" (because there is no version of uapply without a parameter). + (void)v; + + return mtbdd_invalid; +} + +TASK_IMPL_1(MTBDD, mtbdd_bool_to_storm_rational_function, MTBDD, dd) +{ + return mtbdd_uapply(dd, TASK(mtbdd_op_bool_to_storm_rational_function), 0); } /** diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h index 6cdb142a5..fd4ad7f3a 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h @@ -31,6 +31,13 @@ uint32_t sylvan_storm_rational_function_get_type(); */ MTBDD mtbdd_storm_rational_function(storm_rational_function_t val); +/** + * Monad that converts Boolean to a storm::RationalFunction MTBDD, translate terminals true to 1 and to 0 otherwise; + */ +TASK_DECL_2(MTBDD, mtbdd_op_bool_to_storm_rational_function, MTBDD, size_t) +TASK_DECL_1(MTBDD, mtbdd_bool_to_storm_rational_function, MTBDD) +#define mtbdd_bool_to_storm_rational_function(dd) CALL(mtbdd_bool_to_storm_rational_function, dd) + /** * Operation "plus" for two storm::RationalFunction MTBDDs */ diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index 92c6ca642..71975e7c3 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -617,9 +617,8 @@ namespace storm { MTBDD InternalAdd::getLeaf(storm::RationalFunction const& value) { storm_rational_function_ptr_struct helperStruct; helperStruct.storm_rational_function = (void*)(&value); - uint64_t terminalValue = (uint64_t)&helperStruct; - return sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), terminalValue).GetMTBDD(); + return mtbdd_storm_rational_function(helperStruct); } template diff --git a/src/storage/dd/sylvan/InternalSylvanBdd.cpp b/src/storage/dd/sylvan/InternalSylvanBdd.cpp index 0ad6cfa47..09889d6bb 100644 --- a/src/storage/dd/sylvan/InternalSylvanBdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanBdd.cpp @@ -248,7 +248,7 @@ namespace storm { } #ifdef STORM_HAVE_CARL else if (std::is_same::value) { - STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Conversion to ADD is currently unsupported for storm::RationalFunction."); + return InternalAdd(ddManager, this->sylvanBdd.toStormRationalFunctionMtbdd()); } #endif else { From 1345f018fcf814bcf848e26497c0e7f8c5ba1816 Mon Sep 17 00:00:00 2001 From: PBerger Date: Wed, 27 Jul 2016 16:28:10 +0200 Subject: [PATCH 31/49] Fixed some issues with pointers. Former-commit-id: a7fddc12f3b06a6f7af299acc4fb61820aa12c16 --- resources/3rdparty/sylvan/src/sylvan_obj.cpp | 4 ++-- .../3rdparty/sylvan/src/sylvan_storm_rational_function.c | 2 +- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/3rdparty/sylvan/src/sylvan_obj.cpp b/resources/3rdparty/sylvan/src/sylvan_obj.cpp index 068c9a57f..b7b4484fb 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj.cpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj.cpp @@ -609,9 +609,9 @@ Mtbdd::doubleTerminal(double value) Mtbdd Mtbdd::stormRationalFunctionTerminal(storm::RationalFunction const& value) { - storm_rational_function_t functionStruct; + storm_rational_function_ptr_struct functionStruct; functionStruct.storm_rational_function = (void*)(&value); - return mtbdd_storm_rational_function(functionStruct); + return mtbdd_storm_rational_function(&functionStruct); } #endif diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c index 2991f322c..80aa72334 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c @@ -90,7 +90,7 @@ uint32_t sylvan_storm_rational_function_get_type() { MTBDD mtbdd_storm_rational_function(storm_rational_function_t val) { - uint64_t terminalValue = (uint64_t)&val; + uint64_t terminalValue = (uint64_t)val; return mtbdd_makeleaf(sylvan_storm_rational_function_type, terminalValue); } diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index 71975e7c3..51c072126 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -618,7 +618,7 @@ namespace storm { storm_rational_function_ptr_struct helperStruct; helperStruct.storm_rational_function = (void*)(&value); - return mtbdd_storm_rational_function(helperStruct); + return mtbdd_storm_rational_function(&helperStruct); } template From 6ced56a0cc4a2d8a775a7a1eed6473f4427216ad Mon Sep 17 00:00:00 2001 From: PBerger Date: Wed, 27 Jul 2016 16:29:41 +0200 Subject: [PATCH 32/49] More ptr fixes. Former-commit-id: f1f01a0eec1569fa8d69ec17702ebd0d02738551 --- .../3rdparty/sylvan/src/sylvan_storm_rational_function.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c index 80aa72334..43fb85d7c 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c @@ -100,10 +100,10 @@ mtbdd_storm_rational_function(storm_rational_function_t val) TASK_IMPL_2(MTBDD, mtbdd_op_bool_to_storm_rational_function, MTBDD, a, size_t, v) { if (a == mtbdd_false) { - return mtbdd_storm_rational_function(*storm_rational_function_get_zero()); + return mtbdd_storm_rational_function(storm_rational_function_get_zero()); } if (a == mtbdd_true) { - return mtbdd_storm_rational_function(*storm_rational_function_get_one()); + return mtbdd_storm_rational_function(storm_rational_function_get_one()); } // Ugly hack to get rid of the error "unused variable v" (because there is no version of uapply without a parameter). From cdff7d4b0f6b5f986d157e2e09cc6b4cf4d8a033 Mon Sep 17 00:00:00 2001 From: PBerger Date: Wed, 27 Jul 2016 17:13:52 +0200 Subject: [PATCH 33/49] Added template specialization for getIdentity. Former-commit-id: 082b985333d7d709d00b7bd84e38a64c1668ff1d --- src/storage/dd/DdManager.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/storage/dd/DdManager.cpp b/src/storage/dd/DdManager.cpp index 5ad46ac53..0f1e65fee 100644 --- a/src/storage/dd/DdManager.cpp +++ b/src/storage/dd/DdManager.cpp @@ -106,6 +106,21 @@ namespace storm { return result; } +#ifdef STORM_HAVE_CARL + template + template<> + Add DdManager::getIdentity(storm::expressions::Variable const& variable) const { + storm::dd::DdMetaVariable const& metaVariable = this->getMetaVariable(variable); + + Add result = this->getAddZero(); + for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) { + storm::RationalFunction constantFunction(value); + result += this->getEncoding(variable, value).template toAdd() * this->getConstant(constantFunction); + } + return result; + } +#endif + template std::pair DdManager::addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high) { // Check whether the variable name is legal. From b01abf831b414e4fefd547be1c545a2004147a73 Mon Sep 17 00:00:00 2001 From: PBerger Date: Wed, 27 Jul 2016 17:15:52 +0200 Subject: [PATCH 34/49] Fixing template spec. Former-commit-id: bc121341e32c7240334ff4953c11ec91886419fb --- src/storage/dd/DdManager.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/storage/dd/DdManager.cpp b/src/storage/dd/DdManager.cpp index 0f1e65fee..22dc7c753 100644 --- a/src/storage/dd/DdManager.cpp +++ b/src/storage/dd/DdManager.cpp @@ -107,12 +107,11 @@ namespace storm { } #ifdef STORM_HAVE_CARL - template - template<> - Add DdManager::getIdentity(storm::expressions::Variable const& variable) const { - storm::dd::DdMetaVariable const& metaVariable = this->getMetaVariable(variable); + template<> + Add DdManager::getIdentity(storm::expressions::Variable const& variable) const { + storm::dd::DdMetaVariable const& metaVariable = this->getMetaVariable(variable); - Add result = this->getAddZero(); + Add result = this->getAddZero(); for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) { storm::RationalFunction constantFunction(value); result += this->getEncoding(variable, value).template toAdd() * this->getConstant(constantFunction); From dbbae87962113cfbdfe16ae0caa3ab1198beff06 Mon Sep 17 00:00:00 2001 From: PBerger Date: Wed, 27 Jul 2016 17:23:23 +0200 Subject: [PATCH 35/49] Fixed template specialization. Re-Implemented terminal generation. Former-commit-id: 253f95b673e6415f069dc148d0cd6d015d4c029e --- src/storage/dd/DdManager.cpp | 3 ++- src/storage/dd/sylvan/InternalSylvanDdManager.cpp | 7 +------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/storage/dd/DdManager.cpp b/src/storage/dd/DdManager.cpp index 22dc7c753..7a1a9ab8d 100644 --- a/src/storage/dd/DdManager.cpp +++ b/src/storage/dd/DdManager.cpp @@ -108,13 +108,14 @@ namespace storm { #ifdef STORM_HAVE_CARL template<> + template<> Add DdManager::getIdentity(storm::expressions::Variable const& variable) const { storm::dd::DdMetaVariable const& metaVariable = this->getMetaVariable(variable); Add result = this->getAddZero(); for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) { storm::RationalFunction constantFunction(value); - result += this->getEncoding(variable, value).template toAdd() * this->getConstant(constantFunction); + result += this->getEncoding(variable, value).template toAdd() * this->getConstant(constantFunction); } return result; } diff --git a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp index c10235ca8..287fe55c3 100644 --- a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp +++ b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp @@ -131,12 +131,7 @@ namespace storm { #ifdef STORM_HAVE_CARL template<> InternalAdd InternalDdManager::getConstant(storm::RationalFunction const& value) const { - storm::RationalFunction rationalFunction = value; - storm_rational_function_ptr_struct helperStruct; - helperStruct.storm_rational_function = (void*)(&rationalFunction); - uint64_t terminalValue = (uint64_t)&helperStruct; - - return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), terminalValue)); + return InternalAdd(this, sylvan::Mtbdd::stormRationalFunctionTerminal(value)); } #endif From bc7e533d6b8deb0ec230542616408a6278d6b599 Mon Sep 17 00:00:00 2001 From: PBerger Date: Wed, 27 Jul 2016 19:42:08 +0200 Subject: [PATCH 36/49] Some debug, Former-commit-id: aed81724ca265b40f6f39363203bb636064681b5 --- resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c index 43fb85d7c..2b35ed91a 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c @@ -51,6 +51,7 @@ sylvan_storm_rational_function_equals(const uint64_t left, const uint64_t right) static void sylvan_storm_rational_function_create(uint64_t *val) { + printf("sylvan_storm_rational_function_create(val = %zu)\n", *val); /* This function is called by the unique table when a leaf does not yet exist. We make a copy, which will be stored in the hash table. */ storm_rational_function_ptr* x = (storm_rational_function_ptr*)(size_t)val; @@ -91,6 +92,7 @@ MTBDD mtbdd_storm_rational_function(storm_rational_function_t val) { uint64_t terminalValue = (uint64_t)val; + printf("mtbdd_storm_rational_function(val = %zu)\n", terminalValue); return mtbdd_makeleaf(sylvan_storm_rational_function_type, terminalValue); } From 58eb54926c4980a90999423d3d7a33e316df6484 Mon Sep 17 00:00:00 2001 From: PBerger Date: Wed, 3 Aug 2016 04:03:31 +0200 Subject: [PATCH 37/49] Fixed Sylvan bugs. Added a lot of debugging options and output, controlled by #define's. Added more template specializations for storm::RationalFunction. Former-commit-id: 416c32d196b0d848dbdaf1b292ccad198cfe1c74 --- .../sylvan/src/storm_function_wrapper.cpp | 324 ++++++++++------- .../sylvan/src/storm_function_wrapper.h | 15 +- resources/3rdparty/sylvan/src/sylvan_mtbdd.c | 127 ++++++- .../3rdparty/sylvan/src/sylvan_mtbdd_storm.c | 69 ++++ resources/3rdparty/sylvan/src/sylvan_obj.cpp | 6 +- .../sylvan/src/sylvan_obj_mtbdd_storm.hpp | 22 ++ .../3rdparty/sylvan/src/sylvan_obj_storm.cpp | 30 ++ .../src/sylvan_storm_rational_function.c | 99 ++++- .../src/sylvan_storm_rational_function.h | 4 +- src/storage/dd/DdManager.cpp | 16 +- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 240 ++++++++++-- .../dd/sylvan/InternalSylvanDdManager.cpp | 341 +++++++++--------- test/functional/storage/SylvanDdTest.cpp | 21 +- 13 files changed, 925 insertions(+), 389 deletions(-) diff --git a/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp b/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp index 15d2cdc66..74756d121 100644 --- a/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp +++ b/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp @@ -1,132 +1,192 @@ -#include "storm_function_wrapper.h" - -#include -#include "src/adapters/CarlAdapter.h" - -void storm_rational_function_init(storm_rational_function_ptr* a) { - storm_rational_function_ptr srf_ptr = static_cast(malloc(sizeof(storm_rational_function_ptr_struct))); - - if (srf_ptr == nullptr) { - return; - } - - srf_ptr->storm_rational_function = new storm::RationalFunction(*(storm::RationalFunction*)((*a)->storm_rational_function)); - - *a = srf_ptr; -} - -void storm_rational_function_destroy(storm_rational_function_ptr a) { - delete (storm::RationalFunction*)a->storm_rational_function; - a->storm_rational_function = nullptr; - free((void*)a); -} - -int storm_rational_function_equals(storm_rational_function_ptr a, storm_rational_function_ptr b) { - storm::RationalFunction* srf_a = (storm::RationalFunction*)a->storm_rational_function; - storm::RationalFunction* srf_b = (storm::RationalFunction*)b->storm_rational_function; - - if (*srf_a == *srf_b) { - return 0; - } - - return -1; -} - -storm_rational_function_ptr storm_rational_function_plus(storm_rational_function_ptr a, storm_rational_function_ptr b) { - storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; - storm::RationalFunction& srf_b = *(storm::RationalFunction*)b->storm_rational_function; - - storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); - *result_srf += srf_b; - - storm_rational_function_ptr result = (storm_rational_function_ptr)malloc(sizeof(storm_rational_function_ptr_struct)); - result->storm_rational_function = (void*)result_srf; - - return result; -} - -storm_rational_function_ptr storm_rational_function_minus(storm_rational_function_ptr a, storm_rational_function_ptr b) { - storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; - storm::RationalFunction& srf_b = *(storm::RationalFunction*)b->storm_rational_function; - - storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); - *result_srf -= srf_b; - - storm_rational_function_ptr result = (storm_rational_function_ptr)malloc(sizeof(storm_rational_function_ptr_struct)); - result->storm_rational_function = (void*)result_srf; - - return result; -} - -storm_rational_function_ptr storm_rational_function_times(storm_rational_function_ptr a, storm_rational_function_ptr b) { - storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; - storm::RationalFunction& srf_b = *(storm::RationalFunction*)b->storm_rational_function; - - storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); - *result_srf *= srf_b; - - storm_rational_function_ptr result = (storm_rational_function_ptr)malloc(sizeof(storm_rational_function_ptr_struct)); - result->storm_rational_function = (void*)result_srf; - - return result; -} - -storm_rational_function_ptr storm_rational_function_divide(storm_rational_function_ptr a, storm_rational_function_ptr b) { - storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; - storm::RationalFunction& srf_b = *(storm::RationalFunction*)b->storm_rational_function; - - storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); - *result_srf /= srf_b; - - storm_rational_function_ptr result = (storm_rational_function_ptr)malloc(sizeof(storm_rational_function_ptr_struct)); - result->storm_rational_function = (void*)result_srf; - - return result; -} - -uint64_t storm_rational_function_hash(storm_rational_function_ptr const a, uint64_t const seed) { - storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; - - size_t hash = carl::hash_value(srf_a); - uint64_t result = hash ^ seed; - - return result; -} - -storm_rational_function_ptr storm_rational_function_negate(storm_rational_function_ptr a) { - storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; - - storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); - *result_srf = -srf_a; - - storm_rational_function_ptr result = (storm_rational_function_ptr)malloc(sizeof(storm_rational_function_ptr_struct)); - result->storm_rational_function = (void*)result_srf; - - return result; -} - -int storm_rational_function_is_zero(storm_rational_function_ptr a) { - storm::RationalFunction& srf_a = *(storm::RationalFunction*)a->storm_rational_function; - - if (srf_a.isZero()) { - return 1; - } else { - return 0; - } -} - -storm_rational_function_ptr storm_rational_function_get_zero() { - static storm::RationalFunction zeroFunction(0); - static storm_rational_function_ptr_struct functionStruct; - functionStruct.storm_rational_function = (void*)&zeroFunction; - - return &functionStruct; -} - -storm_rational_function_ptr storm_rational_function_get_one() { - static storm::RationalFunction oneFunction(1); - static storm_rational_function_ptr_struct functionStruct; - functionStruct.storm_rational_function = (void*)&oneFunction; - - return &functionStruct; -} +#include "storm_function_wrapper.h" + +#include +#include +#include +#include "src/adapters/CarlAdapter.h" + +#undef DEBUG_STORM_FUNCTION_WRAPPER + +#ifdef DEBUG_STORM_FUNCTION_WRAPPER +#define LOG_I(funcName) std::cout << "Entering function " << funcName << std::endl; +#define LOG_O(funcName) std::cout << "Leaving function " << funcName << std::endl; +#else +#define LOG_I(funcName) +#define LOG_O(funcName) +#endif + +void storm_rational_function_init(storm_rational_function_ptr* a) { + LOG_I("init") + storm_rational_function_ptr srf_ptr = new storm::RationalFunction(*((storm::RationalFunction*)(*a))); + + if (srf_ptr == nullptr) { + std::cerr << "Could not allocate memory in storm_rational_function_init()!" << std::endl; + return; + } + + *a = srf_ptr; + LOG_O("init") +} + +void storm_rational_function_destroy(storm_rational_function_ptr a) { + LOG_I("destroy") + delete (storm::RationalFunction*)a; + LOG_O("destroy") +} + +int storm_rational_function_equals(storm_rational_function_ptr a, storm_rational_function_ptr b) { + LOG_I("equals") + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; + storm::RationalFunction& srf_b = *(storm::RationalFunction*)b; + + LOG_O("equals") + + int result = 0; + if (srf_a == srf_b) { + result = 1; + } + return result; +} + +storm_rational_function_ptr storm_rational_function_plus(storm_rational_function_ptr a, storm_rational_function_ptr b) { + LOG_I("plus") + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; + storm::RationalFunction& srf_b = *(storm::RationalFunction*)b; + + storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); + if (result_srf == nullptr) { + std::cerr << "Could not allocate memory in storm_rational_function_plus()!" << std::endl; + return (storm_rational_function_ptr)nullptr; + } + + *result_srf += srf_b; + + storm_rational_function_ptr result = (storm_rational_function_ptr)result_srf; + + LOG_O("plus") + return result; +} + +storm_rational_function_ptr storm_rational_function_minus(storm_rational_function_ptr a, storm_rational_function_ptr b) { + LOG_I("minus") + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; + storm::RationalFunction& srf_b = *(storm::RationalFunction*)b; + + storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); + if (result_srf == nullptr) { + std::cerr << "Could not allocate memory in storm_rational_function_minus()!" << std::endl; + return (storm_rational_function_ptr)nullptr; + } + + *result_srf -= srf_b; + + storm_rational_function_ptr result = (storm_rational_function_ptr)result_srf; + + LOG_O("minus") + return result; +} + +storm_rational_function_ptr storm_rational_function_times(storm_rational_function_ptr a, storm_rational_function_ptr b) { + LOG_I("times") + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; + storm::RationalFunction& srf_b = *(storm::RationalFunction*)b; + + storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); + if (result_srf == nullptr) { + std::cerr << "Could not allocate memory in storm_rational_function_times()!" << std::endl; + return (storm_rational_function_ptr)nullptr; + } + + *result_srf *= srf_b; + + storm_rational_function_ptr result = (storm_rational_function_ptr)result_srf; + + LOG_O("times") + return result; +} + +storm_rational_function_ptr storm_rational_function_divide(storm_rational_function_ptr a, storm_rational_function_ptr b) { + LOG_I("divide") + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; + storm::RationalFunction& srf_b = *(storm::RationalFunction*)b; + + storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); + if (result_srf == nullptr) { + std::cerr << "Could not allocate memory in storm_rational_function_divide()!" << std::endl; + return (storm_rational_function_ptr)nullptr; + } + + *result_srf /= srf_b; + + storm_rational_function_ptr result = (storm_rational_function_ptr)result_srf; + + LOG_O("divide") + return result; +} + +uint64_t storm_rational_function_hash(storm_rational_function_ptr const a, uint64_t const seed) { + LOG_I("hash") + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; + + size_t hash = carl::hash_value(srf_a); + uint64_t result = hash ^ seed; + + LOG_O("hash") + return result; +} + +storm_rational_function_ptr storm_rational_function_negate(storm_rational_function_ptr a) { + LOG_I("negate") + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; + + storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); + if (result_srf == nullptr) { + std::cerr << "Could not allocate memory in storm_rational_function_negate()!" << std::endl; + return (storm_rational_function_ptr)nullptr; + } + + *result_srf = -srf_a; + + storm_rational_function_ptr result = (storm_rational_function_ptr)result_srf; + + LOG_O("negate") + return result; +} + +int storm_rational_function_is_zero(storm_rational_function_ptr a) { + LOG_I("isZero") + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; + + if (srf_a.isZero()) { + return 1; + } else { + return 0; + } +} + +storm_rational_function_ptr storm_rational_function_get_zero() { + static storm::RationalFunction zeroFunction(0); + LOG_I("getZero") + //return new storm::RationalFunction(0); + return (storm_rational_function_ptr)(&zeroFunction); +} + +storm_rational_function_ptr storm_rational_function_get_one() { + static storm::RationalFunction oneFunction(1); + LOG_I("getOne") + //return new storm::RationalFunction(1); + return (storm_rational_function_ptr)(&oneFunction); +} + +void print_storm_rational_function(storm_rational_function_ptr a) { + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; + std::cout << srf_a << std::flush; +} + +void print_storm_rational_function_to_file(storm_rational_function_ptr a, FILE* out) { + std::stringstream ss; + storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; + ss << srf_a; + std::string s = ss.str(); + fprintf(out, "%s", s.c_str()); +} diff --git a/resources/3rdparty/sylvan/src/storm_function_wrapper.h b/resources/3rdparty/sylvan/src/storm_function_wrapper.h index 08b9f9471..ca5107dcb 100644 --- a/resources/3rdparty/sylvan/src/storm_function_wrapper.h +++ b/resources/3rdparty/sylvan/src/storm_function_wrapper.h @@ -2,17 +2,13 @@ #define SYLVAN_STORM_FUNCTION_WRAPPER_H #include +#include #ifdef __cplusplus extern "C" { #endif -typedef struct { - void* storm_rational_function; -} storm_rational_function_ptr_struct; -typedef storm_rational_function_ptr_struct storm_rational_function_t[1]; -typedef storm_rational_function_ptr_struct* storm_rational_function_ptr; - +typedef void* storm_rational_function_ptr; // equals, plus, minus, divide, times, create, destroy void storm_rational_function_init(storm_rational_function_ptr* a); @@ -29,8 +25,13 @@ int storm_rational_function_is_zero(storm_rational_function_ptr a); storm_rational_function_ptr storm_rational_function_get_zero(); storm_rational_function_ptr storm_rational_function_get_one(); +void print_storm_rational_function(storm_rational_function_ptr a); +void print_storm_rational_function_to_file(storm_rational_function_ptr a, FILE* out); + +int storm_rational_function_is_zero(storm_rational_function_ptr a); + #ifdef __cplusplus } #endif -#endif // SYLVAN_STORM_FUNCTION_WRAPPER_H \ No newline at end of file +#endif // SYLVAN_STORM_FUNCTION_WRAPPER_H diff --git a/resources/3rdparty/sylvan/src/sylvan_mtbdd.c b/resources/3rdparty/sylvan/src/sylvan_mtbdd.c index a4eb1bd62..ac5a8261f 100644 --- a/resources/3rdparty/sylvan/src/sylvan_mtbdd.c +++ b/resources/3rdparty/sylvan/src/sylvan_mtbdd.c @@ -31,6 +31,11 @@ #include #include +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) +#include +#include +#endif + /* Primitives */ int mtbdd_isleaf(MTBDD bdd) @@ -264,9 +269,15 @@ _mtbdd_create_cb(uint64_t *a, uint64_t *b) // for leaf if ((*a & 0x4000000000000000) == 0) return; // huh? uint32_t type = *a & 0xffffffff; - if (type >= cl_registry_count) return; // not in registry + if (type >= cl_registry_count) { // not in registry + printf("ERROR: type >= cl_registry_count!"); + return; + } customleaf_t *c = cl_registry + type; - if (c->create_cb == NULL) return; // not in registry + if (c->create_cb == NULL) { // not in registry + printf("ERROR: create_cb is NULL!"); + return; + } c->create_cb(b); } @@ -276,9 +287,15 @@ _mtbdd_destroy_cb(uint64_t a, uint64_t b) // for leaf if ((a & 0x4000000000000000) == 0) return; // huh? uint32_t type = a & 0xffffffff; - if (type >= cl_registry_count) return; // not in registry + if (type >= cl_registry_count) { // not in registry + printf("ERROR: type >= cl_registry_count! (2)"); + return; + } customleaf_t *c = cl_registry + type; - if (c->destroy_cb == NULL) return; // not in registry + if (c->destroy_cb == NULL) { // not in registry + printf("ERROR: destroy_cb is NULL!"); + return; + } c->destroy_cb(b); } @@ -833,6 +850,11 @@ TASK_2(MTBDD, mtbdd_uop_times_uint, MTBDD, a, size_t, k) uint32_t c = gcd(d, (uint32_t)k); return mtbdd_fraction(n*(k/c), d/c); } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR mtbdd_uop_times_uint type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID"); + } +#endif } return mtbdd_invalid; @@ -857,6 +879,11 @@ TASK_2(MTBDD, mtbdd_uop_pow_uint, MTBDD, a, size_t, k) uint64_t v = mtbddnode_getvalue(na); return mtbdd_fraction(pow((int32_t)(v>>32), k), (uint32_t)v); } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR mtbdd_uop_pow_uint type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID"); + } +#endif } return mtbdd_invalid; @@ -1017,6 +1044,11 @@ TASK_IMPL_2(MTBDD, mtbdd_op_plus, MTBDD*, pa, MTBDD*, pb) // add return mtbdd_fraction(nom_a + nom_b, denom_a); } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR mtbdd_op_plus type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID"); + } +#endif } if (a < b) { @@ -1066,6 +1098,11 @@ TASK_IMPL_2(MTBDD, mtbdd_op_minus, MTBDD*, pa, MTBDD*, pb) // subtract return mtbdd_fraction(nom_a - nom_b, denom_a); } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if ((mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) && (mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID)) { + printf("ERROR: mtbdd_op_minus type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID.\n"); + } +#endif } return mtbdd_invalid; @@ -1113,6 +1150,11 @@ TASK_IMPL_2(MTBDD, mtbdd_op_times, MTBDD*, pa, MTBDD*, pb) denom_a *= (denom_b/d); return mtbdd_fraction(nom_a, denom_a); } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if ((mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) && (mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID)) { + printf("ERROR: mtbdd_op_times type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID.\n"); + } +#endif } if (a < b) { @@ -1169,6 +1211,11 @@ TASK_IMPL_2(MTBDD, mtbdd_op_min, MTBDD*, pa, MTBDD*, pb) // compute lowest return nom_a < nom_b ? a : b; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if ((mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) && (mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID)) { + printf("ERROR: mtbdd_op_min type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID.\n"); + } +#endif } if (a < b) { @@ -1223,6 +1270,11 @@ TASK_IMPL_2(MTBDD, mtbdd_op_max, MTBDD*, pa, MTBDD*, pb) // compute highest return nom_a > nom_b ? a : b; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if ((mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) && (mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID)) { + printf("ERROR: mtbdd_op_max type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID.\n"); + } +#endif } if (a < b) { @@ -1252,6 +1304,11 @@ TASK_IMPL_2(MTBDD, mtbdd_op_negate, MTBDD, a, size_t, k) uint64_t v = mtbddnode_getvalue(na); return mtbdd_fraction(-(int32_t)(v>>32), (uint32_t)v); } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if ((mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID)) { + printf("ERROR: mtbdd_op_negate type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID.\n"); + } +#endif } return mtbdd_invalid; @@ -1335,6 +1392,11 @@ TASK_IMPL_2(MTBDD, mtbdd_op_threshold_double, MTBDD, a, size_t, svalue) d /= mtbdd_getdenom(a); return d >= value ? mtbdd_true : mtbdd_false; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if ((mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID)) { + printf("ERROR: mtbdd_op_threshold_double type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID.\n"); + } +#endif } return mtbdd_invalid; @@ -1361,6 +1423,11 @@ TASK_IMPL_2(MTBDD, mtbdd_op_strict_threshold_double, MTBDD, a, size_t, svalue) d /= mtbdd_getdenom(a); return d > value ? mtbdd_true : mtbdd_false; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if ((mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID)) { + printf("ERROR: mtbdd_op_strict_threshold_double type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID.\n"); + } +#endif } return mtbdd_invalid; @@ -1566,6 +1633,11 @@ TASK_3(MTBDD, mtbdd_leq_rec, MTBDD, a, MTBDD, b, int*, shortcircuit) nom_b *= da/c; result = nom_a <= nom_b ? mtbdd_true : mtbdd_false; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR: mtbdd_leq_rec type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID\n"); + } +#endif } else { /* Get top variable */ uint32_t va = la ? 0xffffffff : mtbddnode_getvariable(na); @@ -1651,6 +1723,11 @@ TASK_3(MTBDD, mtbdd_less_rec, MTBDD, a, MTBDD, b, int*, shortcircuit) nom_b *= da/c; result = nom_a < nom_b ? mtbdd_true : mtbdd_false; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR: mtbdd_less_rec type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID\n"); + } +#endif } else { /* Get top variable */ uint32_t va = la ? 0xffffffff : mtbddnode_getvariable(na); @@ -1736,6 +1813,11 @@ TASK_3(MTBDD, mtbdd_geq_rec, MTBDD, a, MTBDD, b, int*, shortcircuit) nom_b *= da/c; result = nom_a >= nom_b ? mtbdd_true : mtbdd_false; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR: mtbdd_geq_rec type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID\n"); + } +#endif } else { /* Get top variable */ uint32_t va = la ? 0xffffffff : mtbddnode_getvariable(na); @@ -1821,6 +1903,11 @@ TASK_3(MTBDD, mtbdd_greater_rec, MTBDD, a, MTBDD, b, int*, shortcircuit) nom_b *= da/c; result = nom_a > nom_b ? mtbdd_true : mtbdd_false; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR: mtbdd_greater_rec type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID\n"); + } +#endif } else { /* Get top variable */ uint32_t va = la ? 0xffffffff : mtbddnode_getvariable(na); @@ -2041,6 +2128,11 @@ TASK_IMPL_1(MTBDD, mtbdd_minimum, MTBDD, a) nom_h *= denom_l/c; result = nom_l < nom_h ? low : high; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(nl) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nh) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR: mtbdd_minimum type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID\n"); + } +#endif /* Store in cache */ cache_put3(CACHE_MTBDD_MINIMUM, a, 0, 0, result); @@ -2089,6 +2181,11 @@ TASK_IMPL_1(MTBDD, mtbdd_maximum, MTBDD, a) nom_h *= denom_l/c; result = nom_l > nom_h ? low : high; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(nl) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nh) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR: mtbdd_maximum type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID\n"); + } +#endif /* Store in cache */ cache_put3(CACHE_MTBDD_MAXIMUM, a, 0, 0, result); @@ -2237,12 +2334,20 @@ mtbdd_unmark_rec(MTBDD mtbdd) static size_t mtbdd_leafcount_mark(MTBDD mtbdd) { - if (mtbdd == mtbdd_true) return 0; // do not count true/false leaf - if (mtbdd == mtbdd_false) return 0; // do not count true/false leaf + if (mtbdd == mtbdd_true) { // do not count true/false leaf + return 0; + } + if (mtbdd == mtbdd_false) { // do not count true/false leaf + return 0; + } mtbddnode_t n = GETNODE(mtbdd); - if (mtbddnode_getmark(n)) return 0; + if (mtbddnode_getmark(n)) { + return 0; + } mtbddnode_setmark(n, 1); - if (mtbddnode_isleaf(n)) return 1; // count leaf as 1 + if (mtbddnode_isleaf(n)) { // count leaf as 1 + return 1; + } return mtbdd_leafcount_mark(mtbddnode_getlow(n)) + mtbdd_leafcount_mark(mtbddnode_gethigh(n)); } @@ -2372,6 +2477,12 @@ mtbdd_fprintdot_rec(FILE *out, MTBDD mtbdd, print_terminal_label_cb cb) case 2: fprintf(out, "%u/%u", (uint32_t)(value>>32), (uint32_t)value); break; +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + case SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID: + fprintf(out, "srf::"); + print_storm_rational_function_to_file((storm_rational_function_ptr)value, out); + break; +#endif default: cb(out, type, value); break; diff --git a/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.c b/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.c index dab4860c0..2d0796a40 100644 --- a/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.c +++ b/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.c @@ -97,6 +97,12 @@ TASK_IMPL_2(MTBDD, mtbdd_op_divide, MTBDD*, pa, MTBDD*, pb) MTBDD result = mtbdd_fraction(nom_a, denom_a); return result; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR mtbdd_op_divide type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID"); + assert(0); + } +#endif } return mtbdd_invalid; @@ -140,6 +146,12 @@ TASK_IMPL_2(MTBDD, mtbdd_op_equals, MTBDD*, pa, MTBDD*, pb) if (nom_a == nom_b && denom_a == denom_b) return mtbdd_true; return mtbdd_false; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR mtbdd_op_equals type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID"); + assert(0); + } +#endif } if (a < b) { @@ -187,6 +199,12 @@ TASK_IMPL_2(MTBDD, mtbdd_op_less, MTBDD*, pa, MTBDD*, pb) uint64_t denom_b = val_b&0xffffffff; return nom_a * denom_b < nom_b * denom_a ? mtbdd_true : mtbdd_false; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR mtbdd_op_less type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID"); + assert(0); + } +#endif } return mtbdd_invalid; @@ -230,6 +248,12 @@ TASK_IMPL_2(MTBDD, mtbdd_op_less_or_equal, MTBDD*, pa, MTBDD*, pb) nom_b *= denom_a; return nom_a <= nom_b ? mtbdd_true : mtbdd_false; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR mtbdd_op_less_or_equal type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID"); + assert(0); + } +#endif } return mtbdd_invalid; @@ -261,6 +285,12 @@ TASK_IMPL_2(MTBDD, mtbdd_op_pow, MTBDD*, pa, MTBDD*, pb) } else if (mtbddnode_gettype(na) == 2 && mtbddnode_gettype(nb) == 2) { assert(0); } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR mtbdd_op_pow type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID"); + assert(0); + } +#endif } return mtbdd_invalid; @@ -292,6 +322,12 @@ TASK_IMPL_2(MTBDD, mtbdd_op_mod, MTBDD*, pa, MTBDD*, pb) } else if (mtbddnode_gettype(na) == 2 && mtbddnode_gettype(nb) == 2) { assert(0); } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR mtbdd_op_mod type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID"); + assert(0); + } +#endif } return mtbdd_invalid; @@ -323,6 +359,12 @@ TASK_IMPL_2(MTBDD, mtbdd_op_logxy, MTBDD*, pa, MTBDD*, pb) } else if (mtbddnode_gettype(na) == 2 && mtbddnode_gettype(nb) == 2) { assert(0); } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR mtbdd_op_logxy type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID"); + assert(0); + } +#endif } return mtbdd_invalid; @@ -345,6 +387,11 @@ TASK_IMPL_2(MTBDD, mtbdd_op_not_zero, MTBDD, a, size_t, v) } else if (mtbddnode_gettype(na) == 2) { return mtbdd_getnumer(a) != 0 ? mtbdd_true : mtbdd_false; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + return storm_rational_function_is_zero((storm_rational_function_ptr)mtbdd_getvalue(a)) == 0 ? mtbdd_true : mtbdd_false; + } +#endif } // Ugly hack to get rid of the error "unused variable v" (because there is no version of uapply without a parameter). @@ -377,6 +424,12 @@ TASK_IMPL_2(MTBDD, mtbdd_op_floor, MTBDD, a, size_t, v) MTBDD result = mtbdd_fraction(mtbdd_getnumer(a) / mtbdd_getdenom(a), 1); return result; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR mtbdd_op_floor type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID"); + assert(0); + } +#endif } // Ugly hack to get rid of the error "unused variable v" (because there is no version of uapply without a parameter). @@ -409,6 +462,12 @@ TASK_IMPL_2(MTBDD, mtbdd_op_ceil, MTBDD, a, size_t, v) MTBDD result = mtbdd_fraction(mtbdd_getnumer(a) / mtbdd_getdenom(a) + 1, 1); return result; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + printf("ERROR mtbdd_op_ceil type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID"); + assert(0); + } +#endif } // Ugly hack to get rid of the error "unused variable v" (because there is no version of uapply without a parameter). @@ -474,6 +533,11 @@ TASK_IMPL_2(double, mtbdd_non_zero_count, MTBDD, dd, size_t, nvars) } else if (mtbddnode_gettype(na) == 2) { return mtbdd_getnumer(dd) != 0 ? powl(2.0L, nvars) : 0.0; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + return storm_rational_function_is_zero((storm_rational_function_ptr)mtbdd_getvalue(dd)) == 0 ? powl(2.0L, nvars) : 0.0; + } +#endif } /* Perhaps execute garbage collection */ @@ -506,6 +570,11 @@ int mtbdd_iszero(MTBDD dd) { } else if (mtbdd_gettype(dd) == 2) { return mtbdd_getnumer(dd) == 0; } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if (mtbdd_gettype(dd) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { + return storm_rational_function_is_zero((storm_rational_function_ptr)mtbdd_getvalue(dd)) == 1 ? 1 : 0; + } +#endif return 0; } diff --git a/resources/3rdparty/sylvan/src/sylvan_obj.cpp b/resources/3rdparty/sylvan/src/sylvan_obj.cpp index b7b4484fb..b9d0c77f2 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj.cpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj.cpp @@ -609,9 +609,8 @@ Mtbdd::doubleTerminal(double value) Mtbdd Mtbdd::stormRationalFunctionTerminal(storm::RationalFunction const& value) { - storm_rational_function_ptr_struct functionStruct; - functionStruct.storm_rational_function = (void*)(&value); - return mtbdd_storm_rational_function(&functionStruct); + storm_rational_function_ptr ptr = (storm_rational_function_ptr)(&value); + return mtbdd_storm_rational_function(ptr); } #endif @@ -1039,6 +1038,7 @@ void Sylvan::initMtbdd() { sylvan_init_mtbdd(); + sylvan_storm_rational_function_init(); } void diff --git a/resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp b/resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp index 26e5ea4be..83a89f138 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp @@ -8,6 +8,28 @@ */ Mtbdd Divide(const Mtbdd &other) const; +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + /** + * @brief Computes f + g for Rational Functions + */ + Mtbdd PlusRF(const Mtbdd &other) const; + + /** + * @brief Computes f * g for Rational Functions + */ + Mtbdd TimesRF(const Mtbdd &other) const; + + /** + * @brief Computes f - g for Rational Functions + */ + Mtbdd MinusRF(const Mtbdd &other) const; + + /** + * @brief Computes f / g for Rational Functions + */ + Mtbdd DivideRF(const Mtbdd &other) const; +#endif + Bdd NotZero() const; Bdd Equals(const Mtbdd& other) const; diff --git a/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp b/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp index f64ffeaa2..837e906a2 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp @@ -16,6 +16,36 @@ Bdd::toStormRationalFunctionMtbdd() const { LACE_ME; return mtbdd_bool_to_storm_rational_function(bdd); } + +Mtbdd +Mtbdd::PlusRF(const Mtbdd &other) const +{ + LACE_ME; + return sylvan_storm_rational_function_plus(mtbdd, other.mtbdd); +} + + +Mtbdd +Mtbdd::TimesRF(const Mtbdd &other) const +{ + LACE_ME; + return sylvan_storm_rational_function_times(mtbdd, other.mtbdd); +} + +Mtbdd +Mtbdd::MinusRF(const Mtbdd &other) const +{ + LACE_ME; + return sylvan_storm_rational_function_minus(mtbdd, other.mtbdd); +} + +Mtbdd +Mtbdd::DivideRF(const Mtbdd &other) const +{ + LACE_ME; + return sylvan_storm_rational_function_divide(mtbdd, other.mtbdd); +} + #endif Mtbdd diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c index 2b35ed91a..9ecc754b5 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c @@ -15,6 +15,18 @@ #include +#undef SYLVAN_STORM_RATIONAL_FUNCTION_DEBUG + +#ifdef SYLVAN_STORM_RATIONAL_FUNCTION_DEBUG +int depth = 0; + +#define LOG_I(funcName) do { for (int i = 0; i < depth; ++i) { printf(" "); } ++depth; printf("Entering function " funcName "\n"); } while (0 != 0); +#define LOG_O(funcName) do { --depth; for (int i = 0; i < depth; ++i) { printf(" "); } printf("Leaving function " funcName "\n"); } while (0 != 0); +#else +#define LOG_I(funcName) +#define LOG_O(funcName) +#endif + /** * helper function for hash */ @@ -29,42 +41,73 @@ rotl64(uint64_t x, int8_t r) static uint64_t sylvan_storm_rational_function_hash(const uint64_t v, const uint64_t seed) { + LOG_I("i-hash") /* Hash the storm::RationalFunction in pointer v */ - storm_rational_function_ptr x = (storm_rational_function_ptr)(size_t)v; + storm_rational_function_ptr x = (storm_rational_function_ptr)v; + + uint64_t hash = storm_rational_function_hash(x, seed); + +#ifdef SYLVAN_STORM_RATIONAL_FUNCTION_DEBUG + printf("Hashing ptr %p with contents ", x); + print_storm_rational_function(x); + printf(" with seed %zu, hash = %zu\n", seed, hash); +#endif - return storm_rational_function_hash(x, seed); + LOG_O("i-hash") + return hash; } static int sylvan_storm_rational_function_equals(const uint64_t left, const uint64_t right) { + LOG_I("i-equals") /* This function is called by the unique table when comparing a new leaf with an existing leaf */ storm_rational_function_ptr a = (storm_rational_function_ptr)(size_t)left; storm_rational_function_ptr b = (storm_rational_function_ptr)(size_t)right; /* Just compare x and y */ - return (storm_rational_function_equals(a, b) == 0) ? 1 : 0; + int result = storm_rational_function_equals(a, b); + + LOG_O("i-equals") + return result; } static void sylvan_storm_rational_function_create(uint64_t *val) { - printf("sylvan_storm_rational_function_create(val = %zu)\n", *val); + LOG_I("i-create") + +#ifdef SYLVAN_STORM_RATIONAL_FUNCTION_DEBUG + void* tmp = (void*)*val; + printf("sylvan_storm_rational_function_create(ptr = %p, value = ", tmp); + print_storm_rational_function(*((storm_rational_function_ptr*)(size_t)val)); + printf(")\n"); +#endif + /* This function is called by the unique table when a leaf does not yet exist. We make a copy, which will be stored in the hash table. */ storm_rational_function_ptr* x = (storm_rational_function_ptr*)(size_t)val; storm_rational_function_init(x); + +#ifdef SYLVAN_STORM_RATIONAL_FUNCTION_DEBUG + tmp = (void*)*val; + printf("sylvan_storm_rational_function_create_2(ptr = %p)\n", tmp); +#endif + + LOG_O("i-create") } static void sylvan_storm_rational_function_destroy(uint64_t val) { + LOG_I("i-destroy") /* This function is called by the unique table when a leaf is removed during garbage collection. */ storm_rational_function_ptr x = (storm_rational_function_ptr)(size_t)val; storm_rational_function_destroy(x); + LOG_O("i-destroy") } static uint32_t sylvan_storm_rational_function_type; @@ -78,6 +121,12 @@ sylvan_storm_rational_function_init() { /* Register custom leaf 3 */ sylvan_storm_rational_function_type = mtbdd_register_custom_leaf(sylvan_storm_rational_function_hash, sylvan_storm_rational_function_equals, sylvan_storm_rational_function_create, sylvan_storm_rational_function_destroy); + + if (SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID != sylvan_storm_rational_function_type) { + printf("ERROR - ERROR - ERROR\nThe Sylvan Type ID is NOT correct.\nIt was assumed to be %u, but it is actually %u!\nYou NEED to fix this by changing the macro \"SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID\" and recompiling StoRM!\n\n", SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID, sylvan_storm_rational_function_type); + assert(0); + } + CACHE_STORM_RATIONAL_FUNCTION_AND_EXISTS = cache_next_opid(); } @@ -89,11 +138,21 @@ uint32_t sylvan_storm_rational_function_get_type() { * Create storm::RationalFunction leaf */ MTBDD -mtbdd_storm_rational_function(storm_rational_function_t val) +mtbdd_storm_rational_function(storm_rational_function_ptr val) { + LOG_I("i-mtbdd_") uint64_t terminalValue = (uint64_t)val; - printf("mtbdd_storm_rational_function(val = %zu)\n", terminalValue); - return mtbdd_makeleaf(sylvan_storm_rational_function_type, terminalValue); + +#ifdef SYLVAN_STORM_RATIONAL_FUNCTION_DEBUG + printf("mtbdd_storm_rational_function(ptr = %p, value = ", val); + print_storm_rational_function(val); + printf(")\n"); +#endif + + MTBDD result = mtbdd_makeleaf(sylvan_storm_rational_function_type, terminalValue); + + LOG_O("i-mtbdd_") + return result; } /** @@ -101,21 +160,30 @@ mtbdd_storm_rational_function(storm_rational_function_t val) */ TASK_IMPL_2(MTBDD, mtbdd_op_bool_to_storm_rational_function, MTBDD, a, size_t, v) { + LOG_I("task_impl_2 to_srf") if (a == mtbdd_false) { - return mtbdd_storm_rational_function(storm_rational_function_get_zero()); + storm_rational_function_ptr srf_zero = storm_rational_function_get_zero(); + MTBDD result = mtbdd_storm_rational_function(srf_zero); + LOG_O("task_impl_2 to_srf - ZERO") + return result; } if (a == mtbdd_true) { - return mtbdd_storm_rational_function(storm_rational_function_get_one()); + storm_rational_function_ptr srf_one = storm_rational_function_get_one(); + MTBDD result = mtbdd_storm_rational_function(srf_one); + LOG_O("task_impl_2 to_srf - ONE") + return result; } // Ugly hack to get rid of the error "unused variable v" (because there is no version of uapply without a parameter). (void)v; - + + LOG_O("task_impl_2 to_srf - INVALID") return mtbdd_invalid; } TASK_IMPL_1(MTBDD, mtbdd_bool_to_storm_rational_function, MTBDD, dd) { + LOG_I("task_impl_1 to_srf") return mtbdd_uapply(dd, TASK(mtbdd_op_bool_to_storm_rational_function), 0); } @@ -125,6 +193,7 @@ TASK_IMPL_1(MTBDD, mtbdd_bool_to_storm_rational_function, MTBDD, dd) */ TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_plus, MTBDD*, pa, MTBDD*, pb) { + LOG_I("task_impl_2 op_plus") MTBDD a = *pa, b = *pb; /* Check for partial functions */ @@ -159,7 +228,8 @@ TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_plus, MTBDD*, pa, MTBDD*, p */ TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_minus, MTBDD*, pa, MTBDD*, pb) { - MTBDD a = *pa, b = *pb; + LOG_I("task_impl_2 op_minus") + MTBDD a = *pa, b = *pb; /* Check for partial functions */ if (a == mtbdd_false) return sylvan_storm_rational_function_neg(b); @@ -188,6 +258,7 @@ TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_minus, MTBDD*, pa, MTBDD*, */ TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_times, MTBDD*, pa, MTBDD*, pb) { + LOG_I("task_impl_2 op_times") MTBDD a = *pa, b = *pb; /* Check for partial functions and for Boolean (filter) */ @@ -202,7 +273,7 @@ TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_times, MTBDD*, pa, MTBDD*, storm_rational_function_ptr ma = (storm_rational_function_ptr)mtbdd_getvalue(a); storm_rational_function_ptr mb = (storm_rational_function_ptr)mtbdd_getvalue(b); - storm_rational_function_ptr mres = storm_rational_function_times(ma, mb); + storm_rational_function_ptr mres = storm_rational_function_times(ma, mb); MTBDD res = mtbdd_storm_rational_function(mres); // TODO: Delete mres? @@ -225,6 +296,7 @@ TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_times, MTBDD*, pa, MTBDD*, */ TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_divide, MTBDD*, pa, MTBDD*, pb) { + LOG_I("task_impl_2 op_divide") MTBDD a = *pa, b = *pb; /* Check for partial functions */ @@ -254,6 +326,7 @@ TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_divide, MTBDD*, pa, MTBDD*, TASK_IMPL_3(MTBDD, sylvan_storm_rational_function_abstract_op_plus, MTBDD, a, MTBDD, b, int, k) { + LOG_I("task_impl_3 abstract_op_plus") if (k==0) { return mtbdd_apply(a, b, TASK(sylvan_storm_rational_function_op_plus)); } else { @@ -269,6 +342,7 @@ TASK_IMPL_3(MTBDD, sylvan_storm_rational_function_abstract_op_plus, MTBDD, a, MT TASK_IMPL_3(MTBDD, sylvan_storm_rational_function_abstract_op_times, MTBDD, a, MTBDD, b, int, k) { + LOG_I("task_impl_3 abstract_op_times") if (k==0) { return mtbdd_apply(a, b, TASK(sylvan_storm_rational_function_op_times)); } else { @@ -287,6 +361,7 @@ TASK_IMPL_3(MTBDD, sylvan_storm_rational_function_abstract_op_times, MTBDD, a, M */ TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_neg, MTBDD, dd, size_t, p) { + LOG_I("task_impl_2 op_neg") /* Handle partial functions */ if (dd == mtbdd_false) return mtbdd_false; diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h index fd4ad7f3a..f6effbb66 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h @@ -12,6 +12,8 @@ #if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) +#define SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID (3) + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -29,7 +31,7 @@ uint32_t sylvan_storm_rational_function_get_type(); /** * Create storm::RationalFunction leaf */ -MTBDD mtbdd_storm_rational_function(storm_rational_function_t val); +MTBDD mtbdd_storm_rational_function(storm_rational_function_ptr val); /** * Monad that converts Boolean to a storm::RationalFunction MTBDD, translate terminals true to 1 and to 0 otherwise; diff --git a/src/storage/dd/DdManager.cpp b/src/storage/dd/DdManager.cpp index 7a1a9ab8d..7a8df8f21 100644 --- a/src/storage/dd/DdManager.cpp +++ b/src/storage/dd/DdManager.cpp @@ -10,6 +10,7 @@ #include "src/adapters/CarlAdapter.h" #include +#include namespace storm { namespace dd { @@ -105,21 +106,6 @@ namespace storm { } return result; } - -#ifdef STORM_HAVE_CARL - template<> - template<> - Add DdManager::getIdentity(storm::expressions::Variable const& variable) const { - storm::dd::DdMetaVariable const& metaVariable = this->getMetaVariable(variable); - - Add result = this->getAddZero(); - for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) { - storm::RationalFunction constantFunction(value); - result += this->getEncoding(variable, value).template toAdd() * this->getConstant(constantFunction); - } - return result; - } -#endif template std::pair DdManager::addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high) { diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index 51c072126..4b301adf6 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -33,126 +33,298 @@ namespace storm { InternalAdd InternalAdd::operator+(InternalAdd const& other) const { return InternalAdd(ddManager, this->sylvanMtbdd.Plus(other.sylvanMtbdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::operator+(InternalAdd const& other) const { + return InternalAdd(ddManager, this->sylvanMtbdd.PlusRF(other.sylvanMtbdd)); + } +#endif + template InternalAdd& InternalAdd::operator+=(InternalAdd const& other) { this->sylvanMtbdd = this->sylvanMtbdd.Plus(other.sylvanMtbdd); return *this; } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd& InternalAdd::operator+=(InternalAdd const& other) { + this->sylvanMtbdd = this->sylvanMtbdd.PlusRF(other.sylvanMtbdd); + return *this; + } +#endif + template InternalAdd InternalAdd::operator*(InternalAdd const& other) const { return InternalAdd(ddManager, this->sylvanMtbdd.Times(other.sylvanMtbdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::operator*(InternalAdd const& other) const { + return InternalAdd(ddManager, this->sylvanMtbdd.TimesRF(other.sylvanMtbdd)); + } +#endif + template InternalAdd& InternalAdd::operator*=(InternalAdd const& other) { this->sylvanMtbdd = this->sylvanMtbdd.Times(other.sylvanMtbdd); return *this; } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd& InternalAdd::operator*=(InternalAdd const& other) { + this->sylvanMtbdd = this->sylvanMtbdd.TimesRF(other.sylvanMtbdd); + return *this; + } +#endif + template InternalAdd InternalAdd::operator-(InternalAdd const& other) const { return InternalAdd(ddManager, this->sylvanMtbdd.Minus(other.sylvanMtbdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::operator-(InternalAdd const& other) const { + return InternalAdd(ddManager, this->sylvanMtbdd.MinusRF(other.sylvanMtbdd)); + } +#endif + template InternalAdd& InternalAdd::operator-=(InternalAdd const& other) { this->sylvanMtbdd = this->sylvanMtbdd.Minus(other.sylvanMtbdd); return *this; } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd& InternalAdd::operator-=(InternalAdd const& other) { + this->sylvanMtbdd = this->sylvanMtbdd.MinusRF(other.sylvanMtbdd); + return *this; + } +#endif + template InternalAdd InternalAdd::operator/(InternalAdd const& other) const { return InternalAdd(ddManager, this->sylvanMtbdd.Divide(other.sylvanMtbdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::operator/(InternalAdd const& other) const { + return InternalAdd(ddManager, this->sylvanMtbdd.DivideRF(other.sylvanMtbdd)); + } +#endif + template InternalAdd& InternalAdd::operator/=(InternalAdd const& other) { this->sylvanMtbdd = this->sylvanMtbdd.Divide(other.sylvanMtbdd); return *this; } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd& InternalAdd::operator/=(InternalAdd const& other) { + this->sylvanMtbdd = this->sylvanMtbdd.DivideRF(other.sylvanMtbdd); + return *this; + } +#endif + template InternalBdd InternalAdd::equals(InternalAdd const& other) const { return InternalBdd(ddManager, this->sylvanMtbdd.Equals(other.sylvanMtbdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalBdd InternalAdd::equals(InternalAdd const& other) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: Equals"); + } +#endif + template InternalBdd InternalAdd::notEquals(InternalAdd const& other) const { return !this->equals(other); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalBdd InternalAdd::notEquals(InternalAdd const& other) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: Not Equals"); + } +#endif + template InternalBdd InternalAdd::less(InternalAdd const& other) const { return InternalBdd(ddManager, this->sylvanMtbdd.Less(other.sylvanMtbdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalBdd InternalAdd::less(InternalAdd const& other) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: Less"); + } +#endif + template InternalBdd InternalAdd::lessOrEqual(InternalAdd const& other) const { return InternalBdd(ddManager, this->sylvanMtbdd.LessOrEqual(other.sylvanMtbdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalBdd InternalAdd::lessOrEqual(InternalAdd const& other) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: Less or Equal"); + } +#endif + template InternalBdd InternalAdd::greater(InternalAdd const& other) const { return !this->lessOrEqual(other); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalBdd InternalAdd::greater(InternalAdd const& other) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: Greater"); + } +#endif + template InternalBdd InternalAdd::greaterOrEqual(InternalAdd const& other) const { return !this->less(other); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalBdd InternalAdd::greaterOrEqual(InternalAdd const& other) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: Greater or Equal"); + } +#endif + template InternalAdd InternalAdd::pow(InternalAdd const& other) const { return InternalAdd(ddManager, this->sylvanMtbdd.Pow(other.sylvanMtbdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::pow(InternalAdd const& other) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: Pow"); + } +#endif + template InternalAdd InternalAdd::mod(InternalAdd const& other) const { return InternalAdd(ddManager, this->sylvanMtbdd.Mod(other.sylvanMtbdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::mod(InternalAdd const& other) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: Mod"); + } +#endif + template InternalAdd InternalAdd::logxy(InternalAdd const& other) const { return InternalAdd(ddManager, this->sylvanMtbdd.Logxy(other.sylvanMtbdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::logxy(InternalAdd const& other) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: logxy"); + } +#endif + template InternalAdd InternalAdd::floor() const { return InternalAdd(ddManager, this->sylvanMtbdd.Floor()); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::floor() const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: Floor"); + } +#endif + template InternalAdd InternalAdd::ceil() const { return InternalAdd(ddManager, this->sylvanMtbdd.Ceil()); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::ceil() const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: Ceil"); + } +#endif + template InternalAdd InternalAdd::minimum(InternalAdd const& other) const { return InternalAdd(ddManager, this->sylvanMtbdd.Min(other.sylvanMtbdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::minimum(InternalAdd const& other) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: Minimum"); + } +#endif + template InternalAdd InternalAdd::maximum(InternalAdd const& other) const { return InternalAdd(ddManager, this->sylvanMtbdd.Max(other.sylvanMtbdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::maximum(InternalAdd const& other) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: Maximum"); + } +#endif + template InternalAdd InternalAdd::sumAbstract(InternalBdd const& cube) const { return InternalAdd(ddManager, this->sylvanMtbdd.AbstractPlus(cube.sylvanBdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::sumAbstract(InternalBdd const& cube) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: sumAbstract"); + } +#endif + template InternalAdd InternalAdd::minAbstract(InternalBdd const& cube) const { return InternalAdd(ddManager, this->sylvanMtbdd.AbstractMin(cube.sylvanBdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::minAbstract(InternalBdd const& cube) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: minAbstract"); + } +#endif + template InternalAdd InternalAdd::maxAbstract(InternalBdd const& cube) const { return InternalAdd(ddManager, this->sylvanMtbdd.AbstractMax(cube.sylvanBdd)); } - + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalAdd::maxAbstract(InternalBdd const& cube) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: maxAbstract"); + } +#endif + template bool InternalAdd::equalModuloPrecision(InternalAdd const& other, double precision, bool relative) const { if (relative) { @@ -161,7 +333,14 @@ namespace storm { return this->sylvanMtbdd.EqualNorm(other.sylvanMtbdd, precision); } } - + +#ifdef STORM_HAVE_CARL + template<> + bool InternalAdd::equalModuloPrecision(InternalAdd const& other, double precision, bool relative) const { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: equalModuloPrecision"); + } +#endif + template InternalAdd InternalAdd::swapVariables(std::vector> const& from, std::vector> const& to) const { std::vector fromIndices; @@ -615,10 +794,9 @@ namespace storm { template MTBDD InternalAdd::getLeaf(storm::RationalFunction const& value) { - storm_rational_function_ptr_struct helperStruct; - helperStruct.storm_rational_function = (void*)(&value); + storm_rational_function_ptr ptr = (storm_rational_function_ptr)(&value); - return mtbdd_storm_rational_function(&helperStruct); + return mtbdd_storm_rational_function(ptr); } template @@ -639,7 +817,7 @@ namespace storm { else if (std::is_same::value) { STORM_LOG_ASSERT(false, "Non-specialized version of getValue() called for storm::RationalFunction value."); } -#endif +#endif else { STORM_LOG_ASSERT(false, "Illegal or unknown type in MTBDD."); } @@ -655,9 +833,9 @@ namespace storm { STORM_LOG_ASSERT(mtbdd_gettype(node) == sylvan_storm_rational_function_get_type(), "Expected a storm::RationalFunction value."); uint64_t value = mtbdd_getvalue(node); - storm_rational_function_ptr_struct* helperStructPtr = (storm_rational_function_ptr_struct*)value; + storm_rational_function_ptr ptr = (storm_rational_function_ptr)value; - storm::RationalFunction* rationalFunction = (storm::RationalFunction*)(helperStructPtr->storm_rational_function); + storm::RationalFunction* rationalFunction = (storm::RationalFunction*)(ptr); return negated ? -(*rationalFunction) : (*rationalFunction); } diff --git a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp index 287fe55c3..fffc82ec9 100644 --- a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp +++ b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp @@ -1,175 +1,166 @@ -#include "src/storage/dd/sylvan/InternalSylvanDdManager.h" - -#include - -#include "src/settings/SettingsManager.h" -#include "src/settings/modules/SylvanSettings.h" - -#include "src/utility/constants.h" -#include "src/utility/macros.h" -#include "src/exceptions/NotSupportedException.h" - -#include "src/utility/sylvan.h" - -#include "storm-config.h" -// TODO: Remove this later on. -#ifndef STORM_HAVE_CARL -#define STORM_HAVE_CARL 1 -#endif - -namespace storm { - namespace dd { - uint_fast64_t InternalDdManager::numberOfInstances = 0; - - // It is important that the variable pairs start at an even offset, because sylvan assumes this to be true for - // some operations. - uint_fast64_t InternalDdManager::nextFreeVariableIndex = 0; - - uint_fast64_t findLargestPowerOfTwoFitting(uint_fast64_t number) { - for (uint_fast64_t index = 0; index < 64; ++index) { - if ((number & (1ull << (63 - index))) != 0) { - return 63 - index; - } - } - return 0; - } - - InternalDdManager::InternalDdManager() { - if (numberOfInstances == 0) { - // Initialize lace: auto-detect number of workers. - lace_init(storm::settings::getModule().getNumberOfThreads(), 1000000); - lace_startup(0, 0, 0); - - // Each node takes 24 bytes and the maximal memory is specified in megabytes. - uint_fast64_t totalNodesToStore = storm::settings::getModule().getMaximalMemory() * 1024 * 1024 / 24; - - // Compute the power of two that still fits within the total numbers to store. - uint_fast64_t powerOfTwo = findLargestPowerOfTwoFitting(totalNodesToStore); - - sylvan::Sylvan::initPackage(1ull << std::max(16ull, powerOfTwo > 24 ? powerOfTwo - 8 : 0ull), 1ull << (powerOfTwo - 1), 1ull << std::max(16ull, powerOfTwo > 24 ? powerOfTwo - 12 : 0ull), 1ull << (powerOfTwo - 1)); - sylvan::Sylvan::initBdd(1); - sylvan::Sylvan::initMtbdd(); - } - ++numberOfInstances; - } - - InternalDdManager::~InternalDdManager() { - --numberOfInstances; - if (numberOfInstances == 0) { - // Enable this to print the sylvan statistics to a file. -// FILE* filePointer = fopen("sylvan.stats", "w"); -// sylvan_stats_report(filePointer, 0); -// fclose(filePointer); - - sylvan::Sylvan::quitPackage(); - lace_exit(); - } - } - - InternalBdd InternalDdManager::getBddOne() const { - return InternalBdd(this, sylvan::Bdd::bddOne()); - } - - template<> - InternalAdd InternalDdManager::getAddOne() const { - return InternalAdd(this, sylvan::Mtbdd::doubleTerminal(storm::utility::one())); - } - - template<> - InternalAdd InternalDdManager::getAddOne() const { - return InternalAdd(this, sylvan::Mtbdd::int64Terminal(storm::utility::one())); - } - -#ifdef STORM_HAVE_CARL - template<> - InternalAdd InternalDdManager::getAddOne() const { - storm::RationalFunction rationalFunction = storm::utility::one(); - storm_rational_function_ptr_struct helperStruct; - helperStruct.storm_rational_function = (void*)(&rationalFunction); - uint64_t value = (uint64_t)&helperStruct; - - return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), value)); - } -#endif - - InternalBdd InternalDdManager::getBddZero() const { - return InternalBdd(this, sylvan::Bdd::bddZero()); - } - - template<> - InternalAdd InternalDdManager::getAddZero() const { - return InternalAdd(this, sylvan::Mtbdd::doubleTerminal(storm::utility::zero())); - } - - template<> - InternalAdd InternalDdManager::getAddZero() const { - return InternalAdd(this, sylvan::Mtbdd::int64Terminal(storm::utility::zero())); - } - -#ifdef STORM_HAVE_CARL - template<> - InternalAdd InternalDdManager::getAddZero() const { - storm::RationalFunction rationalFunction = storm::utility::zero(); - storm_rational_function_ptr_struct helperStruct; - helperStruct.storm_rational_function = (void*)(&rationalFunction); - uint64_t value = (uint64_t)&helperStruct; - - return InternalAdd(this, sylvan::Mtbdd::terminal(sylvan_storm_rational_function_get_type(), value)); - } -#endif - - template<> - InternalAdd InternalDdManager::getConstant(double const& value) const { - return InternalAdd(this, sylvan::Mtbdd::doubleTerminal(value)); - } - - template<> - InternalAdd InternalDdManager::getConstant(uint_fast64_t const& value) const { - return InternalAdd(this, sylvan::Mtbdd::int64Terminal(value)); - } - -#ifdef STORM_HAVE_CARL - template<> - InternalAdd InternalDdManager::getConstant(storm::RationalFunction const& value) const { - return InternalAdd(this, sylvan::Mtbdd::stormRationalFunctionTerminal(value)); - } -#endif - - std::pair, InternalBdd> InternalDdManager::createNewDdVariablePair() { - InternalBdd first = InternalBdd(this, sylvan::Bdd::bddVar(nextFreeVariableIndex)); - InternalBdd second = InternalBdd(this, sylvan::Bdd::bddVar(nextFreeVariableIndex + 1)); - nextFreeVariableIndex += 2; - return std::make_pair(first, second); - } - - void InternalDdManager::allowDynamicReordering(bool value) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation is not supported by sylvan."); - } - - bool InternalDdManager::isDynamicReorderingAllowed() const { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation is not supported by sylvan."); - } - - void InternalDdManager::triggerReordering() { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation is not supported by sylvan."); - } - - template InternalAdd InternalDdManager::getAddOne() const; - template InternalAdd InternalDdManager::getAddOne() const; -#ifdef STORM_HAVE_CARL - template InternalAdd InternalDdManager::getAddOne() const; -#endif - - template InternalAdd InternalDdManager::getAddZero() const; - template InternalAdd InternalDdManager::getAddZero() const; -#ifdef STORM_HAVE_CARL - template InternalAdd InternalDdManager::getAddZero() const; -#endif - - template InternalAdd InternalDdManager::getConstant(double const& value) const; - template InternalAdd InternalDdManager::getConstant(uint_fast64_t const& value) const; -#ifdef STORM_HAVE_CARL - template InternalAdd InternalDdManager::getConstant(storm::RationalFunction const& value) const; -#endif - } -} \ No newline at end of file +#include "src/storage/dd/sylvan/InternalSylvanDdManager.h" + +#include +#include + +#include "src/settings/SettingsManager.h" +#include "src/settings/modules/SylvanSettings.h" + +#include "src/utility/constants.h" +#include "src/utility/macros.h" +#include "src/exceptions/NotSupportedException.h" + +#include "src/utility/sylvan.h" + +#include "storm-config.h" +// TODO: Remove this later on. +#ifndef STORM_HAVE_CARL +#define STORM_HAVE_CARL 1 +#endif + +namespace storm { + namespace dd { + uint_fast64_t InternalDdManager::numberOfInstances = 0; + + // It is important that the variable pairs start at an even offset, because sylvan assumes this to be true for + // some operations. + uint_fast64_t InternalDdManager::nextFreeVariableIndex = 0; + + uint_fast64_t findLargestPowerOfTwoFitting(uint_fast64_t number) { + for (uint_fast64_t index = 0; index < 64; ++index) { + if ((number & (1ull << (63 - index))) != 0) { + return 63 - index; + } + } + return 0; + } + + InternalDdManager::InternalDdManager() { + if (numberOfInstances == 0) { + // Initialize lace: auto-detect number of workers. + lace_init(storm::settings::getModule().getNumberOfThreads(), 1000000); + lace_startup(0, 0, 0); + + // Each node takes 24 bytes and the maximal memory is specified in megabytes. + uint_fast64_t totalNodesToStore = storm::settings::getModule().getMaximalMemory() * 1024 * 1024 / 24; + + // Compute the power of two that still fits within the total numbers to store. + uint_fast64_t powerOfTwo = findLargestPowerOfTwoFitting(totalNodesToStore); + + sylvan::Sylvan::initPackage(1ull << std::max(16ull, powerOfTwo > 24 ? powerOfTwo - 8 : 0ull), 1ull << (powerOfTwo - 1), 1ull << std::max(16ull, powerOfTwo > 24 ? powerOfTwo - 12 : 0ull), 1ull << (powerOfTwo - 1)); + sylvan::Sylvan::initBdd(1); + sylvan::Sylvan::initMtbdd(); + } + ++numberOfInstances; + } + + InternalDdManager::~InternalDdManager() { + --numberOfInstances; + if (numberOfInstances == 0) { + // Enable this to print the sylvan statistics to a file. +// FILE* filePointer = fopen("sylvan.stats", "w"); +// sylvan_stats_report(filePointer, 0); +// fclose(filePointer); + + sylvan::Sylvan::quitPackage(); + lace_exit(); + } + } + + InternalBdd InternalDdManager::getBddOne() const { + return InternalBdd(this, sylvan::Bdd::bddOne()); + } + + template<> + InternalAdd InternalDdManager::getAddOne() const { + return InternalAdd(this, sylvan::Mtbdd::doubleTerminal(storm::utility::one())); + } + + template<> + InternalAdd InternalDdManager::getAddOne() const { + return InternalAdd(this, sylvan::Mtbdd::int64Terminal(storm::utility::one())); + } + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalDdManager::getAddOne() const { + return InternalAdd(this, sylvan::Mtbdd::stormRationalFunctionTerminal(storm::utility::one())); + } +#endif + + InternalBdd InternalDdManager::getBddZero() const { + return InternalBdd(this, sylvan::Bdd::bddZero()); + } + + template<> + InternalAdd InternalDdManager::getAddZero() const { + return InternalAdd(this, sylvan::Mtbdd::doubleTerminal(storm::utility::zero())); + } + + template<> + InternalAdd InternalDdManager::getAddZero() const { + return InternalAdd(this, sylvan::Mtbdd::int64Terminal(storm::utility::zero())); + } + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalDdManager::getAddZero() const { + return InternalAdd(this, sylvan::Mtbdd::stormRationalFunctionTerminal(storm::utility::zero())); + } +#endif + + template<> + InternalAdd InternalDdManager::getConstant(double const& value) const { + return InternalAdd(this, sylvan::Mtbdd::doubleTerminal(value)); + } + + template<> + InternalAdd InternalDdManager::getConstant(uint_fast64_t const& value) const { + return InternalAdd(this, sylvan::Mtbdd::int64Terminal(value)); + } + +#ifdef STORM_HAVE_CARL + template<> + InternalAdd InternalDdManager::getConstant(storm::RationalFunction const& value) const { + return InternalAdd(this, sylvan::Mtbdd::stormRationalFunctionTerminal(value)); + } +#endif + + std::pair, InternalBdd> InternalDdManager::createNewDdVariablePair() { + InternalBdd first = InternalBdd(this, sylvan::Bdd::bddVar(nextFreeVariableIndex)); + InternalBdd second = InternalBdd(this, sylvan::Bdd::bddVar(nextFreeVariableIndex + 1)); + nextFreeVariableIndex += 2; + return std::make_pair(first, second); + } + + void InternalDdManager::allowDynamicReordering(bool value) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation is not supported by sylvan."); + } + + bool InternalDdManager::isDynamicReorderingAllowed() const { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation is not supported by sylvan."); + } + + void InternalDdManager::triggerReordering() { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation is not supported by sylvan."); + } + + template InternalAdd InternalDdManager::getAddOne() const; + template InternalAdd InternalDdManager::getAddOne() const; +#ifdef STORM_HAVE_CARL + template InternalAdd InternalDdManager::getAddOne() const; +#endif + + template InternalAdd InternalDdManager::getAddZero() const; + template InternalAdd InternalDdManager::getAddZero() const; +#ifdef STORM_HAVE_CARL + template InternalAdd InternalDdManager::getAddZero() const; +#endif + + template InternalAdd InternalDdManager::getConstant(double const& value) const; + template InternalAdd InternalDdManager::getConstant(uint_fast64_t const& value) const; +#ifdef STORM_HAVE_CARL + template InternalAdd InternalDdManager::getConstant(storm::RationalFunction const& value) const; +#endif + } +} diff --git a/test/functional/storage/SylvanDdTest.cpp b/test/functional/storage/SylvanDdTest.cpp index ad5566050..8a5ca130e 100644 --- a/test/functional/storage/SylvanDdTest.cpp +++ b/test/functional/storage/SylvanDdTest.cpp @@ -142,26 +142,25 @@ TEST(SylvanDd, RationalFunctionIdentityTest) { EXPECT_EQ(10ul, identity.getLeafCount()); EXPECT_EQ(21ul, identity.getNodeCount()); } - #endif TEST(SylvanDd, RangeTest) { std::shared_ptr> manager(new storm::dd::DdManager()); std::pair x; ASSERT_NO_THROW(x = manager->addMetaVariable("x", 1, 9)); - + storm::dd::Bdd range; ASSERT_NO_THROW(range = manager->getRange(x.first)); - + EXPECT_EQ(9ul, range.getNonZeroCount()); EXPECT_EQ(1ul, range.getLeafCount()); EXPECT_EQ(5ul, range.getNodeCount()); } -TEST(SylvanDd, IdentityTest) { +TEST(SylvanDd, DoubleIdentityTest) { std::shared_ptr> manager(new storm::dd::DdManager()); std::pair x = manager->addMetaVariable("x", 1, 9); - + storm::dd::Add identity; ASSERT_NO_THROW(identity = manager->getIdentity(x.first)); @@ -170,6 +169,18 @@ TEST(SylvanDd, IdentityTest) { EXPECT_EQ(21ul, identity.getNodeCount()); } +TEST(SylvanDd, UintIdentityTest) { + std::shared_ptr> manager(new storm::dd::DdManager()); + std::pair x = manager->addMetaVariable("x", 1, 9); + + storm::dd::Add identity; + ASSERT_NO_THROW(identity = manager->getIdentity(x.first)); + + EXPECT_EQ(9ul, identity.getNonZeroCount()); + EXPECT_EQ(10ul, identity.getLeafCount()); + EXPECT_EQ(21ul, identity.getNodeCount()); +} + TEST(SylvanDd, OperatorTest) { std::shared_ptr> manager(new storm::dd::DdManager()); std::pair x = manager->addMetaVariable("x", 1, 9); From 867de852abddb12acc1d1af11bf12f779e4ff463 Mon Sep 17 00:00:00 2001 From: PBerger Date: Wed, 3 Aug 2016 04:10:43 +0200 Subject: [PATCH 38/49] Added the conditional debug output in the wrapper to the tracked code. Former-commit-id: adb9cebbd50932660b8e2d20559cbfcb5ed852c9 --- .../sylvan/src/storm_function_wrapper.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp b/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp index 74756d121..79a2a48f6 100644 --- a/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp +++ b/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp @@ -17,6 +17,9 @@ void storm_rational_function_init(storm_rational_function_ptr* a) { LOG_I("init") +#ifdef DEBUG_STORM_FUNCTION_WRAPPER + std::cout << "storm_rational_function_init - ptr of old = " << *a << ", value = " << *((storm::RationalFunction*)(*a)) << std::endl; +#endif storm_rational_function_ptr srf_ptr = new storm::RationalFunction(*((storm::RationalFunction*)(*a))); if (srf_ptr == nullptr) { @@ -25,6 +28,9 @@ void storm_rational_function_init(storm_rational_function_ptr* a) { } *a = srf_ptr; +#ifdef DEBUG_STORM_FUNCTION_WRAPPER + std::cout << "storm_rational_function_init - ptr of new = " << *a << ", value = " << *((storm::RationalFunction*)(*a)) << std::endl; +#endif LOG_O("init") } @@ -45,6 +51,11 @@ int storm_rational_function_equals(storm_rational_function_ptr a, storm_rational if (srf_a == srf_b) { result = 1; } + +#ifdef DEBUG_STORM_FUNCTION_WRAPPER + std::cout << "storm_rational_function_equals called with ptr = " << a << " value a = " << srf_a << " and ptr = " << b << " value b = " << srf_b << " result = " << result << "." << std::endl; +#endif + return result; } @@ -129,6 +140,11 @@ uint64_t storm_rational_function_hash(storm_rational_function_ptr const a, uint6 storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; size_t hash = carl::hash_value(srf_a); + +#ifdef + std::cout << "storm_rational_function_hash of value " << srf_a << " is " << hash << std::endl; +#endif + uint64_t result = hash ^ seed; LOG_O("hash") From 9eee8895390d8b54de8e8d17d02e13d9c0648df9 Mon Sep 17 00:00:00 2001 From: PBerger Date: Wed, 3 Aug 2016 05:00:55 +0200 Subject: [PATCH 39/49] Added missing parameter to #ifdef - its gettings late. Former-commit-id: 4c2ab46ed55226bc70335dd7268f71619300575e --- resources/3rdparty/sylvan/src/storm_function_wrapper.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp b/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp index 79a2a48f6..6cd79305e 100644 --- a/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp +++ b/resources/3rdparty/sylvan/src/storm_function_wrapper.cpp @@ -141,7 +141,7 @@ uint64_t storm_rational_function_hash(storm_rational_function_ptr const a, uint6 size_t hash = carl::hash_value(srf_a); -#ifdef +#ifdef DEBUG_STORM_FUNCTION_WRAPPER std::cout << "storm_rational_function_hash of value " << srf_a << " is " << hash << std::endl; #endif @@ -183,14 +183,12 @@ int storm_rational_function_is_zero(storm_rational_function_ptr a) { storm_rational_function_ptr storm_rational_function_get_zero() { static storm::RationalFunction zeroFunction(0); LOG_I("getZero") - //return new storm::RationalFunction(0); return (storm_rational_function_ptr)(&zeroFunction); } storm_rational_function_ptr storm_rational_function_get_one() { static storm::RationalFunction oneFunction(1); LOG_I("getOne") - //return new storm::RationalFunction(1); return (storm_rational_function_ptr)(&oneFunction); } From 0717ffe053ef9f89e1bf789e567887d7e4cbe868 Mon Sep 17 00:00:00 2001 From: PBerger Date: Sun, 7 Aug 2016 19:06:35 +0200 Subject: [PATCH 40/49] Added AND_EXISTS to sylvan+RationalFunction Former-commit-id: 7b462145cf8ff25aa3341c50ad9c74ff71a9417d --- .../src/sylvan_storm_rational_function.c | 88 +++++++++++++++++-- .../src/sylvan_storm_rational_function.h | 7 ++ test/functional/storage/SylvanDdTest.cpp | 37 ++++++++ 3 files changed, 126 insertions(+), 6 deletions(-) diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c index 9ecc754b5..dd2afab1a 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c @@ -10,7 +10,7 @@ #include #include -/*#include */ +#include #include #include @@ -162,14 +162,12 @@ TASK_IMPL_2(MTBDD, mtbdd_op_bool_to_storm_rational_function, MTBDD, a, size_t, v { LOG_I("task_impl_2 to_srf") if (a == mtbdd_false) { - storm_rational_function_ptr srf_zero = storm_rational_function_get_zero(); - MTBDD result = mtbdd_storm_rational_function(srf_zero); + MTBDD result = mtbdd_storm_rational_function(storm_rational_function_get_zero()); LOG_O("task_impl_2 to_srf - ZERO") return result; } if (a == mtbdd_true) { - storm_rational_function_ptr srf_one = storm_rational_function_get_one(); - MTBDD result = mtbdd_storm_rational_function(srf_one); + MTBDD result = mtbdd_storm_rational_function(storm_rational_function_get_one()); LOG_O("task_impl_2 to_srf - ONE") return result; } @@ -183,7 +181,6 @@ TASK_IMPL_2(MTBDD, mtbdd_op_bool_to_storm_rational_function, MTBDD, a, size_t, v TASK_IMPL_1(MTBDD, mtbdd_bool_to_storm_rational_function, MTBDD, dd) { - LOG_I("task_impl_1 to_srf") return mtbdd_uapply(dd, TASK(mtbdd_op_bool_to_storm_rational_function), 0); } @@ -379,3 +376,82 @@ TASK_IMPL_2(MTBDD, sylvan_storm_rational_function_op_neg, MTBDD, dd, size_t, p) return mtbdd_invalid; (void)p; } + +/** + * Multiply and , and abstract variables using summation. + * This is similar to the "and_exists" operation in BDDs. + */ +TASK_IMPL_3(MTBDD, sylvan_storm_rational_function_and_exists, MTBDD, a, MTBDD, b, MTBDD, v) +{ + /* Check terminal cases */ + + /* If v == true, then is an empty set */ + if (v == mtbdd_true) return mtbdd_apply(a, b, TASK(sylvan_storm_rational_function_op_times)); + + /* Try the times operator on a and b */ + MTBDD result = CALL(sylvan_storm_rational_function_op_times, &a, &b); + if (result != mtbdd_invalid) { + /* Times operator successful, store reference (for garbage collection) */ + mtbdd_refs_push(result); + /* ... and perform abstraction */ + result = mtbdd_abstract(result, v, TASK(sylvan_storm_rational_function_abstract_op_plus)); + mtbdd_refs_pop(1); + /* Note that the operation cache is used in mtbdd_abstract */ + return result; + } + + /* Maybe perform garbage collection */ + sylvan_gc_test(); + + /* Check cache. Note that we do this now, since the times operator might swap a and b (commutative) */ + if (cache_get3(CACHE_STORM_RATIONAL_FUNCTION_AND_EXISTS, a, b, v, &result)) return result; + + /* Now, v is not a constant, and either a or b is not a constant */ + + /* Get top variable */ + int la = mtbdd_isleaf(a); + int lb = mtbdd_isleaf(b); + mtbddnode_t na = la ? 0 : GETNODE(a); + mtbddnode_t nb = lb ? 0 : GETNODE(b); + uint32_t va = la ? 0xffffffff : mtbddnode_getvariable(na); + uint32_t vb = lb ? 0xffffffff : mtbddnode_getvariable(nb); + uint32_t var = va < vb ? va : vb; + + mtbddnode_t nv = GETNODE(v); + uint32_t vv = mtbddnode_getvariable(nv); + + if (vv < var) { + /* Recursive, then abstract result */ + result = CALL(sylvan_storm_rational_function_and_exists, a, b, node_gethigh(v, nv)); + mtbdd_refs_push(result); + result = mtbdd_apply(result, result, TASK(sylvan_storm_rational_function_op_plus)); + mtbdd_refs_pop(1); + } else { + /* Get cofactors */ + MTBDD alow, ahigh, blow, bhigh; + alow = (!la && va == var) ? node_getlow(a, na) : a; + ahigh = (!la && va == var) ? node_gethigh(a, na) : a; + blow = (!lb && vb == var) ? node_getlow(b, nb) : b; + bhigh = (!lb && vb == var) ? node_gethigh(b, nb) : b; + + if (vv == var) { + /* Recursive, then abstract result */ + mtbdd_refs_spawn(SPAWN(sylvan_storm_rational_function_and_exists, ahigh, bhigh, node_gethigh(v, nv))); + MTBDD low = mtbdd_refs_push(CALL(sylvan_storm_rational_function_and_exists, alow, blow, node_gethigh(v, nv))); + MTBDD high = mtbdd_refs_push(mtbdd_refs_sync(SYNC(sylvan_storm_rational_function_and_exists))); + result = CALL(mtbdd_apply, low, high, TASK(sylvan_storm_rational_function_op_plus)); + mtbdd_refs_pop(2); + } else /* vv > v */ { + /* Recursive, then create node */ + mtbdd_refs_spawn(SPAWN(sylvan_storm_rational_function_and_exists, ahigh, bhigh, v)); + MTBDD low = mtbdd_refs_push(CALL(sylvan_storm_rational_function_and_exists, alow, blow, v)); + MTBDD high = mtbdd_refs_sync(SYNC(sylvan_storm_rational_function_and_exists)); + mtbdd_refs_pop(1); + result = mtbdd_makenode(var, low, high); + } + } + + /* Store in cache */ + cache_put3(CACHE_STORM_RATIONAL_FUNCTION_AND_EXISTS, a, b, v, result); + return result; +} diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h index f6effbb66..8aec04f2b 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h @@ -92,6 +92,13 @@ TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_neg, MTBDD, size_t) */ #define sylvan_storm_rational_function_neg(a) mtbdd_uapply(a, TASK(sylvan_storm_rational_function_op_neg), 0); +/** + * Multiply and , and abstract variables using summation. + * This is similar to the "and_exists" operation in BDDs. + */ +TASK_DECL_3(MTBDD, sylvan_storm_rational_function_and_exists, MTBDD, MTBDD, MTBDD); +#define sylvan_storm_rational_function_and_exists(a, b, vars) CALL(sylvan_storm_rational_function_and_exists, a, b, vars) + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/test/functional/storage/SylvanDdTest.cpp b/test/functional/storage/SylvanDdTest.cpp index 8a5ca130e..695265a1d 100644 --- a/test/functional/storage/SylvanDdTest.cpp +++ b/test/functional/storage/SylvanDdTest.cpp @@ -11,6 +11,9 @@ #include "src/storage/SparseMatrix.h" +#include +#include + TEST(SylvanDd, Constants) { std::shared_ptr> manager(new storm::dd::DdManager()); storm::dd::Add zero; @@ -106,6 +109,40 @@ TEST(SylvanDd, RationalFunctionConstants) { EXPECT_EQ(0ul, two.getNonZeroCount()); EXPECT_EQ(1ul, two.getLeafCount()); EXPECT_EQ(1ul, two.getNodeCount()); + + // The cache that is used in case the underlying type needs a cache. + std::shared_ptr>> cache = std::make_shared>>(); + + storm::dd::Add function; + carl::Variable x = carl::freshRealVariable("x"); + carl::Variable y = carl::freshRealVariable("y"); + carl::Variable z = carl::freshRealVariable("z"); + + storm::RationalFunction constantOne(1); + + storm::RationalFunction variableX = storm::RationalFunction(typename storm::RationalFunction::PolyType(typename storm::RationalFunction::PolyType::PolyType(x), cache)); + storm::RationalFunction variableY = storm::RationalFunction(typename storm::RationalFunction::PolyType(typename storm::RationalFunction::PolyType::PolyType(y), cache)); + storm::RationalFunction variableZ = storm::RationalFunction(typename storm::RationalFunction::PolyType(typename storm::RationalFunction::PolyType::PolyType(z), cache)); + + storm::RationalFunction constantOneDivTwo(constantOne / constantTwo); + storm::RationalFunction tmpFunctionA(constantOneDivTwo); + tmpFunctionA *= variableZ; + tmpFunctionA /= variableY; + storm::RationalFunction tmpFunctionB(variableX); + tmpFunctionB *= variableY; + + + //storm::RationalFunction rationalFunction(two * x + x*y + constantOneDivTwo * z / y); + storm::RationalFunction rationalFunction(constantTwo); + rationalFunction *= variableX; + rationalFunction += tmpFunctionB; + rationalFunction += tmpFunctionA; + + ASSERT_NO_THROW(function = manager->template getConstant(rationalFunction)); + + EXPECT_EQ(0ul, function.getNonZeroCount()); + EXPECT_EQ(1ul, function.getLeafCount()); + EXPECT_EQ(1ul, function.getNodeCount()); } TEST(SylvanDd, RationalFunctionEncodingTest) { From 1d3bb3010df51ef883187a7e698e8811978a2804 Mon Sep 17 00:00:00 2001 From: PBerger Date: Sun, 7 Aug 2016 22:45:20 +0200 Subject: [PATCH 41/49] Fixed merge mistake in InternalSylvanDdManager.cpp Former-commit-id: 5919f2402eb7c0b77bb18e58a24d92f2a4f80289 --- src/storage/dd/sylvan/InternalSylvanDdManager.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp index 57fa7caa5..2c9fa88ae 100644 --- a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp +++ b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp @@ -125,12 +125,10 @@ namespace storm { return InternalAdd(this, sylvan::Mtbdd::stormRationalFunctionTerminal(value)); } #endif - + std::pair, InternalBdd> InternalDdManager::createNewDdVariablePair(boost::optional const& position) { STORM_LOG_THROW(!position, storm::exceptions::NotSupportedException, "The manager does not support ordered insertion."); - } - - std::pair, InternalBdd> InternalDdManager::createNewDdVariablePair() { + InternalBdd first = InternalBdd(this, sylvan::Bdd::bddVar(nextFreeVariableIndex)); InternalBdd second = InternalBdd(this, sylvan::Bdd::bddVar(nextFreeVariableIndex + 1)); nextFreeVariableIndex += 2; From 428d21cdeee78d5cbee44700abf3505fbdd5602c Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 8 Aug 2016 00:09:16 +0200 Subject: [PATCH 42/49] Made code compile with GCC: - Added cstdint for uint_fast64_t where necessary. - Moved and/or replaced includes for Expression headers, since std::pair required the concrete implementation and not only the stub. - Added newlines at the end of .cpp files. Former-commit-id: 72b57ce513ef589a6335eb8b0eef36655e4097ab --- src/abstraction/AbstractionDdInformation.cpp | 1 - src/abstraction/AbstractionDdInformation.h | 8 +++----- src/abstraction/AbstractionExpressionInformation.cpp | 2 +- src/abstraction/AbstractionExpressionInformation.h | 1 + src/abstraction/AbstractionInformation.cpp | 5 ++++- src/abstraction/AbstractionInformation.h | 1 + 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/abstraction/AbstractionDdInformation.cpp b/src/abstraction/AbstractionDdInformation.cpp index 598443df6..1014117a0 100644 --- a/src/abstraction/AbstractionDdInformation.cpp +++ b/src/abstraction/AbstractionDdInformation.cpp @@ -3,7 +3,6 @@ #include #include "src/storage/expressions/ExpressionManager.h" -#include "src/storage/expressions/Expression.h" #include "src/storage/dd/DdManager.h" #include "src/storage/dd/Bdd.h" diff --git a/src/abstraction/AbstractionDdInformation.h b/src/abstraction/AbstractionDdInformation.h index 0c6301936..0f9961bbd 100644 --- a/src/abstraction/AbstractionDdInformation.h +++ b/src/abstraction/AbstractionDdInformation.h @@ -5,8 +5,10 @@ #include #include #include +#include #include "src/storage/dd/DdType.h" +#include "src/storage/expressions/Expression.h" #include "src/storage/expressions/Variable.h" namespace storm { @@ -17,11 +19,7 @@ namespace storm { template class Bdd; } - - namespace expressions { - class Expression; - } - + namespace abstraction { template diff --git a/src/abstraction/AbstractionExpressionInformation.cpp b/src/abstraction/AbstractionExpressionInformation.cpp index f3ef47074..8a0ddd6f9 100644 --- a/src/abstraction/AbstractionExpressionInformation.cpp +++ b/src/abstraction/AbstractionExpressionInformation.cpp @@ -61,4 +61,4 @@ namespace storm { } } -} \ No newline at end of file +} diff --git a/src/abstraction/AbstractionExpressionInformation.h b/src/abstraction/AbstractionExpressionInformation.h index 97c3ec54e..f26958b2f 100644 --- a/src/abstraction/AbstractionExpressionInformation.h +++ b/src/abstraction/AbstractionExpressionInformation.h @@ -2,6 +2,7 @@ #include #include +#include namespace storm { namespace expressions { diff --git a/src/abstraction/AbstractionInformation.cpp b/src/abstraction/AbstractionInformation.cpp index 071f9150e..2a3aafe3a 100644 --- a/src/abstraction/AbstractionInformation.cpp +++ b/src/abstraction/AbstractionInformation.cpp @@ -1,5 +1,8 @@ #include "src/abstraction/AbstractionInformation.h" +#include "src/storage/expressions/Expression.h" +#include "src/storage/expressions/ExpressionManager.h" + namespace storm { namespace abstraction { @@ -74,4 +77,4 @@ namespace storm { template class AbstractionInformation; template class AbstractionInformation; } -} \ No newline at end of file +} diff --git a/src/abstraction/AbstractionInformation.h b/src/abstraction/AbstractionInformation.h index 6af6e7e17..3035853f1 100644 --- a/src/abstraction/AbstractionInformation.h +++ b/src/abstraction/AbstractionInformation.h @@ -2,6 +2,7 @@ #include #include +#include #include "src/storage/dd/DdType.h" From 4fff7b39efdba634bc66f19fea068117bf871065 Mon Sep 17 00:00:00 2001 From: PBerger Date: Tue, 9 Aug 2016 16:57:47 +0200 Subject: [PATCH 43/49] Added template instanziation for storm::RationalFunction. Added a test for Prism AbstractPrograms with storm::RationalFunction. Former-commit-id: 5a696149cbbe0fe53f35dda04acf30aaf10262fa --- .../sylvan/src/sylvan_obj_mtbdd_storm.hpp | 2 ++ .../3rdparty/sylvan/src/sylvan_obj_storm.cpp | 5 +++++ .../src/sylvan_storm_rational_function.h | 5 +++++ src/abstraction/MenuGame.cpp | 9 ++++++-- src/abstraction/MenuGameAbstractor.cpp | 2 +- src/abstraction/StateSetAbstractor.cpp | 6 ++++++ src/abstraction/prism/AbstractCommand.cpp | 10 +++++++-- src/abstraction/prism/AbstractModule.cpp | 8 ++++++- src/abstraction/prism/AbstractProgram.cpp | 11 +++++++--- src/adapters/AddExpressionAdapter.cpp | 7 ++++++- src/modelchecker/DFTAnalyser.h | 2 +- src/models/symbolic/Model.cpp | 7 ++++++- src/models/symbolic/NondeterministicModel.cpp | 7 ++++++- .../symbolic/StochasticTwoPlayerGame.cpp | 12 ++++++++--- src/storage/dd/sylvan/InternalSylvanAdd.cpp | 2 +- src/storage/dd/sylvan/InternalSylvanAdd.h | 5 ----- src/storage/dd/sylvan/InternalSylvanBdd.cpp | 7 +------ .../dd/sylvan/InternalSylvanDdManager.cpp | 4 ---- .../dd/sylvan/InternalSylvanDdManager.h | 7 +------ src/storage/dd/sylvan/SylvanAddIterator.cpp | 5 ----- .../abstraction/PrismMenuGameTest.cpp | 21 +++++++++++++++++++ 21 files changed, 101 insertions(+), 43 deletions(-) diff --git a/resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp b/resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp index 83a89f138..92dd1172c 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp @@ -28,6 +28,8 @@ * @brief Computes f / g for Rational Functions */ Mtbdd DivideRF(const Mtbdd &other) const; + + Mtbdd AbstractPlusRF(const BddSet &variables) const; #endif Bdd NotZero() const; diff --git a/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp b/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp index 837e906a2..d84f49281 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp @@ -46,6 +46,11 @@ Mtbdd::DivideRF(const Mtbdd &other) const return sylvan_storm_rational_function_divide(mtbdd, other.mtbdd); } +Mtbdd Mtbdd::AbstractPlusRF(const BddSet &variables) const { + LACE_ME; + return sylvan_storm_rational_function_abstract_plus(mtbdd, variables.set.bdd); +} + #endif Mtbdd diff --git a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h index 8aec04f2b..98a2fdffd 100644 --- a/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h +++ b/resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h @@ -99,6 +99,11 @@ TASK_DECL_2(MTBDD, sylvan_storm_rational_function_op_neg, MTBDD, size_t) TASK_DECL_3(MTBDD, sylvan_storm_rational_function_and_exists, MTBDD, MTBDD, MTBDD); #define sylvan_storm_rational_function_and_exists(a, b, vars) CALL(sylvan_storm_rational_function_and_exists, a, b, vars) +/** + * Abstract the variables in from by taking the sum of all values + */ +#define sylvan_storm_rational_function_abstract_plus(dd, v) mtbdd_abstract(dd, v, TASK(sylvan_storm_rational_function_abstract_op_plus)) + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/abstraction/MenuGame.cpp b/src/abstraction/MenuGame.cpp index 6e4420aa9..3702d8cda 100644 --- a/src/abstraction/MenuGame.cpp +++ b/src/abstraction/MenuGame.cpp @@ -8,6 +8,9 @@ #include "src/models/symbolic/StandardRewardModel.h" +#include "storm-config.h" +#include "src/adapters/CarlAdapter.h" + namespace storm { namespace abstraction { @@ -25,7 +28,7 @@ namespace storm { std::set const& player2Variables, std::set const& allNondeterminismVariables, std::set const& probabilisticBranchingVariables, - std::map> const& expressionToBddMap) : storm::models::symbolic::StochasticTwoPlayerGame(manager, reachableStates, initialStates, deadlockStates, transitionMatrix.sumAbstract(probabilisticBranchingVariables), rowVariables, nullptr, columnVariables, nullptr, rowColumnMetaVariablePairs, player1Variables, player2Variables, allNondeterminismVariables), probabilisticBranchingVariables(probabilisticBranchingVariables), expressionToBddMap(expressionToBddMap), bottomStates(bottomStates) { + std::map> const& expressionToBddMap) : storm::models::symbolic::StochasticTwoPlayerGame(manager, reachableStates, initialStates, deadlockStates, transitionMatrix.sumAbstract(probabilisticBranchingVariables), rowVariables, nullptr, columnVariables, nullptr, rowColumnMetaVariablePairs, player1Variables, player2Variables, allNondeterminismVariables), probabilisticBranchingVariables(probabilisticBranchingVariables), expressionToBddMap(expressionToBddMap), bottomStates(bottomStates) { // Intentionally left empty. } @@ -62,7 +65,9 @@ namespace storm { template class MenuGame; template class MenuGame; - +#ifdef STORM_HAVE_CARL + template class MenuGame; +#endif } } diff --git a/src/abstraction/MenuGameAbstractor.cpp b/src/abstraction/MenuGameAbstractor.cpp index dc9f1ceac..22fa866b3 100644 --- a/src/abstraction/MenuGameAbstractor.cpp +++ b/src/abstraction/MenuGameAbstractor.cpp @@ -1 +1 @@ -#include "src/abstraction/MenuGameAbstractor.h" \ No newline at end of file +#include "src/abstraction/MenuGameAbstractor.h" diff --git a/src/abstraction/StateSetAbstractor.cpp b/src/abstraction/StateSetAbstractor.cpp index e3d6b6949..098d68894 100644 --- a/src/abstraction/StateSetAbstractor.cpp +++ b/src/abstraction/StateSetAbstractor.cpp @@ -7,6 +7,9 @@ #include "src/utility/macros.h" #include "src/utility/solver.h" +#include "storm-config.h" +#include "src/adapters/CarlAdapter.h" + namespace storm { namespace abstraction { @@ -159,5 +162,8 @@ namespace storm { template class StateSetAbstractor; template class StateSetAbstractor; +#ifdef STORM_HAVE_CARL + template class StateSetAbstractor; +#endif } } diff --git a/src/abstraction/prism/AbstractCommand.cpp b/src/abstraction/prism/AbstractCommand.cpp index ca6a3a141..2e82f7c41 100644 --- a/src/abstraction/prism/AbstractCommand.cpp +++ b/src/abstraction/prism/AbstractCommand.cpp @@ -13,6 +13,9 @@ #include "src/utility/solver.h" #include "src/utility/macros.h" +#include "storm-config.h" +#include "src/adapters/CarlAdapter.h" + namespace storm { namespace abstraction { namespace prism { @@ -32,7 +35,7 @@ namespace storm { // Refine the command based on all initial predicates. std::vector allPredicateIndices(abstractionInformation.getNumberOfPredicates()); - for (auto index = 0; index < abstractionInformation.getNumberOfPredicates(); ++index) { + for (decltype(abstractionInformation.getNumberOfPredicates()) index = 0; index < abstractionInformation.getNumberOfPredicates(); ++index) { allPredicateIndices[index] = index; } this->refine(allPredicateIndices); @@ -313,6 +316,9 @@ namespace storm { template class AbstractCommand; template class AbstractCommand; +#ifdef STORM_HAVE_CARL + template class AbstractCommand; +#endif } } -} \ No newline at end of file +} diff --git a/src/abstraction/prism/AbstractModule.cpp b/src/abstraction/prism/AbstractModule.cpp index 3adcc9860..7bd8e0f97 100644 --- a/src/abstraction/prism/AbstractModule.cpp +++ b/src/abstraction/prism/AbstractModule.cpp @@ -7,6 +7,9 @@ #include "src/storage/prism/Module.h" +#include "storm-config.h" +#include "src/adapters/CarlAdapter.h" + namespace storm { namespace abstraction { namespace prism { @@ -62,6 +65,9 @@ namespace storm { template class AbstractModule; template class AbstractModule; +#ifdef STORM_HAVE_CARL + template class AbstractModule; +#endif } } -} \ No newline at end of file +} diff --git a/src/abstraction/prism/AbstractProgram.cpp b/src/abstraction/prism/AbstractProgram.cpp index 1eeeef9ad..f3d3eb219 100644 --- a/src/abstraction/prism/AbstractProgram.cpp +++ b/src/abstraction/prism/AbstractProgram.cpp @@ -12,6 +12,9 @@ #include "src/exceptions/WrongFormatException.h" #include "src/exceptions/InvalidArgumentException.h" +#include "storm-config.h" +#include "src/adapters/CarlAdapter.h" + namespace storm { namespace abstraction { namespace prism { @@ -160,7 +163,7 @@ namespace storm { } // Construct the transition matrix by cutting away the transitions of unreachable states. - storm::dd::Add transitionMatrix = (gameBdd.first && reachableStates).template toAdd() * commandUpdateProbabilitiesAdd + deadlockTransitions; + storm::dd::Add transitionMatrix = (gameBdd.first && reachableStates).template toAdd() * commandUpdateProbabilitiesAdd + deadlockTransitions; std::set usedPlayer2Variables(abstractionInformation.getPlayer2Variables().begin(), abstractionInformation.getPlayer2Variables().begin() + gameBdd.second); @@ -191,7 +194,9 @@ namespace storm { // Explicitly instantiate the class. template class AbstractProgram; template class AbstractProgram; - +#ifdef STORM_HAVE_CARL + template class AbstractProgram; +#endif } } -} \ No newline at end of file +} diff --git a/src/adapters/AddExpressionAdapter.cpp b/src/adapters/AddExpressionAdapter.cpp index e50620db8..682c26e7f 100644 --- a/src/adapters/AddExpressionAdapter.cpp +++ b/src/adapters/AddExpressionAdapter.cpp @@ -8,6 +8,9 @@ #include "src/storage/dd/Add.h" #include "src/storage/dd/Bdd.h" +#include "storm-config.h" +#include "src/adapters/CarlAdapter.h" + namespace storm { namespace adapters { @@ -201,6 +204,8 @@ namespace storm { // Explicitly instantiate the symbolic expression adapter template class AddExpressionAdapter; template class AddExpressionAdapter; - +#ifdef STORM_HAVE_CARL + template class AddExpressionAdapter; +#endif } // namespace adapters } // namespace storm diff --git a/src/modelchecker/DFTAnalyser.h b/src/modelchecker/DFTAnalyser.h index 24c1068ba..d822b036c 100644 --- a/src/modelchecker/DFTAnalyser.h +++ b/src/modelchecker/DFTAnalyser.h @@ -122,7 +122,7 @@ private: STORM_LOG_TRACE("Result for permutation:"<(1) << nrM) && permutation != 0); } if(invResults) { return storm::utility::one() - result; diff --git a/src/models/symbolic/Model.cpp b/src/models/symbolic/Model.cpp index 97c1537c4..d63c45743 100644 --- a/src/models/symbolic/Model.cpp +++ b/src/models/symbolic/Model.cpp @@ -13,6 +13,9 @@ #include "src/models/symbolic/StandardRewardModel.h" +#include "storm-config.h" +#include "src/adapters/CarlAdapter.h" + namespace storm { namespace models { namespace symbolic { @@ -243,7 +246,9 @@ namespace storm { // Explicitly instantiate the template class. template class Model; template class Model; - +#ifdef STORM_HAVE_CARL + template class Model; +#endif } // namespace symbolic } // namespace models } // namespace storm diff --git a/src/models/symbolic/NondeterministicModel.cpp b/src/models/symbolic/NondeterministicModel.cpp index da3607d02..53119fcab 100644 --- a/src/models/symbolic/NondeterministicModel.cpp +++ b/src/models/symbolic/NondeterministicModel.cpp @@ -6,6 +6,9 @@ #include "src/models/symbolic/StandardRewardModel.h" +#include "storm-config.h" +#include "src/adapters/CarlAdapter.h" + namespace storm { namespace models { namespace symbolic { @@ -76,7 +79,9 @@ namespace storm { // Explicitly instantiate the template class. template class NondeterministicModel; template class NondeterministicModel; - +#ifdef STORM_HAVE_CARL + template class NondeterministicModel; +#endif } // namespace symbolic } // namespace models } // namespace storm \ No newline at end of file diff --git a/src/models/symbolic/StochasticTwoPlayerGame.cpp b/src/models/symbolic/StochasticTwoPlayerGame.cpp index e945b85d6..6ee650314 100644 --- a/src/models/symbolic/StochasticTwoPlayerGame.cpp +++ b/src/models/symbolic/StochasticTwoPlayerGame.cpp @@ -6,6 +6,9 @@ #include "src/models/symbolic/StandardRewardModel.h" +#include "storm-config.h" +#include "src/adapters/CarlAdapter.h" + namespace storm { namespace models { namespace symbolic { @@ -60,9 +63,12 @@ namespace storm { } // Explicitly instantiate the template class. - template class StochasticTwoPlayerGame; - template class StochasticTwoPlayerGame; + template class StochasticTwoPlayerGame; + template class StochasticTwoPlayerGame; +#ifdef STORM_HAVE_CARL + template class StochasticTwoPlayerGame; +#endif } // namespace symbolic } // namespace models -} // namespace storm \ No newline at end of file +} // namespace storm diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.cpp b/src/storage/dd/sylvan/InternalSylvanAdd.cpp index ad75e2048..af7832945 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanAdd.cpp @@ -297,7 +297,7 @@ namespace storm { #ifdef STORM_HAVE_CARL template<> InternalAdd InternalAdd::sumAbstract(InternalBdd const& cube) const { - STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented: sumAbstract"); + return InternalAdd(ddManager, this->sylvanMtbdd.AbstractPlusRF(cube.sylvanBdd)); } #endif diff --git a/src/storage/dd/sylvan/InternalSylvanAdd.h b/src/storage/dd/sylvan/InternalSylvanAdd.h index 21d5259b8..b073af6cb 100644 --- a/src/storage/dd/sylvan/InternalSylvanAdd.h +++ b/src/storage/dd/sylvan/InternalSylvanAdd.h @@ -14,12 +14,7 @@ #include "src/storage/expressions/Variable.h" #include "src/adapters/CarlAdapter.h" - #include "storm-config.h" -// TODO: Remove this later on. -#ifndef STORM_HAVE_CARL -#define STORM_HAVE_CARL 1 -#endif namespace storm { namespace storage { diff --git a/src/storage/dd/sylvan/InternalSylvanBdd.cpp b/src/storage/dd/sylvan/InternalSylvanBdd.cpp index a157dc410..ac4e1180e 100644 --- a/src/storage/dd/sylvan/InternalSylvanBdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanBdd.cpp @@ -14,12 +14,7 @@ #include "src/exceptions/NotSupportedException.h" #include "src/adapters/CarlAdapter.h" - #include "storm-config.h" -// TODO: Remove this later on. -#ifndef STORM_HAVE_CARL -#define STORM_HAVE_CARL 1 -#endif namespace storm { namespace dd { @@ -503,4 +498,4 @@ namespace storm { template InternalAdd InternalBdd::ite(InternalAdd const& thenAdd, InternalAdd const& elseAdd) const; template InternalAdd InternalBdd::ite(InternalAdd const& thenAdd, InternalAdd const& elseAdd) const; } -} \ No newline at end of file +} diff --git a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp index 2c9fa88ae..ee795d08b 100644 --- a/src/storage/dd/sylvan/InternalSylvanDdManager.cpp +++ b/src/storage/dd/sylvan/InternalSylvanDdManager.cpp @@ -13,10 +13,6 @@ #include "src/utility/sylvan.h" #include "storm-config.h" -// TODO: Remove this later on. -#ifndef STORM_HAVE_CARL -#define STORM_HAVE_CARL 1 -#endif namespace storm { namespace dd { diff --git a/src/storage/dd/sylvan/InternalSylvanDdManager.h b/src/storage/dd/sylvan/InternalSylvanDdManager.h index 374b35d8d..7919bd103 100644 --- a/src/storage/dd/sylvan/InternalSylvanDdManager.h +++ b/src/storage/dd/sylvan/InternalSylvanDdManager.h @@ -10,12 +10,7 @@ #include "src/storage/dd/sylvan/InternalSylvanAdd.h" #include "src/adapters/CarlAdapter.h" - #include "storm-config.h" -// TODO: Remove this later on. -#ifndef STORM_HAVE_CARL -#define STORM_HAVE_CARL 1 -#endif namespace storm { namespace dd { @@ -170,4 +165,4 @@ namespace storm { } } -#endif /* STORM_STORAGE_DD_SYLVAN_INTERNALSYLVANDDMANAGER_H_ */ \ No newline at end of file +#endif /* STORM_STORAGE_DD_SYLVAN_INTERNALSYLVANDDMANAGER_H_ */ diff --git a/src/storage/dd/sylvan/SylvanAddIterator.cpp b/src/storage/dd/sylvan/SylvanAddIterator.cpp index d4efc2fcb..827d2937c 100644 --- a/src/storage/dd/sylvan/SylvanAddIterator.cpp +++ b/src/storage/dd/sylvan/SylvanAddIterator.cpp @@ -11,12 +11,7 @@ #include #include "src/adapters/CarlAdapter.h" - #include "storm-config.h" -// TODO: Remove this later on. -#ifndef STORM_HAVE_CARL -#define STORM_HAVE_CARL 1 -#endif namespace storm { namespace dd { diff --git a/test/functional/abstraction/PrismMenuGameTest.cpp b/test/functional/abstraction/PrismMenuGameTest.cpp index 148bd6f25..70624a1ff 100644 --- a/test/functional/abstraction/PrismMenuGameTest.cpp +++ b/test/functional/abstraction/PrismMenuGameTest.cpp @@ -16,6 +16,8 @@ #include "src/utility/solver.h" +#include "src/adapters/CarlAdapter.h" + TEST(PrismMenuGame, DieAbstractionTest_Cudd) { storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/die.pm"); @@ -50,6 +52,25 @@ TEST(PrismMenuGame, DieAbstractionTest_Sylvan) { EXPECT_EQ(0, game.getBottomStates().getNonZeroCount()); } +#ifdef STORM_HAVE_CARL +TEST(PrismMenuGame, DieAbstractionTest_SylvanWithRationalFunction) { + storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/die.pm"); + + std::vector initialPredicates; + storm::expressions::ExpressionManager& manager = program.getManager(); + + initialPredicates.push_back(manager.getVariableExpression("s") < manager.integer(3)); + + storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + + storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); + + EXPECT_EQ(10, game.getNumberOfTransitions()); + EXPECT_EQ(2, game.getNumberOfStates()); + EXPECT_EQ(0, game.getBottomStates().getNonZeroCount()); +} +#endif + TEST(PrismMenuGame, DieAbstractionAndRefinementTest_Cudd) { storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/die.pm"); From 81311690abfb49ab3d379cdf8fcb5de1485ade00 Mon Sep 17 00:00:00 2001 From: PBerger Date: Tue, 9 Aug 2016 18:28:41 +0200 Subject: [PATCH 44/49] Fixed errors because of changed API. Former-commit-id: 7f771dc576e939cd9df17f9bd760507d6afad1f2 --- .../abstraction/PrismMenuGameTest.cpp | 52 +++++++++---------- test/functional/storage/PrismProgramTest.cpp | 4 +- test/functional/utility/GraphTest.cpp | 8 +-- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/test/functional/abstraction/PrismMenuGameTest.cpp b/test/functional/abstraction/PrismMenuGameTest.cpp index 70624a1ff..038ea6eb8 100644 --- a/test/functional/abstraction/PrismMenuGameTest.cpp +++ b/test/functional/abstraction/PrismMenuGameTest.cpp @@ -26,7 +26,7 @@ TEST(PrismMenuGame, DieAbstractionTest_Cudd) { initialPredicates.push_back(manager.getVariableExpression("s") < manager.integer(3)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -43,7 +43,7 @@ TEST(PrismMenuGame, DieAbstractionTest_Sylvan) { initialPredicates.push_back(manager.getVariableExpression("s") < manager.integer(3)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -61,7 +61,7 @@ TEST(PrismMenuGame, DieAbstractionTest_SylvanWithRationalFunction) { initialPredicates.push_back(manager.getVariableExpression("s") < manager.integer(3)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -79,7 +79,7 @@ TEST(PrismMenuGame, DieAbstractionAndRefinementTest_Cudd) { initialPredicates.push_back(manager.getVariableExpression("s") < manager.integer(3)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); ASSERT_NO_THROW(abstractProgram.refine({manager.getVariableExpression("s") == manager.integer(7)})); @@ -98,7 +98,7 @@ TEST(PrismMenuGame, DieAbstractionAndRefinementTest_Sylvan) { initialPredicates.push_back(manager.getVariableExpression("s") < manager.integer(3)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); ASSERT_NO_THROW(abstractProgram.refine({manager.getVariableExpression("s") == manager.integer(7)})); @@ -132,7 +132,7 @@ TEST(PrismMenuGame, DieFullAbstractionTest_Cudd) { initialPredicates.push_back(manager.getVariableExpression("d") == manager.integer(5)); initialPredicates.push_back(manager.getVariableExpression("d") == manager.integer(6)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -164,7 +164,7 @@ TEST(PrismMenuGame, DieFullAbstractionTest_Sylvan) { initialPredicates.push_back(manager.getVariableExpression("d") == manager.integer(5)); initialPredicates.push_back(manager.getVariableExpression("d") == manager.integer(6)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -182,7 +182,7 @@ TEST(PrismMenuGame, CrowdsAbstractionTest_Cudd) { initialPredicates.push_back(manager.getVariableExpression("phase") < manager.integer(3)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -200,7 +200,7 @@ TEST(PrismMenuGame, CrowdsAbstractionTest_Sylvan) { initialPredicates.push_back(manager.getVariableExpression("phase") < manager.integer(3)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -218,7 +218,7 @@ TEST(PrismMenuGame, CrowdsAbstractionAndRefinementTest_Cudd) { initialPredicates.push_back(manager.getVariableExpression("phase") < manager.integer(3)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); ASSERT_NO_THROW(abstractProgram.refine({manager.getVariableExpression("observe0") + manager.getVariableExpression("observe1") + manager.getVariableExpression("observe2") + manager.getVariableExpression("observe3") + manager.getVariableExpression("observe4") <= manager.getVariableExpression("runCount")})); @@ -238,7 +238,7 @@ TEST(PrismMenuGame, CrowdsAbstractionAndRefinementTest_Sylvan) { initialPredicates.push_back(manager.getVariableExpression("phase") < manager.integer(3)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); ASSERT_NO_THROW(abstractProgram.refine({manager.getVariableExpression("observe0") + manager.getVariableExpression("observe1") + manager.getVariableExpression("observe2") + manager.getVariableExpression("observe3") + manager.getVariableExpression("observe4") <= manager.getVariableExpression("runCount")})); @@ -312,7 +312,7 @@ TEST(PrismMenuGame, CrowdsFullAbstractionTest_Cudd) { initialPredicates.push_back(manager.getVariableExpression("lastSeen") == manager.integer(3)); initialPredicates.push_back(manager.getVariableExpression("lastSeen") == manager.integer(4)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -384,7 +384,7 @@ TEST(PrismMenuGame, CrowdsFullAbstractionTest_Sylvan) { initialPredicates.push_back(manager.getVariableExpression("lastSeen") == manager.integer(3)); initialPredicates.push_back(manager.getVariableExpression("lastSeen") == manager.integer(4)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -404,7 +404,7 @@ TEST(PrismMenuGame, TwoDiceAbstractionTest_Cudd) { initialPredicates.push_back(manager.getVariableExpression("s1") < manager.integer(3)); initialPredicates.push_back(manager.getVariableExpression("s2") == manager.integer(0)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -424,7 +424,7 @@ TEST(PrismMenuGame, TwoDiceAbstractionTest_Sylvan) { initialPredicates.push_back(manager.getVariableExpression("s1") < manager.integer(3)); initialPredicates.push_back(manager.getVariableExpression("s2") == manager.integer(0)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -444,7 +444,7 @@ TEST(PrismMenuGame, TwoDiceAbstractionAndRefinementTest_Cudd) { initialPredicates.push_back(manager.getVariableExpression("s1") < manager.integer(3)); initialPredicates.push_back(manager.getVariableExpression("s2") == manager.integer(0)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); ASSERT_NO_THROW(abstractProgram.refine({manager.getVariableExpression("d1") + manager.getVariableExpression("d2") == manager.integer(7)})); @@ -466,7 +466,7 @@ TEST(PrismMenuGame, TwoDiceAbstractionAndRefinementTest_Sylvan) { initialPredicates.push_back(manager.getVariableExpression("s1") < manager.integer(3)); initialPredicates.push_back(manager.getVariableExpression("s2") == manager.integer(0)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); ASSERT_NO_THROW(abstractProgram.refine({manager.getVariableExpression("d1") + manager.getVariableExpression("d2") == manager.integer(7)})); @@ -519,7 +519,7 @@ TEST(PrismMenuGame, TwoDiceFullAbstractionTest_Cudd) { initialPredicates.push_back(manager.getVariableExpression("d2") == manager.integer(5)); initialPredicates.push_back(manager.getVariableExpression("d2") == manager.integer(6)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -570,7 +570,7 @@ TEST(PrismMenuGame, TwoDiceFullAbstractionTest_Sylvan) { initialPredicates.push_back(manager.getVariableExpression("d2") == manager.integer(5)); initialPredicates.push_back(manager.getVariableExpression("d2") == manager.integer(6)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -591,7 +591,7 @@ TEST(PrismMenuGame, WlanAbstractionTest_Cudd) { initialPredicates.push_back(manager.getVariableExpression("bc1") == manager.integer(0)); initialPredicates.push_back(manager.getVariableExpression("c1") == manager.getVariableExpression("c2")); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -612,7 +612,7 @@ TEST(PrismMenuGame, WlanAbstractionTest_Sylvan) { initialPredicates.push_back(manager.getVariableExpression("bc1") == manager.integer(0)); initialPredicates.push_back(manager.getVariableExpression("c1") == manager.getVariableExpression("c2")); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -633,7 +633,7 @@ TEST(PrismMenuGame, WlanAbstractionAndRefinementTest_Cudd) { initialPredicates.push_back(manager.getVariableExpression("bc1") == manager.integer(0)); initialPredicates.push_back(manager.getVariableExpression("c1") == manager.getVariableExpression("c2")); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); ASSERT_NO_THROW(abstractProgram.refine({manager.getVariableExpression("backoff1") < manager.integer(7)})); @@ -656,7 +656,7 @@ TEST(PrismMenuGame, WlanAbstractionAndRefinementTest_Sylvan) { initialPredicates.push_back(manager.getVariableExpression("bc1") == manager.integer(0)); initialPredicates.push_back(manager.getVariableExpression("c1") == manager.getVariableExpression("c2")); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); ASSERT_NO_THROW(abstractProgram.refine({manager.getVariableExpression("backoff1") < manager.integer(7)})); @@ -777,7 +777,7 @@ TEST(PrismMenuGame, WlanFullAbstractionTest_Cudd) { initialPredicates.push_back(manager.getVariableExpression("bc2") == manager.integer(0)); initialPredicates.push_back(manager.getVariableExpression("bc2") == manager.integer(1)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -896,7 +896,7 @@ TEST(PrismMenuGame, WlanFullAbstractionTest_Sylvan) { initialPredicates.push_back(manager.getVariableExpression("bc2") == manager.integer(0)); initialPredicates.push_back(manager.getVariableExpression("bc2") == manager.integer(1)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -905,4 +905,4 @@ TEST(PrismMenuGame, WlanFullAbstractionTest_Sylvan) { EXPECT_EQ(0, game.getBottomStates().getNonZeroCount()); } -#endif \ No newline at end of file +#endif diff --git a/test/functional/storage/PrismProgramTest.cpp b/test/functional/storage/PrismProgramTest.cpp index 1ae7c4f32..281d981c0 100644 --- a/test/functional/storage/PrismProgramTest.cpp +++ b/test/functional/storage/PrismProgramTest.cpp @@ -11,7 +11,7 @@ TEST(PrismProgramTest, FlattenModules) { storm::prism::Program result; ASSERT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/leader3.nm")); - std::unique_ptr smtSolverFactory(new storm::utility::solver::MathsatSmtSolverFactory()); + std::shared_ptr smtSolverFactory(new storm::utility::solver::MathsatSmtSolverFactory()); ASSERT_NO_THROW(result = result.flattenModules(smtSolverFactory)); EXPECT_EQ(1, result.getNumberOfModules()); @@ -46,4 +46,4 @@ TEST(PrismProgramTest, ConvertToJani) { ASSERT_NO_THROW(prismProgram = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/nand-5-2.pm")); ASSERT_NO_THROW(janiModel = prismProgram.toJani()); -} \ No newline at end of file +} diff --git a/test/functional/utility/GraphTest.cpp b/test/functional/utility/GraphTest.cpp index 8f88c696a..62c52b0f9 100644 --- a/test/functional/utility/GraphTest.cpp +++ b/test/functional/utility/GraphTest.cpp @@ -207,7 +207,7 @@ TEST(GraphTest, SymbolicProb01StochasticGameDieSmall) { initialPredicates.push_back(manager.getVariableExpression("s") < manager.integer(3)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -343,7 +343,7 @@ TEST(GraphTest, SymbolicProb01StochasticGameTwoDice) { initialPredicates.push_back(manager.getVariableExpression("d2") == manager.integer(5)); initialPredicates.push_back(manager.getVariableExpression("d2") == manager.integer(6)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -512,7 +512,7 @@ TEST(GraphTest, SymbolicProb01StochasticGameWlan) { initialPredicates.push_back(manager.getVariableExpression("bc2") == manager.integer(0)); initialPredicates.push_back(manager.getVariableExpression("bc2") == manager.integer(1)); - storm::abstraction::prism::AbstractProgram abstractProgram(program.getManager(), program, initialPredicates, std::make_unique(), false); + storm::abstraction::prism::AbstractProgram abstractProgram(program, initialPredicates, std::make_shared(), false); storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); @@ -644,4 +644,4 @@ TEST(GraphTest, ExplicitProb01MinMax) { ASSERT_NO_THROW(statesWithProbability01 = storm::utility::graph::performProb01Max(*model->as>(), storm::storage::BitVector(model->getNumberOfStates(), true), model->getStates("collision_max_backoff"))); EXPECT_EQ(993ul, statesWithProbability01.first.getNumberOfSetBits()); EXPECT_EQ(16ul, statesWithProbability01.second.getNumberOfSetBits()); -} \ No newline at end of file +} From be7353358fc75e0690ba551250fcc335ea0d531a Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 15 Aug 2016 02:38:18 +0200 Subject: [PATCH 45/49] Added Test for constants in Cudd/Sylvan. Added functionality for existsAbstractRepresentative in Sylvan. Still very broken! Former-commit-id: df2b36a8d8bc433b8557757fe9a22c91436d5fbe --- resources/3rdparty/sylvan/src/sylvan_bdd.c | 2 + .../3rdparty/sylvan/src/sylvan_bdd_storm.c | 152 ++++++++++++++++++ .../3rdparty/sylvan/src/sylvan_bdd_storm.h | 5 +- .../sylvan/src/sylvan_obj_bdd_storm.hpp | 1 + .../3rdparty/sylvan/src/sylvan_obj_storm.cpp | 6 + src/storage/dd/sylvan/InternalSylvanBdd.cpp | 2 +- test/functional/storage/CuddDdTest.cpp | 51 +++++- test/functional/storage/SylvanDdTest.cpp | 48 ++++++ 8 files changed, 264 insertions(+), 3 deletions(-) create mode 100644 resources/3rdparty/sylvan/src/sylvan_bdd_storm.c diff --git a/resources/3rdparty/sylvan/src/sylvan_bdd.c b/resources/3rdparty/sylvan/src/sylvan_bdd.c index 74936a62d..6b6b3f74f 100644 --- a/resources/3rdparty/sylvan/src/sylvan_bdd.c +++ b/resources/3rdparty/sylvan/src/sylvan_bdd.c @@ -2818,3 +2818,5 @@ TASK_IMPL_1(int, sylvan_test_isbdd, BDD, bdd) if (!SYNC(sylvan_test_isbdd_rec)) result = 0; return result; } + +#include "sylvan_bdd_storm.c" diff --git a/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c b/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c new file mode 100644 index 000000000..c3226c947 --- /dev/null +++ b/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c @@ -0,0 +1,152 @@ +/* */ + +/** + * Calculates \exists variables . a + */ +TASK_IMPL_3(BDD, sylvan_existsRepresentative, BDD, a, BDD, variables, BDDVAR, prev_level) +{ + int aIsNegated = (a & sylvan_complement) == ((uint64_t)0) ? 0 : 1; + + BDD aRegular = (aIsNegated) ? sylvan_not(a) : a; + + if (aRegular == sylvan_false) { + if (aIsNegated) { + //printf("return in preprocessing...1\n"); + return a; + } + + if (sylvan_set_isempty(variables)) { + //printf("return in preprocessing...2\n"); + return sylvan_true; + } else { + //printf("return in preprocessing...3\n"); + return variables; + } + } else if (sylvan_set_isempty(variables)) { + //printf("return in preprocessing...4\n"); + return a; + } + /* From now on, f and cube are non-constant. */ + bddnode_t na = GETNODE(a); + BDDVAR level = bddnode_getvariable(na); + + bddnode_t nv = GETNODE(variables); + BDDVAR vv = bddnode_getvariable(nv); + + //printf("a level %i and cube level %i\n", level, vv); + + /* Abstract a variable that does not appear in f. */ + if (level > vv) { + BDD _v = sylvan_set_next(variables); + BDD res = CALL(sylvan_existsRepresentative, a, _v, level); + if (res == sylvan_invalid) { + return sylvan_invalid; + } + bdd_refs_push(res); + + BDD res1 = sylvan_makenode(vv, sylvan_false, res); + + if (res1 == sylvan_invalid) { + bdd_refs_pop(1); + return sylvan_invalid; + } + bdd_refs_pop(1); + + //printf("return after abstr. var that does not appear in f...\n"); + return res1; + } + + /* Compute the cofactors of a. */ + BDD aLow = node_low(a, na); // ELSE + BDD aHigh = node_high(a, na); // THEN + + /* If the two indices are the same, so are their levels. */ + if (level == vv) { + BDD _v = sylvan_set_next(variables); + BDD res1 = CALL(sylvan_existsRepresentative, aLow, _v, level); + if (res1 == sylvan_invalid) { + return sylvan_invalid; + } + if (res1 == sylvan_true) { + return sylvan_true; + } + bdd_refs_push(res1); + + BDD res2 = CALL(sylvan_existsRepresentative, aHigh, _v, level); + if (res2 == sylvan_invalid) { + bdd_refs_pop(1); + return sylvan_invalid; + } + bdd_refs_push(res2); + + BDD left = CALL(sylvan_exists, aLow, _v, 0); + if (left == sylvan_invalid) { + bdd_refs_pop(2); + return sylvan_invalid; + } + + bdd_refs_push(left); + + BDD res1Inf = sylvan_ite(left, res1, sylvan_false); + if (res1Inf == sylvan_invalid) { + bdd_refs_pop(3); + return sylvan_invalid; + } + bdd_refs_push(res1Inf); + + //Cudd_IterDerefBdd(manager,res1); + + BDD res2Inf = sylvan_ite(left, sylvan_false, res2); + if (res2Inf == sylvan_invalid) { + bdd_refs_pop(4); + return sylvan_invalid; + } + bdd_refs_push(res2Inf); + + //Cudd_IterDerefBdd(manager,res2); + //Cudd_IterDerefBdd(manager,left); + + assert(res1Inf != res2Inf); + BDD res = sylvan_makenode(level, res2Inf, res1Inf); + + if (res == sylvan_invalid) { + bdd_refs_pop(5); + return sylvan_invalid; + } + + // cuddCacheInsert2(manager, Cudd_bddExistAbstractRepresentative, f, cube, res); + // TODO: CACHING HERE + + //printf("return properly computed result...\n"); + bdd_refs_pop(5); + return res; + } else { /* if (level == vv) */ + BDD res1 = CALL(sylvan_existsRepresentative, aLow, variables, level); + if (res1 == sylvan_invalid){ + return sylvan_invalid; + } + bdd_refs_push(res1); + + BDD res2 = CALL(sylvan_existsRepresentative, aHigh, variables, level); + if (res2 == sylvan_invalid) { + bdd_refs_pop(1); + return sylvan_invalid; + } + bdd_refs_push(res2); + + /* ITE takes care of possible complementation of res1 and of the + ** case in which res1 == res2. */ + BDD res = sylvan_makenode(level, res2, res1); + if (res == sylvan_invalid) { + bdd_refs_pop(2); + return sylvan_invalid; + } + + bdd_refs_pop(2); + //printf("return of last case...\n"); + return res; + } + + // Prevent unused variable warning + (void)prev_level; +} diff --git a/resources/3rdparty/sylvan/src/sylvan_bdd_storm.h b/resources/3rdparty/sylvan/src/sylvan_bdd_storm.h index 5806fba5d..f28259a84 100644 --- a/resources/3rdparty/sylvan/src/sylvan_bdd_storm.h +++ b/resources/3rdparty/sylvan/src/sylvan_bdd_storm.h @@ -1,3 +1,6 @@ #define bdd_isnegated(dd) ((dd & sylvan_complement) ? 1 : 0) #define bdd_regular(dd) (dd & ~sylvan_complement) -#define bdd_isterminal(dd) (dd == sylvan_false || dd == sylvan_true) \ No newline at end of file +#define bdd_isterminal(dd) (dd == sylvan_false || dd == sylvan_true) + +TASK_DECL_3(BDD, sylvan_existsRepresentative, BDD, BDD, BDDVAR); +#define sylvan_existsRepresentative(a, vars) (CALL(sylvan_existsRepresentative, a, vars, 0)) diff --git a/resources/3rdparty/sylvan/src/sylvan_obj_bdd_storm.hpp b/resources/3rdparty/sylvan/src/sylvan_obj_bdd_storm.hpp index 172bcf5c6..afcc027e6 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj_bdd_storm.hpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj_bdd_storm.hpp @@ -4,3 +4,4 @@ Mtbdd toStormRationalFunctionMtbdd() const; #endif Mtbdd Ite(Mtbdd const& thenDd, Mtbdd const& elseDd) const; + Bdd ExistAbstractRepresentative(const BddSet& cube) const; diff --git a/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp b/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp index d84f49281..e055478f3 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp @@ -1,3 +1,9 @@ +Bdd +Bdd::ExistAbstractRepresentative(const BddSet& cube) const { + LACE_ME; + return sylvan_existsRepresentative(bdd, cube.set.bdd); +} + Mtbdd Bdd::toDoubleMtbdd() const { LACE_ME; diff --git a/src/storage/dd/sylvan/InternalSylvanBdd.cpp b/src/storage/dd/sylvan/InternalSylvanBdd.cpp index ac4e1180e..c173a1e51 100644 --- a/src/storage/dd/sylvan/InternalSylvanBdd.cpp +++ b/src/storage/dd/sylvan/InternalSylvanBdd.cpp @@ -161,7 +161,7 @@ namespace storm { } InternalBdd InternalBdd::existsAbstractRepresentative(InternalBdd const& cube) const { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "This operation is currently not supported by sylvan."); + return InternalBdd(ddManager, this->sylvanBdd.ExistAbstractRepresentative(cube.sylvanBdd)); } InternalBdd InternalBdd::universalAbstract(InternalBdd const& cube) const { diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp index 695d247e2..b05edcaf7 100644 --- a/test/functional/storage/CuddDdTest.cpp +++ b/test/functional/storage/CuddDdTest.cpp @@ -11,7 +11,7 @@ #include "src/storage/SparseMatrix.h" -TEST(CuddDd, Constants) { +TEST(CuddDd, AddConstants) { std::shared_ptr> manager(new storm::dd::DdManager()); storm::dd::Add zero; ASSERT_NO_THROW(zero = manager->template getAddZero()); @@ -41,6 +41,55 @@ TEST(CuddDd, Constants) { EXPECT_EQ(2, two.getMax()); } +TEST(CuddDd, BddConstants) { + std::shared_ptr> manager(new storm::dd::DdManager()); + storm::dd::Bdd zero; + ASSERT_NO_THROW(zero = manager->getBddZero()); + + EXPECT_EQ(0ul, zero.getNonZeroCount()); + EXPECT_EQ(1ul, zero.getLeafCount()); + EXPECT_EQ(1ul, zero.getNodeCount()); + + storm::dd::Bdd one; + ASSERT_NO_THROW(one = manager->getBddOne()); + + EXPECT_EQ(0ul, one.getNonZeroCount()); + EXPECT_EQ(1ul, one.getLeafCount()); + EXPECT_EQ(1ul, one.getNodeCount()); +} + +TEST(CuddDd, BddExistAbstractRepresentative) { + std::shared_ptr> manager(new storm::dd::DdManager()); + std::pair x; + std::pair y; + std::pair z; + ASSERT_NO_THROW(x = manager->addMetaVariable("x", 0, 1)); + ASSERT_NO_THROW(y = manager->addMetaVariable("y", 0, 1)); + ASSERT_NO_THROW(z = manager->addMetaVariable("z", 0, 1)); + + storm::dd::Bdd bddX = manager->getEncoding(x.first, 1); + //bddX.exportToDot("/opt/masterThesis/storm/build/test_bdd_x.dot"); + storm::dd::Bdd bddY = manager->getEncoding(y.first, 0); + //bddY.exportToDot("/opt/masterThesis/storm/build/test_bdd_y.dot"); + storm::dd::Bdd bddZ = manager->getEncoding(z.first, 0); + //bddZ.exportToDot("/opt/masterThesis/storm/build/test_bdd_z.dot"); + + storm::dd::Bdd bddX1Y0Z0 = (bddX && bddY) && bddZ; + //bddX1Y0Z0.exportToDot("/opt/masterThesis/storm/build/test_bddX1Y0Z0.dot"); + + EXPECT_EQ(1ul, bddX1Y0Z0.getNonZeroCount()); + EXPECT_EQ(1ul, bddX1Y0Z0.getLeafCount()); + EXPECT_EQ(4ul, bddX1Y0Z0.getNodeCount()); + + storm::dd::Bdd representative_x = bddX1Y0Z0.existsAbstractRepresentative({x.first}); + //representative_x.exportToDot("/opt/masterThesis/storm/build/test_representative_x.dot"); + storm::dd::Bdd representative_y = bddX1Y0Z0.existsAbstractRepresentative({y.first}); + //representative_y.exportToDot("/opt/masterThesis/storm/build/test_representative_y.dot"); + storm::dd::Bdd representative_z = bddX1Y0Z0.existsAbstractRepresentative({z.first}); + //representative_z.exportToDot("/opt/masterThesis/storm/build/test_representative_z.dot"); +} + + TEST(CuddDd, AddGetMetaVariableTest) { std::shared_ptr> manager(new storm::dd::DdManager()); ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9)); diff --git a/test/functional/storage/SylvanDdTest.cpp b/test/functional/storage/SylvanDdTest.cpp index 133643744..6695d34f7 100644 --- a/test/functional/storage/SylvanDdTest.cpp +++ b/test/functional/storage/SylvanDdTest.cpp @@ -44,6 +44,54 @@ TEST(SylvanDd, Constants) { EXPECT_EQ(2, two.getMax()); } +TEST(SylvanDd, BddConstants) { + std::shared_ptr> manager(new storm::dd::DdManager()); + storm::dd::Bdd zero; + ASSERT_NO_THROW(zero = manager->getBddZero()); + + EXPECT_EQ(0ul, zero.getNonZeroCount()); + EXPECT_EQ(1ul, zero.getLeafCount()); + EXPECT_EQ(1ul, zero.getNodeCount()); + + storm::dd::Bdd one; + ASSERT_NO_THROW(one = manager->getBddOne()); + + EXPECT_EQ(0ul, one.getNonZeroCount()); + EXPECT_EQ(1ul, one.getLeafCount()); + EXPECT_EQ(1ul, one.getNodeCount()); +} + +TEST(SylvanDd, BddExistAbstractRepresentative) { + std::shared_ptr> manager(new storm::dd::DdManager()); + std::pair x; + std::pair y; + std::pair z; + ASSERT_NO_THROW(x = manager->addMetaVariable("x", 0, 1)); + ASSERT_NO_THROW(y = manager->addMetaVariable("y", 0, 1)); + ASSERT_NO_THROW(z = manager->addMetaVariable("z", 0, 1)); + + storm::dd::Bdd bddX = manager->getEncoding(x.first, 1); + //bddX.exportToDot("/opt/masterThesis/storm/build/tests_bdd_x.dot"); + storm::dd::Bdd bddY = manager->getEncoding(y.first, 0); + //bddY.exportToDot("/opt/masterThesis/storm/build/tests_bdd_y.dot"); + storm::dd::Bdd bddZ = manager->getEncoding(z.first, 0); + //bddZ.exportToDot("/opt/masterThesis/storm/build/tests_bdd_z.dot"); + + storm::dd::Bdd bddX1Y0Z0 = (bddX && bddY) && bddZ; + //bddX1Y0Z0.exportToDot("/opt/masterThesis/storm/build/tests_bddX1Y0Z0.dot"); + + EXPECT_EQ(1ul, bddX1Y0Z0.getNonZeroCount()); + EXPECT_EQ(1ul, bddX1Y0Z0.getLeafCount()); + EXPECT_EQ(4ul, bddX1Y0Z0.getNodeCount()); + + storm::dd::Bdd representative_x = bddX1Y0Z0.existsAbstractRepresentative({x.first}); + //representative_x.exportToDot("/opt/masterThesis/storm/build/tests_representative_x.dot"); + storm::dd::Bdd representative_y = bddX1Y0Z0.existsAbstractRepresentative({y.first}); + //representative_y.exportToDot("/opt/masterThesis/storm/build/tests_representative_y.dot"); + storm::dd::Bdd representative_z = bddX1Y0Z0.existsAbstractRepresentative({z.first}); + //representative_z.exportToDot("/opt/masterThesis/storm/build/tests_representative_z.dot"); +} + TEST(SylvanDd, AddGetMetaVariableTest) { std::shared_ptr> manager(new storm::dd::DdManager()); ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9)); From e45b3d2940205d08d18537c1f50621020ba05ed4 Mon Sep 17 00:00:00 2001 From: PBerger Date: Thu, 18 Aug 2016 01:19:30 +0200 Subject: [PATCH 46/49] Fixed Sylvan implementation of existsAbstractRepresentative. Added more tests. Former-commit-id: 6a4003bb5eea6a4ea8a45aac77d34c5795e91ba9 --- .../3rdparty/cudd-3.0.0/cudd/cuddBddAbs.c | 2 +- .../3rdparty/sylvan/src/sylvan_bdd_storm.c | 96 ++++++++++--------- test/functional/storage/CuddDdTest.cpp | 86 ++++++++++++----- test/functional/storage/SylvanDdTest.cpp | 86 +++++++++++++---- 4 files changed, 178 insertions(+), 92 deletions(-) diff --git a/resources/3rdparty/cudd-3.0.0/cudd/cuddBddAbs.c b/resources/3rdparty/cudd-3.0.0/cudd/cuddBddAbs.c index 2c01c6404..b9f6a7db9 100644 --- a/resources/3rdparty/cudd-3.0.0/cudd/cuddBddAbs.c +++ b/resources/3rdparty/cudd-3.0.0/cudd/cuddBddAbs.c @@ -614,7 +614,7 @@ cuddBddExistAbstractRepresentativeRecur( // FIXME if (res1 == one) { if (F->ref != 1) { - cuddCacheInsert2(manager, Cudd_bddExistAbstractRepresentative, f, cube, one); + cuddCacheInsert2(manager, Cudd_bddExistAbstractRepresentative, f, cube, Cudd_Not(cube)); } return(Cudd_Not(cube)); } diff --git a/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c b/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c index c3226c947..3841049e8 100644 --- a/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c +++ b/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c @@ -11,30 +11,29 @@ TASK_IMPL_3(BDD, sylvan_existsRepresentative, BDD, a, BDD, variables, BDDVAR, pr if (aRegular == sylvan_false) { if (aIsNegated) { - //printf("return in preprocessing...1\n"); - return a; - } - - if (sylvan_set_isempty(variables)) { - //printf("return in preprocessing...2\n"); - return sylvan_true; + if (sylvan_set_isempty(variables)) { + //printf("return in preprocessing...2\n"); + return sylvan_true; + } else { + //printf("return in preprocessing...3\n"); + return variables; + } } else { - //printf("return in preprocessing...3\n"); - return variables; + return a; } } else if (sylvan_set_isempty(variables)) { //printf("return in preprocessing...4\n"); - return a; + return a; } - /* From now on, f and cube are non-constant. */ + /* From now on, f and cube are non-constant. */ bddnode_t na = GETNODE(a); BDDVAR level = bddnode_getvariable(na); bddnode_t nv = GETNODE(variables); BDDVAR vv = bddnode_getvariable(nv); - + //printf("a level %i and cube level %i\n", level, vv); - + /* Abstract a variable that does not appear in f. */ if (level > vv) { BDD _v = sylvan_set_next(variables); @@ -42,20 +41,20 @@ TASK_IMPL_3(BDD, sylvan_existsRepresentative, BDD, a, BDD, variables, BDDVAR, pr if (res == sylvan_invalid) { return sylvan_invalid; } - bdd_refs_push(res); - - BDD res1 = sylvan_makenode(vv, sylvan_false, res); + sylvan_ref(res); + + BDD res1 = sylvan_ite(sylvan_ithvar(vv), sylvan_false, res); if (res1 == sylvan_invalid) { - bdd_refs_pop(1); + sylvan_deref(res); return sylvan_invalid; } - bdd_refs_pop(1); + sylvan_deref(res); //printf("return after abstr. var that does not appear in f...\n"); return res1; } - + /* Compute the cofactors of a. */ BDD aLow = node_low(a, na); // ELSE BDD aHigh = node_high(a, na); // THEN @@ -68,81 +67,88 @@ TASK_IMPL_3(BDD, sylvan_existsRepresentative, BDD, a, BDD, variables, BDDVAR, pr return sylvan_invalid; } if (res1 == sylvan_true) { - return sylvan_true; + return sylvan_not(variables); } - bdd_refs_push(res1); + sylvan_ref(res1); BDD res2 = CALL(sylvan_existsRepresentative, aHigh, _v, level); if (res2 == sylvan_invalid) { - bdd_refs_pop(1); + sylvan_deref(res1); return sylvan_invalid; } - bdd_refs_push(res2); + sylvan_ref(res2); BDD left = CALL(sylvan_exists, aLow, _v, 0); if (left == sylvan_invalid) { - bdd_refs_pop(2); + sylvan_deref(res1); + sylvan_deref(res2); return sylvan_invalid; } - - bdd_refs_push(left); + sylvan_ref(left); BDD res1Inf = sylvan_ite(left, res1, sylvan_false); if (res1Inf == sylvan_invalid) { - bdd_refs_pop(3); + sylvan_deref(res1); + sylvan_deref(res2); + sylvan_deref(left); return sylvan_invalid; } - bdd_refs_push(res1Inf); - - //Cudd_IterDerefBdd(manager,res1); + sylvan_ref(res1Inf); + sylvan_deref(res1); BDD res2Inf = sylvan_ite(left, sylvan_false, res2); if (res2Inf == sylvan_invalid) { - bdd_refs_pop(4); + sylvan_deref(res2); + sylvan_deref(left); + sylvan_deref(res1Inf); return sylvan_invalid; } - bdd_refs_push(res2Inf); - - //Cudd_IterDerefBdd(manager,res2); - //Cudd_IterDerefBdd(manager,left); + sylvan_ref(res2Inf); + sylvan_deref(res2); + sylvan_deref(left); assert(res1Inf != res2Inf); - BDD res = sylvan_makenode(level, res2Inf, res1Inf); - + BDD res = sylvan_ite(sylvan_ithvar(level), res2Inf, res1Inf); if (res == sylvan_invalid) { - bdd_refs_pop(5); + sylvan_deref(res1Inf); + sylvan_deref(res2Inf); return sylvan_invalid; } // cuddCacheInsert2(manager, Cudd_bddExistAbstractRepresentative, f, cube, res); // TODO: CACHING HERE + sylvan_deref(res1Inf); + sylvan_deref(res2Inf); + //printf("return properly computed result...\n"); - bdd_refs_pop(5); return res; } else { /* if (level == vv) */ BDD res1 = CALL(sylvan_existsRepresentative, aLow, variables, level); if (res1 == sylvan_invalid){ return sylvan_invalid; } - bdd_refs_push(res1); + sylvan_ref(res1); BDD res2 = CALL(sylvan_existsRepresentative, aHigh, variables, level); if (res2 == sylvan_invalid) { - bdd_refs_pop(1); + sylvan_deref(res1); return sylvan_invalid; } - bdd_refs_push(res2); + sylvan_ref(res2); /* ITE takes care of possible complementation of res1 and of the ** case in which res1 == res2. */ - BDD res = sylvan_makenode(level, res2, res1); + BDD res = sylvan_ite(sylvan_ithvar(level), res2, res1); if (res == sylvan_invalid) { - bdd_refs_pop(2); + sylvan_deref(res1); + sylvan_deref(res2); return sylvan_invalid; } - bdd_refs_pop(2); + sylvan_deref(res1); + sylvan_deref(res2); + //printf("return of last case...\n"); return res; } diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp index 743456578..763fa0a69 100644 --- a/test/functional/storage/CuddDdTest.cpp +++ b/test/functional/storage/CuddDdTest.cpp @@ -59,46 +59,80 @@ TEST(CuddDd, BddConstants) { } TEST(CuddDd, BddExistAbstractRepresentative) { - std::shared_ptr> manager(new storm::dd::DdManager()); + std::shared_ptr> manager(new storm::dd::DdManager()); std::pair x; std::pair y; std::pair z; - ASSERT_NO_THROW(x = manager->addMetaVariable("x", 0, 1)); + ASSERT_NO_THROW(x = manager->addMetaVariable("x", 0, 1)); ASSERT_NO_THROW(y = manager->addMetaVariable("y", 0, 1)); ASSERT_NO_THROW(z = manager->addMetaVariable("z", 0, 1)); - - storm::dd::Bdd bddX = manager->getEncoding(x.first, 1); - //bddX.template toAdd().exportToDot("/opt/masterThesis/storm/build/test_cudd_add_x.dot"); - storm::dd::Bdd bddY = manager->getEncoding(y.first, 0); - //bddY.template toAdd().exportToDot("/opt/masterThesis/storm/build/test_cudd_add_y.dot"); - storm::dd::Bdd bddZ = manager->getEncoding(z.first, 0); - //bddZ.template toAdd().exportToDot("/opt/masterThesis/storm/build/test_cudd_add_z.dot"); - - storm::dd::Bdd bddX1Y0Z0 = (bddX && bddY) && bddZ; - //bddX1Y0Z0.template toAdd().exportToDot("/opt/masterThesis/storm/build/test_cudd_bddX1Y0Z0.dot"); - - EXPECT_EQ(1ul, bddX1Y0Z0.getNonZeroCount()); - EXPECT_EQ(1ul, bddX1Y0Z0.getLeafCount()); - EXPECT_EQ(4ul, bddX1Y0Z0.getNodeCount()); - + + storm::dd::Bdd bddX1 = manager->getEncoding(x.first, 1); + storm::dd::Bdd bddY0 = manager->getEncoding(y.first, 0); + storm::dd::Bdd bddZ0 = manager->getEncoding(z.first, 0); + + storm::dd::Bdd bddX1Y0Z0 = (bddX1 && bddY0) && bddZ0; + EXPECT_EQ(1ul, bddX1Y0Z0.getNonZeroCount()); + EXPECT_EQ(1ul, bddX1Y0Z0.getLeafCount()); + EXPECT_EQ(4ul, bddX1Y0Z0.getNodeCount()); + storm::dd::Bdd representative_x = bddX1Y0Z0.existsAbstractRepresentative({x.first}); EXPECT_EQ(1ul, representative_x.getNonZeroCount()); - EXPECT_EQ(1ul, representative_x.getLeafCount()); - EXPECT_EQ(4ul, representative_x.getNodeCount()); + EXPECT_EQ(1ul, representative_x.getLeafCount()); + EXPECT_EQ(4ul, representative_x.getNodeCount()); EXPECT_TRUE(bddX1Y0Z0 == representative_x); - //representative_x.template toAdd().exportToDot("/opt/masterThesis/storm/build/test_representativea_x.dot"); + storm::dd::Bdd representative_y = bddX1Y0Z0.existsAbstractRepresentative({y.first}); EXPECT_EQ(1ul, representative_y.getNonZeroCount()); - EXPECT_EQ(1ul, representative_y.getLeafCount()); - EXPECT_EQ(4ul, representative_y.getNodeCount()); + EXPECT_EQ(1ul, representative_y.getLeafCount()); + EXPECT_EQ(4ul, representative_y.getNodeCount()); EXPECT_TRUE(bddX1Y0Z0 == representative_y); - //representative_y.template toAdd().exportToDot("/opt/masterThesis/storm/build/test_representativea_y.dot"); + storm::dd::Bdd representative_z = bddX1Y0Z0.existsAbstractRepresentative({z.first}); EXPECT_EQ(1ul, representative_z.getNonZeroCount()); - EXPECT_EQ(1ul, representative_z.getLeafCount()); - EXPECT_EQ(4ul, representative_z.getNodeCount()); + EXPECT_EQ(1ul, representative_z.getLeafCount()); + EXPECT_EQ(4ul, representative_z.getNodeCount()); EXPECT_TRUE(bddX1Y0Z0 == representative_z); - //representative_z.template toAdd().exportToDot("/opt/masterThesis/storm/build/test_representativea_z.dot"); + + storm::dd::Bdd representative_xyz = bddX1Y0Z0.existsAbstractRepresentative({x.first, y.first, z.first}); + EXPECT_EQ(1ul, representative_xyz.getNonZeroCount()); + EXPECT_EQ(1ul, representative_xyz.getLeafCount()); + EXPECT_EQ(4ul, representative_xyz.getNodeCount()); + EXPECT_TRUE(bddX1Y0Z0 == representative_xyz); + + storm::dd::Bdd bddX0 = manager->getEncoding(x.first, 0); + storm::dd::Bdd bddY1 = manager->getEncoding(y.first, 1); + storm::dd::Bdd bddZ1 = manager->getEncoding(z.first, 1); + + storm::dd::Bdd bddX0Y0Z0 = (bddX0 && bddY0) && bddZ0; + storm::dd::Bdd bddX1Y1Z1 = (bddX1 && bddY1) && bddZ1; + + storm::dd::Bdd bddAllTrueOrAllFalse = bddX0Y0Z0 || bddX1Y1Z1; + //bddAllTrueOrAllFalse.template toAdd().exportToDot("test_cudd_addAllTrueOrAllFalse.dot"); + + representative_x = bddAllTrueOrAllFalse.existsAbstractRepresentative({x.first}); + EXPECT_EQ(2ul, representative_x.getNonZeroCount()); + EXPECT_EQ(1ul, representative_x.getLeafCount()); + EXPECT_EQ(5ul, representative_x.getNodeCount()); + EXPECT_TRUE(bddAllTrueOrAllFalse == representative_x); + + representative_y = bddAllTrueOrAllFalse.existsAbstractRepresentative({y.first}); + EXPECT_EQ(2ul, representative_y.getNonZeroCount()); + EXPECT_EQ(1ul, representative_y.getLeafCount()); + EXPECT_EQ(5ul, representative_y.getNodeCount()); + EXPECT_TRUE(bddAllTrueOrAllFalse == representative_y); + + representative_z = bddAllTrueOrAllFalse.existsAbstractRepresentative({z.first}); + EXPECT_EQ(2ul, representative_z.getNonZeroCount()); + EXPECT_EQ(1ul, representative_z.getLeafCount()); + EXPECT_EQ(5ul, representative_z.getNodeCount()); + EXPECT_TRUE(bddAllTrueOrAllFalse == representative_z); + + representative_xyz = bddAllTrueOrAllFalse.existsAbstractRepresentative({x.first, y.first, z.first}); + EXPECT_EQ(1ul, representative_xyz.getNonZeroCount()); + EXPECT_EQ(1ul, representative_xyz.getLeafCount()); + EXPECT_EQ(4ul, representative_xyz.getNodeCount()); + EXPECT_TRUE(bddX0Y0Z0 == representative_xyz); } TEST(CuddDd, AddGetMetaVariableTest) { diff --git a/test/functional/storage/SylvanDdTest.cpp b/test/functional/storage/SylvanDdTest.cpp index 6695d34f7..5b0c26b47 100644 --- a/test/functional/storage/SylvanDdTest.cpp +++ b/test/functional/storage/SylvanDdTest.cpp @@ -62,34 +62,80 @@ TEST(SylvanDd, BddConstants) { } TEST(SylvanDd, BddExistAbstractRepresentative) { - std::shared_ptr> manager(new storm::dd::DdManager()); + std::shared_ptr> manager(new storm::dd::DdManager()); std::pair x; std::pair y; std::pair z; - ASSERT_NO_THROW(x = manager->addMetaVariable("x", 0, 1)); + ASSERT_NO_THROW(x = manager->addMetaVariable("x", 0, 1)); ASSERT_NO_THROW(y = manager->addMetaVariable("y", 0, 1)); ASSERT_NO_THROW(z = manager->addMetaVariable("z", 0, 1)); - - storm::dd::Bdd bddX = manager->getEncoding(x.first, 1); - //bddX.exportToDot("/opt/masterThesis/storm/build/tests_bdd_x.dot"); - storm::dd::Bdd bddY = manager->getEncoding(y.first, 0); - //bddY.exportToDot("/opt/masterThesis/storm/build/tests_bdd_y.dot"); - storm::dd::Bdd bddZ = manager->getEncoding(z.first, 0); - //bddZ.exportToDot("/opt/masterThesis/storm/build/tests_bdd_z.dot"); - - storm::dd::Bdd bddX1Y0Z0 = (bddX && bddY) && bddZ; - //bddX1Y0Z0.exportToDot("/opt/masterThesis/storm/build/tests_bddX1Y0Z0.dot"); - - EXPECT_EQ(1ul, bddX1Y0Z0.getNonZeroCount()); - EXPECT_EQ(1ul, bddX1Y0Z0.getLeafCount()); - EXPECT_EQ(4ul, bddX1Y0Z0.getNodeCount()); - + + storm::dd::Bdd bddX1 = manager->getEncoding(x.first, 1); + storm::dd::Bdd bddY0 = manager->getEncoding(y.first, 0); + storm::dd::Bdd bddZ0 = manager->getEncoding(z.first, 0); + + storm::dd::Bdd bddX1Y0Z0 = (bddX1 && bddY0) && bddZ0; + EXPECT_EQ(1ul, bddX1Y0Z0.getNonZeroCount()); + EXPECT_EQ(1ul, bddX1Y0Z0.getLeafCount()); + EXPECT_EQ(4ul, bddX1Y0Z0.getNodeCount()); + storm::dd::Bdd representative_x = bddX1Y0Z0.existsAbstractRepresentative({x.first}); - //representative_x.exportToDot("/opt/masterThesis/storm/build/tests_representative_x.dot"); + EXPECT_EQ(1ul, representative_x.getNonZeroCount()); + EXPECT_EQ(1ul, representative_x.getLeafCount()); + EXPECT_EQ(4ul, representative_x.getNodeCount()); + EXPECT_TRUE(bddX1Y0Z0 == representative_x); + storm::dd::Bdd representative_y = bddX1Y0Z0.existsAbstractRepresentative({y.first}); - //representative_y.exportToDot("/opt/masterThesis/storm/build/tests_representative_y.dot"); + EXPECT_EQ(1ul, representative_y.getNonZeroCount()); + EXPECT_EQ(1ul, representative_y.getLeafCount()); + EXPECT_EQ(4ul, representative_y.getNodeCount()); + EXPECT_TRUE(bddX1Y0Z0 == representative_y); + storm::dd::Bdd representative_z = bddX1Y0Z0.existsAbstractRepresentative({z.first}); - //representative_z.exportToDot("/opt/masterThesis/storm/build/tests_representative_z.dot"); + EXPECT_EQ(1ul, representative_z.getNonZeroCount()); + EXPECT_EQ(1ul, representative_z.getLeafCount()); + EXPECT_EQ(4ul, representative_z.getNodeCount()); + EXPECT_TRUE(bddX1Y0Z0 == representative_z); + + storm::dd::Bdd representative_xyz = bddX1Y0Z0.existsAbstractRepresentative({x.first, y.first, z.first}); + EXPECT_EQ(1ul, representative_xyz.getNonZeroCount()); + EXPECT_EQ(1ul, representative_xyz.getLeafCount()); + EXPECT_EQ(4ul, representative_xyz.getNodeCount()); + EXPECT_TRUE(bddX1Y0Z0 == representative_xyz); + + storm::dd::Bdd bddX0 = manager->getEncoding(x.first, 0); + storm::dd::Bdd bddY1 = manager->getEncoding(y.first, 1); + storm::dd::Bdd bddZ1 = manager->getEncoding(z.first, 1); + + storm::dd::Bdd bddX0Y0Z0 = (bddX0 && bddY0) && bddZ0; + storm::dd::Bdd bddX1Y1Z1 = (bddX1 && bddY1) && bddZ1; + + storm::dd::Bdd bddAllTrueOrAllFalse = bddX0Y0Z0 || bddX1Y1Z1; + //bddAllTrueOrAllFalse.template toAdd().exportToDot("test_Sylvan_addAllTrueOrAllFalse.dot"); + + representative_x = bddAllTrueOrAllFalse.existsAbstractRepresentative({x.first}); + EXPECT_EQ(2ul, representative_x.getNonZeroCount()); + EXPECT_EQ(1ul, representative_x.getLeafCount()); + EXPECT_EQ(5ul, representative_x.getNodeCount()); + EXPECT_TRUE(bddAllTrueOrAllFalse == representative_x); + + representative_y = bddAllTrueOrAllFalse.existsAbstractRepresentative({y.first}); + EXPECT_EQ(2ul, representative_y.getNonZeroCount()); + EXPECT_EQ(1ul, representative_y.getLeafCount()); + EXPECT_EQ(5ul, representative_y.getNodeCount()); + EXPECT_TRUE(bddAllTrueOrAllFalse == representative_y); + + representative_z = bddAllTrueOrAllFalse.existsAbstractRepresentative({z.first}); + EXPECT_EQ(2ul, representative_z.getNonZeroCount()); + EXPECT_EQ(1ul, representative_z.getLeafCount()); + EXPECT_EQ(5ul, representative_z.getNodeCount()); + EXPECT_TRUE(bddAllTrueOrAllFalse == representative_z); + + representative_xyz = bddAllTrueOrAllFalse.existsAbstractRepresentative({x.first, y.first, z.first}); + EXPECT_EQ(1ul, representative_xyz.getNonZeroCount()); + EXPECT_EQ(1ul, representative_xyz.getLeafCount()); + EXPECT_EQ(4ul, representative_xyz.getNodeCount()); + EXPECT_TRUE(bddX0Y0Z0 == representative_xyz); } TEST(SylvanDd, AddGetMetaVariableTest) { From b5aa778c51bf3b414f60c271a1f9ef37ed9ef0f0 Mon Sep 17 00:00:00 2001 From: PBerger Date: Thu, 18 Aug 2016 03:27:25 +0200 Subject: [PATCH 47/49] Fixed PrismMenuGameTest. Former-commit-id: edce18058a1b2ae2164e1c4cfd538def350d6b3c --- test/functional/abstraction/PrismMenuGameTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/functional/abstraction/PrismMenuGameTest.cpp b/test/functional/abstraction/PrismMenuGameTest.cpp index 397213e68..0d628fb75 100644 --- a/test/functional/abstraction/PrismMenuGameTest.cpp +++ b/test/functional/abstraction/PrismMenuGameTest.cpp @@ -65,9 +65,9 @@ TEST(PrismMenuGame, DieAbstractionTest_SylvanWithRationalFunction) { storm::abstraction::MenuGame game = abstractProgram.getAbstractGame(); - EXPECT_EQ(10, game.getNumberOfTransitions()); - EXPECT_EQ(2, game.getNumberOfStates()); - EXPECT_EQ(0, game.getBottomStates().getNonZeroCount()); + EXPECT_EQ(26, game.getNumberOfTransitions()); + EXPECT_EQ(4, game.getNumberOfStates()); + EXPECT_EQ(2, game.getBottomStates().getNonZeroCount()); } #endif From c184f6a5413d37583c811c8b96834703b99442fe Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 22 Aug 2016 20:36:28 +0200 Subject: [PATCH 48/49] Worked on Sylvan min/max ADD abstract w. representative. More tests for existsRepr. Former-commit-id: 08c5d6e9bb6d15cb8c60f826d7748d7670d7bfb0 --- .../3rdparty/sylvan/src/sylvan_bdd_storm.c | 34 ++- resources/3rdparty/sylvan/src/sylvan_mtbdd.h | 2 +- .../3rdparty/sylvan/src/sylvan_mtbdd_storm.c | 225 +++++++++++++++++- .../3rdparty/sylvan/src/sylvan_mtbdd_storm.h | 34 ++- .../sylvan/src/sylvan_obj_mtbdd_storm.hpp | 10 + .../3rdparty/sylvan/src/sylvan_obj_storm.cpp | 13 + test/functional/storage/CuddDdTest.cpp | 132 +++++++++- test/functional/storage/SylvanDdTest.cpp | 35 ++- 8 files changed, 469 insertions(+), 16 deletions(-) diff --git a/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c b/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c index 3841049e8..4f0d3f81d 100644 --- a/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c +++ b/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c @@ -16,7 +16,20 @@ TASK_IMPL_3(BDD, sylvan_existsRepresentative, BDD, a, BDD, variables, BDDVAR, pr return sylvan_true; } else { //printf("return in preprocessing...3\n"); - return variables; + BDD _v = sylvan_set_next(variables); + BDD res = CALL(sylvan_existsRepresentative, a, _v, prev_level); + if (res == sylvan_invalid) { + return sylvan_invalid; + } + sylvan_ref(res); + + BDD res1 = sylvan_ite(sylvan_ithvar(bddnode_getvariable(GETNODE(variables))), sylvan_false, res); + if (res1 == sylvan_invalid) { + sylvan_deref(res); + return sylvan_invalid; + } + sylvan_deref(res); + return res1; } } else { return a; @@ -67,7 +80,24 @@ TASK_IMPL_3(BDD, sylvan_existsRepresentative, BDD, a, BDD, variables, BDDVAR, pr return sylvan_invalid; } if (res1 == sylvan_true) { - return sylvan_not(variables); + BDD res = CALL(sylvan_existsRepresentative, a, _v, level); + if (res == sylvan_invalid) { + return sylvan_invalid; + } + sylvan_ref(res); + + BDD res1 = sylvan_ite(sylvan_ithvar(vv), sylvan_false, res); + + if (res1 == sylvan_invalid) { + sylvan_deref(res); + return sylvan_invalid; + } + sylvan_deref(res); + + //printf("return after abstr. var that does not appear in f...\n"); + return res1; + + //return sylvan_not(variables); } sylvan_ref(res1); diff --git a/resources/3rdparty/sylvan/src/sylvan_mtbdd.h b/resources/3rdparty/sylvan/src/sylvan_mtbdd.h index 1a7de3f57..60d484f50 100644 --- a/resources/3rdparty/sylvan/src/sylvan_mtbdd.h +++ b/resources/3rdparty/sylvan/src/sylvan_mtbdd.h @@ -307,7 +307,7 @@ TASK_DECL_3(MTBDD, mtbdd_abstract_op_max, MTBDD, MTBDD, int); * must be a Boolean MTBDD (or standard BDD). */ TASK_DECL_3(MTBDD, mtbdd_ite, MTBDD, MTBDD, MTBDD); -#define mtbdd_ite(f, g, h) CALL(mtbdd_ite, f, g, h); +#define mtbdd_ite(f, g, h) CALL(mtbdd_ite, f, g, h) /** * Multiply and , and abstract variables using summation. diff --git a/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.c b/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.c index 2d0796a40..87e9bb590 100644 --- a/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.c +++ b/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.c @@ -580,4 +580,227 @@ int mtbdd_iszero(MTBDD dd) { int mtbdd_isnonzero(MTBDD dd) { return mtbdd_iszero(dd) ? 0 : 1; -} \ No newline at end of file +} + +MTBDD +mtbdd_ithvar(uint32_t level) { + return mtbdd_makenode(level, mtbdd_false, mtbdd_true); +} + +TASK_IMPL_2(MTBDD, mtbdd_op_complement, MTBDD, a, size_t, k) +{ + // if a is false, then it is a partial function. Keep partial! + if (a == mtbdd_false) return mtbdd_false; + + // a != constant + mtbddnode_t na = GETNODE(a); + + if (mtbddnode_isleaf(na)) { + if (mtbddnode_gettype(na) == 0) { + int64_t v = mtbdd_getint64(a); + if (v == 0) { + return mtbdd_int64(1); + } else { + return mtbdd_int64(0); + } + } else if (mtbddnode_gettype(na) == 1) { + double d = mtbdd_getdouble(a); + if (d == 0.0) { + return mtbdd_double(1.0); + } else { + return mtbdd_double(0.0); + } + } else if (mtbddnode_gettype(na) == 2) { + printf("ERROR: mtbdd_op_complement type FRACTION.\n"); + assert(0); + } +#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) + else if ((mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID)) { + printf("ERROR: mtbdd_op_complement type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID.\n"); + assert(0); + } +#endif + } + + return mtbdd_invalid; + (void)k; // unused variable +} + +TASK_IMPL_3(MTBDD, mtbdd_minExistsRepresentative, MTBDD, a, MTBDD, variables, uint32_t, prev_level) { + MTBDD zero = mtbdd_false; + + /* Maybe perform garbage collection */ + sylvan_gc_test(); + + /* Cube is guaranteed to be a cube at this point. */ + if (mtbdd_isleaf(a)) { + if (mtbdd_set_isempty(variables)) { + return a; // FIXME? + } else { + return variables; + } + } + + mtbddnode_t na = GETNODE(a); + uint32_t va = mtbddnode_getvariable(na); + mtbddnode_t nv = GETNODE(variables); + uint32_t vv = mtbddnode_getvariable(nv); + + /* Abstract a variable that does not appear in a. */ + if (va > vv) { + MTBDD _v = mtbdd_set_next(variables); + MTBDD res = CALL(mtbdd_minExistsRepresentative, a, _v, va); + if (res == mtbdd_invalid) { + return mtbdd_invalid; + } + + // Fill in the missing variables to make representative unique. + mtbdd_ref(res); + MTBDD res1 = mtbdd_ite(mtbdd_ithvar(vv), zero, res); + if (res1 == mtbdd_invalid) { + mtbdd_deref(res); + return mtbdd_invalid; + } + mtbdd_deref(res); + return res1; + } + + /* TODO: Caching here. */ + /*if ((res = cuddCacheLookup2(manager, Cudd_addMinAbstractRepresentative, f, cube)) != NULL) { + return(res); + }*/ + + + MTBDD E = mtbdd_getlow(a); + MTBDD T = mtbdd_gethigh(a); + + /* If the two indices are the same, so are their levels. */ + if (va == vv) { + MTBDD _v = mtbdd_set_next(variables); + MTBDD res1 = CALL(mtbdd_minExistsRepresentative, E, _v, va); + if (res1 == mtbdd_invalid) { + return mtbdd_invalid; + } + mtbdd_ref(res1); + + MTBDD res2 = CALL(mtbdd_minExistsRepresentative, T, _v, va); + if (res2 == mtbdd_invalid) { + mtbdd_deref(res1); + return mtbdd_invalid; + } + mtbdd_ref(res2); + + MTBDD left = mtbdd_abstract_min(E, _v); + if (left == mtbdd_invalid) { + mtbdd_deref(res1); + mtbdd_deref(res2); + return mtbdd_invalid; + } + mtbdd_ref(left); + + MTBDD right = mtbdd_abstract_min(T, _v); + if (right == mtbdd_invalid) { + mtbdd_deref(res1); + mtbdd_deref(res2); + mtbdd_deref(left); + return mtbdd_invalid; + } + mtbdd_ref(right); + + MTBDD tmp = mtbdd_less_or_equal_as_bdd(left, right); + if (tmp == mtbdd_invalid) { + mtbdd_deref(res1); + mtbdd_deref(res2); + mtbdd_deref(left); + mtbdd_deref(right); + return mtbdd_invalid; + } + mtbdd_ref(tmp); + + mtbdd_deref(left); + mtbdd_deref(right); + + MTBDD res1Inf = mtbdd_ite(tmp, res1, zero); + if (res1Inf == mtbdd_invalid) { + mtbdd_deref(res1); + mtbdd_deref(res2); + mtbdd_deref(tmp); + return mtbdd_invalid; + } + mtbdd_ref(res1Inf); + mtbdd_deref(res1); + + MTBDD tmp2 = mtbdd_get_complement(tmp); + if (tmp2 == mtbdd_invalid) { + mtbdd_deref(res2); + mtbdd_deref(left); + mtbdd_deref(right); + mtbdd_deref(tmp); + return mtbdd_invalid; + } + mtbdd_ref(tmp2); + mtbdd_deref(tmp); + + MTBDD res2Inf = mtbdd_ite(tmp2, res2, zero); + if (res2Inf == mtbdd_invalid) { + mtbdd_deref(res2); + mtbdd_deref(res1Inf); + mtbdd_deref(tmp2); + return mtbdd_invalid; + } + mtbdd_ref(res2Inf); + mtbdd_deref(res2); + mtbdd_deref(tmp2); + + MTBDD res = (res1Inf == res2Inf) ? mtbdd_ite(mtbdd_ithvar(va), zero, res1Inf) : mtbdd_ite(mtbdd_ithvar(va), res2Inf, res1Inf); + + if (res == mtbdd_invalid) { + mtbdd_deref(res1Inf); + mtbdd_deref(res2Inf); + return mtbdd_invalid; + } + mtbdd_ref(res); + mtbdd_deref(res1Inf); + mtbdd_deref(res2Inf); + + /* TODO: Caching here. */ + //cuddCacheInsert2(manager, Cudd_addMinAbstractRepresentative, f, cube, res); + + mtbdd_deref(res); + return res; + } + else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ + MTBDD res1 = CALL(mtbdd_minExistsRepresentative, E, variables, va); + if (res1 == mtbdd_invalid) { + return mtbdd_invalid; + } + mtbdd_ref(res1); + MTBDD res2 = CALL(mtbdd_minExistsRepresentative, T, variables, va); + if (res2 == mtbdd_invalid) { + mtbdd_deref(res1); + return mtbdd_invalid; + } + mtbdd_ref(res2); + + MTBDD res = (res1 == res2) ? mtbdd_ite(mtbdd_ithvar(va), zero, res1) : mtbdd_ite(mtbdd_ithvar(va), res2, res1); + if (res == mtbdd_invalid) { + mtbdd_deref(res1); + mtbdd_deref(res2); + return mtbdd_invalid; + } + mtbdd_deref(res1); + mtbdd_deref(res2); + /* TODO: Caching here. */ + //cuddCacheInsert2(manager, Cudd_addMinAbstractRepresentative, f, cube, res); + return res; + } + + // Prevent unused variable warning + (void)prev_level; +} + +TASK_IMPL_3(MTBDD, mtbdd_maxExistsRepresentative, MTBDD, a, MTBDD, variables, uint32_t, prev_level) { + (void)variables; + (void)prev_level; + return a; +} diff --git a/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.h b/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.h index a35fd8398..d1119438b 100644 --- a/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.h +++ b/resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.h @@ -71,14 +71,14 @@ TASK_DECL_1(MTBDD, mtbdd_not_zero, MTBDD) #define mtbdd_not_zero(dd) CALL(mtbdd_not_zero, dd) /** - * Monad that floors all values Double and Fraction values. + * Monad that floors all Double and Fraction values. */ TASK_DECL_2(MTBDD, mtbdd_op_floor, MTBDD, size_t) TASK_DECL_1(MTBDD, mtbdd_floor, MTBDD) #define mtbdd_floor(dd) CALL(mtbdd_floor, dd) /** - * Monad that ceils all values Double and Fraction values. + * Monad that ceils all Double and Fraction values. */ TASK_DECL_2(MTBDD, mtbdd_op_ceil, MTBDD, size_t) TASK_DECL_1(MTBDD, mtbdd_ceil, MTBDD) @@ -109,3 +109,33 @@ int mtbdd_iszero(MTBDD); int mtbdd_isnonzero(MTBDD); #define mtbdd_regular(dd) (dd & ~mtbdd_complement) + +#define mtbdd_set_next(set) (mtbdd_gethigh(set)) +#define mtbdd_set_isempty(set) (set == mtbdd_true) + +/* Create a MTBDD representing just or the negation of */ +MTBDD mtbdd_ithvar(uint32_t var); + +/** + * Unary operation Complement. + * Supported domains: Integer, Real + */ +TASK_DECL_2(MTBDD, mtbdd_op_complement, MTBDD, size_t); + +/** + * Compute the complement of a. + */ +#define mtbdd_get_complement(a) mtbdd_uapply(a, TASK(mtbdd_op_complement), 0) + +/** + * Just like mtbdd_abstract_min, but instead of abstracting the variables in the given cube, picks a unique representative that realizes the minimal function value. + */ +TASK_DECL_3(MTBDD, mtbdd_minExistsRepresentative, MTBDD, MTBDD, uint32_t); +#define mtbdd_minExistsRepresentative(a, vars) (CALL(mtbdd_minExistsRepresentative, a, vars, 0)) + +/** + * Just like mtbdd_abstract_max but instead of abstracting the variables in the given cube, picks a unique representative that realizes the maximal function value. + */ +TASK_DECL_3(MTBDD, mtbdd_maxExistsRepresentative, MTBDD, MTBDD, uint32_t); +#define mtbdd_maxExistsRepresentative(a, vars) (CALL(mtbdd_maxExistsRepresentative, a, vars, 0)) + diff --git a/resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp b/resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp index 92dd1172c..87ab6735e 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp @@ -32,6 +32,16 @@ Mtbdd AbstractPlusRF(const BddSet &variables) const; #endif + /** + * @brief Computes abstraction by minimum + */ + Mtbdd AbstractMinRepresentative(const BddSet &variables) const; + + /** + * @brief Computes abstraction by maximum + */ + Mtbdd AbstractMaxRepresentative(const BddSet &variables) const; + Bdd NotZero() const; Bdd Equals(const Mtbdd& other) const; diff --git a/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp b/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp index e055478f3..7ef934fbe 100644 --- a/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp +++ b/resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp @@ -188,3 +188,16 @@ Mtbdd::GetShaHash() const { return std::string(buf); } +Mtbdd +Mtbdd::AbstractMinRepresentative(const BddSet &variables) const +{ + LACE_ME; + return mtbdd_minExistsRepresentative(mtbdd, variables.set.bdd); +} + +Mtbdd +Mtbdd::AbstractMaxRepresentative(const BddSet &variables) const +{ + LACE_ME; + return mtbdd_maxExistsRepresentative(mtbdd, variables.set.bdd); +} diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp index 763fa0a69..b499da1b7 100644 --- a/test/functional/storage/CuddDdTest.cpp +++ b/test/functional/storage/CuddDdTest.cpp @@ -60,16 +60,45 @@ TEST(CuddDd, BddConstants) { TEST(CuddDd, BddExistAbstractRepresentative) { std::shared_ptr> manager(new storm::dd::DdManager()); + + storm::dd::Bdd zero; + ASSERT_NO_THROW(zero = manager->getBddZero()); + storm::dd::Bdd one; + ASSERT_NO_THROW(one = manager->getBddOne()); + std::pair x; std::pair y; std::pair z; ASSERT_NO_THROW(x = manager->addMetaVariable("x", 0, 1)); ASSERT_NO_THROW(y = manager->addMetaVariable("y", 0, 1)); ASSERT_NO_THROW(z = manager->addMetaVariable("z", 0, 1)); - + + storm::dd::Bdd bddX0 = manager->getEncoding(x.first, 0); storm::dd::Bdd bddX1 = manager->getEncoding(x.first, 1); storm::dd::Bdd bddY0 = manager->getEncoding(y.first, 0); + storm::dd::Bdd bddY1 = manager->getEncoding(y.first, 1); storm::dd::Bdd bddZ0 = manager->getEncoding(z.first, 0); + storm::dd::Bdd bddZ1 = manager->getEncoding(z.first, 1); + + // Abstract from FALSE + storm::dd::Bdd representative_false_x = zero.existsAbstractRepresentative({x.first}); + EXPECT_EQ(0ul, representative_false_x.getNonZeroCount()); + EXPECT_EQ(1ul, representative_false_x.getLeafCount()); + EXPECT_EQ(1ul, representative_false_x.getNodeCount()); + EXPECT_TRUE(representative_false_x == zero); + + // Abstract from TRUE + storm::dd::Bdd representative_true_x = one.existsAbstractRepresentative({x.first}); + EXPECT_EQ(0ul, representative_true_x.getNonZeroCount()); + EXPECT_EQ(1ul, representative_true_x.getLeafCount()); + EXPECT_EQ(1ul, representative_true_x.getNodeCount()); + EXPECT_TRUE(representative_true_x == bddX0); + + storm::dd::Bdd representative_true_xyz = one.existsAbstractRepresentative({x.first, y.first, z.first}); + EXPECT_EQ(0ul, representative_true_xyz.getNonZeroCount()); + EXPECT_EQ(1ul, representative_true_xyz.getLeafCount()); + EXPECT_EQ(4ul, representative_true_xyz.getNodeCount()); + EXPECT_TRUE(representative_true_xyz == ((bddX0 && bddY0) && bddZ0)); storm::dd::Bdd bddX1Y0Z0 = (bddX1 && bddY0) && bddZ0; EXPECT_EQ(1ul, bddX1Y0Z0.getNonZeroCount()); @@ -100,10 +129,6 @@ TEST(CuddDd, BddExistAbstractRepresentative) { EXPECT_EQ(4ul, representative_xyz.getNodeCount()); EXPECT_TRUE(bddX1Y0Z0 == representative_xyz); - storm::dd::Bdd bddX0 = manager->getEncoding(x.first, 0); - storm::dd::Bdd bddY1 = manager->getEncoding(y.first, 1); - storm::dd::Bdd bddZ1 = manager->getEncoding(z.first, 1); - storm::dd::Bdd bddX0Y0Z0 = (bddX0 && bddY0) && bddZ0; storm::dd::Bdd bddX1Y1Z1 = (bddX1 && bddY1) && bddZ1; @@ -134,6 +159,103 @@ TEST(CuddDd, BddExistAbstractRepresentative) { EXPECT_EQ(4ul, representative_xyz.getNodeCount()); EXPECT_TRUE(bddX0Y0Z0 == representative_xyz); } +/* +TEST(CuddDd, AddMinExistAbstractRepresentative) { + std::shared_ptr> manager(new storm::dd::DdManager()); + + storm::dd::Add zero; + ASSERT_NO_THROW(zero = manager->template getAddZero()); + storm::dd::Add one; + ASSERT_NO_THROW(one = manager->template getAddOne()); + + std::pair x; + std::pair y; + std::pair z; + ASSERT_NO_THROW(x = manager->addMetaVariable("x", 0, 1)); + ASSERT_NO_THROW(y = manager->addMetaVariable("y", 0, 1)); + ASSERT_NO_THROW(z = manager->addMetaVariable("z", 0, 1)); + + // Abstract from FALSE + storm::dd::Add representative_false_x = zero.existsAbstractRepresentative({x.first}); + EXPECT_EQ(0ul, representative_false_x.getNonZeroCount()); + EXPECT_EQ(1ul, representative_false_x.getLeafCount()); + EXPECT_EQ(1ul, representative_false_x.getNodeCount()); + EXPECT_TRUE(representative_false_x == zero); + + // Abstract from TRUE + storm::dd::Add representative_true_x = one.existsAbstractRepresentative({x.first}); + EXPECT_EQ(1ul, representative_true_x.getNonZeroCount()); + EXPECT_EQ(1ul, representative_true_x.getLeafCount()); + EXPECT_EQ(1ul, representative_true_x.getNodeCount()); + EXPECT_TRUE(representative_true_x == manager->getEncoding(x.first, 0)); + + storm::dd::Add bddX1 = manager->getEncoding(x.first, 1); + storm::dd::Add bddY0 = manager->getEncoding(y.first, 0); + storm::dd::Add bddZ0 = manager->getEncoding(z.first, 0); + + storm::dd::Add bddX1Y0Z0 = (bddX1 && bddY0) && bddZ0; + EXPECT_EQ(1ul, bddX1Y0Z0.getNonZeroCount()); + EXPECT_EQ(1ul, bddX1Y0Z0.getLeafCount()); + EXPECT_EQ(4ul, bddX1Y0Z0.getNodeCount()); + + storm::dd::Add representative_x = bddX1Y0Z0.existsAbstractRepresentative({x.first}); + EXPECT_EQ(1ul, representative_x.getNonZeroCount()); + EXPECT_EQ(1ul, representative_x.getLeafCount()); + EXPECT_EQ(4ul, representative_x.getNodeCount()); + EXPECT_TRUE(bddX1Y0Z0 == representative_x); + + storm::dd::Add representative_y = bddX1Y0Z0.existsAbstractRepresentative({y.first}); + EXPECT_EQ(1ul, representative_y.getNonZeroCount()); + EXPECT_EQ(1ul, representative_y.getLeafCount()); + EXPECT_EQ(4ul, representative_y.getNodeCount()); + EXPECT_TRUE(bddX1Y0Z0 == representative_y); + + storm::dd::Add representative_z = bddX1Y0Z0.existsAbstractRepresentative({z.first}); + EXPECT_EQ(1ul, representative_z.getNonZeroCount()); + EXPECT_EQ(1ul, representative_z.getLeafCount()); + EXPECT_EQ(4ul, representative_z.getNodeCount()); + EXPECT_TRUE(bddX1Y0Z0 == representative_z); + + storm::dd::Add representative_xyz = bddX1Y0Z0.existsAbstractRepresentative({x.first, y.first, z.first}); + EXPECT_EQ(1ul, representative_xyz.getNonZeroCount()); + EXPECT_EQ(1ul, representative_xyz.getLeafCount()); + EXPECT_EQ(4ul, representative_xyz.getNodeCount()); + EXPECT_TRUE(bddX1Y0Z0 == representative_xyz); + + storm::dd::Add bddX0 = manager->getEncoding(x.first, 0); + storm::dd::Add bddY1 = manager->getEncoding(y.first, 1); + storm::dd::Add bddZ1 = manager->getEncoding(z.first, 1); + + storm::dd::Add bddX0Y0Z0 = (bddX0 && bddY0) && bddZ0; + storm::dd::Add bddX1Y1Z1 = (bddX1 && bddY1) && bddZ1; + + storm::dd::Add bddAllTrueOrAllFalse = bddX0Y0Z0 || bddX1Y1Z1; + //bddAllTrueOrAllFalse.template toAdd().exportToDot("test_cudd_addAllTrueOrAllFalse.dot"); + + representative_x = bddAllTrueOrAllFalse.existsAbstractRepresentative({x.first}); + EXPECT_EQ(2ul, representative_x.getNonZeroCount()); + EXPECT_EQ(1ul, representative_x.getLeafCount()); + EXPECT_EQ(5ul, representative_x.getNodeCount()); + EXPECT_TRUE(bddAllTrueOrAllFalse == representative_x); + + representative_y = bddAllTrueOrAllFalse.existsAbstractRepresentative({y.first}); + EXPECT_EQ(2ul, representative_y.getNonZeroCount()); + EXPECT_EQ(1ul, representative_y.getLeafCount()); + EXPECT_EQ(5ul, representative_y.getNodeCount()); + EXPECT_TRUE(bddAllTrueOrAllFalse == representative_y); + + representative_z = bddAllTrueOrAllFalse.existsAbstractRepresentative({z.first}); + EXPECT_EQ(2ul, representative_z.getNonZeroCount()); + EXPECT_EQ(1ul, representative_z.getLeafCount()); + EXPECT_EQ(5ul, representative_z.getNodeCount()); + EXPECT_TRUE(bddAllTrueOrAllFalse == representative_z); + + representative_xyz = bddAllTrueOrAllFalse.existsAbstractRepresentative({x.first, y.first, z.first}); + EXPECT_EQ(1ul, representative_xyz.getNonZeroCount()); + EXPECT_EQ(1ul, representative_xyz.getLeafCount()); + EXPECT_EQ(4ul, representative_xyz.getNodeCount()); + EXPECT_TRUE(bddX0Y0Z0 == representative_xyz); +}*/ TEST(CuddDd, AddGetMetaVariableTest) { std::shared_ptr> manager(new storm::dd::DdManager()); diff --git a/test/functional/storage/SylvanDdTest.cpp b/test/functional/storage/SylvanDdTest.cpp index 5b0c26b47..8b5c38859 100644 --- a/test/functional/storage/SylvanDdTest.cpp +++ b/test/functional/storage/SylvanDdTest.cpp @@ -63,16 +63,45 @@ TEST(SylvanDd, BddConstants) { TEST(SylvanDd, BddExistAbstractRepresentative) { std::shared_ptr> manager(new storm::dd::DdManager()); + + storm::dd::Bdd zero; + ASSERT_NO_THROW(zero = manager->getBddZero()); + storm::dd::Bdd one; + ASSERT_NO_THROW(one = manager->getBddOne()); + std::pair x; std::pair y; std::pair z; ASSERT_NO_THROW(x = manager->addMetaVariable("x", 0, 1)); ASSERT_NO_THROW(y = manager->addMetaVariable("y", 0, 1)); ASSERT_NO_THROW(z = manager->addMetaVariable("z", 0, 1)); - + + storm::dd::Bdd bddX0 = manager->getEncoding(x.first, 0); storm::dd::Bdd bddX1 = manager->getEncoding(x.first, 1); storm::dd::Bdd bddY0 = manager->getEncoding(y.first, 0); + storm::dd::Bdd bddY1 = manager->getEncoding(y.first, 1); storm::dd::Bdd bddZ0 = manager->getEncoding(z.first, 0); + storm::dd::Bdd bddZ1 = manager->getEncoding(z.first, 1); + + // Abstract from FALSE + storm::dd::Bdd representative_false_x = zero.existsAbstractRepresentative({x.first}); + EXPECT_EQ(0ul, representative_false_x.getNonZeroCount()); + EXPECT_EQ(1ul, representative_false_x.getLeafCount()); + EXPECT_EQ(1ul, representative_false_x.getNodeCount()); + EXPECT_TRUE(representative_false_x == zero); + + // Abstract from TRUE + storm::dd::Bdd representative_true_x = one.existsAbstractRepresentative({x.first}); + EXPECT_EQ(0ul, representative_true_x.getNonZeroCount()); + EXPECT_EQ(1ul, representative_true_x.getLeafCount()); + EXPECT_EQ(2ul, representative_true_x.getNodeCount()); + EXPECT_TRUE(representative_true_x == bddX0); + + storm::dd::Bdd representative_true_xyz = one.existsAbstractRepresentative({x.first, y.first, z.first}); + EXPECT_EQ(0ul, representative_true_xyz.getNonZeroCount()); + EXPECT_EQ(1ul, representative_true_xyz.getLeafCount()); + EXPECT_EQ(4ul, representative_true_xyz.getNodeCount()); + EXPECT_TRUE(representative_true_xyz == ((bddX0 && bddY0) && bddZ0)); storm::dd::Bdd bddX1Y0Z0 = (bddX1 && bddY0) && bddZ0; EXPECT_EQ(1ul, bddX1Y0Z0.getNonZeroCount()); @@ -103,10 +132,6 @@ TEST(SylvanDd, BddExistAbstractRepresentative) { EXPECT_EQ(4ul, representative_xyz.getNodeCount()); EXPECT_TRUE(bddX1Y0Z0 == representative_xyz); - storm::dd::Bdd bddX0 = manager->getEncoding(x.first, 0); - storm::dd::Bdd bddY1 = manager->getEncoding(y.first, 1); - storm::dd::Bdd bddZ1 = manager->getEncoding(z.first, 1); - storm::dd::Bdd bddX0Y0Z0 = (bddX0 && bddY0) && bddZ0; storm::dd::Bdd bddX1Y1Z1 = (bddX1 && bddY1) && bddZ1; From 73a3461650650cc8ef457f200c0bcc1fe2377d4a Mon Sep 17 00:00:00 2001 From: PBerger Date: Mon, 22 Aug 2016 20:57:40 +0200 Subject: [PATCH 49/49] Fixed CUDD and Sylvan existsRepresentative. Former-commit-id: e3ec69ab377fc15e230380acfb19200efdd9038f --- .../3rdparty/cudd-3.0.0/cudd/cuddBddAbs.c | 19 +++++++++++++++++-- .../3rdparty/sylvan/src/sylvan_bdd_storm.c | 19 +------------------ test/functional/storage/CuddDdTest.cpp | 2 +- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/resources/3rdparty/cudd-3.0.0/cudd/cuddBddAbs.c b/resources/3rdparty/cudd-3.0.0/cudd/cuddBddAbs.c index 9643cbfaa..21160e263 100644 --- a/resources/3rdparty/cudd-3.0.0/cudd/cuddBddAbs.c +++ b/resources/3rdparty/cudd-3.0.0/cudd/cuddBddAbs.c @@ -542,12 +542,27 @@ cuddBddExistAbstractRepresentativeRecur( if (cube == one) { // printf("return in preprocessing...\n"); return one; - } + } else { + res = cuddBddExistAbstractRepresentativeRecur(manager, f, cuddT(cube)); + if (res == NULL) { + return(NULL); + } + cuddRef(res); + + res1 = cuddBddIteRecur(manager, manager->vars[cube->index], zero, res); + if (res1 == NULL) { + Cudd_IterDerefBdd(manager,res); + Cudd_IterDerefBdd(manager,zero); + return(NULL); + } + cuddDeref(res); + return(res1); + } } else if (cube == one) { // printf("return in preprocessing...\n"); return f; } - /* From now on, cube is non-constant, but f might be constant. */ + /* From now on, cube and f are non-constant. */ // printf("F perm %i and cube perm %i\n", manager->perm[F->index], manager->perm[cube->index]); diff --git a/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c b/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c index 4f0d3f81d..ff9fddc48 100644 --- a/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c +++ b/resources/3rdparty/sylvan/src/sylvan_bdd_storm.c @@ -80,24 +80,7 @@ TASK_IMPL_3(BDD, sylvan_existsRepresentative, BDD, a, BDD, variables, BDDVAR, pr return sylvan_invalid; } if (res1 == sylvan_true) { - BDD res = CALL(sylvan_existsRepresentative, a, _v, level); - if (res == sylvan_invalid) { - return sylvan_invalid; - } - sylvan_ref(res); - - BDD res1 = sylvan_ite(sylvan_ithvar(vv), sylvan_false, res); - - if (res1 == sylvan_invalid) { - sylvan_deref(res); - return sylvan_invalid; - } - sylvan_deref(res); - - //printf("return after abstr. var that does not appear in f...\n"); - return res1; - - //return sylvan_not(variables); + return sylvan_not(variables); } sylvan_ref(res1); diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp index b499da1b7..33a58ab4c 100644 --- a/test/functional/storage/CuddDdTest.cpp +++ b/test/functional/storage/CuddDdTest.cpp @@ -91,7 +91,7 @@ TEST(CuddDd, BddExistAbstractRepresentative) { storm::dd::Bdd representative_true_x = one.existsAbstractRepresentative({x.first}); EXPECT_EQ(0ul, representative_true_x.getNonZeroCount()); EXPECT_EQ(1ul, representative_true_x.getLeafCount()); - EXPECT_EQ(1ul, representative_true_x.getNodeCount()); + EXPECT_EQ(2ul, representative_true_x.getNodeCount()); EXPECT_TRUE(representative_true_x == bddX0); storm::dd::Bdd representative_true_xyz = one.existsAbstractRepresentative({x.first, y.first, z.first});