Browse Source
separated rational numbers and rational functions and added support for rational numbers to sylvan
tempestpy_adaptions
separated rational numbers and rational functions and added support for rational numbers to sylvan
tempestpy_adaptions
dehnert
8 years ago
32 changed files with 2314 additions and 1718 deletions
-
3CMakeLists.txt
-
109resources/3rdparty/CMakeLists.txt
-
6resources/3rdparty/sylvan/src/CMakeLists.txt
-
475resources/3rdparty/sylvan/src/storm_function_wrapper.cpp
-
58resources/3rdparty/sylvan/src/storm_function_wrapper.h
-
612resources/3rdparty/sylvan/src/storm_wrapper.cpp
-
102resources/3rdparty/sylvan/src/storm_wrapper.h
-
44resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.c
-
2resources/3rdparty/sylvan/src/sylvan_mtbdd_storm.h
-
14resources/3rdparty/sylvan/src/sylvan_obj_bdd_storm.hpp
-
167resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp
-
408resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp
-
516resources/3rdparty/sylvan/src/sylvan_storm_rational_function.c
-
156resources/3rdparty/sylvan/src/sylvan_storm_rational_function.h
-
641resources/3rdparty/sylvan/src/sylvan_storm_rational_number.c
-
89resources/3rdparty/sylvan/src/sylvan_storm_rational_number.h
-
59src/storm/adapters/CarlAdapter.h
-
38src/storm/adapters/NumberAdapter.h
-
2src/storm/generator/JaniNextStateGenerator.cpp
-
37src/storm/storage/dd/Add.cpp
-
16src/storm/storage/dd/Add.h
-
192src/storm/storage/dd/sylvan/InternalSylvanAdd.cpp
-
19src/storm/storage/dd/sylvan/InternalSylvanAdd.h
-
26src/storm/storage/dd/sylvan/InternalSylvanDdManager.cpp
-
3src/storm/storage/dd/sylvan/SylvanAddIterator.cpp
-
2src/storm/storage/geometry/NativePolytope.cpp
-
4src/storm/storage/geometry/nativepolytopeconversion/HyperplaneEnumeration.cpp
-
6src/storm/storage/geometry/nativepolytopeconversion/QuickHull.cpp
-
5src/storm/utility/constants.cpp
-
1src/storm/utility/sylvan.h
-
211src/test/storage/SylvanDdTest.cpp
-
9storm-config.h.in
@ -1,475 +0,0 @@ |
|||
#include "storm_function_wrapper.h"
|
|||
|
|||
#include <cstring>
|
|||
#include <iostream>
|
|||
#include <sstream>
|
|||
#include <set>
|
|||
#include <map>
|
|||
#include <mutex>
|
|||
|
|||
#include "storm/adapters/CarlAdapter.h"
|
|||
#include "storm/utility/constants.h"
|
|||
#include "sylvan_storm_rational_function.h"
|
|||
|
|||
#include "storm/exceptions/InvalidOperationException.h"
|
|||
|
|||
#include <sylvan_config.h>
|
|||
#include <sylvan.h>
|
|||
#include <sylvan_common.h>
|
|||
#include <sylvan_mtbdd.h>
|
|||
|
|||
std::mutex carlMutex; |
|||
|
|||
void storm_rational_function_init(storm_rational_function_ptr* a) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
{ |
|||
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; |
|||
} |
|||
} |
|||
|
|||
void storm_rational_function_destroy(storm_rational_function_ptr a) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
{ |
|||
storm::RationalFunction* srf = (storm::RationalFunction*)a; |
|||
delete srf; |
|||
} |
|||
} |
|||
|
|||
int storm_rational_function_equals(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
int result = 0; |
|||
{ |
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
storm::RationalFunction& srf_b = *(storm::RationalFunction*)b; |
|||
|
|||
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) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
storm_rational_function_ptr result = (storm_rational_function_ptr)nullptr; |
|||
|
|||
{ |
|||
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 result; |
|||
} |
|||
|
|||
*result_srf += srf_b; |
|||
result = (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_minus(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
storm_rational_function_ptr result = (storm_rational_function_ptr)nullptr; |
|||
|
|||
{ |
|||
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 result; |
|||
} |
|||
|
|||
*result_srf -= srf_b; |
|||
result = (storm_rational_function_ptr)result_srf; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_times(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
storm_rational_function_ptr result = (storm_rational_function_ptr)nullptr; |
|||
|
|||
{ |
|||
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 result; |
|||
} |
|||
|
|||
*result_srf *= srf_b; |
|||
result = (storm_rational_function_ptr)result_srf; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_divide(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
storm_rational_function_ptr result = (storm_rational_function_ptr)nullptr; |
|||
|
|||
{ |
|||
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 result; |
|||
} |
|||
|
|||
*result_srf /= srf_b; |
|||
result = (storm_rational_function_ptr)result_srf; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_pow(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
storm_rational_function_ptr result = (storm_rational_function_ptr)nullptr; |
|||
|
|||
{ |
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
storm::RationalFunction& srf_b = *(storm::RationalFunction*)b; |
|||
|
|||
uint64_t exponentAsInteger = carl::toInt<unsigned long>(srf_b.nominatorAsNumber()); |
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(carl::pow(srf_a, exponentAsInteger)); |
|||
if (result_srf == nullptr) { |
|||
std::cerr << "Could not allocate memory in storm_rational_function_pow()!" << std::endl; |
|||
return result; |
|||
} |
|||
result = (storm_rational_function_ptr)result_srf; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_mod(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
storm_rational_function_ptr result = (storm_rational_function_ptr)nullptr; |
|||
|
|||
{ |
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
storm::RationalFunction& srf_b = *(storm::RationalFunction*)b; |
|||
if (!storm::utility::isInteger(srf_a) || !storm::utility::isInteger(srf_b)) { |
|||
throw storm::exceptions::InvalidOperationException() << "Operands of mod must not be rational function."; |
|||
} |
|||
throw storm::exceptions::InvalidOperationException() << "Modulo not supported for rationals."; |
|||
|
|||
// storm::RationalFunction* result_srf = new storm::RationalFunction(carl::mod(srf_a.nominatorAsNumber(), srf_b.nominatorAsNumber()));
|
|||
// if (result_srf == nullptr) {
|
|||
// std::cerr << "Could not allocate memory in storm_rational_function_pow()!" << std::endl;
|
|||
// return result;
|
|||
// }
|
|||
// result = (storm_rational_function_ptr)result_srf;
|
|||
|
|||
} |
|||
return result; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_min(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
storm_rational_function_ptr result = (storm_rational_function_ptr)nullptr; |
|||
|
|||
{ |
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
storm::RationalFunction& srf_b = *(storm::RationalFunction*)b; |
|||
if (!storm::utility::isInteger(srf_a) || !storm::utility::isInteger(srf_b)) { |
|||
throw storm::exceptions::InvalidOperationException() << "Operands of min must not be rational function."; |
|||
} |
|||
|
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(std::min(srf_a.nominatorAsNumber(), srf_b.nominatorAsNumber())); |
|||
if (result_srf == nullptr) { |
|||
std::cerr << "Could not allocate memory in storm_rational_function_pow()!" << std::endl; |
|||
return result; |
|||
} |
|||
result = (storm_rational_function_ptr)result_srf; |
|||
|
|||
} |
|||
return result; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_max(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
storm_rational_function_ptr result = (storm_rational_function_ptr)nullptr; |
|||
|
|||
{ |
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
storm::RationalFunction& srf_b = *(storm::RationalFunction*)b; |
|||
if (!storm::utility::isInteger(srf_a) || !storm::utility::isInteger(srf_b)) { |
|||
throw storm::exceptions::InvalidOperationException() << "Operands of max must not be rational function."; |
|||
} |
|||
|
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(std::max(srf_a.nominatorAsNumber(), srf_b.nominatorAsNumber())); |
|||
if (result_srf == nullptr) { |
|||
std::cerr << "Could not allocate memory in storm_rational_function_pow()!" << std::endl; |
|||
return result; |
|||
} |
|||
result = (storm_rational_function_ptr)result_srf; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
int storm_rational_function_less(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
|
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
storm::RationalFunction& srf_b = *(storm::RationalFunction*)b; |
|||
if (!storm::utility::isInteger(srf_a) || !storm::utility::isInteger(srf_b)) { |
|||
throw storm::exceptions::InvalidOperationException() << "Operands of less must not be rational functions."; |
|||
} |
|||
|
|||
if (srf_a.nominatorAsNumber() < srf_b.nominatorAsNumber()) { |
|||
return 1; |
|||
} else { |
|||
return 0; |
|||
} |
|||
return -1; |
|||
} |
|||
|
|||
int storm_rational_function_less_or_equal(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
|
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
storm::RationalFunction& srf_b = *(storm::RationalFunction*)b; |
|||
if (!storm::utility::isInteger(srf_a) || !storm::utility::isInteger(srf_b)) { |
|||
throw storm::exceptions::InvalidOperationException() << "Operands of less-or-equal must not be rational functions."; |
|||
} |
|||
if (srf_a.nominatorAsNumber() <= srf_b.nominatorAsNumber()) { |
|||
return 1; |
|||
} else { |
|||
return 0; |
|||
} |
|||
|
|||
return -1; |
|||
} |
|||
|
|||
uint64_t storm_rational_function_hash(storm_rational_function_ptr const a, uint64_t const seed) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
|
|||
uint64_t result = seed; |
|||
{ |
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
// carl::hash_add(result, srf_a);
|
|||
result = seed ^ (carl::hash_value(srf_a) + 0x9e3779b9 + (seed<<6) + (seed>>2)); |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_negate(storm_rational_function_ptr a) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
storm_rational_function_ptr result = (storm_rational_function_ptr)nullptr; |
|||
|
|||
{ |
|||
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 result; |
|||
} |
|||
|
|||
*result_srf = -srf_a; |
|||
result = (storm_rational_function_ptr)result_srf; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_floor(storm_rational_function_ptr a) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
storm_rational_function_ptr result = (storm_rational_function_ptr)nullptr; |
|||
|
|||
{ |
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
if (!storm::utility::isInteger(srf_a)) { |
|||
throw storm::exceptions::InvalidOperationException() << "Operand of floor must not be rational function."; |
|||
} |
|||
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 result; |
|||
} |
|||
|
|||
*result_srf = storm::RationalFunction(carl::floor(srf_a.nominatorAsNumber())); |
|||
result = (storm_rational_function_ptr)result_srf; |
|||
|
|||
} |
|||
return result; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_ceil(storm_rational_function_ptr a) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
storm_rational_function_ptr result = (storm_rational_function_ptr)nullptr; |
|||
|
|||
{ |
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
if (!storm::utility::isInteger(srf_a)) { |
|||
throw storm::exceptions::InvalidOperationException() << "Operand of ceil must not be rational function."; |
|||
} |
|||
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 result; |
|||
} |
|||
|
|||
*result_srf = storm::RationalFunction(carl::ceil(srf_a.nominatorAsNumber())); |
|||
result = (storm_rational_function_ptr)result_srf; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
int storm_rational_function_is_zero(storm_rational_function_ptr a) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
|
|||
bool resultIsZero = false; |
|||
{ |
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
resultIsZero = srf_a.isZero(); |
|||
} |
|||
|
|||
if (resultIsZero) { |
|||
return 1; |
|||
} else { |
|||
return 0; |
|||
} |
|||
} |
|||
|
|||
double storm_rational_function_get_constant(storm_rational_function_ptr a) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
|
|||
double result = -1.0; |
|||
{ |
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
|
|||
if (srf_a.isConstant()) { |
|||
result = carl::toDouble(storm::RationalNumber(srf_a.nominatorAsNumber() / srf_a.denominatorAsNumber())); |
|||
} else { |
|||
std::cout << "Defaulting to -1.0 since this is not a constant: " << srf_a << std::endl; |
|||
} |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_get_zero() { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
storm_rational_function_ptr result = (storm_rational_function_ptr)nullptr; |
|||
|
|||
{ |
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(0); |
|||
if (result_srf == nullptr) { |
|||
std::cerr << "Could not allocate memory in storm_rational_function_get_zero()!" << std::endl; |
|||
return result; |
|||
} |
|||
result = (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_get_one() { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
storm_rational_function_ptr result = (storm_rational_function_ptr)nullptr; |
|||
|
|||
{ |
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(1); |
|||
if (result_srf == nullptr) { |
|||
std::cerr << "Could not allocate memory in storm_rational_function_get_one()!" << std::endl; |
|||
return result; |
|||
} |
|||
result = (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
void print_storm_rational_function(storm_rational_function_ptr a) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
{ |
|||
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::lock_guard<std::mutex> lock(carlMutex); |
|||
{ |
|||
std::stringstream ss; |
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
ss << srf_a; |
|||
std::string s = ss.str(); |
|||
fprintf(out, "%s", s.c_str()); |
|||
} |
|||
} |
|||
|
|||
MTBDD testiTest(storm::RationalFunction const& currentFunction, std::map<uint32_t, std::pair<storm::RationalFunctionVariable, std::pair<storm::RationalNumber, storm::RationalNumber>>> const& replacements) { |
|||
if (currentFunction.isConstant()) { |
|||
return mtbdd_storm_rational_function((storm_rational_function_ptr)¤tFunction); |
|||
} |
|||
|
|||
std::set<storm::RationalFunctionVariable> variablesInFunction = currentFunction.gatherVariables(); |
|||
std::map<uint32_t, std::pair<storm::RationalFunctionVariable, std::pair<storm::RationalNumber, storm::RationalNumber>>>::const_iterator it = replacements.cbegin(); |
|||
std::map<uint32_t, std::pair<storm::RationalFunctionVariable, std::pair<storm::RationalNumber, storm::RationalNumber>>>::const_iterator end = replacements.cend(); |
|||
|
|||
// Walking the (ordered) map enforces an ordering on the MTBDD
|
|||
for (; it != end; ++it) { |
|||
if (variablesInFunction.find(it->second.first) != variablesInFunction.cend()) { |
|||
std::map<storm::RationalFunctionVariable, storm::RationalNumber> highReplacement = {{it->second.first, it->second.second.first}}; |
|||
std::map<storm::RationalFunctionVariable, storm::RationalNumber> lowReplacement = {{it->second.first, it->second.second.second}}; |
|||
|
|||
std::lock_guard<std::mutex>* lock = new std::lock_guard<std::mutex>(carlMutex); |
|||
storm::RationalFunction const highSrf = currentFunction.substitute(highReplacement); |
|||
storm::RationalFunction const lowSrf = currentFunction.substitute(lowReplacement); |
|||
delete lock; |
|||
|
|||
MTBDD high = testiTest(highSrf, replacements); |
|||
MTBDD low = testiTest(lowSrf, replacements); |
|||
LACE_ME |
|||
return mtbdd_ite(mtbdd_ithvar(it->first), high, low); |
|||
} else { |
|||
//std::cout << "No match for variable " << it->second.first << std::endl;
|
|||
} |
|||
} |
|||
|
|||
return mtbdd_storm_rational_function((storm_rational_function_ptr)¤tFunction); |
|||
} |
|||
|
|||
|
|||
MTBDD storm_rational_function_leaf_parameter_replacement(MTBDD dd, storm_rational_function_ptr a, void* context) { |
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)a; |
|||
{ |
|||
// Scope the lock.
|
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
if (srf_a.isConstant()) { |
|||
return dd; |
|||
} |
|||
} |
|||
|
|||
std::map<uint32_t, std::pair<storm::RationalFunctionVariable, std::pair<storm::RationalNumber, storm::RationalNumber>>>* replacements = (std::map<uint32_t, std::pair<storm::RationalFunctionVariable, std::pair<storm::RationalNumber, storm::RationalNumber>>>*)context; |
|||
return testiTest(srf_a, *replacements); |
|||
} |
|||
|
|||
char* storm_rational_function_to_str(storm_rational_function_ptr val, char *buf, size_t buflen) { |
|||
std::lock_guard<std::mutex> lock(carlMutex); |
|||
std::stringstream ss; |
|||
storm::RationalFunction& srf_a = *(storm::RationalFunction*)val; |
|||
ss << srf_a; |
|||
std::string s = ss.str(); |
|||
char* result = (char*)malloc(s.size() + 1); |
|||
std::memcpy(result, s.c_str(), s.size() + 1); |
|||
return result; |
|||
} |
@ -1,58 +0,0 @@ |
|||
#ifndef SYLVAN_STORM_FUNCTION_WRAPPER_H |
|||
#define SYLVAN_STORM_FUNCTION_WRAPPER_H |
|||
|
|||
#include <stdint.h> |
|||
#include <stdio.h> |
|||
#include <sylvan.h> |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
typedef void* storm_rational_function_ptr; |
|||
|
|||
// basic functions (for sylvan) |
|||
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); |
|||
|
|||
// binary |
|||
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_pow(storm_rational_function_ptr a, storm_rational_function_ptr b); |
|||
|
|||
storm_rational_function_ptr storm_rational_function_mod(storm_rational_function_ptr a, storm_rational_function_ptr b); |
|||
storm_rational_function_ptr storm_rational_function_min(storm_rational_function_ptr a, storm_rational_function_ptr b); |
|||
storm_rational_function_ptr storm_rational_function_max(storm_rational_function_ptr a, storm_rational_function_ptr b); |
|||
|
|||
int storm_rational_function_less(storm_rational_function_ptr a, storm_rational_function_ptr b); |
|||
int storm_rational_function_less_or_equal(storm_rational_function_ptr a, storm_rational_function_ptr b); |
|||
|
|||
// unary |
|||
storm_rational_function_ptr storm_rational_function_negate(storm_rational_function_ptr a); |
|||
|
|||
storm_rational_function_ptr storm_rational_function_floor(storm_rational_function_ptr a); |
|||
storm_rational_function_ptr storm_rational_function_ceil(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); |
|||
|
|||
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); |
|||
|
|||
MTBDD storm_rational_function_leaf_parameter_replacement(MTBDD dd, storm_rational_function_ptr a, void* context); |
|||
|
|||
double storm_rational_function_get_constant(storm_rational_function_ptr a); |
|||
|
|||
char* storm_rational_function_to_str(storm_rational_function_ptr val, char *buf, size_t buflen); |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif // SYLVAN_STORM_FUNCTION_WRAPPER_H |
@ -0,0 +1,612 @@ |
|||
#include "storm_wrapper.h"
|
|||
|
|||
#include <cstring>
|
|||
#include <iostream>
|
|||
#include <sstream>
|
|||
#include <set>
|
|||
#include <map>
|
|||
#include <mutex>
|
|||
|
|||
#include "storm/adapters/CarlAdapter.h"
|
|||
#include "storm/utility/constants.h"
|
|||
#include "storm/exceptions/InvalidOperationException.h"
|
|||
|
|||
#include <sylvan_config.h>
|
|||
#include <sylvan.h>
|
|||
#include <sylvan_common.h>
|
|||
#include <sylvan_mtbdd.h>
|
|||
|
|||
// TODO: remove and replace by proper detection in cmake
|
|||
#define RATIONAL_NUMBER_THREAD_SAFE
|
|||
|
|||
// A mutex that is used to lock all operations accessing rational numbers as they are not necessarily thread-safe.
|
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::mutex rationalNumberMutex; |
|||
#endif
|
|||
|
|||
// A mutex that is used to lock all operations accessing rational functions as carl is not necessarily thread-safe.
|
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::mutex rationalFunctionMutex; |
|||
#endif
|
|||
|
|||
/***************************************************
|
|||
Function-wrappers for storm::RationalNumber |
|||
****************************************************/ |
|||
|
|||
void storm_rational_number_init(storm_rational_number_ptr* a) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm_rational_number_ptr srn_ptr = new storm::RationalNumber(*((storm::RationalNumber*)(*a))); |
|||
*a = srn_ptr; |
|||
} |
|||
|
|||
void storm_rational_number_destroy(storm_rational_number_ptr a) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction* srn_ptr = (storm::RationalFunction*)a; |
|||
delete srn_ptr; |
|||
} |
|||
|
|||
int storm_rational_number_equals(storm_rational_number_ptr a, storm_rational_number_ptr b) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber*)a; |
|||
storm::RationalNumber const& srn_b = *(storm::RationalNumber*)b; |
|||
|
|||
return (srn_a == srn_b) ? 1 : 0; |
|||
} |
|||
|
|||
char* storm_rational_number_to_str(storm_rational_number_ptr val, char *buf, size_t buflen) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
std::stringstream ss; |
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber*)val; |
|||
ss << srn_a; |
|||
std::string s = ss.str(); |
|||
if (s.size() < buflen + 1) { |
|||
std::memcpy(buf, s.c_str(), s.size() + 1); |
|||
return buf; |
|||
} else { |
|||
char* result = (char*)malloc(s.size() + 1); |
|||
std::memcpy(result, s.c_str(), s.size() + 1); |
|||
return result; |
|||
} |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_clone(storm_rational_number_ptr a) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber* result_srn = new storm::RationalNumber(*((storm::RationalNumber const*)a)); |
|||
return (storm_rational_number_ptr)result_srn; |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_get_zero() { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber* result_srn = new storm::RationalNumber(storm::utility::zero<storm::RationalNumber>()); |
|||
return (storm_rational_number_ptr)result_srn; |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_get_one() { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber* result_srn = new storm::RationalNumber(storm::utility::one<storm::RationalNumber>()); |
|||
return (storm_rational_number_ptr)result_srn; |
|||
} |
|||
|
|||
int storm_rational_number_is_zero(storm_rational_number_ptr a) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
return storm::utility::isZero(*(storm::RationalNumber const*)a) ? 1 : 0; |
|||
} |
|||
|
|||
uint64_t storm_rational_number_hash(storm_rational_number_ptr const a, uint64_t const seed) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
|
|||
// Taken from boost::hash_combine that we do not call here for the lack of boost headers.
|
|||
return seed ^ (std::hash<storm::RationalNumber>()(srn_a) + 0x9e3779b9 + (seed<<6) + (seed>>2)); |
|||
} |
|||
|
|||
double storm_rational_number_get_value_double(storm_rational_number_ptr a) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
return storm::utility::convertNumber<double>(srn_a); |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_plus(storm_rational_number_ptr a, storm_rational_number_ptr b) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
storm::RationalNumber const& srn_b = *(storm::RationalNumber const*)b; |
|||
|
|||
storm::RationalNumber* result_srn = new storm::RationalNumber(srn_a + srn_b); |
|||
return (storm_rational_number_ptr)result_srn; |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_minus(storm_rational_number_ptr a, storm_rational_number_ptr b) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
storm::RationalNumber const& srn_b = *(storm::RationalNumber const*)b; |
|||
|
|||
storm::RationalNumber* result_srn = new storm::RationalNumber(srn_a - srn_b); |
|||
return (storm_rational_number_ptr)result_srn; |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_times(storm_rational_number_ptr a, storm_rational_number_ptr b) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
storm::RationalNumber const& srn_b = *(storm::RationalNumber const*)b; |
|||
|
|||
storm::RationalNumber* result_srn = new storm::RationalNumber(srn_a * srn_b); |
|||
return (storm_rational_number_ptr)result_srn; |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_divide(storm_rational_number_ptr a, storm_rational_number_ptr b) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
storm::RationalNumber const& srn_b = *(storm::RationalNumber const*)b; |
|||
|
|||
storm::RationalNumber* result_srn = new storm::RationalNumber(srn_a / srn_b); |
|||
return (storm_rational_number_ptr)result_srn; |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_pow(storm_rational_number_ptr a, storm_rational_number_ptr b) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
storm::RationalNumber const& srn_b = *(storm::RationalNumber const*)b; |
|||
|
|||
uint64_t exponentAsInteger = carl::toInt<unsigned long>(srn_b); |
|||
storm::RationalNumber* result_srn = new storm::RationalNumber(carl::pow(srn_a, exponentAsInteger)); |
|||
return (storm_rational_number_ptr)result_srn; |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_mod(storm_rational_number_ptr a, storm_rational_number_ptr b) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
storm::RationalNumber const& srn_b = *(storm::RationalNumber const*)b; |
|||
|
|||
throw storm::exceptions::InvalidOperationException() << "Modulo not supported for rational numbers."; |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_min(storm_rational_number_ptr a, storm_rational_number_ptr b) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
return storm_rational_number_less_or_equal(a, b) ? storm_rational_number_clone(a) : storm_rational_number_clone(b); |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_max(storm_rational_number_ptr a, storm_rational_number_ptr b) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
return storm_rational_number_less(a, b) ? storm_rational_number_clone(b) : storm_rational_number_clone(a); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
int storm_rational_number_less(storm_rational_number_ptr a, storm_rational_number_ptr b) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
storm::RationalNumber const& srn_b = *(storm::RationalNumber const*)b; |
|||
|
|||
return srn_a < srn_b ? 1 : 0; |
|||
} |
|||
|
|||
int storm_rational_number_less_or_equal(storm_rational_number_ptr a, storm_rational_number_ptr b) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
storm::RationalNumber const& srn_b = *(storm::RationalNumber const*)b; |
|||
|
|||
return srn_a <= srn_b ? 1 : 0; |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_negate(storm_rational_number_ptr a) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
storm::RationalNumber* result_srn = new storm::RationalNumber(-srn_a); |
|||
return (storm_rational_number_ptr)result_srn; |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_floor(storm_rational_number_ptr a) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
storm::RationalNumber* result_srn = new storm::RationalNumber(carl::floor(srn_a)); |
|||
return (storm_rational_number_ptr)result_srn; |
|||
} |
|||
|
|||
storm_rational_number_ptr storm_rational_number_ceil(storm_rational_number_ptr a) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
storm::RationalNumber* result_srn = new storm::RationalNumber(carl::ceil(srn_a)); |
|||
return (storm_rational_number_ptr)result_srn; |
|||
} |
|||
|
|||
|
|||
void print_storm_rational_number(storm_rational_number_ptr a) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
std::cout << srn_a << std::flush; |
|||
} |
|||
|
|||
void print_storm_rational_number_to_file(storm_rational_number_ptr a, FILE* out) { |
|||
#ifndef RATIONAL_NUMBER_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalNumberMutex); |
|||
#endif
|
|||
|
|||
std::stringstream ss; |
|||
storm::RationalNumber const& srn_a = *(storm::RationalNumber const*)a; |
|||
ss << srn_a; |
|||
std::string s = ss.str(); |
|||
fprintf(out, "%s", s.c_str()); |
|||
} |
|||
|
|||
/***************************************************
|
|||
Function-wrappers for storm::RationalFunction |
|||
****************************************************/ |
|||
|
|||
void storm_rational_function_init(storm_rational_function_ptr* a) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm_rational_function_ptr srf_ptr = new storm::RationalFunction(*((storm::RationalFunction*)(*a))); |
|||
*a = srf_ptr; |
|||
} |
|||
|
|||
void storm_rational_function_destroy(storm_rational_function_ptr a) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction* srf = (storm::RationalFunction*)a; |
|||
delete srf; |
|||
} |
|||
|
|||
int storm_rational_function_equals(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction*)a; |
|||
storm::RationalFunction const& srf_b = *(storm::RationalFunction*)b; |
|||
|
|||
return (srf_a == srf_b) ? 1 : 0; |
|||
} |
|||
|
|||
char* storm_rational_function_to_str(storm_rational_function_ptr val, char *buf, size_t buflen) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
std::stringstream ss; |
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction*)val; |
|||
ss << srf_a; |
|||
std::string s = ss.str(); |
|||
if (s.size() < buflen + 1) { |
|||
std::memcpy(buf, s.c_str(), s.size() + 1); |
|||
return buf; |
|||
} else { |
|||
char* result = (char*)malloc(s.size() + 1); |
|||
std::memcpy(result, s.c_str(), s.size() + 1); |
|||
return result; |
|||
} |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_clone(storm_rational_function_ptr a) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(*((storm::RationalFunction const*)a)); |
|||
return (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_get_zero() { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(storm::utility::zero<storm::RationalFunction>()); |
|||
return (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_get_one() { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(storm::utility::one<storm::RationalFunction>()); |
|||
return (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
int storm_rational_function_is_zero(storm_rational_function_ptr a) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
return storm::utility::isZero(*(storm::RationalFunction const*)a) ? 1 : 0; |
|||
} |
|||
|
|||
uint64_t storm_rational_function_hash(storm_rational_function_ptr const a, uint64_t const seed) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
|
|||
// Taken from boost::hash_combine that we do not call here for the lack of boost headers.
|
|||
return seed ^ (carl::hash_value(srf_a) + 0x9e3779b9 + (seed<<6) + (seed>>2)); |
|||
} |
|||
|
|||
double storm_rational_function_get_value_double(storm_rational_function_ptr a) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
if (srf_a.isConstant()) { |
|||
return storm::utility::convertNumber<double>(srf_a); |
|||
} else { |
|||
throw storm::exceptions::InvalidOperationException() << "Cannot evaluate rational function as it's not constant."; |
|||
} |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_plus(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
storm::RationalFunction const& srf_b = *(storm::RationalFunction const*)b; |
|||
|
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); |
|||
*result_srf += srf_b; |
|||
return (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_minus(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
storm::RationalFunction const& srf_b = *(storm::RationalFunction const*)b; |
|||
|
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); |
|||
*result_srf -= srf_b; |
|||
return (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_times(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
storm::RationalFunction const& srf_b = *(storm::RationalFunction const*)b; |
|||
|
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); |
|||
*result_srf *= srf_b; |
|||
return (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_divide(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
storm::RationalFunction const& srf_b = *(storm::RationalFunction const*)b; |
|||
|
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(srf_a); |
|||
*result_srf *= srf_b; |
|||
return (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_pow(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
storm::RationalFunction const& srf_b = *(storm::RationalFunction const*)b; |
|||
|
|||
uint64_t exponentAsInteger = carl::toInt<unsigned long>(srf_b.nominatorAsNumber()); |
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(carl::pow(srf_a, exponentAsInteger)); |
|||
return (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_mod(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
storm::RationalFunction const& srf_b = *(storm::RationalFunction const*)b; |
|||
|
|||
if (!storm::utility::isInteger(srf_a) || !storm::utility::isInteger(srf_b)) { |
|||
throw storm::exceptions::InvalidOperationException() << "Operands of mod must not be non-constant rational functions."; |
|||
} |
|||
throw storm::exceptions::InvalidOperationException() << "Modulo not supported for rational functions."; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_min(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
if (storm_rational_function_less_or_equal(a, b)) { |
|||
return storm_rational_function_clone(a); |
|||
} else { |
|||
return storm_rational_function_clone(b); |
|||
} |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_max(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
if (storm_rational_function_less(a, b)) { |
|||
return storm_rational_function_clone(b); |
|||
} else { |
|||
return storm_rational_function_clone(a); |
|||
} |
|||
} |
|||
|
|||
int storm_rational_function_less(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
storm::RationalFunction const& srf_b = *(storm::RationalFunction const*)b; |
|||
if (!storm::utility::isInteger(srf_a) || !storm::utility::isInteger(srf_b)) { |
|||
throw storm::exceptions::InvalidOperationException() << "Operands of less must not be non-constant rational functions."; |
|||
} |
|||
|
|||
if (srf_a.nominatorAsNumber() < srf_b.nominatorAsNumber()) { |
|||
return 1; |
|||
} else { |
|||
return 0; |
|||
} |
|||
return -1; |
|||
} |
|||
|
|||
int storm_rational_function_less_or_equal(storm_rational_function_ptr a, storm_rational_function_ptr b) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
storm::RationalFunction const& srf_b = *(storm::RationalFunction const*)b; |
|||
if (!storm::utility::isInteger(srf_a) || !storm::utility::isInteger(srf_b)) { |
|||
throw storm::exceptions::InvalidOperationException() << "Operands of less-or-equal must not be non-constant rational functions."; |
|||
} |
|||
|
|||
if (srf_a.nominatorAsNumber() <= srf_b.nominatorAsNumber()) { |
|||
return 1; |
|||
} else { |
|||
return 0; |
|||
} |
|||
return -1; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_negate(storm_rational_function_ptr a) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(-srf_a); |
|||
return (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_floor(storm_rational_function_ptr a) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
if (!storm::utility::isInteger(srf_a)) { |
|||
throw storm::exceptions::InvalidOperationException() << "Operand of floor must not be non-constant rational function."; |
|||
} |
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(carl::floor(srf_a.nominatorAsNumber())); |
|||
return (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
storm_rational_function_ptr storm_rational_function_ceil(storm_rational_function_ptr a) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
if (!storm::utility::isInteger(srf_a)) { |
|||
throw storm::exceptions::InvalidOperationException() << "Operand of ceil must not be non-constant rational function."; |
|||
} |
|||
storm::RationalFunction* result_srf = new storm::RationalFunction(carl::ceil(srf_a.nominatorAsNumber())); |
|||
return (storm_rational_function_ptr)result_srf; |
|||
} |
|||
|
|||
|
|||
void print_storm_rational_function(storm_rational_function_ptr a) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
std::cout << srf_a << std::flush; |
|||
} |
|||
|
|||
void print_storm_rational_function_to_file(storm_rational_function_ptr a, FILE* out) { |
|||
#ifndef RATIONAL_FUNCTION_THREAD_SAFE
|
|||
std::lock_guard<std::mutex> lock(rationalFunctionMutex); |
|||
#endif
|
|||
|
|||
std::stringstream ss; |
|||
storm::RationalFunction const& srf_a = *(storm::RationalFunction const*)a; |
|||
ss << srf_a; |
|||
std::string s = ss.str(); |
|||
fprintf(out, "%s", s.c_str()); |
|||
} |
@ -0,0 +1,102 @@ |
|||
#ifndef SYLVAN_STORM_FUNCTION_WRAPPER_H |
|||
#define SYLVAN_STORM_FUNCTION_WRAPPER_H |
|||
|
|||
#include <stdint.h> |
|||
#include <stdio.h> |
|||
#include <sylvan.h> |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/*************************************************** |
|||
Function-wrappers for storm::RationalNumber |
|||
****************************************************/ |
|||
|
|||
typedef void* storm_rational_number_ptr; |
|||
|
|||
// Functions that are registered to sylvan for the rational number type. |
|||
void storm_rational_number_init(storm_rational_number_ptr* a); |
|||
void storm_rational_number_destroy(storm_rational_number_ptr a); |
|||
int storm_rational_number_equals(storm_rational_number_ptr a, storm_rational_number_ptr b); |
|||
char* storm_rational_number_to_str(storm_rational_number_ptr val, char *buf, size_t buflen); |
|||
|
|||
// Fundamental functions. |
|||
storm_rational_number_ptr storm_rational_number_clone(storm_rational_number_ptr a); |
|||
storm_rational_number_ptr storm_rational_number_get_zero(); |
|||
storm_rational_number_ptr storm_rational_number_get_one(); |
|||
int storm_rational_number_is_zero(storm_rational_number_ptr a); |
|||
uint64_t storm_rational_number_hash(storm_rational_number_ptr const a, uint64_t const seed); |
|||
double storm_rational_number_get_value_double(storm_rational_number_ptr a); |
|||
|
|||
// Binary operations. |
|||
storm_rational_number_ptr storm_rational_number_plus(storm_rational_number_ptr a, storm_rational_number_ptr b); |
|||
storm_rational_number_ptr storm_rational_number_minus(storm_rational_number_ptr a, storm_rational_number_ptr b); |
|||
storm_rational_number_ptr storm_rational_number_times(storm_rational_number_ptr a, storm_rational_number_ptr b); |
|||
storm_rational_number_ptr storm_rational_number_divide(storm_rational_number_ptr a, storm_rational_number_ptr b); |
|||
storm_rational_number_ptr storm_rational_number_pow(storm_rational_number_ptr a, storm_rational_number_ptr b); |
|||
storm_rational_number_ptr storm_rational_number_mod(storm_rational_number_ptr a, storm_rational_number_ptr b); |
|||
storm_rational_number_ptr storm_rational_number_min(storm_rational_number_ptr a, storm_rational_number_ptr b); |
|||
storm_rational_number_ptr storm_rational_number_max(storm_rational_number_ptr a, storm_rational_number_ptr b); |
|||
|
|||
// Binary relations. |
|||
int storm_rational_number_less(storm_rational_number_ptr a, storm_rational_number_ptr b); |
|||
int storm_rational_number_less_or_equal(storm_rational_number_ptr a, storm_rational_number_ptr b); |
|||
|
|||
// Unary operations. |
|||
storm_rational_number_ptr storm_rational_number_negate(storm_rational_number_ptr a); |
|||
storm_rational_number_ptr storm_rational_number_floor(storm_rational_number_ptr a); |
|||
storm_rational_number_ptr storm_rational_number_ceil(storm_rational_number_ptr a); |
|||
|
|||
// Printing functions. |
|||
void print_storm_rational_number(storm_rational_number_ptr a); |
|||
void print_storm_rational_number_to_file(storm_rational_number_ptr a, FILE* out); |
|||
|
|||
/*************************************************** |
|||
Function-wrappers for storm::RationalFunction |
|||
****************************************************/ |
|||
|
|||
typedef void* storm_rational_function_ptr; |
|||
|
|||
// Functions that are registered to sylvan for the rational function type. |
|||
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); |
|||
char* storm_rational_function_to_str(storm_rational_function_ptr val, char *buf, size_t buflen); |
|||
|
|||
// Fundamental functions. |
|||
storm_rational_function_ptr storm_rational_function_clone(storm_rational_function_ptr a); |
|||
storm_rational_function_ptr storm_rational_function_get_zero(); |
|||
storm_rational_function_ptr storm_rational_function_get_one(); |
|||
int storm_rational_function_is_zero(storm_rational_function_ptr a); |
|||
uint64_t storm_rational_function_hash(storm_rational_function_ptr const a, uint64_t const seed); |
|||
double storm_rational_function_get_value_double(storm_rational_function_ptr a); |
|||
|
|||
// Binary operations. |
|||
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_pow(storm_rational_function_ptr a, storm_rational_function_ptr b); |
|||
storm_rational_function_ptr storm_rational_function_mod(storm_rational_function_ptr a, storm_rational_function_ptr b); |
|||
storm_rational_function_ptr storm_rational_function_min(storm_rational_function_ptr a, storm_rational_function_ptr b); |
|||
storm_rational_function_ptr storm_rational_function_max(storm_rational_function_ptr a, storm_rational_function_ptr b); |
|||
|
|||
// Binary relations. |
|||
int storm_rational_function_less(storm_rational_function_ptr a, storm_rational_function_ptr b); |
|||
int storm_rational_function_less_or_equal(storm_rational_function_ptr a, storm_rational_function_ptr b); |
|||
|
|||
// Unary operations. |
|||
storm_rational_function_ptr storm_rational_function_negate(storm_rational_function_ptr a); |
|||
storm_rational_function_ptr storm_rational_function_floor(storm_rational_function_ptr a); |
|||
storm_rational_function_ptr storm_rational_function_ceil(storm_rational_function_ptr a); |
|||
|
|||
// Printing functions. |
|||
void print_storm_rational_function(storm_rational_function_ptr a); |
|||
void print_storm_rational_function_to_file(storm_rational_function_ptr a, FILE* out); |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif // SYLVAN_STORM_FUNCTION_WRAPPER_H |
@ -1,7 +1,11 @@ |
|||
Mtbdd toDoubleMtbdd() const; |
|||
Mtbdd toInt64Mtbdd() const; |
|||
// Methods to convert a BDD to the canonical 0/1 MTBDD for different types.
|
|||
Mtbdd toDoubleMtbdd() const; |
|||
Mtbdd toInt64Mtbdd() const; |
|||
Mtbdd toStormRationalNumberMtbdd() const; |
|||
#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL)
|
|||
Mtbdd toStormRationalFunctionMtbdd() const; |
|||
Mtbdd toStormRationalFunctionMtbdd() const; |
|||
#endif
|
|||
Mtbdd Ite(Mtbdd const& thenDd, Mtbdd const& elseDd) const; |
|||
Bdd ExistAbstractRepresentative(const BddSet& cube) const; |
|||
|
|||
// Other functions to add to sylvan's Bdd class.
|
|||
Mtbdd Ite(Mtbdd const& thenDd, Mtbdd const& elseDd) const; |
|||
Bdd ExistAbstractRepresentative(const BddSet& cube) const; |
@ -1,119 +1,96 @@ |
|||
// Functions that are to be added to sylvan's Mtbdd class.
|
|||
|
|||
// Functions that operate on all or standard Mtbdds.
|
|||
Bdd NotZero() const; |
|||
size_t CountLeaves() const; |
|||
double NonZeroCount(size_t variableCount) const; |
|||
bool isValid() const; |
|||
void PrintDot(FILE *out) const; |
|||
std::string GetShaHash() const; |
|||
|
|||
/**
|
|||
* @brief Computes f - g |
|||
*/ |
|||
Mtbdd Minus(const Mtbdd &other) const; |
|||
Mtbdd Minus(const Mtbdd &other) const; |
|||
Mtbdd Divide(const Mtbdd &other) const; |
|||
|
|||
/**
|
|||
* @brief Computes f / g |
|||
*/ |
|||
Mtbdd Divide(const Mtbdd &other) const; |
|||
|
|||
#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL)
|
|||
/**
|
|||
* @brief Creates a Mtbdd leaf representing the rational function value <value> |
|||
*/ |
|||
static Mtbdd stormRationalFunctionTerminal(storm::RationalFunction const& value); |
|||
|
|||
Bdd EqualsRF(const Mtbdd& other) const; |
|||
Bdd LessRF(const Mtbdd& other) const; |
|||
Bdd LessOrEqualRF(const Mtbdd& other) const; |
|||
|
|||
Mtbdd MinRF(const Mtbdd& other) const; |
|||
Mtbdd MaxRF(const Mtbdd& other) const; |
|||
|
|||
/**
|
|||
* @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; |
|||
Bdd Equals(const Mtbdd& other) const; |
|||
Bdd Less(const Mtbdd& other) const; |
|||
Bdd LessOrEqual(const Mtbdd& other) const; |
|||
|
|||
Mtbdd AndExistsRF(const Mtbdd &other, const BddSet &variables) const; |
|||
Bdd AbstractMinRepresentative(const BddSet &variables) const; |
|||
Bdd AbstractMaxRepresentative(const BddSet &variables) const; |
|||
|
|||
/**
|
|||
* @brief Computes f - g for Rational Functions |
|||
*/ |
|||
Mtbdd MinusRF(const Mtbdd &other) const; |
|||
Mtbdd Pow(const Mtbdd& other) const; |
|||
Mtbdd Mod(const Mtbdd& other) const; |
|||
Mtbdd Logxy(const Mtbdd& other) const; |
|||
|
|||
/**
|
|||
* @brief Computes f / g for Rational Functions |
|||
*/ |
|||
Mtbdd DivideRF(const Mtbdd &other) const; |
|||
Mtbdd Floor() const; |
|||
Mtbdd Ceil() const; |
|||
Mtbdd Minimum() const; |
|||
Mtbdd Maximum() const; |
|||
|
|||
Mtbdd PowRF(const Mtbdd& other) const; |
|||
bool EqualNorm(const Mtbdd& other, double epsilon) const; |
|||
bool EqualNormRel(const Mtbdd& other, double epsilon) const; |
|||
|
|||
Mtbdd AbstractPlusRF(const BddSet &variables) const; |
|||
|
|||
Mtbdd ReplaceLeavesRF(void* context) const; |
|||
// Functions that operate on Mtbdds over rational numbers.
|
|||
static Mtbdd stormRationalNumberTerminal(storm::RationalNumber const& value); |
|||
|
|||
Mtbdd FloorRF() const; |
|||
Mtbdd CeilRF() const; |
|||
Bdd EqualsRN(const Mtbdd& other) const; |
|||
Bdd LessRN(const Mtbdd& other) const; |
|||
Bdd LessOrEqualRN(const Mtbdd& other) const; |
|||
|
|||
Mtbdd AbstractMinRF(const BddSet &variables) const; |
|||
Mtbdd AbstractMaxRF(const BddSet &variables) const; |
|||
Mtbdd MinRN(const Mtbdd& other) const; |
|||
Mtbdd MaxRN(const Mtbdd& other) const; |
|||
|
|||
Bdd BddThresholdRF(storm::RationalFunction const& rf) const; |
|||
Bdd BddStrictThresholdRF(storm::RationalFunction const& rf) const; |
|||
Mtbdd PlusRN(const Mtbdd &other) const; |
|||
Mtbdd MinusRN(const Mtbdd &other) const; |
|||
Mtbdd TimesRN(const Mtbdd &other) const; |
|||
Mtbdd DivideRN(const Mtbdd &other) const; |
|||
|
|||
Mtbdd MinimumRF() const; |
|||
Mtbdd MaximumRF() const; |
|||
Mtbdd FloorRN() const; |
|||
Mtbdd CeilRN() const; |
|||
Mtbdd PowRN(const Mtbdd& other) const; |
|||
Mtbdd MinimumRN() const; |
|||
Mtbdd MaximumRN() const; |
|||
|
|||
Mtbdd ToDoubleRF() const; |
|||
#endif
|
|||
|
|||
/**
|
|||
* @brief Computes abstraction by minimum |
|||
*/ |
|||
Bdd AbstractMinRepresentative(const BddSet &variables) const; |
|||
|
|||
/**
|
|||
* @brief Computes abstraction by maximum |
|||
*/ |
|||
Bdd AbstractMaxRepresentative(const BddSet &variables) const; |
|||
|
|||
Bdd NotZero() const; |
|||
|
|||
Bdd Equals(const Mtbdd& other) const; |
|||
|
|||
Bdd Less(const Mtbdd& other) const; |
|||
|
|||
Bdd LessOrEqual(const Mtbdd& other) const; |
|||
Mtbdd AndExistsRN(const Mtbdd &other, const BddSet &variables) const; |
|||
Mtbdd AbstractPlusRN(const BddSet &variables) const; |
|||
Mtbdd AbstractMinRN(const BddSet &variables) const; |
|||
Mtbdd AbstractMaxRN(const BddSet &variables) const; |
|||
|
|||
Mtbdd Minimum() const; |
|||
Bdd BddThresholdRN(storm::RationalNumber const& rn) const; |
|||
Bdd BddStrictThresholdRN(storm::RationalNumber const& rn) const; |
|||
|
|||
Mtbdd Maximum() const; |
|||
Mtbdd ToDoubleRN() const; |
|||
|
|||
bool EqualNorm(const Mtbdd& other, double epsilon) const; |
|||
// Functions that operate on Mtbdds over rational functions.
|
|||
#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL)
|
|||
static Mtbdd stormRationalFunctionTerminal(storm::RationalFunction const& value); |
|||
|
|||
bool EqualNormRel(const Mtbdd& other, double epsilon) const; |
|||
|
|||
Mtbdd Floor() const; |
|||
Bdd EqualsRF(const Mtbdd& other) const; |
|||
Bdd LessRF(const Mtbdd& other) const; |
|||
Bdd LessOrEqualRF(const Mtbdd& other) const; |
|||
|
|||
Mtbdd Ceil() const; |
|||
|
|||
Mtbdd Pow(const Mtbdd& other) const; |
|||
Mtbdd MinRF(const Mtbdd& other) const; |
|||
Mtbdd MaxRF(const Mtbdd& other) const; |
|||
|
|||
Mtbdd Mod(const Mtbdd& other) const; |
|||
Mtbdd PlusRF(const Mtbdd &other) const; |
|||
Mtbdd MinusRF(const Mtbdd &other) const; |
|||
Mtbdd TimesRF(const Mtbdd &other) const; |
|||
Mtbdd DivideRF(const Mtbdd &other) const; |
|||
|
|||
Mtbdd Logxy(const Mtbdd& other) const; |
|||
|
|||
size_t CountLeaves() const; |
|||
Mtbdd FloorRF() const; |
|||
Mtbdd CeilRF() const; |
|||
Mtbdd PowRF(const Mtbdd& other) const; |
|||
Mtbdd MinimumRF() const; |
|||
Mtbdd MaximumRF() const; |
|||
|
|||
/**
|
|||
* @brief Compute the number of non-zero variable assignments, using variables in cube. |
|||
*/ |
|||
double NonZeroCount(size_t variableCount) const; |
|||
Mtbdd AndExistsRF(const Mtbdd &other, const BddSet &variables) const; |
|||
Mtbdd AbstractPlusRF(const BddSet &variables) const; |
|||
Mtbdd AbstractMinRF(const BddSet &variables) const; |
|||
Mtbdd AbstractMaxRF(const BddSet &variables) const; |
|||
|
|||
bool isValid() const; |
|||
Bdd BddThresholdRF(storm::RationalFunction const& rf) const; |
|||
Bdd BddStrictThresholdRF(storm::RationalFunction const& rf) const; |
|||
|
|||
/**
|
|||
* @brief Writes .dot file of this Bdd. Not thread-safe! |
|||
*/ |
|||
void PrintDot(FILE *out) const; |
|||
Mtbdd ToDoubleRF() const; |
|||
#endif
|
|||
|
|||
std::string GetShaHash() const; |
@ -0,0 +1,641 @@ |
|||
#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_cache.h> |
|||
#include <sylvan_int.h> |
|||
#include <sylvan_mtbdd_int.h> |
|||
#include <sylvan_storm_rational_number.h> |
|||
|
|||
uint32_t srn_type; |
|||
|
|||
static uint64_t sylvan_storm_rational_number_hash(const uint64_t v, const uint64_t seed) { |
|||
storm_rational_number_ptr x = (storm_rational_number_ptr)v; |
|||
return storm_rational_number_hash(x, seed); |
|||
} |
|||
|
|||
static int sylvan_storm_rational_number_equals(const uint64_t left, const uint64_t right) { |
|||
return storm_rational_number_equals((storm_rational_number_ptr)(size_t)left, (storm_rational_number_ptr)(size_t)right); |
|||
} |
|||
|
|||
static void sylvan_storm_rational_number_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_number_ptr* x = (storm_rational_number_ptr*)(size_t)val; |
|||
storm_rational_number_init(x); |
|||
} |
|||
|
|||
static void sylvan_storm_rational_number_destroy(uint64_t val) { |
|||
// This function is called by the unique table when a leaf is removed during garbage collection. |
|||
storm_rational_number_ptr x = (storm_rational_number_ptr)(size_t)val; |
|||
storm_rational_number_destroy(x); |
|||
} |
|||
|
|||
static char* sylvan_storm_rational_number_to_str(int comp, uint64_t val, char *buf, size_t buflen) { |
|||
return storm_rational_number_to_str((storm_rational_number_ptr)(size_t)val, *buf, buflen); |
|||
(void)comp; |
|||
} |
|||
|
|||
void sylvan_storm_rational_number_init() { |
|||
// Register custom leaf type storing rational functions. |
|||
srn_type = sylvan_mt_create_type(); |
|||
sylvan_mt_set_hash(srn_type, sylvan_storm_rational_number_hash); |
|||
sylvan_mt_set_equals(srn_type, sylvan_storm_rational_number_equals); |
|||
sylvan_mt_set_create(srn_type, sylvan_storm_rational_number_create); |
|||
sylvan_mt_set_destroy(srn_type, sylvan_storm_rational_number_destroy); |
|||
sylvan_mt_set_to_str(srn_type, sylvan_storm_rational_number_to_str); |
|||
// sylvan_mt_set_write_binary(srn_type, sylvan_storm_rational_number_write_binary); |
|||
// sylvan_mt_set_read_binary(srn_type, sylvan_storm_rational_number_read_binary); |
|||
} |
|||
|
|||
uint32_t sylvan_storm_rational_number_get_type() { |
|||
return srn_type; |
|||
} |
|||
|
|||
MTBDD mtbdd_storm_rational_number(storm_rational_number_ptr val) { |
|||
uint64_t terminalValue = (uint64_t)val; |
|||
return mtbdd_makeleaf(srn_type, terminalValue); |
|||
} |
|||
|
|||
storm_rational_number_ptr mtbdd_getstorm_rational_number_ptr(MTBDD terminal) { |
|||
uint64_t value = mtbdd_getvalue(terminal); |
|||
return (storm_rational_number_ptr*)value; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, mtbdd_op_bool_to_storm_rational_number, MTBDD, a, size_t, v) { |
|||
if (a == mtbdd_false) { |
|||
return mtbdd_storm_rational_number(storm_rational_number_get_zero()); |
|||
} |
|||
if (a == mtbdd_true) { |
|||
return mtbdd_storm_rational_number(storm_rational_number_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_number, MTBDD, dd) { |
|||
return mtbdd_uapply(dd, TASK(mtbdd_op_bool_to_storm_rational_number), 0); |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_equals, MTBDD*, pa, MTBDD*, pb) { |
|||
MTBDD a = *pa, b = *pb; |
|||
|
|||
/* Check for partial functions */ |
|||
if (a == mtbdd_false || b == mtbdd_false) return mtbdd_false; |
|||
|
|||
if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { |
|||
storm_rational_number_ptr ma = mtbdd_getstorm_rational_number_ptr(a); |
|||
storm_rational_number_ptr mb = mtbdd_getstorm_rational_number_ptr(b); |
|||
return storm_rational_number_equals(ma, mb) ? mtbdd_true : mtbdd_false; |
|||
} |
|||
|
|||
/* Commutative, so swap a,b for better cache performance */ |
|||
if (a < b) { |
|||
*pa = b; |
|||
*pb = a; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_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_number_ptr ma = mtbdd_getstorm_rational_number_ptr(a); |
|||
storm_rational_number_ptr mb = mtbdd_getstorm_rational_number_ptr(b); |
|||
|
|||
storm_rational_number_ptr mres = storm_rational_number_plus(ma, mb); |
|||
MTBDD res = mtbdd_storm_rational_number(mres); |
|||
storm_rational_number_destroy(mres); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
/* Commutative, so swap a,b for better cache performance */ |
|||
if (a < b) { |
|||
*pa = b; |
|||
*pb = a; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_minus, MTBDD*, pa, MTBDD*, pb) { |
|||
MTBDD a = *pa, b = *pb; |
|||
|
|||
/* Check for partial functions */ |
|||
if (a == mtbdd_false) return sylvan_storm_rational_number_neg(b); |
|||
if (b == mtbdd_false) return a; |
|||
|
|||
/* If both leaves, compute minus */ |
|||
if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { |
|||
storm_rational_number_ptr ma = mtbdd_getstorm_rational_number_ptr(a); |
|||
storm_rational_number_ptr mb = mtbdd_getstorm_rational_number_ptr(b); |
|||
|
|||
storm_rational_number_ptr mres = storm_rational_number_minus(ma, mb); |
|||
MTBDD res = mtbdd_storm_rational_number(mres); |
|||
storm_rational_number_destroy(mres); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_times, MTBDD*, pa, MTBDD*, pb) { |
|||
MTBDD a = *pa, b = *pb; |
|||
|
|||
/* Check for partial functions */ |
|||
if (a == mtbdd_false || b == mtbdd_false) return mtbdd_false; |
|||
|
|||
/* If both leaves, compute multiplication */ |
|||
if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { |
|||
storm_rational_number_ptr ma = mtbdd_getstorm_rational_number_ptr(a); |
|||
storm_rational_number_ptr mb = mtbdd_getstorm_rational_number_ptr(b); |
|||
|
|||
storm_rational_number_ptr mres = storm_rational_number_times(ma, mb); |
|||
MTBDD res = mtbdd_storm_rational_number(mres); |
|||
storm_rational_number_destroy(mres); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
/* Commutative, so make "a" the lowest for better cache performance */ |
|||
if (a < b) { |
|||
*pa = b; |
|||
*pb = a; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_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; |
|||
|
|||
/* If both leaves, compute division */ |
|||
if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { |
|||
storm_rational_number_ptr ma = mtbdd_getstorm_rational_number_ptr(a); |
|||
storm_rational_number_ptr mres; |
|||
if (storm_rational_number_is_zero(ma)) { |
|||
mres = storm_rational_number_get_zero(); |
|||
} else { |
|||
storm_rational_number_ptr mb = mtbdd_getstorm_rational_number_ptr(b); |
|||
mres = storm_rational_number_divide(ma, mb); |
|||
} |
|||
MTBDD res = mtbdd_storm_rational_number(mres); |
|||
storm_rational_number_destroy(mres); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_less, 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 both leaves, compute less */ |
|||
if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { |
|||
storm_rational_number_ptr ma = mtbdd_getstorm_rational_number_ptr(a); |
|||
storm_rational_number_ptr mb = mtbdd_getstorm_rational_number_ptr(b); |
|||
|
|||
return storm_rational_number_less(ma, mb) ? mtbdd_true : mtbdd_false; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_less_or_equal, 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 both leaves, compute less or equal */ |
|||
if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { |
|||
storm_rational_number_ptr ma = mtbdd_getstorm_rational_number_ptr(a); |
|||
storm_rational_number_ptr mb = mtbdd_getstorm_rational_number_ptr(b); |
|||
|
|||
return storm_rational_number_less_or_equal(ma, mb) ? mtbdd_true : mtbdd_false; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_mod, 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 both leaves, compute modulo */ |
|||
if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { |
|||
storm_rational_number_ptr ma = mtbdd_getstorm_rational_number_ptr(a); |
|||
storm_rational_number_ptr mb = mtbdd_getstorm_rational_number_ptr(b); |
|||
|
|||
storm_rational_number_ptr mres = storm_rational_number_mod(ma, mb); |
|||
MTBDD res = mtbdd_storm_rational_number(mres); |
|||
storm_rational_number_destroy(mres); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_min, 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 both leaves, compute min */ |
|||
if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { |
|||
storm_rational_number_ptr ma = mtbdd_getstorm_rational_number_ptr(a); |
|||
storm_rational_number_ptr mb = mtbdd_getstorm_rational_number_ptr(b); |
|||
|
|||
storm_rational_number_ptr mres = storm_rational_number_min(ma, mb); |
|||
MTBDD res = mtbdd_storm_rational_number(mres); |
|||
storm_rational_number_destroy(mres); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
/* Commutative, so make "a" the lowest for better cache performance */ |
|||
if (a < b) { |
|||
*pa = b; |
|||
*pb = a; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
} |
|||
|
|||
TASK_IMPL_3(MTBDD, sylvan_storm_rational_number_abstract_op_min, MTBDD, a, MTBDD, b, int, k) { |
|||
if (k==0) { |
|||
return mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_min)); |
|||
} else { |
|||
MTBDD res = a; |
|||
for (int i=0; i<k; i++) { |
|||
mtbdd_refs_push(res); |
|||
res = mtbdd_apply(res, res, TASK(sylvan_storm_rational_number_op_min)); |
|||
mtbdd_refs_pop(1); |
|||
} |
|||
return res; |
|||
} |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_max, 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 both leaves, compute max */ |
|||
if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { |
|||
storm_rational_number_ptr ma = mtbdd_getstorm_rational_number_ptr(a); |
|||
storm_rational_number_ptr mb = mtbdd_getstorm_rational_number_ptr(b); |
|||
|
|||
storm_rational_number_ptr mres = storm_rational_number_max(ma, mb); |
|||
MTBDD res = mtbdd_storm_rational_number(mres); |
|||
storm_rational_number_destroy(mres); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
/* Commutative, so make "a" the lowest for better cache performance */ |
|||
if (a < b) { |
|||
*pa = b; |
|||
*pb = a; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
} |
|||
|
|||
TASK_IMPL_3(MTBDD, sylvan_storm_rational_number_abstract_op_max, MTBDD, a, MTBDD, b, int, k) { |
|||
if (k==0) { |
|||
return mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_max)); |
|||
} else { |
|||
MTBDD res = a; |
|||
for (int i=0; i<k; i++) { |
|||
mtbdd_refs_push(res); |
|||
res = mtbdd_apply(res, res, TASK(sylvan_storm_rational_number_op_max)); |
|||
mtbdd_refs_pop(1); |
|||
} |
|||
return res; |
|||
} |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_pow, 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; |
|||
|
|||
/* Handle multiplication of leaves */ |
|||
if (mtbdd_isleaf(a) && mtbdd_isleaf(b)) { |
|||
storm_rational_number_ptr ma = mtbdd_getstorm_rational_number_ptr(a); |
|||
storm_rational_number_ptr mb = mtbdd_getstorm_rational_number_ptr(b); |
|||
|
|||
storm_rational_number_ptr mres = storm_rational_number_pow(ma, mb); |
|||
MTBDD res = mtbdd_storm_rational_number(mres); |
|||
storm_rational_number_destroy(mres); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
} |
|||
|
|||
TASK_IMPL_3(MTBDD, sylvan_storm_rational_number_abstract_op_plus, MTBDD, a, MTBDD, b, int, k) { |
|||
if (k==0) { |
|||
return mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_plus)); |
|||
} else { |
|||
MTBDD res = a; |
|||
for (int i=0; i<k; i++) { |
|||
mtbdd_refs_push(res); |
|||
res = mtbdd_apply(res, res, TASK(sylvan_storm_rational_number_op_plus)); |
|||
mtbdd_refs_pop(1); |
|||
} |
|||
return res; |
|||
} |
|||
} |
|||
|
|||
TASK_IMPL_3(MTBDD, sylvan_storm_rational_number_abstract_op_times, MTBDD, a, MTBDD, b, int, k) { |
|||
if (k==0) { |
|||
return mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_times)); |
|||
} else { |
|||
MTBDD res = a; |
|||
for (int i=0; i<k; i++) { |
|||
mtbdd_refs_push(res); |
|||
res = mtbdd_apply(res, res, TASK(sylvan_storm_rational_number_op_times)); |
|||
mtbdd_refs_pop(1); |
|||
} |
|||
return res; |
|||
} |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_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_number_ptr mdd = mtbdd_getstorm_rational_number_ptr(dd); |
|||
|
|||
storm_rational_number_ptr mres = storm_rational_number_negate(mdd); |
|||
MTBDD res = mtbdd_storm_rational_number(mres); |
|||
storm_rational_number_destroy(mres); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
(void)p; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_floor, 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_number_ptr mdd = mtbdd_getstorm_rational_number_ptr(dd); |
|||
|
|||
storm_rational_number_ptr mres = storm_rational_number_floor(mdd); |
|||
MTBDD res = mtbdd_storm_rational_number(mres); |
|||
storm_rational_number_destroy(mres); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
(void)p; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_ceil, 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_number_ptr mdd = mtbdd_getstorm_rational_number_ptr(dd); |
|||
|
|||
storm_rational_number_ptr mres = storm_rational_number_ceil(mdd); |
|||
MTBDD res = mtbdd_storm_rational_number(mres); |
|||
storm_rational_number_destroy(mres); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
(void)p; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_to_double, 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_number_ptr mdd = mtbdd_getstorm_rational_number_ptr(dd); |
|||
MTBDD result = mtbdd_double(storm_rational_number_get_value_double(mdd)); |
|||
return result; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
(void)p; |
|||
} |
|||
|
|||
TASK_IMPL_3(MTBDD, sylvan_storm_rational_number_and_exists, MTBDD, a, MTBDD, b, MTBDD, v) { |
|||
/* Check terminal cases */ |
|||
|
|||
/* If v == true, then <vars> is an empty set */ |
|||
if (v == mtbdd_true) return mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_times)); |
|||
|
|||
/* Try the times operator on a and b */ |
|||
MTBDD result = CALL(sylvan_storm_rational_number_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_number_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_MTBDD_AND_EXISTS_RF, 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 : MTBDD_GETNODE(a); |
|||
mtbddnode_t nb = lb ? 0 : MTBDD_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 = MTBDD_GETNODE(v); |
|||
uint32_t vv = mtbddnode_getvariable(nv); |
|||
|
|||
if (vv < var) { |
|||
/* Recursive, then abstract result */ |
|||
result = CALL(sylvan_storm_rational_number_and_exists, a, b, node_gethigh(v, nv)); |
|||
mtbdd_refs_push(result); |
|||
result = mtbdd_apply(result, result, TASK(sylvan_storm_rational_number_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_number_and_exists, ahigh, bhigh, node_gethigh(v, nv))); |
|||
MTBDD low = mtbdd_refs_push(CALL(sylvan_storm_rational_number_and_exists, alow, blow, node_gethigh(v, nv))); |
|||
MTBDD high = mtbdd_refs_push(mtbdd_refs_sync(SYNC(sylvan_storm_rational_number_and_exists))); |
|||
result = CALL(mtbdd_apply, low, high, TASK(sylvan_storm_rational_number_op_plus)); |
|||
mtbdd_refs_pop(2); |
|||
} else /* vv > v */ { |
|||
/* Recursive, then create node */ |
|||
mtbdd_refs_spawn(SPAWN(sylvan_storm_rational_number_and_exists, ahigh, bhigh, v)); |
|||
MTBDD low = mtbdd_refs_push(CALL(sylvan_storm_rational_number_and_exists, alow, blow, v)); |
|||
MTBDD high = mtbdd_refs_sync(SYNC(sylvan_storm_rational_number_and_exists)); |
|||
mtbdd_refs_pop(1); |
|||
result = mtbdd_makenode(var, low, high); |
|||
} |
|||
} |
|||
|
|||
/* Store in cache */ |
|||
cache_put3(CACHE_MTBDD_AND_EXISTS_RF, a, b, v, result); |
|||
return result; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_threshold, MTBDD, a, size_t, svalue) { |
|||
storm_rational_number_ptr value = (storm_rational_number_ptr)svalue; |
|||
|
|||
if (mtbdd_isleaf(a)) { |
|||
storm_rational_number_ptr ma = mtbdd_getstorm_rational_number_ptr(a); |
|||
return storm_rational_number_less_or_equal(ma, value) ? mtbdd_false : mtbdd_true; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_op_strict_threshold, MTBDD, a, size_t, svalue) { |
|||
storm_rational_number_ptr value = (storm_rational_number_ptr)svalue; |
|||
|
|||
if (mtbdd_isleaf(a)) { |
|||
storm_rational_number_ptr ma = mtbdd_getstorm_rational_number_ptr(a); |
|||
|
|||
return storm_rational_number_less(ma, value) ? mtbdd_false : mtbdd_true; |
|||
} |
|||
|
|||
return mtbdd_invalid; |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_threshold, MTBDD, dd, storm_rational_number_ptr, value) |
|||
{ |
|||
return mtbdd_uapply(dd, TASK(sylvan_storm_rational_number_op_threshold), *(size_t*)value); |
|||
} |
|||
|
|||
TASK_IMPL_2(MTBDD, sylvan_storm_rational_number_strict_threshold, MTBDD, dd, storm_rational_number_ptr, value) |
|||
{ |
|||
return mtbdd_uapply(dd, TASK(sylvan_storm_rational_number_op_strict_threshold), *(size_t*)value); |
|||
} |
|||
|
|||
TASK_IMPL_1(MTBDD, sylvan_storm_rational_number_minimum, MTBDD, a) { |
|||
/* Check terminal case */ |
|||
if (a == mtbdd_false) return mtbdd_false; |
|||
mtbddnode_t na = MTBDD_GETNODE(a); |
|||
if (mtbddnode_isleaf(na)) return a; |
|||
|
|||
/* Maybe perform garbage collection */ |
|||
sylvan_gc_test(); |
|||
|
|||
/* Check cache */ |
|||
MTBDD result; |
|||
if (cache_get3(CACHE_MTBDD_MINIMUM_RF, a, 0, 0, &result)) return result; |
|||
|
|||
/* Call recursive */ |
|||
SPAWN(mtbdd_minimum, node_getlow(a, na)); |
|||
MTBDD high = CALL(sylvan_storm_rational_number_minimum, node_gethigh(a, na)); |
|||
MTBDD low = SYNC(sylvan_storm_rational_number_minimum); |
|||
|
|||
storm_rational_number_ptr fl = mtbdd_getstorm_rational_number_ptr(low); |
|||
storm_rational_number_ptr fh = mtbdd_getstorm_rational_number_ptr(high); |
|||
|
|||
if (storm_rational_number_less_or_equal(fl, fh)) { |
|||
return low; |
|||
} else { |
|||
return high; |
|||
} |
|||
|
|||
/* Store in cache */ |
|||
cache_put3(CACHE_MTBDD_MINIMUM_RF, a, 0, 0, result); |
|||
return result; |
|||
} |
|||
|
|||
TASK_IMPL_1(MTBDD, sylvan_storm_rational_number_maximum, MTBDD, a) |
|||
{ |
|||
/* Check terminal case */ |
|||
if (a == mtbdd_false) return mtbdd_false; |
|||
mtbddnode_t na = MTBDD_GETNODE(a); |
|||
if (mtbddnode_isleaf(na)) return a; |
|||
|
|||
/* Maybe perform garbage collection */ |
|||
sylvan_gc_test(); |
|||
|
|||
/* Check cache */ |
|||
MTBDD result; |
|||
if (cache_get3(CACHE_MTBDD_MAXIMUM_RF, a, 0, 0, &result)) return result; |
|||
|
|||
/* Call recursive */ |
|||
SPAWN(mtbdd_minimum, node_getlow(a, na)); |
|||
MTBDD high = CALL(sylvan_storm_rational_number_maximum, node_gethigh(a, na)); |
|||
MTBDD low = SYNC(sylvan_storm_rational_number_maximum); |
|||
|
|||
storm_rational_number_ptr fl = mtbdd_getstorm_rational_number_ptr(low); |
|||
storm_rational_number_ptr fh = mtbdd_getstorm_rational_number_ptr(high); |
|||
|
|||
if (storm_rational_number_less(fl, fh)) { |
|||
return high; |
|||
} else { |
|||
return low; |
|||
} |
|||
|
|||
/* Store in cache */ |
|||
cache_put3(CACHE_MTBDD_MAXIMUM_RF, a, 0, 0, result); |
|||
return result; |
|||
} |
@ -0,0 +1,89 @@ |
|||
#ifndef SYLVAN_STORM_RATIONAL_NUMBER_H |
|||
#define SYLVAN_STORM_RATIONAL_NUMBER_H |
|||
|
|||
#include <sylvan.h> |
|||
#include <storm_wrapper.h> |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif /* __cplusplus */ |
|||
|
|||
void sylvan_storm_rational_number_init(); |
|||
uint32_t sylvan_storm_rational_number_get_type(); |
|||
MTBDD mtbdd_storm_rational_number(storm_rational_number_ptr val); |
|||
storm_rational_number_ptr mtbdd_getstorm_rational_number_ptr(MTBDD terminal); |
|||
|
|||
TASK_DECL_2(MTBDD, mtbdd_op_bool_to_storm_rational_number, MTBDD, size_t) |
|||
TASK_DECL_1(MTBDD, mtbdd_bool_to_storm_rational_number, MTBDD) |
|||
#define mtbdd_bool_to_storm_rational_number(dd) CALL(mtbdd_bool_to_storm_rational_number, dd) |
|||
|
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_equals, MTBDD*, MTBDD*) |
|||
#define mtbdd_equals_rational_number(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_equals)) |
|||
|
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_plus, MTBDD*, MTBDD*) |
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_minus, MTBDD*, MTBDD*) |
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_times, MTBDD*, MTBDD*) |
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_divide, MTBDD*, MTBDD*) |
|||
|
|||
TASK_DECL_3(MTBDD, sylvan_storm_rational_number_abstract_op_plus, MTBDD, MTBDD, int) |
|||
TASK_DECL_3(MTBDD, sylvan_storm_rational_number_abstract_op_times, MTBDD, MTBDD, int) |
|||
TASK_DECL_3(MTBDD, sylvan_storm_rational_number_abstract_op_min, MTBDD, MTBDD, int) |
|||
TASK_DECL_3(MTBDD, sylvan_storm_rational_number_abstract_op_max, MTBDD, MTBDD, int) |
|||
|
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_less, MTBDD*, MTBDD*) |
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_less_or_equal, MTBDD*, MTBDD*) |
|||
|
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_mod, MTBDD*, MTBDD*) |
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_pow, MTBDD*, MTBDD*) |
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_min, MTBDD*, MTBDD*) |
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_max, MTBDD*, MTBDD*) |
|||
|
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_neg, MTBDD, size_t) |
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_floor, MTBDD, size_t) |
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_ceil, MTBDD, size_t) |
|||
|
|||
#define sylvan_storm_rational_number_plus(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_plus)) |
|||
#define sylvan_storm_rational_number_minus(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_minus)) |
|||
#define sylvan_storm_rational_number_times(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_times)) |
|||
#define sylvan_storm_rational_number_divide(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_divide)) |
|||
#define sylvan_storm_rational_number_less(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_less)) |
|||
#define sylvan_storm_rational_number_less_or_equal(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_less_or_equal)) |
|||
#define sylvan_storm_rational_number_mod(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_less_or_equal)) |
|||
#define sylvan_storm_rational_number_min(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_min)) |
|||
#define sylvan_storm_rational_number_max(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_max)) |
|||
#define sylvan_storm_rational_number_neg(a) mtbdd_uapply(a, TASK(sylvan_storm_rational_number_op_neg), 0) |
|||
#define sylvan_storm_rational_number_floor(a) mtbdd_uapply(a, TASK(sylvan_storm_rational_number_op_floor), 0) |
|||
#define sylvan_storm_rational_number_ceil(a) mtbdd_uapply(a, TASK(sylvan_storm_rational_number_op_ceil), 0) |
|||
#define sylvan_storm_rational_number_pow(a, b) mtbdd_apply(a, b, TASK(sylvan_storm_rational_number_op_pow)) |
|||
|
|||
TASK_DECL_1(MTBDD, sylvan_storm_rational_number_minimum, MTBDD); |
|||
#define sylvan_storm_rational_number_minimum(dd) CALL(sylvan_storm_rational_number_minimum, dd) |
|||
|
|||
TASK_DECL_1(MTBDD, sylvan_storm_rational_number_maximum, MTBDD); |
|||
#define sylvan_storm_rational_number_maximum(dd) CALL(sylvan_storm_rational_number_maximum, dd) |
|||
|
|||
TASK_DECL_3(MTBDD, sylvan_storm_rational_number_and_exists, MTBDD, MTBDD, MTBDD); |
|||
#define sylvan_storm_rational_number_and_exists(a, b, vars) CALL(sylvan_storm_rational_number_and_exists, a, b, vars) |
|||
|
|||
#define sylvan_storm_rational_number_abstract_plus(dd, v) mtbdd_abstract(dd, v, TASK(sylvan_storm_rational_number_abstract_op_plus)) |
|||
#define sylvan_storm_rational_number_abstract_min(dd, v) mtbdd_abstract(dd, v, TASK(sylvan_storm_rational_number_abstract_op_min)) |
|||
#define sylvan_storm_rational_number_abstract_max(dd, v) mtbdd_abstract(dd, v, TASK(sylvan_storm_rational_number_abstract_op_max)) |
|||
|
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_to_double, MTBDD, size_t) |
|||
#define sylvan_storm_rational_number_to_double(a) mtbdd_uapply_nocache(a, TASK(sylvan_storm_rational_number_op_to_double), 0) |
|||
|
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_threshold, MTBDD, size_t) |
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_op_strict_threshold, MTBDD, size_t) |
|||
|
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_threshold, MTBDD, storm_rational_number_ptr); |
|||
#define sylvan_storm_rational_number_threshold(dd, value) CALL(sylvan_storm_rational_number_strict_threshold, dd, value) |
|||
|
|||
TASK_DECL_2(MTBDD, sylvan_storm_rational_number_strict_threshold, MTBDD, storm_rational_number_ptr); |
|||
#define sylvan_storm_rational_number_strict_threshold(dd, value) CALL(sylvan_storm_rational_number_strict_threshold, dd, value) |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif /* __cplusplus */ |
|||
|
|||
|
|||
#endif // SYLVAN_STORM_RATIONAL_NUMBER_H |
Write
Preview
Loading…
Cancel
Save
Reference in new issue