Browse Source
			
			
			Initial commit.
			
				
		Initial commit.
	
		
	
			
				The basic Implementation compiles. No tests yet.
Former-commit-id: 60b6d0f892
			
			
				main
			
			
		
				 9 changed files with 637 additions and 1 deletions
			
			
		- 
					2resources/3rdparty/CMakeLists.txt
 - 
					18resources/3rdparty/sylvan/CMakeLists.txt
 - 
					6resources/3rdparty/sylvan/examples/CMakeLists.txt
 - 
					127resources/3rdparty/sylvan/examples/storm.cpp
 - 
					9resources/3rdparty/sylvan/src/CMakeLists.txt
 - 
					116resources/3rdparty/sylvan/src/storm_function_wrapper.cpp
 - 
					33resources/3rdparty/sylvan/src/storm_function_wrapper.h
 - 
					240resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c
 - 
					87resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h
 
@ -0,0 +1,127 @@ | 
			
		|||||
 | 
				#ifdef NDEBUG
 | 
			
		||||
 | 
				#undef NDEBUG
 | 
			
		||||
 | 
				#endif
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include <assert.h>
 | 
			
		||||
 | 
				#include <stdio.h>
 | 
			
		||||
 | 
				#include <stdint.h>
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include <sylvan.h>
 | 
			
		||||
 | 
				#include <sylvan_obj.hpp>
 | 
			
		||||
 | 
				#include <storm_function_wrapper.h>
 | 
			
		||||
 | 
				#include <sylvan_storm_rational_function.h>
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				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<unsigned char> 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<uint8_t>({0, 0}))); | 
			
		||||
 | 
				    assert((!a * b)  == Bdd::bddCube(variables, std::vector<uint8_t>({0, 1}))); | 
			
		||||
 | 
				    assert((!a)      == Bdd::bddCube(variables, std::vector<uint8_t>({0, 2}))); | 
			
		||||
 | 
				    assert((a * !b)  == Bdd::bddCube(variables, std::vector<uint8_t>({1, 0}))); | 
			
		||||
 | 
				    assert((a * b)   == Bdd::bddCube(variables, std::vector<uint8_t>({1, 1}))); | 
			
		||||
 | 
				    assert((a)       == Bdd::bddCube(variables, std::vector<uint8_t>({1, 2}))); | 
			
		||||
 | 
				    assert((!b)      == Bdd::bddCube(variables, std::vector<uint8_t>({2, 0}))); | 
			
		||||
 | 
				    assert((b)       == Bdd::bddCube(variables, std::vector<uint8_t>({2, 1}))); | 
			
		||||
 | 
				    assert(one       == Bdd::bddCube(variables, std::vector<uint8_t>({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 <n_workers> 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
 | 
			
		||||
 | 
				} | 
			
		||||
@ -0,0 +1,116 @@ | 
			
		|||||
 | 
				#include "storm_function_wrapper.h"
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include <cstring>
 | 
			
		||||
 | 
				#include "src/adapters/CarlAdapter.h"
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				void storm_rational_function_init(storm_rational_function_ptr* a) { | 
			
		||||
 | 
					storm_rational_function_ptr srf_ptr = static_cast<storm_rational_function_ptr>(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; | 
			
		||||
 | 
					} | 
			
		||||
 | 
				} | 
			
		||||
@ -0,0 +1,33 @@ | 
			
		|||||
 | 
				#ifndef SYLVAN_STORM_FUNCTION_WRAPPER_H | 
			
		||||
 | 
				#define SYLVAN_STORM_FUNCTION_WRAPPER_H | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include <stdint.h> | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#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 | 
			
		||||
@ -0,0 +1,240 @@ | 
			
		|||||
 | 
				#include <sylvan_config.h> | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include <assert.h> | 
			
		||||
 | 
				#include <inttypes.h> | 
			
		||||
 | 
				#include <math.h> | 
			
		||||
 | 
				#include <stdint.h> | 
			
		||||
 | 
				#include <stdio.h> | 
			
		||||
 | 
				#include <stdlib.h> | 
			
		||||
 | 
				#include <string.h> | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include <sylvan.h> | 
			
		||||
 | 
				#include <sylvan_common.h> | 
			
		||||
 | 
				/*#include <sylvan_mtbdd_int.h>*/ | 
			
		||||
 | 
				#include <sylvan_storm_rational_function.h> | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#include <storm_function_wrapper.h> | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				/** | 
			
		||||
 | 
				 * helper function for hash | 
			
		||||
 | 
				 */ | 
			
		||||
 | 
				#ifndef rotl64 | 
			
		||||
 | 
				static inline uint64_t | 
			
		||||
 | 
				rotl64(uint64_t x, int8_t r) | 
			
		||||
 | 
				{ | 
			
		||||
 | 
				    return ((x<<r) | (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; | 
			
		||||
 | 
				} | 
			
		||||
@ -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 <sylvan.h> | 
			
		||||
 | 
				#include <storm_function_wrapper.h> | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#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 | 
			
		||||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue