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

  1. /*
  2. * Copyright 2011-2015 Formal Methods and Tools, University of Twente
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef SYLVAN_OBJ_H
  17. #define SYLVAN_OBJ_H
  18. #include <string>
  19. #include <vector>
  20. #include <lace.h>
  21. #include <sylvan.h>
  22. namespace sylvan {
  23. class BddSet;
  24. class BddMap;
  25. class Mtbdd;
  26. class Bdd {
  27. friend class Sylvan;
  28. friend class BddSet;
  29. friend class BddMap;
  30. friend class Mtbdd;
  31. public:
  32. Bdd() { bdd = sylvan_false; sylvan_protect(&bdd); }
  33. Bdd(const BDD from) : bdd(from) { sylvan_protect(&bdd); }
  34. Bdd(const Bdd &from) : bdd(from.bdd) { sylvan_protect(&bdd); }
  35. Bdd(const uint32_t var) { bdd = sylvan_ithvar(var); sylvan_protect(&bdd); }
  36. ~Bdd() { sylvan_unprotect(&bdd); }
  37. /**
  38. * @brief Creates a Bdd representing just the variable index in its positive form
  39. * The variable index must be a 0<=index<=2^23 (we use 24 bits internally)
  40. */
  41. static Bdd bddVar(uint32_t index);
  42. /**
  43. * @brief Returns the Bdd representing "True"
  44. */
  45. static Bdd bddOne();
  46. /**
  47. * @brief Returns the Bdd representing "False"
  48. */
  49. static Bdd bddZero();
  50. /**
  51. * @brief Returns the Bdd representing a cube of variables, according to the given values.
  52. * @param variables the variables that will be in the cube in their positive or negative form
  53. * @param values a character array describing how the variables will appear in the result
  54. * The length of string must be equal to the number of variables in the cube.
  55. * For every ith char in string, if it is 0, the corresponding variable will appear in its negative form,
  56. * if it is 1, it will appear in its positive form, and if it is 2, it will appear as "any", thus it will
  57. * be skipped.
  58. */
  59. static Bdd bddCube(const BddSet &variables, unsigned char *values);
  60. /**
  61. * @brief Returns the Bdd representing a cube of variables, according to the given values.
  62. * @param variables the variables that will be in the cube in their positive or negative form
  63. * @param string a character array describing how the variables will appear in the result
  64. * The length of string must be equal to the number of variables in the cube.
  65. * For every ith char in string, if it is 0, the corresponding variable will appear in its negative form,
  66. * if it is 1, it will appear in its positive form, and if it is 2, it will appear as "any", thus it will
  67. * be skipped.
  68. */
  69. static Bdd bddCube(const BddSet &variables, std::vector<uint8_t> values);
  70. int operator==(const Bdd& other) const;
  71. int operator!=(const Bdd& other) const;
  72. Bdd operator=(const Bdd& right);
  73. int operator<=(const Bdd& other) const;
  74. int operator>=(const Bdd& other) const;
  75. int operator<(const Bdd& other) const;
  76. int operator>(const Bdd& other) const;
  77. Bdd operator!() const;
  78. Bdd operator~() const;
  79. Bdd operator*(const Bdd& other) const;
  80. Bdd operator*=(const Bdd& other);
  81. Bdd operator&(const Bdd& other) const;
  82. Bdd operator&=(const Bdd& other);
  83. Bdd operator+(const Bdd& other) const;
  84. Bdd operator+=(const Bdd& other);
  85. Bdd operator|(const Bdd& other) const;
  86. Bdd operator|=(const Bdd& other);
  87. Bdd operator^(const Bdd& other) const;
  88. Bdd operator^=(const Bdd& other);
  89. Bdd operator-(const Bdd& other) const;
  90. Bdd operator-=(const Bdd& other);
  91. /**
  92. * @brief Returns non-zero if this Bdd is bddOne() or bddZero()
  93. */
  94. int isConstant() const;
  95. /**
  96. * @brief Returns non-zero if this Bdd is bddOne() or bddZero()
  97. */
  98. int isTerminal() const;
  99. /**
  100. * @brief Returns non-zero if this Bdd is bddOne()
  101. */
  102. int isOne() const;
  103. /**
  104. * @brief Returns non-zero if this Bdd is bddZero()
  105. */
  106. int isZero() const;
  107. /**
  108. * @brief Returns the top variable index of this Bdd (the variable in the root node)
  109. */
  110. uint32_t TopVar() const;
  111. /**
  112. * @brief Follows the high edge ("then") of the root node of this Bdd
  113. */
  114. Bdd Then() const;
  115. /**
  116. * @brief Follows the low edge ("else") of the root node of this Bdd
  117. */
  118. Bdd Else() const;
  119. /**
  120. * @brief Computes \exists cube: f \and g
  121. */
  122. Bdd AndAbstract(const Bdd& g, const BddSet& cube) const;
  123. /**
  124. * @brief Computes \exists cube: f
  125. */
  126. Bdd ExistAbstract(const BddSet& cube) const;
  127. /**
  128. * @brief Computes \forall cube: f
  129. */
  130. Bdd UnivAbstract(const BddSet& cube) const;
  131. /**
  132. * @brief Computes if f then g else h
  133. */
  134. Bdd Ite(const Bdd& g, const Bdd& h) const;
  135. /**
  136. * @brief Computes f \and g
  137. */
  138. Bdd And(const Bdd& g) const;
  139. /**
  140. * @brief Computes f \or g
  141. */
  142. Bdd Or(const Bdd& g) const;
  143. /**
  144. * @brief Computes \not (f \and g)
  145. */
  146. Bdd Nand(const Bdd& g) const;
  147. /**
  148. * @brief Computes \not (f \or g)
  149. */
  150. Bdd Nor(const Bdd& g) const;
  151. /**
  152. * @brief Computes f \xor g
  153. */
  154. Bdd Xor(const Bdd& g) const;
  155. /**
  156. * @brief Computes \not (f \xor g), i.e. f \equiv g
  157. */
  158. Bdd Xnor(const Bdd& g) const;
  159. /**
  160. * @brief Returns whether all elements in f are also in g
  161. */
  162. int Leq(const Bdd& g) const;
  163. /**
  164. * @brief Computes the reverse application of a transition relation to this set.
  165. * @param relation the transition relation to apply
  166. * @param cube the variables that are in the transition relation
  167. * This function assumes that s,t are interleaved with s even and t odd (s+1).
  168. * Other variables in the relation are ignored (by existential quantification)
  169. * Set cube to "false" (illegal cube) to assume all encountered variables are in s,t
  170. *
  171. * Use this function to concatenate two relations --> -->
  172. * or to take the 'previous' of a set --> S
  173. */
  174. Bdd RelPrev(const Bdd& relation, const BddSet& cube) const;
  175. /**
  176. * @brief Computes the application of a transition relation to this set.
  177. * @param relation the transition relation to apply
  178. * @param cube the variables that are in the transition relation
  179. * This function assumes that s,t are interleaved with s even and t odd (s+1).
  180. * Other variables in the relation are ignored (by existential quantification)
  181. * Set cube to "false" (illegal cube) to assume all encountered variables are in s,t
  182. *
  183. * Use this function to take the 'next' of a set S -->
  184. */
  185. Bdd RelNext(const Bdd& relation, const BddSet& cube) const;
  186. /**
  187. * @brief Computes the transitive closure by traversing the BDD recursively.
  188. * See Y. Matsunaga, P. C. McGeer, R. K. Brayton
  189. * On Computing the Transitive Closre of a State Transition Relation
  190. * 30th ACM Design Automation Conference, 1993.
  191. */
  192. Bdd Closure() const;
  193. /**
  194. * @brief Computes the constrain f @ c
  195. */
  196. Bdd Constrain(const Bdd &c) const;
  197. /**
  198. * @brief Computes the BDD restrict according to Coudert and Madre's algorithm (ICCAD90).
  199. */
  200. Bdd Restrict(const Bdd &c) const;
  201. /**
  202. * @brief Functional composition. Whenever a variable v in the map m is found in the BDD,
  203. * it is substituted by the associated function.
  204. * You can also use this function to implement variable reordering.
  205. */
  206. Bdd Compose(const BddMap &m) const;
  207. /**
  208. * @brief Substitute all variables in the array from by the corresponding variables in to.
  209. */
  210. Bdd Permute(const std::vector<uint32_t>& from, const std::vector<uint32_t>& to) const;
  211. /**
  212. * @brief Computes the support of a Bdd.
  213. */
  214. Bdd Support() const;
  215. /**
  216. * @brief Gets the BDD of this Bdd (for C functions)
  217. */
  218. BDD GetBDD() const;
  219. /**
  220. * @brief Writes .dot file of this Bdd. Not thread-safe!
  221. */
  222. void PrintDot(FILE *out) const;
  223. /**
  224. * @brief Gets a SHA2 hash that describes the structure of this Bdd.
  225. * @param string a character array of at least 65 characters (includes zero-termination)
  226. * This hash is 64 characters long and is independent of the memory locations of BDD nodes.
  227. */
  228. void GetShaHash(char *string) const;
  229. std::string GetShaHash() const;
  230. /**
  231. * @brief Computes the number of satisfying variable assignments, using variables in cube.
  232. */
  233. double SatCount(const BddSet &cube) const;
  234. /**
  235. * @brief Compute the number of satisfying variable assignments, using the given number of variables.
  236. */
  237. double SatCount(const size_t nvars) const;
  238. /**
  239. * @brief Gets one satisfying assignment according to the variables.
  240. * @param variables The set of variables to be assigned, must include the support of the Bdd.
  241. */
  242. void PickOneCube(const BddSet &variables, uint8_t *string) const;
  243. /**
  244. * @brief Gets one satisfying assignment according to the variables.
  245. * @param variables The set of variables to be assigned, must include the support of the Bdd.
  246. * Returns an empty vector when either this Bdd equals bddZero() or the cube is empty.
  247. */
  248. std::vector<bool> PickOneCube(const BddSet &variables) const;
  249. /**
  250. * @brief Gets a cube that satisfies this Bdd.
  251. */
  252. Bdd PickOneCube() const;
  253. /**
  254. * @brief Faster version of: *this + Sylvan::bddCube(variables, values);
  255. */
  256. Bdd UnionCube(const BddSet &variables, uint8_t *values) const;
  257. /**
  258. * @brief Faster version of: *this + Sylvan::bddCube(variables, values);
  259. */
  260. Bdd UnionCube(const BddSet &variables, std::vector<uint8_t> values) const;
  261. /**
  262. * @brief Generate a cube representing a set of variables
  263. */
  264. static Bdd VectorCube(const std::vector<Bdd> variables);
  265. /**
  266. * @brief Generate a cube representing a set of variables
  267. * @param variables An sorted set of variable indices
  268. */
  269. static Bdd VariablesCube(const std::vector<uint32_t> variables);
  270. /**
  271. * @brief Gets the number of nodes in this Bdd. Not thread-safe!
  272. */
  273. size_t NodeCount() const;
  274. #include "sylvan_obj_bdd_storm.hpp"
  275. private:
  276. BDD bdd;
  277. };
  278. class BddSet
  279. {
  280. friend class Bdd;
  281. friend class Mtbdd;
  282. Bdd set;
  283. public:
  284. /**
  285. * @brief Create a new empty set.
  286. */
  287. BddSet() : set(Bdd::bddOne()) {}
  288. /**
  289. * @brief Wrap the BDD cube <other> in a set.
  290. */
  291. BddSet(const Bdd &other) : set(other) {}
  292. /**
  293. * @brief Create a copy of the set <other>.
  294. */
  295. BddSet(const BddSet &other) : set(other.set) {}
  296. /**
  297. * @brief Add the variable <variable> to this set.
  298. */
  299. void add(uint32_t variable) {
  300. set *= Bdd::bddVar(variable);
  301. }
  302. /**
  303. * @brief Add all variables in the set <other> to this set.
  304. */
  305. void add(BddSet &other) {
  306. set *= other.set;
  307. }
  308. /**
  309. * @brief Remove the variable <variable> from this set.
  310. */
  311. void remove(uint32_t variable) {
  312. set = set.ExistAbstract(Bdd::bddVar(variable));
  313. }
  314. /**
  315. * @brief Remove all variables in the set <other> from this set.
  316. */
  317. void remove(BddSet &other) {
  318. set = set.ExistAbstract(other.set);
  319. }
  320. /**
  321. * @brief Retrieve the head of the set. (The first variable.)
  322. */
  323. uint32_t TopVar() const {
  324. return set.TopVar();
  325. }
  326. /**
  327. * @brief Retrieve the tail of the set. (The set containing all but the first variables.)
  328. */
  329. BddSet Next() const {
  330. Bdd then = set.Then();
  331. return BddSet(then);
  332. }
  333. /**
  334. * @brief Return true if this set is empty, or false otherwise.
  335. */
  336. bool isEmpty() const {
  337. return set.isOne();
  338. }
  339. /**
  340. * @brief Return true if this set contains the variable <variable>, or false otherwise.
  341. */
  342. bool contains(uint32_t variable) const {
  343. if (isEmpty()) return false;
  344. else if (TopVar() == variable) return true;
  345. else return Next().contains(variable);
  346. }
  347. /**
  348. * @brief Return the number of variables in this set.
  349. */
  350. size_t size() const {
  351. if (isEmpty()) return 0;
  352. else return 1 + Next().size();
  353. }
  354. /**
  355. * @brief Create a set containing the <length> variables in <arr>.
  356. * It is advised to have the variables in <arr> in ascending order.
  357. */
  358. static BddSet fromArray(BDDVAR *arr, size_t length) {
  359. BddSet set;
  360. for (size_t i = 0; i < length; i++) {
  361. set.add(arr[length-i-1]);
  362. }
  363. return set;
  364. }
  365. /**
  366. * @brief Create a set containing the variables in <variables>.
  367. * It is advised to have the variables in <arr> in ascending order.
  368. */
  369. static BddSet fromVector(const std::vector<Bdd> variables) {
  370. BddSet set;
  371. for (int i=variables.size()-1; i>=0; i--) {
  372. set.set *= variables[i];
  373. }
  374. return set;
  375. }
  376. /**
  377. * @brief Create a set containing the variables in <variables>.
  378. * It is advised to have the variables in <arr> in ascending order.
  379. */
  380. static BddSet fromVector(const std::vector<uint32_t> variables) {
  381. BddSet set;
  382. for (int i=variables.size()-1; i>=0; i--) {
  383. set.add(variables[i]);
  384. }
  385. return set;
  386. }
  387. /**
  388. * @brief Write all variables in this set to <arr>.
  389. * @param arr An array of at least size this.size().
  390. */
  391. void toArray(BDDVAR *arr) const {
  392. if (!isEmpty()) {
  393. *arr = TopVar();
  394. Next().toArray(arr+1);
  395. }
  396. }
  397. /**
  398. * @brief Return the vector of all variables in this set.
  399. */
  400. std::vector<uint32_t> toVector() const {
  401. std::vector<uint32_t> result;
  402. Bdd x = set;
  403. while (!x.isOne()) {
  404. result.push_back(x.TopVar());
  405. x = x.Then();
  406. }
  407. return result;
  408. }
  409. };
  410. class BddMap
  411. {
  412. friend class Bdd;
  413. BDD bdd;
  414. BddMap(const BDD from) : bdd(from) { sylvan_protect(&bdd); }
  415. BddMap(const Bdd &from) : bdd(from.bdd) { sylvan_protect(&bdd); }
  416. public:
  417. BddMap() : bdd(sylvan_map_empty()) { sylvan_protect(&bdd); }
  418. ~BddMap() { sylvan_unprotect(&bdd); }
  419. BddMap(uint32_t key_variable, const Bdd value);
  420. BddMap operator+(const Bdd& other) const;
  421. BddMap operator+=(const Bdd& other);
  422. BddMap operator-(const Bdd& other) const;
  423. BddMap operator-=(const Bdd& other);
  424. /**
  425. * @brief Adds a key-value pair to the map
  426. */
  427. void put(uint32_t key, Bdd value);
  428. /**
  429. * @brief Removes a key-value pair from the map
  430. */
  431. void removeKey(uint32_t key);
  432. /**
  433. * @brief Returns the number of key-value pairs in this map
  434. */
  435. size_t size() const;
  436. /**
  437. * @brief Returns non-zero when this map is empty
  438. */
  439. int isEmpty() const;
  440. };
  441. class MtbddMap;
  442. class Mtbdd {
  443. friend class Sylvan;
  444. friend class MtbddMap;
  445. public:
  446. Mtbdd() { mtbdd = sylvan_false; mtbdd_protect(&mtbdd); }
  447. Mtbdd(const MTBDD from) : mtbdd(from) { mtbdd_protect(&mtbdd); }
  448. Mtbdd(const Mtbdd &from) : mtbdd(from.mtbdd) { mtbdd_protect(&mtbdd); }
  449. Mtbdd(const Bdd &from) : mtbdd(from.bdd) { mtbdd_protect(&mtbdd); }
  450. ~Mtbdd() { mtbdd_unprotect(&mtbdd); }
  451. /**
  452. * @brief Creates a Mtbdd leaf representing the int64 value <value>
  453. */
  454. static Mtbdd int64Terminal(int64_t value);
  455. /**
  456. * @brief Creates a Mtbdd leaf representing the floating-point value <value>
  457. */
  458. static Mtbdd doubleTerminal(double value);
  459. /**
  460. * @brief Creates a Mtbdd leaf representing the fraction value <nominator>/<denominator>
  461. * Internally, Sylvan uses 32-bit values and reports overflows to stderr.
  462. */
  463. static Mtbdd fractionTerminal(int64_t nominator, uint64_t denominator);
  464. /**
  465. * @brief Creates a Mtbdd leaf of type <type> holding value <value>
  466. * This is useful for custom Mtbdd types.
  467. */
  468. static Mtbdd terminal(uint32_t type, uint64_t value);
  469. /**
  470. * @brief Creates a Boolean Mtbdd representing jsut the variable index in its positive form
  471. * The variable index must be 0<=index<=2^23 (Sylvan uses 24 bits internally)
  472. */
  473. static Mtbdd mtbddVar(uint32_t variable);
  474. /**
  475. * @brief Returns the Boolean Mtbdd representing "True"
  476. */
  477. static Mtbdd mtbddOne();
  478. /**
  479. * @brief Returns the Boolean Mtbdd representing "False"
  480. */
  481. static Mtbdd mtbddZero();
  482. /**
  483. * @brief Returns the Mtbdd representing a cube of variables, according to the given values.
  484. * @param variables the variables that will be in the cube in their positive or negative form
  485. * @param values a character array describing how the variables will appear in the result
  486. * @param terminal the leaf of the cube
  487. * The length of string must be equal to the number of variables in the cube.
  488. * For every ith char in string, if it is 0, the corresponding variable will appear in its negative form,
  489. * if it is 1, it will appear in its positive form, and if it is 2, it will appear as "any", thus it will
  490. * be skipped.
  491. */
  492. static Mtbdd mtbddCube(const BddSet &variables, unsigned char *values, const Mtbdd &terminal);
  493. /**
  494. * @brief Returns the Mtbdd representing a cube of variables, according to the given values.
  495. * @param variables the variables that will be in the cube in their positive or negative form
  496. * @param values a character array describing how the variables will appear in the result
  497. * @param terminal the leaf of the cube
  498. * The length of string must be equal to the number of variables in the cube.
  499. * For every ith char in string, if it is 0, the corresponding variable will appear in its negative form,
  500. * if it is 1, it will appear in its positive form, and if it is 2, it will appear as "any", thus it will
  501. * be skipped.
  502. */
  503. static Mtbdd mtbddCube(const BddSet &variables, std::vector<uint8_t> values, const Mtbdd &terminal);
  504. int operator==(const Mtbdd& other) const;
  505. int operator!=(const Mtbdd& other) const;
  506. Mtbdd operator=(const Mtbdd& right);
  507. Mtbdd operator!() const;
  508. Mtbdd operator~() const;
  509. Mtbdd operator*(const Mtbdd& other) const;
  510. Mtbdd operator*=(const Mtbdd& other);
  511. Mtbdd operator+(const Mtbdd& other) const;
  512. Mtbdd operator+=(const Mtbdd& other);
  513. Mtbdd operator-(const Mtbdd& other) const;
  514. Mtbdd operator-=(const Mtbdd& other);
  515. // not implemented (compared to Bdd): <=, >=, <, >, &, &=, |, |=, ^, ^=
  516. /**
  517. * @brief Returns non-zero if this Mtbdd is a leaf
  518. */
  519. int isTerminal() const;
  520. /**
  521. * @brief Returns non-zero if this Mtbdd is a leaf
  522. */
  523. int isLeaf() const;
  524. /**
  525. * @brief Returns non-zero if this Mtbdd is mtbddOne()
  526. */
  527. int isOne() const;
  528. /**
  529. * @brief Returns non-zero if this Mtbdd is mtbddZero()
  530. */
  531. int isZero() const;
  532. /**
  533. * @brief Returns the top variable index of this Mtbdd (the variable in the root node)
  534. */
  535. uint32_t TopVar() const;
  536. /**
  537. * @brief Follows the high edge ("then") of the root node of this Mtbdd
  538. */
  539. Mtbdd Then() const;
  540. /**
  541. * @brief Follows the low edge ("else") of the root node of this Mtbdd
  542. */
  543. Mtbdd Else() const;
  544. /**
  545. * @brief Returns the negation of the MTBDD (every terminal negative)
  546. * Do not use this for Boolean MTBDDs, only for Integer/Double/Fraction MTBDDs.
  547. */
  548. Mtbdd Negate() const;
  549. /**
  550. * @brief Applies the binary operation <op>
  551. */
  552. Mtbdd Apply(const Mtbdd &other, mtbdd_apply_op op) const;
  553. /**
  554. * @brief Applies the unary operation <op> with parameter <param>
  555. */
  556. Mtbdd UApply(mtbdd_uapply_op op, size_t param) const;
  557. /**
  558. * @brief Computers the abstraction on variables <variables> using operator <op>.
  559. * See also: AbstractPlus, AbstractTimes, AbstractMin, AbstractMax
  560. */
  561. Mtbdd Abstract(const BddSet &variables, mtbdd_abstract_op op) const;
  562. /**
  563. * @brief Computes if f then g else h
  564. * This Mtbdd must be a Boolean Mtbdd
  565. */
  566. Mtbdd Ite(const Mtbdd &g, const Mtbdd &h) const;
  567. /**
  568. * @brief Computes f + g
  569. */
  570. Mtbdd Plus(const Mtbdd &other) const;
  571. /**
  572. * @brief Computes f * g
  573. */
  574. Mtbdd Times(const Mtbdd &other) const;
  575. /**
  576. * @brief Computes min(f, g)
  577. */
  578. Mtbdd Min(const Mtbdd &other) const;
  579. /**
  580. * @brief Computes max(f, g)
  581. */
  582. Mtbdd Max(const Mtbdd &other) const;
  583. /**
  584. * @brief Computes abstraction by summation (existential quantification)
  585. */
  586. Mtbdd AbstractPlus(const BddSet &variables) const;
  587. /**
  588. * @brief Computes abstraction by multiplication (universal quantification)
  589. */
  590. Mtbdd AbstractTimes(const BddSet &variables) const;
  591. /**
  592. * @brief Computes abstraction by minimum
  593. */
  594. Mtbdd AbstractMin(const BddSet &variables) const;
  595. /**
  596. * @brief Computes abstraction by maximum
  597. */
  598. Mtbdd AbstractMax(const BddSet &variables) const;
  599. /**
  600. * @brief Computes abstraction by summation of f \times g
  601. */
  602. Mtbdd AndExists(const Mtbdd &other, const BddSet &variables) const;
  603. /**
  604. * @brief Convert floating-point/fraction Mtbdd to a Boolean Mtbdd, leaf >= value ? true : false
  605. */
  606. Mtbdd MtbddThreshold(double value) const;
  607. /**
  608. * @brief Convert floating-point/fraction Mtbdd to a Boolean Mtbdd, leaf > value ? true : false
  609. */
  610. Mtbdd MtbddStrictThreshold(double value) const;
  611. /**
  612. * @brief Convert floating-point/fraction Mtbdd to a Boolean Mtbdd, leaf >= value ? true : false
  613. * Same as MtbddThreshold (Bdd = Boolean Mtbdd)
  614. */
  615. Bdd BddThreshold(double value) const;
  616. /**
  617. * @brief Convert floating-point/fraction Mtbdd to a Boolean Mtbdd, leaf > value ? true : false
  618. * Same as MtbddStrictThreshold (Bdd = Boolean Mtbdd)
  619. */
  620. Bdd BddStrictThreshold(double value) const;
  621. /**
  622. * @brief Computes the support of a Mtbdd.
  623. */
  624. Mtbdd Support() const;
  625. /**
  626. * @brief Gets the MTBDD of this Mtbdd (for C functions)
  627. */
  628. MTBDD GetMTBDD() const;
  629. /**
  630. * @brief Functional composition. Whenever a variable v in the map m is found in the MTBDD,
  631. * it is substituted by the associated function (which should be a Boolean MTBDD)
  632. * You can also use this function to implement variable reordering.
  633. */
  634. Mtbdd Compose(MtbddMap &m) const;
  635. /**
  636. * @brief Substitute all variables in the array from by the corresponding variables in to.
  637. */
  638. Mtbdd Permute(const std::vector<uint32_t>& from, const std::vector<uint32_t>& to) const;
  639. /**
  640. * @brief Compute the number of satisfying variable assignments, using variables in cube.
  641. */
  642. double SatCount(const BddSet &variables) const;
  643. /**
  644. * @brief Compute the number of satisfying variable assignments, using the given number of variables.
  645. */
  646. double SatCount(const size_t nvars) const;
  647. /**
  648. * @brief Gets the number of nodes in this Bdd. Not thread-safe!
  649. */
  650. size_t NodeCount() const;
  651. #include "sylvan_obj_mtbdd_storm.hpp"
  652. private:
  653. MTBDD mtbdd;
  654. };
  655. class MtbddMap
  656. {
  657. friend class Mtbdd;
  658. MTBDD mtbdd;
  659. MtbddMap(MTBDD from) : mtbdd(from) { mtbdd_protect(&mtbdd); }
  660. MtbddMap(Mtbdd &from) : mtbdd(from.mtbdd) { mtbdd_protect(&mtbdd); }
  661. public:
  662. MtbddMap() : mtbdd(mtbdd_map_empty()) { mtbdd_protect(&mtbdd); }
  663. ~MtbddMap() { mtbdd_unprotect(&mtbdd); }
  664. MtbddMap(uint32_t key_variable, Mtbdd value);
  665. MtbddMap operator+(const Mtbdd& other) const;
  666. MtbddMap operator+=(const Mtbdd& other);
  667. MtbddMap operator-(const Mtbdd& other) const;
  668. MtbddMap operator-=(const Mtbdd& other);
  669. /**
  670. * @brief Adds a key-value pair to the map
  671. */
  672. void put(uint32_t key, Mtbdd value);
  673. /**
  674. * @brief Removes a key-value pair from the map
  675. */
  676. void removeKey(uint32_t key);
  677. /**
  678. * @brief Returns the number of key-value pairs in this map
  679. */
  680. size_t size();
  681. /**
  682. * @brief Returns non-zero when this map is empty
  683. */
  684. int isEmpty();
  685. };
  686. class Sylvan {
  687. public:
  688. /**
  689. * @brief Initializes the Sylvan framework, call this only once in your program.
  690. * @param initialTableSize The initial size of the nodes table. Must be a power of two.
  691. * @param maxTableSize The maximum size of the nodes table. Must be a power of two.
  692. * @param initialCacheSize The initial size of the operation cache. Must be a power of two.
  693. * @param maxCacheSize The maximum size of the operation cache. Must be a power of two.
  694. */
  695. static void initPackage(size_t initialTableSize, size_t maxTableSize, size_t initialCacheSize, size_t maxCacheSize);
  696. /**
  697. * @brief Initializes the BDD module of the Sylvan framework.
  698. * @param granularity determins operation cache behavior; for higher values (2+) it will use the operation cache less often.
  699. * Values of 3-7 may result in better performance, since occasionally not using the operation cache is fine in practice.
  700. * A granularity of 1 means that every BDD operation will be cached at every variable level.
  701. */
  702. static void initBdd(int granularity);
  703. /**
  704. * @brief Initializes the MTBDD module of the Sylvan framework.
  705. */
  706. static void initMtbdd();
  707. /**
  708. * @brief Frees all memory in use by Sylvan.
  709. * Warning: if you have any Bdd objects which are not bddZero() or bddOne() after this, your program may crash!
  710. */
  711. static void quitPackage();
  712. };
  713. }
  714. #endif