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.

127 lines
4.2 KiB

  1. #ifdef NDEBUG
  2. #undef NDEBUG
  3. #endif
  4. #include <assert.h>
  5. #include <stdio.h>
  6. #include <stdint.h>
  7. #include <sylvan.h>
  8. #include <sylvan_obj.hpp>
  9. #include <storm_function_wrapper.h>
  10. #include <sylvan_storm_rational_function.h>
  11. using namespace sylvan;
  12. VOID_TASK_0(storm_rf)
  13. {
  14. Bdd one = Bdd::bddOne(); // the True terminal
  15. Bdd zero = Bdd::bddZero(); // the False terminal
  16. // check if they really are the True/False terminal
  17. assert(one.GetBDD() == sylvan_true);
  18. assert(zero.GetBDD() == sylvan_false);
  19. Bdd a = Bdd::bddVar(0); // create a BDD variable x_0
  20. Bdd b = Bdd::bddVar(1); // create a BDD variable x_1
  21. // check if a really is the Boolean formula "x_0"
  22. assert(!a.isConstant());
  23. assert(a.TopVar() == 0);
  24. assert(a.Then() == one);
  25. assert(a.Else() == zero);
  26. // check if b really is the Boolean formula "x_1"
  27. assert(!b.isConstant());
  28. assert(b.TopVar() == 1);
  29. assert(b.Then() == one);
  30. assert(b.Else() == zero);
  31. // compute !a
  32. Bdd not_a = !a;
  33. // check if !!a is really a
  34. assert((!not_a) == a);
  35. // compute a * b and !(!a + !b) and check if they are equivalent
  36. Bdd a_and_b = a * b;
  37. Bdd not_not_a_or_not_b = !(!a + !b);
  38. assert(a_and_b == not_not_a_or_not_b);
  39. // perform some simple quantification and check the results
  40. Bdd ex = a_and_b.ExistAbstract(a); // \exists a . a * b
  41. assert(ex == b);
  42. Bdd andabs = a.AndAbstract(b, a); // \exists a . a * b using AndAbstract
  43. assert(ex == andabs);
  44. Bdd univ = a_and_b.UnivAbstract(a); // \forall a . a * b
  45. assert(univ == zero);
  46. // alternative method to get the cube "ab" using bddCube
  47. BddSet variables = a * b;
  48. std::vector<unsigned char> vec = {1, 1};
  49. assert(a_and_b == Bdd::bddCube(variables, vec));
  50. // test the bddCube method for all combinations
  51. assert((!a * !b) == Bdd::bddCube(variables, std::vector<uint8_t>({0, 0})));
  52. assert((!a * b) == Bdd::bddCube(variables, std::vector<uint8_t>({0, 1})));
  53. assert((!a) == Bdd::bddCube(variables, std::vector<uint8_t>({0, 2})));
  54. assert((a * !b) == Bdd::bddCube(variables, std::vector<uint8_t>({1, 0})));
  55. assert((a * b) == Bdd::bddCube(variables, std::vector<uint8_t>({1, 1})));
  56. assert((a) == Bdd::bddCube(variables, std::vector<uint8_t>({1, 2})));
  57. assert((!b) == Bdd::bddCube(variables, std::vector<uint8_t>({2, 0})));
  58. assert((b) == Bdd::bddCube(variables, std::vector<uint8_t>({2, 1})));
  59. assert(one == Bdd::bddCube(variables, std::vector<uint8_t>({2, 2})));
  60. }
  61. VOID_TASK_1(_main, void*, arg)
  62. {
  63. // Initialize Sylvan
  64. // With starting size of the nodes table 1 << 21, and maximum size 1 << 27.
  65. // With starting size of the cache table 1 << 20, and maximum size 1 << 20.
  66. // Memory usage: 24 bytes per node, and 36 bytes per cache bucket
  67. // - 1<<24 nodes: 384 MB
  68. // - 1<<25 nodes: 768 MB
  69. // - 1<<26 nodes: 1536 MB
  70. // - 1<<27 nodes: 3072 MB
  71. // - 1<<24 cache: 576 MB
  72. // - 1<<25 cache: 1152 MB
  73. // - 1<<26 cache: 2304 MB
  74. // - 1<<27 cache: 4608 MB
  75. sylvan_init_package(1LL<<22, 1LL<<26, 1LL<<22, 1LL<<26);
  76. // Initialize the BDD module with granularity 1 (cache every operation)
  77. // A higher granularity (e.g. 6) often results in better performance in practice
  78. sylvan_init_bdd(1);
  79. // Now we can do some simple stuff using the C++ objects.
  80. CALL(storm_rf);
  81. // Report statistics (if SYLVAN_STATS is 1 in the configuration)
  82. sylvan_stats_report(stdout, 1);
  83. // And quit, freeing memory
  84. sylvan_quit();
  85. // We didn't use arg
  86. (void)arg;
  87. }
  88. int
  89. main (int argc, char *argv[])
  90. {
  91. int n_workers = 0; // automatically detect number of workers
  92. size_t deque_size = 0; // default value for the size of task deques for the workers
  93. size_t program_stack_size = 0; // default value for the program stack of each pthread
  94. // Initialize the Lace framework for <n_workers> workers.
  95. lace_init(n_workers, deque_size);
  96. // Spawn and start all worker pthreads; suspends current thread until done.
  97. lace_startup(program_stack_size, TASK(_main), NULL);
  98. // The lace_startup command also exits Lace after _main is completed.
  99. return 0;
  100. (void)argc; // unused variable
  101. (void)argv; // unused variable
  102. }