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.

654 lines
20 KiB

  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #include <unistd.h>
  7. #include <time.h>
  8. #include <sys/types.h>
  9. #include <sys/time.h>
  10. #include <inttypes.h>
  11. #include <assert.h>
  12. #include "llmsset.h"
  13. #include "sylvan.h"
  14. #define BLACK "\33[22;30m"
  15. #define GRAY "\33[01;30m"
  16. #define RED "\33[22;31m"
  17. #define LRED "\33[01;31m"
  18. #define GREEN "\33[22;32m"
  19. #define LGREEN "\33[01;32m"
  20. #define BLUE "\33[22;34m"
  21. #define LBLUE "\33[01;34m"
  22. #define BROWN "\33[22;33m"
  23. #define YELLOW "\33[01;33m"
  24. #define CYAN "\33[22;36m"
  25. #define LCYAN "\33[22;36m"
  26. #define MAGENTA "\33[22;35m"
  27. #define LMAGENTA "\33[01;35m"
  28. #define NC "\33[0m"
  29. #define BOLD "\33[1m"
  30. #define ULINE "\33[4m" //underline
  31. #define BLINK "\33[5m"
  32. #define INVERT "\33[7m"
  33. __thread uint64_t seed = 1;
  34. uint64_t
  35. xorshift_rand(void)
  36. {
  37. uint64_t x = seed;
  38. if (seed == 0) seed = rand();
  39. x ^= x >> 12;
  40. x ^= x << 25;
  41. x ^= x >> 27;
  42. seed = x;
  43. return x * 2685821657736338717LL;
  44. }
  45. double
  46. uniform_deviate(uint64_t seed)
  47. {
  48. return seed * (1.0 / (0xffffffffffffffffL + 1.0));
  49. }
  50. int
  51. rng(int low, int high)
  52. {
  53. return low + uniform_deviate(xorshift_rand()) * (high-low);
  54. }
  55. static inline BDD
  56. make_random(int i, int j)
  57. {
  58. if (i == j) return rng(0, 2) ? sylvan_true : sylvan_false;
  59. BDD yes = make_random(i+1, j);
  60. BDD no = make_random(i+1, j);
  61. BDD result = sylvan_invalid;
  62. switch(rng(0, 4)) {
  63. case 0:
  64. result = no;
  65. sylvan_deref(yes);
  66. break;
  67. case 1:
  68. result = yes;
  69. sylvan_deref(no);
  70. break;
  71. case 2:
  72. result = sylvan_ref(sylvan_makenode(i, yes, no));
  73. sylvan_deref(no);
  74. sylvan_deref(yes);
  75. break;
  76. case 3:
  77. default:
  78. result = sylvan_ref(sylvan_makenode(i, no, yes));
  79. sylvan_deref(no);
  80. sylvan_deref(yes);
  81. break;
  82. }
  83. return result;
  84. }
  85. void testFun(BDD p1, BDD p2, BDD r1, BDD r2)
  86. {
  87. if (r1 == r2) return;
  88. printf("Parameter 1:\n");
  89. fflush(stdout);
  90. sylvan_printdot(p1);
  91. sylvan_print(p1);printf("\n");
  92. printf("Parameter 2:\n");
  93. fflush(stdout);
  94. sylvan_printdot(p2);
  95. sylvan_print(p2);printf("\n");
  96. printf("Result 1:\n");
  97. fflush(stdout);
  98. sylvan_printdot(r1);
  99. printf("Result 2:\n");
  100. fflush(stdout);
  101. sylvan_printdot(r2);
  102. assert(0);
  103. }
  104. int testEqual(BDD a, BDD b)
  105. {
  106. if (a == b) return 1;
  107. if (a == sylvan_invalid) {
  108. printf("a is invalid!\n");
  109. return 0;
  110. }
  111. if (b == sylvan_invalid) {
  112. printf("b is invalid!\n");
  113. return 0;
  114. }
  115. printf("Not Equal!\n");
  116. fflush(stdout);
  117. sylvan_print(a);printf("\n");
  118. sylvan_print(b);printf("\n");
  119. return 0;
  120. }
  121. void
  122. test_bdd()
  123. {
  124. sylvan_gc_disable();
  125. assert(sylvan_makenode(sylvan_ithvar(1), sylvan_true, sylvan_true) == sylvan_not(sylvan_makenode(sylvan_ithvar(1), sylvan_false, sylvan_false)));
  126. assert(sylvan_makenode(sylvan_ithvar(1), sylvan_false, sylvan_true) == sylvan_not(sylvan_makenode(sylvan_ithvar(1), sylvan_true, sylvan_false)));
  127. assert(sylvan_makenode(sylvan_ithvar(1), sylvan_true, sylvan_false) == sylvan_not(sylvan_makenode(sylvan_ithvar(1), sylvan_false, sylvan_true)));
  128. assert(sylvan_makenode(sylvan_ithvar(1), sylvan_false, sylvan_false) == sylvan_not(sylvan_makenode(sylvan_ithvar(1), sylvan_true, sylvan_true)));
  129. sylvan_gc_enable();
  130. }
  131. void
  132. test_cube()
  133. {
  134. LACE_ME;
  135. BDDSET vars = sylvan_set_fromarray(((BDDVAR[]){1,2,3,4,6,8}), 6);
  136. uint8_t cube[6], check[6];
  137. int i, j;
  138. for (i=0;i<6;i++) cube[i] = rng(0,3);
  139. BDD bdd = sylvan_cube(vars, cube);
  140. sylvan_sat_one(bdd, vars, check);
  141. for (i=0; i<6;i++) assert(cube[i] == check[i] || cube[i] == 2 && check[i] == 0);
  142. BDD picked = sylvan_pick_cube(bdd);
  143. assert(testEqual(sylvan_and(picked, bdd), picked));
  144. BDD t1 = sylvan_cube(vars, ((uint8_t[]){1,1,2,2,0,0}));
  145. BDD t2 = sylvan_cube(vars, ((uint8_t[]){1,1,1,0,0,2}));
  146. assert(testEqual(sylvan_union_cube(t1, vars, ((uint8_t[]){1,1,1,0,0,2})), sylvan_or(t1, t2)));
  147. t2 = sylvan_cube(vars, ((uint8_t[]){2,2,2,1,1,0}));
  148. assert(testEqual(sylvan_union_cube(t1, vars, ((uint8_t[]){2,2,2,1,1,0})), sylvan_or(t1, t2)));
  149. t2 = sylvan_cube(vars, ((uint8_t[]){1,1,1,0,0,0}));
  150. assert(testEqual(sylvan_union_cube(t1, vars, ((uint8_t[]){1,1,1,0,0,0})), sylvan_or(t1, t2)));
  151. sylvan_gc_disable();
  152. bdd = make_random(1, 16);
  153. for (j=0;j<10;j++) {
  154. for (i=0;i<6;i++) cube[i] = rng(0,3);
  155. BDD c = sylvan_cube(vars, cube);
  156. assert(sylvan_union_cube(bdd, vars, cube) == sylvan_or(bdd, c));
  157. }
  158. for (i=0;i<10;i++) {
  159. picked = sylvan_pick_cube(bdd);
  160. assert(testEqual(sylvan_and(picked, bdd), picked));
  161. }
  162. sylvan_gc_enable();
  163. }
  164. static void
  165. test_operators()
  166. {
  167. // We need to test: xor, and, or, nand, nor, imp, biimp, invimp, diff, less
  168. sylvan_gc_disable();
  169. LACE_ME;
  170. //int i;
  171. BDD a = sylvan_ithvar(1);
  172. BDD b = sylvan_ithvar(2);
  173. BDD one = make_random(1, 12);
  174. BDD two = make_random(6, 24);
  175. // Test or
  176. assert(testEqual(sylvan_or(a, b), sylvan_makenode(1, b, sylvan_true)));
  177. assert(testEqual(sylvan_or(a, b), sylvan_or(b, a)));
  178. assert(testEqual(sylvan_or(one, two), sylvan_or(two, one)));
  179. // Test and
  180. assert(testEqual(sylvan_and(a, b), sylvan_makenode(1, sylvan_false, b)));
  181. assert(testEqual(sylvan_and(a, b), sylvan_and(b, a)));
  182. assert(testEqual(sylvan_and(one, two), sylvan_and(two, one)));
  183. // Test xor
  184. assert(testEqual(sylvan_xor(a, b), sylvan_makenode(1, b, sylvan_not(b))));
  185. assert(testEqual(sylvan_xor(a, b), sylvan_xor(a, b)));
  186. assert(testEqual(sylvan_xor(a, b), sylvan_xor(b, a)));
  187. assert(testEqual(sylvan_xor(one, two), sylvan_xor(two, one)));
  188. assert(testEqual(sylvan_xor(a, b), sylvan_ite(a, sylvan_not(b), b)));
  189. // Test diff
  190. assert(testEqual(sylvan_diff(a, b), sylvan_diff(a, b)));
  191. assert(testEqual(sylvan_diff(a, b), sylvan_diff(a, sylvan_and(a, b))));
  192. assert(testEqual(sylvan_diff(a, b), sylvan_and(a, sylvan_not(b))));
  193. assert(testEqual(sylvan_diff(a, b), sylvan_ite(b, sylvan_false, a)));
  194. assert(testEqual(sylvan_diff(one, two), sylvan_diff(one, two)));
  195. assert(testEqual(sylvan_diff(one, two), sylvan_diff(one, sylvan_and(one, two))));
  196. assert(testEqual(sylvan_diff(one, two), sylvan_and(one, sylvan_not(two))));
  197. assert(testEqual(sylvan_diff(one, two), sylvan_ite(two, sylvan_false, one)));
  198. // Test biimp
  199. assert(testEqual(sylvan_biimp(a, b), sylvan_makenode(1, sylvan_not(b), b)));
  200. assert(testEqual(sylvan_biimp(a, b), sylvan_biimp(b, a)));
  201. assert(testEqual(sylvan_biimp(one, two), sylvan_biimp(two, one)));
  202. // Test nand / and
  203. assert(testEqual(sylvan_not(sylvan_and(a, b)), sylvan_nand(b, a)));
  204. assert(testEqual(sylvan_not(sylvan_and(one, two)), sylvan_nand(two, one)));
  205. // Test nor / or
  206. assert(testEqual(sylvan_not(sylvan_or(a, b)), sylvan_nor(b, a)));
  207. assert(testEqual(sylvan_not(sylvan_or(one, two)), sylvan_nor(two, one)));
  208. // Test xor / biimp
  209. assert(testEqual(sylvan_xor(a, b), sylvan_not(sylvan_biimp(b, a))));
  210. assert(testEqual(sylvan_xor(one, two), sylvan_not(sylvan_biimp(two, one))));
  211. // Test imp
  212. assert(testEqual(sylvan_imp(a, b), sylvan_ite(a, b, sylvan_true)));
  213. assert(testEqual(sylvan_imp(one, two), sylvan_ite(one, two, sylvan_true)));
  214. assert(testEqual(sylvan_imp(one, two), sylvan_not(sylvan_diff(one, two))));
  215. assert(testEqual(sylvan_invimp(one, two), sylvan_not(sylvan_less(one, two))));
  216. assert(testEqual(sylvan_imp(a, b), sylvan_invimp(b, a)));
  217. assert(testEqual(sylvan_imp(one, two), sylvan_invimp(two, one)));
  218. // Test constrain, exists and forall
  219. sylvan_gc_enable();
  220. }
  221. static void
  222. test_relprod()
  223. {
  224. LACE_ME;
  225. sylvan_gc_disable();
  226. BDDVAR vars[] = {0,2,4};
  227. BDDVAR all_vars[] = {0,1,2,3,4,5};
  228. BDDSET vars_set = sylvan_set_fromarray(vars, 3);
  229. BDDSET all_vars_set = sylvan_set_fromarray(all_vars, 6);
  230. BDD s, t, next, prev;
  231. BDD zeroes, ones;
  232. // transition relation: 000 --> 111 and !000 --> 000
  233. t = sylvan_false;
  234. t = sylvan_union_cube(t, all_vars_set, ((uint8_t[]){0,1,0,1,0,1}));
  235. t = sylvan_union_cube(t, all_vars_set, ((uint8_t[]){1,0,2,0,2,0}));
  236. t = sylvan_union_cube(t, all_vars_set, ((uint8_t[]){2,0,1,0,2,0}));
  237. t = sylvan_union_cube(t, all_vars_set, ((uint8_t[]){2,0,2,0,1,0}));
  238. s = sylvan_cube(vars_set, (uint8_t[]){0,0,1});
  239. zeroes = sylvan_cube(vars_set, (uint8_t[]){0,0,0});
  240. ones = sylvan_cube(vars_set, (uint8_t[]){1,1,1});
  241. next = sylvan_relnext(s, t, all_vars_set);
  242. prev = sylvan_relprev(t, next, all_vars_set);
  243. assert(next == zeroes);
  244. assert(prev == sylvan_not(zeroes));
  245. next = sylvan_relnext(next, t, all_vars_set);
  246. prev = sylvan_relprev(t, next, all_vars_set);
  247. assert(next == ones);
  248. assert(prev == zeroes);
  249. t = sylvan_cube(all_vars_set, (uint8_t[]){0,0,0,0,0,1});
  250. assert(sylvan_relprev(t, s, all_vars_set) == zeroes);
  251. assert(sylvan_relprev(t, sylvan_not(s), all_vars_set) == sylvan_false);
  252. assert(sylvan_relnext(s, t, all_vars_set) == sylvan_false);
  253. assert(sylvan_relnext(zeroes, t, all_vars_set) == s);
  254. t = sylvan_cube(all_vars_set, (uint8_t[]){0,0,0,0,0,2});
  255. assert(sylvan_relprev(t, s, all_vars_set) == zeroes);
  256. assert(sylvan_relprev(t, zeroes, all_vars_set) == zeroes);
  257. assert(sylvan_relnext(sylvan_not(zeroes), t, all_vars_set) == sylvan_false);
  258. sylvan_gc_enable();
  259. }
  260. static void
  261. test_compose()
  262. {
  263. sylvan_gc_disable();
  264. LACE_ME;
  265. BDD a = sylvan_ithvar(1);
  266. BDD b = sylvan_ithvar(2);
  267. BDD a_or_b = sylvan_or(a, b);
  268. BDD one = make_random(3, 16);
  269. BDD two = make_random(8, 24);
  270. BDDMAP map = sylvan_map_empty();
  271. map = sylvan_map_add(map, 1, one);
  272. map = sylvan_map_add(map, 2, two);
  273. assert(sylvan_map_key(map) == 1);
  274. assert(sylvan_map_value(map) == one);
  275. assert(sylvan_map_key(sylvan_map_next(map)) == 2);
  276. assert(sylvan_map_value(sylvan_map_next(map)) == two);
  277. assert(testEqual(one, sylvan_compose(a, map)));
  278. assert(testEqual(two, sylvan_compose(b, map)));
  279. assert(testEqual(sylvan_or(one, two), sylvan_compose(a_or_b, map)));
  280. map = sylvan_map_add(map, 2, one);
  281. assert(testEqual(sylvan_compose(a_or_b, map), one));
  282. map = sylvan_map_add(map, 1, two);
  283. assert(testEqual(sylvan_or(one, two), sylvan_compose(a_or_b, map)));
  284. assert(testEqual(sylvan_and(one, two), sylvan_compose(sylvan_and(a, b), map)));
  285. sylvan_gc_enable();
  286. }
  287. /** GC testing */
  288. VOID_TASK_2(gctest_fill, int, levels, int, width)
  289. {
  290. if (levels > 1) {
  291. int i;
  292. for (i=0; i<width; i++) { SPAWN(gctest_fill, levels-1, width); }
  293. for (i=0; i<width; i++) { SYNC(gctest_fill); }
  294. } else {
  295. sylvan_deref(make_random(0, 10));
  296. }
  297. }
  298. void report_table()
  299. {
  300. llmsset_t __sylvan_get_internal_data();
  301. llmsset_t tbl = __sylvan_get_internal_data();
  302. LACE_ME;
  303. size_t filled = llmsset_count_marked(tbl);
  304. size_t total = llmsset_get_size(tbl);
  305. printf("done, table: %0.1f%% full (%zu nodes).\n", 100.0*(double)filled/total, filled);
  306. }
  307. void test_gc(int threads)
  308. {
  309. LACE_ME;
  310. int N_canaries = 16;
  311. BDD canaries[N_canaries];
  312. char* hashes[N_canaries];
  313. char* hashes2[N_canaries];
  314. int i,j;
  315. for (i=0;i<N_canaries;i++) {
  316. canaries[i] = make_random(0, 10);
  317. hashes[i] = (char*)malloc(80);
  318. hashes2[i] = (char*)malloc(80);
  319. sylvan_getsha(canaries[i], hashes[i]);
  320. sylvan_test_isbdd(canaries[i]);
  321. }
  322. assert(sylvan_count_refs() == (size_t)N_canaries);
  323. for (j=0;j<10*threads;j++) {
  324. CALL(gctest_fill, 6, 5);
  325. for (i=0;i<N_canaries;i++) {
  326. sylvan_test_isbdd(canaries[i]);
  327. sylvan_getsha(canaries[i], hashes2[i]);
  328. assert(strcmp(hashes[i], hashes2[i]) == 0);
  329. }
  330. }
  331. assert(sylvan_count_refs() == (size_t)N_canaries);
  332. }
  333. TASK_2(MDD, random_ldd, int, depth, int, count)
  334. {
  335. uint32_t n[depth];
  336. MDD result = lddmc_false;
  337. int i, j;
  338. for (i=0; i<count; i++) {
  339. for (j=0; j<depth; j++) {
  340. n[j] = rng(0, 10);
  341. }
  342. MDD old = result;
  343. result = lddmc_union_cube(result, n, depth);
  344. assert(lddmc_cube(n, depth) != lddmc_true);
  345. assert(result == lddmc_union(old, lddmc_cube(n, depth)));
  346. assert(result != lddmc_true);
  347. }
  348. return result;
  349. }
  350. VOID_TASK_3(enumer, uint32_t*, values, size_t, count, void*, context)
  351. {
  352. return;
  353. (void)values;
  354. (void)count;
  355. (void)context;
  356. }
  357. void
  358. test_lddmc()
  359. {
  360. LACE_ME;
  361. sylvan_init_package(1LL<<24, 1LL<<24, 1LL<<24, 1LL<<24);
  362. sylvan_init_ldd();
  363. sylvan_gc_disable();
  364. MDD a, b, c;
  365. // Test union, union_cube, member_cube, satcount
  366. a = lddmc_cube((uint32_t[]){1,2,3,5,4,3}, 6);
  367. a = lddmc_union(a,lddmc_cube((uint32_t[]){2,2,3,5,4,3}, 6));
  368. c = b = a = lddmc_union_cube(a, (uint32_t[]){2,2,3,5,4,2}, 6);
  369. a = lddmc_union_cube(a, (uint32_t[]){2,3,3,5,4,3}, 6);
  370. a = lddmc_union(a, lddmc_cube((uint32_t[]){2,3,4,4,4,3}, 6));
  371. assert(lddmc_member_cube(a, (uint32_t[]){2,3,3,5,4,3}, 6));
  372. assert(lddmc_member_cube(a, (uint32_t[]){1,2,3,5,4,3}, 6));
  373. assert(lddmc_member_cube(a, (uint32_t[]){2,2,3,5,4,3}, 6));
  374. assert(lddmc_member_cube(a, (uint32_t[]){2,2,3,5,4,2}, 6));
  375. assert(lddmc_satcount(a) == 5);
  376. lddmc_sat_all_par(a, TASK(enumer), NULL);
  377. // Test minus, member_cube, satcount
  378. a = lddmc_minus(a, b);
  379. assert(lddmc_member_cube(a, (uint32_t[]){2,3,3,5,4,3}, 6));
  380. assert(!lddmc_member_cube(a, (uint32_t[]){1,2,3,5,4,3}, 6));
  381. assert(!lddmc_member_cube(a, (uint32_t[]){2,2,3,5,4,3}, 6));
  382. assert(!lddmc_member_cube(a, (uint32_t[]){2,2,3,5,4,2}, 6));
  383. assert(lddmc_member_cube(a, (uint32_t[]){2,3,4,4,4,3}, 6));
  384. assert(lddmc_satcount(a) == 2);
  385. // Test intersect
  386. assert(lddmc_satcount(lddmc_intersect(a,b)) == 0);
  387. assert(lddmc_intersect(b,c)==lddmc_intersect(c,b));
  388. assert(lddmc_intersect(b,c)==c);
  389. // Test project, project_minus
  390. a = lddmc_cube((uint32_t[]){1,2,3,5,4,3}, 6);
  391. a = lddmc_union_cube(a, (uint32_t[]){2,2,3,5,4,3}, 6);
  392. a = lddmc_union_cube(a, (uint32_t[]){2,2,3,5,4,2}, 6);
  393. a = lddmc_union_cube(a, (uint32_t[]){2,3,3,5,4,3}, 6);
  394. a = lddmc_union_cube(a, (uint32_t[]){2,3,4,4,4,3}, 6);
  395. // a = {<1,2,3,5,4,3>,<2,2,3,5,4,3>,<2,2,3,5,4,2>,<2,3,3,5,4,3>,<2,3,4,4,4,3>}
  396. MDD proj = lddmc_cube((uint32_t[]){1,1,-2},3);
  397. b = lddmc_cube((uint32_t[]){1,2}, 2);
  398. b = lddmc_union_cube(b, (uint32_t[]){2,2}, 2);
  399. b = lddmc_union_cube(b, (uint32_t[]){2,3}, 2);
  400. assert(lddmc_project(a, proj)==b);
  401. assert(lddmc_project_minus(a, proj, lddmc_false)==b);
  402. assert(lddmc_project_minus(a, proj, b)==lddmc_false);
  403. // Test relprod
  404. a = lddmc_cube((uint32_t[]){1},1);
  405. b = lddmc_cube((uint32_t[]){1,2},2);
  406. proj = lddmc_cube((uint32_t[]){1,2,-1}, 3);
  407. assert(lddmc_cube((uint32_t[]){2},1) == lddmc_relprod(a, b, proj));
  408. assert(lddmc_cube((uint32_t[]){3},1) == lddmc_relprod(a, lddmc_cube((uint32_t[]){1,3},2), proj));
  409. a = lddmc_union_cube(a, (uint32_t[]){2},1);
  410. assert(lddmc_satcount(a) == 2);
  411. assert(lddmc_cube((uint32_t[]){2},1) == lddmc_relprod(a, b, proj));
  412. b = lddmc_union_cube(b, (uint32_t[]){2,2},2);
  413. assert(lddmc_cube((uint32_t[]){2},1) == lddmc_relprod(a, b, proj));
  414. b = lddmc_union_cube(b, (uint32_t[]){2,3},2);
  415. assert(lddmc_satcount(lddmc_relprod(a, b, proj)) == 2);
  416. assert(lddmc_union(lddmc_cube((uint32_t[]){2},1),lddmc_cube((uint32_t[]){3},1)) == lddmc_relprod(a, b, proj));
  417. // Test relprev
  418. MDD universe = lddmc_union(lddmc_cube((uint32_t[]){1},1), lddmc_cube((uint32_t[]){2},1));
  419. a = lddmc_cube((uint32_t[]){2},1);
  420. b = lddmc_cube((uint32_t[]){1,2},2);
  421. assert(lddmc_cube((uint32_t[]){1},1) == lddmc_relprev(a, b, proj, universe));
  422. assert(lddmc_cube((uint32_t[]){1},1) == lddmc_relprev(a, b, proj, lddmc_cube((uint32_t[]){1},1)));
  423. a = lddmc_cube((uint32_t[]){1},1);
  424. MDD next = lddmc_relprod(a, b, proj);
  425. assert(lddmc_relprev(next, b, proj, a) == a);
  426. // Random tests
  427. MDD rnd1, rnd2;
  428. int i;
  429. for (i=0; i<200; i++) {
  430. int depth = rng(1, 20);
  431. rnd1 = CALL(random_ldd, depth, rng(0, 30));
  432. rnd2 = CALL(random_ldd, depth, rng(0, 30));
  433. assert(rnd1 != lddmc_true);
  434. assert(rnd2 != lddmc_true);
  435. assert(lddmc_intersect(rnd1,rnd2) == lddmc_intersect(rnd2,rnd1));
  436. assert(lddmc_union(rnd1,rnd2) == lddmc_union(rnd2,rnd1));
  437. MDD tmp = lddmc_union(lddmc_minus(rnd1, rnd2), lddmc_minus(rnd2, rnd1));
  438. assert(lddmc_intersect(tmp, lddmc_intersect(rnd1, rnd2)) == lddmc_false);
  439. assert(lddmc_union(tmp, lddmc_intersect(rnd1, rnd2)) == lddmc_union(rnd1, rnd2));
  440. assert(lddmc_minus(rnd1,rnd2) == lddmc_minus(rnd1, lddmc_intersect(rnd1,rnd2)));
  441. }
  442. // Test file stuff
  443. for (i=0; i<10; i++) {
  444. FILE *f = fopen("__lddmc_test_bdd", "w+");
  445. int N = 20;
  446. MDD rnd[N];
  447. size_t a[N];
  448. char sha[N][65];
  449. int j;
  450. for (j=0;j<N;j++) rnd[j] = CALL(random_ldd, 5, 500);
  451. for (j=0;j<N;j++) lddmc_getsha(rnd[j], sha[j]);
  452. for (j=0;j<N;j++) { a[j] = lddmc_serialize_add(rnd[j]); lddmc_serialize_tofile(f); }
  453. for (j=0;j<N;j++) assert(a[j] == lddmc_serialize_get(rnd[j]));
  454. for (j=0;j<N;j++) assert(rnd[j] == lddmc_serialize_get_reversed(a[j]));
  455. fseek(f, 0, SEEK_SET);
  456. lddmc_serialize_reset();
  457. sylvan_quit();
  458. sylvan_init_package(1LL<<24, 1LL<<24, 1LL<<24, 1LL<<24);
  459. sylvan_init_ldd();
  460. sylvan_gc_disable();
  461. for (j=0;j<N;j++) lddmc_serialize_fromfile(f);
  462. fclose(f);
  463. unlink("__lddmc_test_bdd");
  464. for (j=0;j<N;j++) rnd[j] = lddmc_serialize_get_reversed(a[j]);
  465. char sha2[N][65];
  466. for (j=0;j<N;j++) lddmc_getsha(rnd[j], sha2[j]);
  467. for (j=0;j<N;j++) assert(memcmp(sha[j], sha2[j], 64)==0);
  468. lddmc_serialize_reset();
  469. }
  470. sylvan_quit();
  471. }
  472. void runtests(int threads)
  473. {
  474. lace_init(threads, 100000);
  475. lace_startup(0, NULL, NULL);
  476. printf(BOLD "Testing LDDMC... ");
  477. fflush(stdout);
  478. test_lddmc();
  479. printf(LGREEN "success" NC "!\n");
  480. printf(BOLD "Testing Sylvan\n");
  481. printf(NC "Testing basic bdd functionality... ");
  482. fflush(stdout);
  483. sylvan_init_package(1LL<<16, 1LL<<16, 1LL<<16, 1LL<<16);
  484. sylvan_init_bdd(1);
  485. test_bdd();
  486. sylvan_quit();
  487. printf(LGREEN "success" NC "!\n");
  488. // what happens if we make a cube
  489. printf(NC "Testing cube function... ");
  490. fflush(stdout);
  491. int j;
  492. sylvan_init_package(1LL<<24, 1LL<<24, 1LL<<24, 1LL<<24);
  493. sylvan_init_bdd(1);
  494. for (j=0;j<20;j++) test_cube();
  495. sylvan_quit();
  496. printf(LGREEN "success" NC "!\n");
  497. printf(NC "Testing relational products... ");
  498. fflush(stdout);
  499. sylvan_init_package(1LL<<24, 1LL<<24, 1LL<<24, 1LL<<24);
  500. sylvan_init_bdd(1);
  501. for (j=0;j<20;j++) test_relprod();
  502. sylvan_quit();
  503. printf(LGREEN "success" NC "!\n");
  504. printf(NC "Testing function composition... ");
  505. fflush(stdout);
  506. sylvan_init_package(1LL<<24, 1LL<<24, 1LL<<24, 1LL<<24);
  507. sylvan_init_bdd(1);
  508. for (j=0;j<20;j++) test_compose();
  509. sylvan_quit();
  510. printf(LGREEN "success" NC "!\n");
  511. printf(NC "Testing garbage collection... ");
  512. fflush(stdout);
  513. sylvan_init_package(1LL<<14, 1LL<<14, 1LL<<20, 1LL<<20);
  514. sylvan_init_bdd(1);
  515. test_gc(threads);
  516. sylvan_quit();
  517. printf(LGREEN "success" NC "!\n");
  518. printf(NC "Testing operators... ");
  519. fflush(stdout);
  520. sylvan_init_package(1LL<<24, 1LL<<24, 1LL<<24, 1LL<<24);
  521. sylvan_init_bdd(1);
  522. for (j=0;j<20;j++) test_operators();
  523. sylvan_quit();
  524. printf(LGREEN "success" NC "!\n");
  525. lace_exit();
  526. }
  527. int main(int argc, char **argv)
  528. {
  529. int threads = 2;
  530. if (argc > 1) sscanf(argv[1], "%d", &threads);
  531. runtests(threads);
  532. printf(NC);
  533. exit(0);
  534. }