You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
855 lines
25 KiB
855 lines
25 KiB
/*
|
|
* Copyright 2011-2015 Formal Methods and Tools, University of Twente
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef SYLVAN_OBJ_H
|
|
#define SYLVAN_OBJ_H
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <lace.h>
|
|
#include <sylvan.h>
|
|
|
|
namespace sylvan {
|
|
|
|
class BddSet;
|
|
class BddMap;
|
|
class Mtbdd;
|
|
|
|
class Bdd {
|
|
friend class Sylvan;
|
|
friend class BddSet;
|
|
friend class BddMap;
|
|
friend class Mtbdd;
|
|
|
|
public:
|
|
Bdd() { bdd = sylvan_false; sylvan_protect(&bdd); }
|
|
Bdd(const BDD from) : bdd(from) { sylvan_protect(&bdd); }
|
|
Bdd(const Bdd &from) : bdd(from.bdd) { sylvan_protect(&bdd); }
|
|
Bdd(const uint32_t var) { bdd = sylvan_ithvar(var); sylvan_protect(&bdd); }
|
|
~Bdd() { sylvan_unprotect(&bdd); }
|
|
|
|
/**
|
|
* @brief Creates a Bdd representing just the variable index in its positive form
|
|
* The variable index must be a 0<=index<=2^23 (we use 24 bits internally)
|
|
*/
|
|
static Bdd bddVar(uint32_t index);
|
|
|
|
/**
|
|
* @brief Returns the Bdd representing "True"
|
|
*/
|
|
static Bdd bddOne();
|
|
|
|
/**
|
|
* @brief Returns the Bdd representing "False"
|
|
*/
|
|
static Bdd bddZero();
|
|
|
|
/**
|
|
* @brief Returns the Bdd representing a cube of variables, according to the given values.
|
|
* @param variables the variables that will be in the cube in their positive or negative form
|
|
* @param values a character array describing how the variables will appear in the result
|
|
* The length of string must be equal to the number of variables in the cube.
|
|
* For every ith char in string, if it is 0, the corresponding variable will appear in its negative form,
|
|
* if it is 1, it will appear in its positive form, and if it is 2, it will appear as "any", thus it will
|
|
* be skipped.
|
|
*/
|
|
static Bdd bddCube(const BddSet &variables, unsigned char *values);
|
|
|
|
/**
|
|
* @brief Returns the Bdd representing a cube of variables, according to the given values.
|
|
* @param variables the variables that will be in the cube in their positive or negative form
|
|
* @param string a character array describing how the variables will appear in the result
|
|
* The length of string must be equal to the number of variables in the cube.
|
|
* For every ith char in string, if it is 0, the corresponding variable will appear in its negative form,
|
|
* if it is 1, it will appear in its positive form, and if it is 2, it will appear as "any", thus it will
|
|
* be skipped.
|
|
*/
|
|
static Bdd bddCube(const BddSet &variables, std::vector<uint8_t> values);
|
|
|
|
int operator==(const Bdd& other) const;
|
|
int operator!=(const Bdd& other) const;
|
|
Bdd operator=(const Bdd& right);
|
|
int operator<=(const Bdd& other) const;
|
|
int operator>=(const Bdd& other) const;
|
|
int operator<(const Bdd& other) const;
|
|
int operator>(const Bdd& other) const;
|
|
Bdd operator!() const;
|
|
Bdd operator~() const;
|
|
Bdd operator*(const Bdd& other) const;
|
|
Bdd operator*=(const Bdd& other);
|
|
Bdd operator&(const Bdd& other) const;
|
|
Bdd operator&=(const Bdd& other);
|
|
Bdd operator+(const Bdd& other) const;
|
|
Bdd operator+=(const Bdd& other);
|
|
Bdd operator|(const Bdd& other) const;
|
|
Bdd operator|=(const Bdd& other);
|
|
Bdd operator^(const Bdd& other) const;
|
|
Bdd operator^=(const Bdd& other);
|
|
Bdd operator-(const Bdd& other) const;
|
|
Bdd operator-=(const Bdd& other);
|
|
|
|
/**
|
|
* @brief Returns non-zero if this Bdd is bddOne() or bddZero()
|
|
*/
|
|
int isConstant() const;
|
|
|
|
/**
|
|
* @brief Returns non-zero if this Bdd is bddOne() or bddZero()
|
|
*/
|
|
int isTerminal() const;
|
|
|
|
/**
|
|
* @brief Returns non-zero if this Bdd is bddOne()
|
|
*/
|
|
int isOne() const;
|
|
|
|
/**
|
|
* @brief Returns non-zero if this Bdd is bddZero()
|
|
*/
|
|
int isZero() const;
|
|
|
|
/**
|
|
* @brief Returns the top variable index of this Bdd (the variable in the root node)
|
|
*/
|
|
uint32_t TopVar() const;
|
|
|
|
/**
|
|
* @brief Follows the high edge ("then") of the root node of this Bdd
|
|
*/
|
|
Bdd Then() const;
|
|
|
|
/**
|
|
* @brief Follows the low edge ("else") of the root node of this Bdd
|
|
*/
|
|
Bdd Else() const;
|
|
|
|
/**
|
|
* @brief Computes \exists cube: f \and g
|
|
*/
|
|
Bdd AndAbstract(const Bdd& g, const BddSet& cube) const;
|
|
|
|
/**
|
|
* @brief Computes \exists cube: f
|
|
*/
|
|
Bdd ExistAbstract(const BddSet& cube) const;
|
|
|
|
/**
|
|
* @brief Computes \forall cube: f
|
|
*/
|
|
Bdd UnivAbstract(const BddSet& cube) const;
|
|
|
|
/**
|
|
* @brief Computes if f then g else h
|
|
*/
|
|
Bdd Ite(const Bdd& g, const Bdd& h) const;
|
|
|
|
/**
|
|
* @brief Computes f \and g
|
|
*/
|
|
Bdd And(const Bdd& g) const;
|
|
|
|
/**
|
|
* @brief Computes f \or g
|
|
*/
|
|
Bdd Or(const Bdd& g) const;
|
|
|
|
/**
|
|
* @brief Computes \not (f \and g)
|
|
*/
|
|
Bdd Nand(const Bdd& g) const;
|
|
|
|
/**
|
|
* @brief Computes \not (f \or g)
|
|
*/
|
|
Bdd Nor(const Bdd& g) const;
|
|
|
|
/**
|
|
* @brief Computes f \xor g
|
|
*/
|
|
Bdd Xor(const Bdd& g) const;
|
|
|
|
/**
|
|
* @brief Computes \not (f \xor g), i.e. f \equiv g
|
|
*/
|
|
Bdd Xnor(const Bdd& g) const;
|
|
|
|
/**
|
|
* @brief Returns whether all elements in f are also in g
|
|
*/
|
|
int Leq(const Bdd& g) const;
|
|
|
|
/**
|
|
* @brief Computes the reverse application of a transition relation to this set.
|
|
* @param relation the transition relation to apply
|
|
* @param cube the variables that are in the transition relation
|
|
* This function assumes that s,t are interleaved with s even and t odd (s+1).
|
|
* Other variables in the relation are ignored (by existential quantification)
|
|
* Set cube to "false" (illegal cube) to assume all encountered variables are in s,t
|
|
*
|
|
* Use this function to concatenate two relations --> -->
|
|
* or to take the 'previous' of a set --> S
|
|
*/
|
|
Bdd RelPrev(const Bdd& relation, const BddSet& cube) const;
|
|
|
|
/**
|
|
* @brief Computes the application of a transition relation to this set.
|
|
* @param relation the transition relation to apply
|
|
* @param cube the variables that are in the transition relation
|
|
* This function assumes that s,t are interleaved with s even and t odd (s+1).
|
|
* Other variables in the relation are ignored (by existential quantification)
|
|
* Set cube to "false" (illegal cube) to assume all encountered variables are in s,t
|
|
*
|
|
* Use this function to take the 'next' of a set S -->
|
|
*/
|
|
Bdd RelNext(const Bdd& relation, const BddSet& cube) const;
|
|
|
|
/**
|
|
* @brief Computes the transitive closure by traversing the BDD recursively.
|
|
* See Y. Matsunaga, P. C. McGeer, R. K. Brayton
|
|
* On Computing the Transitive Closre of a State Transition Relation
|
|
* 30th ACM Design Automation Conference, 1993.
|
|
*/
|
|
Bdd Closure() const;
|
|
|
|
/**
|
|
* @brief Computes the constrain f @ c
|
|
*/
|
|
Bdd Constrain(const Bdd &c) const;
|
|
|
|
/**
|
|
* @brief Computes the BDD restrict according to Coudert and Madre's algorithm (ICCAD90).
|
|
*/
|
|
Bdd Restrict(const Bdd &c) const;
|
|
|
|
/**
|
|
* @brief Functional composition. Whenever a variable v in the map m is found in the BDD,
|
|
* it is substituted by the associated function.
|
|
* You can also use this function to implement variable reordering.
|
|
*/
|
|
Bdd Compose(const BddMap &m) const;
|
|
|
|
/**
|
|
* @brief Substitute all variables in the array from by the corresponding variables in to.
|
|
*/
|
|
Bdd Permute(const std::vector<uint32_t>& from, const std::vector<uint32_t>& to) const;
|
|
|
|
/**
|
|
* @brief Computes the support of a Bdd.
|
|
*/
|
|
Bdd Support() const;
|
|
|
|
/**
|
|
* @brief Gets the BDD of this Bdd (for C functions)
|
|
*/
|
|
BDD GetBDD() const;
|
|
|
|
/**
|
|
* @brief Writes .dot file of this Bdd. Not thread-safe!
|
|
*/
|
|
void PrintDot(FILE *out) const;
|
|
|
|
/**
|
|
* @brief Gets a SHA2 hash that describes the structure of this Bdd.
|
|
* @param string a character array of at least 65 characters (includes zero-termination)
|
|
* This hash is 64 characters long and is independent of the memory locations of BDD nodes.
|
|
*/
|
|
void GetShaHash(char *string) const;
|
|
|
|
std::string GetShaHash() const;
|
|
|
|
/**
|
|
* @brief Computes the number of satisfying variable assignments, using variables in cube.
|
|
*/
|
|
double SatCount(const BddSet &cube) const;
|
|
|
|
/**
|
|
* @brief Compute the number of satisfying variable assignments, using the given number of variables.
|
|
*/
|
|
double SatCount(const size_t nvars) const;
|
|
|
|
/**
|
|
* @brief Gets one satisfying assignment according to the variables.
|
|
* @param variables The set of variables to be assigned, must include the support of the Bdd.
|
|
*/
|
|
void PickOneCube(const BddSet &variables, uint8_t *string) const;
|
|
|
|
/**
|
|
* @brief Gets one satisfying assignment according to the variables.
|
|
* @param variables The set of variables to be assigned, must include the support of the Bdd.
|
|
* Returns an empty vector when either this Bdd equals bddZero() or the cube is empty.
|
|
*/
|
|
std::vector<bool> PickOneCube(const BddSet &variables) const;
|
|
|
|
/**
|
|
* @brief Gets a cube that satisfies this Bdd.
|
|
*/
|
|
Bdd PickOneCube() const;
|
|
|
|
/**
|
|
* @brief Faster version of: *this + Sylvan::bddCube(variables, values);
|
|
*/
|
|
Bdd UnionCube(const BddSet &variables, uint8_t *values) const;
|
|
|
|
/**
|
|
* @brief Faster version of: *this + Sylvan::bddCube(variables, values);
|
|
*/
|
|
Bdd UnionCube(const BddSet &variables, std::vector<uint8_t> values) const;
|
|
|
|
/**
|
|
* @brief Generate a cube representing a set of variables
|
|
*/
|
|
static Bdd VectorCube(const std::vector<Bdd> variables);
|
|
|
|
/**
|
|
* @brief Generate a cube representing a set of variables
|
|
* @param variables An sorted set of variable indices
|
|
*/
|
|
static Bdd VariablesCube(const std::vector<uint32_t> variables);
|
|
|
|
/**
|
|
* @brief Gets the number of nodes in this Bdd. Not thread-safe!
|
|
*/
|
|
size_t NodeCount() const;
|
|
|
|
#include "sylvan_obj_bdd_storm.hpp"
|
|
|
|
private:
|
|
BDD bdd;
|
|
};
|
|
|
|
class BddSet
|
|
{
|
|
friend class Bdd;
|
|
friend class Mtbdd;
|
|
Bdd set;
|
|
|
|
public:
|
|
/**
|
|
* @brief Create a new empty set.
|
|
*/
|
|
BddSet() : set(Bdd::bddOne()) {}
|
|
|
|
/**
|
|
* @brief Wrap the BDD cube <other> in a set.
|
|
*/
|
|
BddSet(const Bdd &other) : set(other) {}
|
|
|
|
/**
|
|
* @brief Create a copy of the set <other>.
|
|
*/
|
|
BddSet(const BddSet &other) : set(other.set) {}
|
|
|
|
/**
|
|
* @brief Add the variable <variable> to this set.
|
|
*/
|
|
void add(uint32_t variable) {
|
|
set *= Bdd::bddVar(variable);
|
|
}
|
|
|
|
/**
|
|
* @brief Add all variables in the set <other> to this set.
|
|
*/
|
|
void add(BddSet &other) {
|
|
set *= other.set;
|
|
}
|
|
|
|
/**
|
|
* @brief Remove the variable <variable> from this set.
|
|
*/
|
|
void remove(uint32_t variable) {
|
|
set = set.ExistAbstract(Bdd::bddVar(variable));
|
|
}
|
|
|
|
/**
|
|
* @brief Remove all variables in the set <other> from this set.
|
|
*/
|
|
void remove(BddSet &other) {
|
|
set = set.ExistAbstract(other.set);
|
|
}
|
|
|
|
/**
|
|
* @brief Retrieve the head of the set. (The first variable.)
|
|
*/
|
|
uint32_t TopVar() const {
|
|
return set.TopVar();
|
|
}
|
|
|
|
/**
|
|
* @brief Retrieve the tail of the set. (The set containing all but the first variables.)
|
|
*/
|
|
BddSet Next() const {
|
|
Bdd then = set.Then();
|
|
return BddSet(then);
|
|
}
|
|
|
|
/**
|
|
* @brief Return true if this set is empty, or false otherwise.
|
|
*/
|
|
bool isEmpty() const {
|
|
return set.isOne();
|
|
}
|
|
|
|
/**
|
|
* @brief Return true if this set contains the variable <variable>, or false otherwise.
|
|
*/
|
|
bool contains(uint32_t variable) const {
|
|
if (isEmpty()) return false;
|
|
else if (TopVar() == variable) return true;
|
|
else return Next().contains(variable);
|
|
}
|
|
|
|
/**
|
|
* @brief Return the number of variables in this set.
|
|
*/
|
|
size_t size() const {
|
|
if (isEmpty()) return 0;
|
|
else return 1 + Next().size();
|
|
}
|
|
|
|
/**
|
|
* @brief Create a set containing the <length> variables in <arr>.
|
|
* It is advised to have the variables in <arr> in ascending order.
|
|
*/
|
|
static BddSet fromArray(BDDVAR *arr, size_t length) {
|
|
BddSet set;
|
|
for (size_t i = 0; i < length; i++) {
|
|
set.add(arr[length-i-1]);
|
|
}
|
|
return set;
|
|
}
|
|
|
|
/**
|
|
* @brief Create a set containing the variables in <variables>.
|
|
* It is advised to have the variables in <arr> in ascending order.
|
|
*/
|
|
static BddSet fromVector(const std::vector<Bdd> variables) {
|
|
BddSet set;
|
|
for (int i=variables.size()-1; i>=0; i--) {
|
|
set.set *= variables[i];
|
|
}
|
|
return set;
|
|
}
|
|
|
|
/**
|
|
* @brief Create a set containing the variables in <variables>.
|
|
* It is advised to have the variables in <arr> in ascending order.
|
|
*/
|
|
static BddSet fromVector(const std::vector<uint32_t> variables) {
|
|
BddSet set;
|
|
for (int i=variables.size()-1; i>=0; i--) {
|
|
set.add(variables[i]);
|
|
}
|
|
return set;
|
|
}
|
|
|
|
/**
|
|
* @brief Write all variables in this set to <arr>.
|
|
* @param arr An array of at least size this.size().
|
|
*/
|
|
void toArray(BDDVAR *arr) const {
|
|
if (!isEmpty()) {
|
|
*arr = TopVar();
|
|
Next().toArray(arr+1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Return the vector of all variables in this set.
|
|
*/
|
|
std::vector<uint32_t> toVector() const {
|
|
std::vector<uint32_t> result;
|
|
Bdd x = set;
|
|
while (!x.isOne()) {
|
|
result.push_back(x.TopVar());
|
|
x = x.Then();
|
|
}
|
|
return result;
|
|
}
|
|
};
|
|
|
|
class BddMap
|
|
{
|
|
friend class Bdd;
|
|
BDD bdd;
|
|
BddMap(const BDD from) : bdd(from) { sylvan_protect(&bdd); }
|
|
BddMap(const Bdd &from) : bdd(from.bdd) { sylvan_protect(&bdd); }
|
|
public:
|
|
BddMap() : bdd(sylvan_map_empty()) { sylvan_protect(&bdd); }
|
|
~BddMap() { sylvan_unprotect(&bdd); }
|
|
|
|
BddMap(uint32_t key_variable, const Bdd value);
|
|
|
|
BddMap operator+(const Bdd& other) const;
|
|
BddMap operator+=(const Bdd& other);
|
|
BddMap operator-(const Bdd& other) const;
|
|
BddMap operator-=(const Bdd& other);
|
|
|
|
/**
|
|
* @brief Adds a key-value pair to the map
|
|
*/
|
|
void put(uint32_t key, Bdd value);
|
|
|
|
/**
|
|
* @brief Removes a key-value pair from the map
|
|
*/
|
|
void removeKey(uint32_t key);
|
|
|
|
/**
|
|
* @brief Returns the number of key-value pairs in this map
|
|
*/
|
|
size_t size() const;
|
|
|
|
/**
|
|
* @brief Returns non-zero when this map is empty
|
|
*/
|
|
int isEmpty() const;
|
|
};
|
|
|
|
class MtbddMap;
|
|
|
|
class Mtbdd {
|
|
friend class Sylvan;
|
|
friend class MtbddMap;
|
|
|
|
public:
|
|
Mtbdd() { mtbdd = sylvan_false; mtbdd_protect(&mtbdd); }
|
|
Mtbdd(const MTBDD from) : mtbdd(from) { mtbdd_protect(&mtbdd); }
|
|
Mtbdd(const Mtbdd &from) : mtbdd(from.mtbdd) { mtbdd_protect(&mtbdd); }
|
|
Mtbdd(const Bdd &from) : mtbdd(from.bdd) { mtbdd_protect(&mtbdd); }
|
|
~Mtbdd() { mtbdd_unprotect(&mtbdd); }
|
|
|
|
/**
|
|
* @brief Creates a Mtbdd leaf representing the int64 value <value>
|
|
*/
|
|
static Mtbdd int64Terminal(int64_t value);
|
|
|
|
/**
|
|
* @brief Creates a Mtbdd leaf representing the floating-point value <value>
|
|
*/
|
|
static Mtbdd doubleTerminal(double value);
|
|
|
|
/**
|
|
* @brief Creates a Mtbdd leaf representing the fraction value <nominator>/<denominator>
|
|
* Internally, Sylvan uses 32-bit values and reports overflows to stderr.
|
|
*/
|
|
static Mtbdd fractionTerminal(int64_t nominator, uint64_t denominator);
|
|
|
|
/**
|
|
* @brief Creates a Mtbdd leaf of type <type> holding value <value>
|
|
* This is useful for custom Mtbdd types.
|
|
*/
|
|
static Mtbdd terminal(uint32_t type, uint64_t value);
|
|
|
|
/**
|
|
* @brief Creates a Boolean Mtbdd representing jsut the variable index in its positive form
|
|
* The variable index must be 0<=index<=2^23 (Sylvan uses 24 bits internally)
|
|
*/
|
|
static Mtbdd mtbddVar(uint32_t variable);
|
|
|
|
/**
|
|
* @brief Returns the Boolean Mtbdd representing "True"
|
|
*/
|
|
static Mtbdd mtbddOne();
|
|
|
|
/**
|
|
* @brief Returns the Boolean Mtbdd representing "False"
|
|
*/
|
|
static Mtbdd mtbddZero();
|
|
|
|
/**
|
|
* @brief Returns the Mtbdd representing a cube of variables, according to the given values.
|
|
* @param variables the variables that will be in the cube in their positive or negative form
|
|
* @param values a character array describing how the variables will appear in the result
|
|
* @param terminal the leaf of the cube
|
|
* The length of string must be equal to the number of variables in the cube.
|
|
* For every ith char in string, if it is 0, the corresponding variable will appear in its negative form,
|
|
* if it is 1, it will appear in its positive form, and if it is 2, it will appear as "any", thus it will
|
|
* be skipped.
|
|
*/
|
|
static Mtbdd mtbddCube(const BddSet &variables, unsigned char *values, const Mtbdd &terminal);
|
|
|
|
/**
|
|
* @brief Returns the Mtbdd representing a cube of variables, according to the given values.
|
|
* @param variables the variables that will be in the cube in their positive or negative form
|
|
* @param values a character array describing how the variables will appear in the result
|
|
* @param terminal the leaf of the cube
|
|
* The length of string must be equal to the number of variables in the cube.
|
|
* For every ith char in string, if it is 0, the corresponding variable will appear in its negative form,
|
|
* if it is 1, it will appear in its positive form, and if it is 2, it will appear as "any", thus it will
|
|
* be skipped.
|
|
*/
|
|
static Mtbdd mtbddCube(const BddSet &variables, std::vector<uint8_t> values, const Mtbdd &terminal);
|
|
|
|
int operator==(const Mtbdd& other) const;
|
|
int operator!=(const Mtbdd& other) const;
|
|
Mtbdd operator=(const Mtbdd& right);
|
|
Mtbdd operator!() const;
|
|
Mtbdd operator~() const;
|
|
Mtbdd operator*(const Mtbdd& other) const;
|
|
Mtbdd operator*=(const Mtbdd& other);
|
|
Mtbdd operator+(const Mtbdd& other) const;
|
|
Mtbdd operator+=(const Mtbdd& other);
|
|
Mtbdd operator-(const Mtbdd& other) const;
|
|
Mtbdd operator-=(const Mtbdd& other);
|
|
|
|
// not implemented (compared to Bdd): <=, >=, <, >, &, &=, |, |=, ^, ^=
|
|
|
|
/**
|
|
* @brief Returns non-zero if this Mtbdd is a leaf
|
|
*/
|
|
int isTerminal() const;
|
|
|
|
/**
|
|
* @brief Returns non-zero if this Mtbdd is a leaf
|
|
*/
|
|
int isLeaf() const;
|
|
|
|
/**
|
|
* @brief Returns non-zero if this Mtbdd is mtbddOne()
|
|
*/
|
|
int isOne() const;
|
|
|
|
/**
|
|
* @brief Returns non-zero if this Mtbdd is mtbddZero()
|
|
*/
|
|
int isZero() const;
|
|
|
|
/**
|
|
* @brief Returns the top variable index of this Mtbdd (the variable in the root node)
|
|
*/
|
|
uint32_t TopVar() const;
|
|
|
|
/**
|
|
* @brief Follows the high edge ("then") of the root node of this Mtbdd
|
|
*/
|
|
Mtbdd Then() const;
|
|
|
|
/**
|
|
* @brief Follows the low edge ("else") of the root node of this Mtbdd
|
|
*/
|
|
Mtbdd Else() const;
|
|
|
|
/**
|
|
* @brief Returns the negation of the MTBDD (every terminal negative)
|
|
* Do not use this for Boolean MTBDDs, only for Integer/Double/Fraction MTBDDs.
|
|
*/
|
|
Mtbdd Negate() const;
|
|
|
|
/**
|
|
* @brief Applies the binary operation <op>
|
|
*/
|
|
Mtbdd Apply(const Mtbdd &other, mtbdd_apply_op op) const;
|
|
|
|
/**
|
|
* @brief Applies the unary operation <op> with parameter <param>
|
|
*/
|
|
Mtbdd UApply(mtbdd_uapply_op op, size_t param) const;
|
|
|
|
/**
|
|
* @brief Computers the abstraction on variables <variables> using operator <op>.
|
|
* See also: AbstractPlus, AbstractTimes, AbstractMin, AbstractMax
|
|
*/
|
|
Mtbdd Abstract(const BddSet &variables, mtbdd_abstract_op op) const;
|
|
|
|
/**
|
|
* @brief Computes if f then g else h
|
|
* This Mtbdd must be a Boolean Mtbdd
|
|
*/
|
|
Mtbdd Ite(const Mtbdd &g, const Mtbdd &h) const;
|
|
|
|
/**
|
|
* @brief Computes f + g
|
|
*/
|
|
Mtbdd Plus(const Mtbdd &other) const;
|
|
|
|
/**
|
|
* @brief Computes f * g
|
|
*/
|
|
Mtbdd Times(const Mtbdd &other) const;
|
|
|
|
/**
|
|
* @brief Computes min(f, g)
|
|
*/
|
|
Mtbdd Min(const Mtbdd &other) const;
|
|
|
|
/**
|
|
* @brief Computes max(f, g)
|
|
*/
|
|
Mtbdd Max(const Mtbdd &other) const;
|
|
|
|
/**
|
|
* @brief Computes abstraction by summation (existential quantification)
|
|
*/
|
|
Mtbdd AbstractPlus(const BddSet &variables) const;
|
|
|
|
/**
|
|
* @brief Computes abstraction by multiplication (universal quantification)
|
|
*/
|
|
Mtbdd AbstractTimes(const BddSet &variables) const;
|
|
|
|
/**
|
|
* @brief Computes abstraction by minimum
|
|
*/
|
|
Mtbdd AbstractMin(const BddSet &variables) const;
|
|
|
|
/**
|
|
* @brief Computes abstraction by maximum
|
|
*/
|
|
Mtbdd AbstractMax(const BddSet &variables) const;
|
|
|
|
/**
|
|
* @brief Computes abstraction by summation of f \times g
|
|
*/
|
|
Mtbdd AndExists(const Mtbdd &other, const BddSet &variables) const;
|
|
|
|
/**
|
|
* @brief Convert floating-point/fraction Mtbdd to a Boolean Mtbdd, leaf >= value ? true : false
|
|
*/
|
|
Mtbdd MtbddThreshold(double value) const;
|
|
|
|
/**
|
|
* @brief Convert floating-point/fraction Mtbdd to a Boolean Mtbdd, leaf > value ? true : false
|
|
*/
|
|
Mtbdd MtbddStrictThreshold(double value) const;
|
|
|
|
/**
|
|
* @brief Convert floating-point/fraction Mtbdd to a Boolean Mtbdd, leaf >= value ? true : false
|
|
* Same as MtbddThreshold (Bdd = Boolean Mtbdd)
|
|
*/
|
|
Bdd BddThreshold(double value) const;
|
|
|
|
/**
|
|
* @brief Convert floating-point/fraction Mtbdd to a Boolean Mtbdd, leaf > value ? true : false
|
|
* Same as MtbddStrictThreshold (Bdd = Boolean Mtbdd)
|
|
*/
|
|
Bdd BddStrictThreshold(double value) const;
|
|
|
|
/**
|
|
* @brief Computes the support of a Mtbdd.
|
|
*/
|
|
Mtbdd Support() const;
|
|
|
|
/**
|
|
* @brief Gets the MTBDD of this Mtbdd (for C functions)
|
|
*/
|
|
MTBDD GetMTBDD() const;
|
|
|
|
/**
|
|
* @brief Functional composition. Whenever a variable v in the map m is found in the MTBDD,
|
|
* it is substituted by the associated function (which should be a Boolean MTBDD)
|
|
* You can also use this function to implement variable reordering.
|
|
*/
|
|
Mtbdd Compose(MtbddMap &m) const;
|
|
|
|
/**
|
|
* @brief Substitute all variables in the array from by the corresponding variables in to.
|
|
*/
|
|
Mtbdd Permute(const std::vector<uint32_t>& from, const std::vector<uint32_t>& to) const;
|
|
|
|
/**
|
|
* @brief Compute the number of satisfying variable assignments, using variables in cube.
|
|
*/
|
|
double SatCount(const BddSet &variables) const;
|
|
|
|
/**
|
|
* @brief Compute the number of satisfying variable assignments, using the given number of variables.
|
|
*/
|
|
double SatCount(const size_t nvars) const;
|
|
|
|
/**
|
|
* @brief Gets the number of nodes in this Bdd. Not thread-safe!
|
|
*/
|
|
size_t NodeCount() const;
|
|
|
|
#include "sylvan_obj_mtbdd_storm.hpp"
|
|
|
|
private:
|
|
MTBDD mtbdd;
|
|
};
|
|
|
|
class MtbddMap
|
|
{
|
|
friend class Mtbdd;
|
|
MTBDD mtbdd;
|
|
MtbddMap(MTBDD from) : mtbdd(from) { mtbdd_protect(&mtbdd); }
|
|
MtbddMap(Mtbdd &from) : mtbdd(from.mtbdd) { mtbdd_protect(&mtbdd); }
|
|
public:
|
|
MtbddMap() : mtbdd(mtbdd_map_empty()) { mtbdd_protect(&mtbdd); }
|
|
~MtbddMap() { mtbdd_unprotect(&mtbdd); }
|
|
|
|
MtbddMap(uint32_t key_variable, Mtbdd value);
|
|
|
|
MtbddMap operator+(const Mtbdd& other) const;
|
|
MtbddMap operator+=(const Mtbdd& other);
|
|
MtbddMap operator-(const Mtbdd& other) const;
|
|
MtbddMap operator-=(const Mtbdd& other);
|
|
|
|
/**
|
|
* @brief Adds a key-value pair to the map
|
|
*/
|
|
void put(uint32_t key, Mtbdd value);
|
|
|
|
/**
|
|
* @brief Removes a key-value pair from the map
|
|
*/
|
|
void removeKey(uint32_t key);
|
|
|
|
/**
|
|
* @brief Returns the number of key-value pairs in this map
|
|
*/
|
|
size_t size();
|
|
|
|
/**
|
|
* @brief Returns non-zero when this map is empty
|
|
*/
|
|
int isEmpty();
|
|
};
|
|
|
|
class Sylvan {
|
|
public:
|
|
/**
|
|
* @brief Initializes the Sylvan framework, call this only once in your program.
|
|
* @param initialTableSize The initial size of the nodes table. Must be a power of two.
|
|
* @param maxTableSize The maximum size of the nodes table. Must be a power of two.
|
|
* @param initialCacheSize The initial size of the operation cache. Must be a power of two.
|
|
* @param maxCacheSize The maximum size of the operation cache. Must be a power of two.
|
|
*/
|
|
static void initPackage(size_t initialTableSize, size_t maxTableSize, size_t initialCacheSize, size_t maxCacheSize);
|
|
|
|
/**
|
|
* @brief Initializes the BDD module of the Sylvan framework.
|
|
* @param granularity determins operation cache behavior; for higher values (2+) it will use the operation cache less often.
|
|
* Values of 3-7 may result in better performance, since occasionally not using the operation cache is fine in practice.
|
|
* A granularity of 1 means that every BDD operation will be cached at every variable level.
|
|
*/
|
|
static void initBdd(int granularity);
|
|
|
|
/**
|
|
* @brief Initializes the MTBDD module of the Sylvan framework.
|
|
*/
|
|
static void initMtbdd();
|
|
|
|
/**
|
|
* @brief Frees all memory in use by Sylvan.
|
|
* Warning: if you have any Bdd objects which are not bddZero() or bddOne() after this, your program may crash!
|
|
*/
|
|
static void quitPackage();
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|