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.

2253 lines
59 KiB

2 months ago
  1. /**
  2. @file
  3. @ingroup nanotrav
  4. @brief %BDD test functions for the nanotrav program.
  5. @author Fabio Somenzi
  6. @copyright@parblock
  7. Copyright (c) 1995-2015, Regents of the University of Colorado
  8. All rights reserved.
  9. Redistribution and use in source and binary forms, with or without
  10. modification, are permitted provided that the following conditions
  11. are met:
  12. Redistributions of source code must retain the above copyright
  13. notice, this list of conditions and the following disclaimer.
  14. Redistributions in binary form must reproduce the above copyright
  15. notice, this list of conditions and the following disclaimer in the
  16. documentation and/or other materials provided with the distribution.
  17. Neither the name of the University of Colorado nor the names of its
  18. contributors may be used to endorse or promote products derived from
  19. this software without specific prior written permission.
  20. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  23. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  24. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  26. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  28. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  30. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  31. POSSIBILITY OF SUCH DAMAGE.
  32. @endparblock
  33. */
  34. #include "ntr.h"
  35. #include "cuddInt.h"
  36. /*---------------------------------------------------------------------------*/
  37. /* Constant declarations */
  38. /*---------------------------------------------------------------------------*/
  39. /*---------------------------------------------------------------------------*/
  40. /* Stucture declarations */
  41. /*---------------------------------------------------------------------------*/
  42. /*---------------------------------------------------------------------------*/
  43. /* Type declarations */
  44. /*---------------------------------------------------------------------------*/
  45. /*---------------------------------------------------------------------------*/
  46. /* Variable declarations */
  47. /*---------------------------------------------------------------------------*/
  48. /*---------------------------------------------------------------------------*/
  49. /* Macro declarations */
  50. /*---------------------------------------------------------------------------*/
  51. /** \cond */
  52. /*---------------------------------------------------------------------------*/
  53. /* Static function prototypes */
  54. /*---------------------------------------------------------------------------*/
  55. static int ntrTestMinimizationAux (DdManager *dd, BnetNetwork *net1, DdNode *f, char *name, DdNode *c, char *cname, NtrOptions *option);
  56. static int ntrTestDensityAux (DdManager *dd, BnetNetwork *net, DdNode *f, char *name, NtrOptions *option);
  57. static int ntrTestDecompAux (DdManager *dd, BnetNetwork *net, DdNode *f, char *name, NtrOptions *option);
  58. static int ntrTestCofEstAux (DdManager * dd, BnetNetwork * net, DdNode * f, char * name, NtrOptions * option);
  59. static int ntrTestClippingAux (DdManager *dd, BnetNetwork *net1, DdNode *f, char *name, DdNode *g, char *gname, NtrOptions *option);
  60. static int ntrTestEquivAndContainAux (DdManager *dd, BnetNetwork *net1, DdNode *f, char *fname, DdNode *g, char *gname, DdNode *d, char *dname, NtrOptions *option);
  61. static int ntrTestClosestCubeAux (DdManager *dd, BnetNetwork *net, DdNode *f, char *fname, DdNode *g, char *gname, DdNode **vars, NtrOptions *option);
  62. static int ntrTestCharToVect(DdManager * dd, DdNode * f, NtrOptions *option);
  63. #if 0
  64. static DdNode * ntrCompress1 (DdManager *dd, DdNode *f, int nvars, int threshold);
  65. #endif
  66. static DdNode * ntrCompress2 (DdManager *dd, DdNode *f, int nvars, int threshold);
  67. static BnetNode * ntrNodeIsBuffer (BnetNode *nd, st_table *hash);
  68. /** \endcond */
  69. /*---------------------------------------------------------------------------*/
  70. /* Definition of exported functions */
  71. /*---------------------------------------------------------------------------*/
  72. /**
  73. @brief Tests %BDD minimization functions.
  74. @details Tests %BDD minimization functions, including
  75. leaf-identifying compaction, squeezing, and restrict. This function
  76. uses as constraint the first output of net2 and computes positive
  77. and negative cofactors of all the outputs of net1. For each
  78. cofactor, it checks whether compaction was safe (cofactor not larger
  79. than original function) and that the expansion based on each
  80. minimization function (used as a generalized cofactor) equals the
  81. original function.
  82. @return 1 if successful; 0 otherwise.
  83. @sideeffect None
  84. */
  85. int
  86. Ntr_TestMinimization(
  87. DdManager * dd,
  88. BnetNetwork * net1,
  89. BnetNetwork * net2,
  90. NtrOptions * option)
  91. {
  92. DdNode *f;
  93. DdNode *c = NULL;
  94. char *cname = NULL;
  95. BnetNode *node;
  96. int i;
  97. int result;
  98. int nsize, csize;
  99. if (option->second == FALSE) return(1);
  100. (void) printf("Testing BDD minimization algorithms\n");
  101. /* Use largest output of second network as constraint. */
  102. csize = -1;
  103. for (i = 0; i < net2->noutputs; i++) {
  104. if (!st_lookup(net2->hash,net2->outputs[i],(void **)&node)) {
  105. return(0);
  106. }
  107. nsize = Cudd_DagSize(node->dd);
  108. if (nsize > csize) {
  109. c = node->dd;
  110. cname = node->name;
  111. csize = nsize;
  112. }
  113. }
  114. if (c == NULL || cname == NULL) return(0);
  115. (void) printf("TEST-MINI: Constrain (%s) %d nodes\n",
  116. cname, Cudd_DagSize(c));
  117. if (option->node == NULL) {
  118. for (i = 0; i < net1->noutputs; i++) {
  119. if (!st_lookup(net1->hash,net1->outputs[i],(void **)&node)) {
  120. return(0);
  121. }
  122. f = node->dd;
  123. if (f == NULL) return(0);
  124. result = ntrTestMinimizationAux(dd,net1,f,node->name,c,cname,
  125. option);
  126. if (result == 0) return(0);
  127. }
  128. } else {
  129. if (!st_lookup(net1->hash,option->node,(void **)&node)) {
  130. return(0);
  131. }
  132. f = node->dd;
  133. if (f == NULL) return(0);
  134. result = ntrTestMinimizationAux(dd,net1,f,option->node,c,cname,option);
  135. if (result == 0) return(0);
  136. }
  137. return(1);
  138. } /* end of Ntr_TestMinimization */
  139. /**
  140. @brief Tests %BDD density-related functions.
  141. @return 1 if successful; 0 otherwise.
  142. @sideeffect None
  143. */
  144. int
  145. Ntr_TestDensity(
  146. DdManager * dd,
  147. BnetNetwork * net1,
  148. NtrOptions * option)
  149. {
  150. DdNode *f;
  151. BnetNode *node;
  152. int i;
  153. int result;
  154. if (option->density == FALSE) return(1);
  155. (void) printf("Testing BDD density-related algorithms\n");
  156. if (option->node == NULL) {
  157. for (i = 0; i < net1->noutputs; i++) {
  158. if (!st_lookup(net1->hash,net1->outputs[i],(void **)&node)) {
  159. return(0);
  160. }
  161. f = node->dd;
  162. if (f == NULL) return(0);
  163. result = ntrTestDensityAux(dd,net1,f,node->name,option);
  164. if (result == 0) return(0);
  165. }
  166. } else {
  167. if (!st_lookup(net1->hash,option->node,(void **)&node)) {
  168. return(0);
  169. }
  170. f = node->dd;
  171. if (f == NULL) return(0);
  172. result = ntrTestDensityAux(dd,net1,f,option->node,option);
  173. if (result == 0) return(0);
  174. }
  175. return(1);
  176. } /* end of Ntr_TestDensity */
  177. /**
  178. @brief Tests %BDD decomposition functions.
  179. @return 1 if successful; 0 otherwise.
  180. @sideeffect None
  181. */
  182. int
  183. Ntr_TestDecomp(
  184. DdManager * dd,
  185. BnetNetwork * net1,
  186. NtrOptions * option)
  187. {
  188. DdNode *f;
  189. BnetNode *node;
  190. int i;
  191. int result;
  192. if (option->decomp == FALSE) return(1);
  193. (void) printf("Testing BDD decomposition algorithms\n");
  194. if (option->node == NULL) {
  195. for (i = 0; i < net1->noutputs; i++) {
  196. if (!st_lookup(net1->hash,net1->outputs[i],(void **)&node)) {
  197. return(0);
  198. }
  199. f = node->dd;
  200. if (f == NULL) return(0);
  201. result = ntrTestDecompAux(dd,net1,f,node->name,option);
  202. if (result == 0) return(0);
  203. }
  204. } else {
  205. if (!st_lookup(net1->hash,option->node,(void **)&node)) {
  206. return(0);
  207. }
  208. f = node->dd;
  209. if (f == NULL) return(0);
  210. result = ntrTestDecompAux(dd,net1,f,option->node,option);
  211. if (result == 0) return(0);
  212. }
  213. return(1);
  214. } /* end of ntrTestDecomp */
  215. /**
  216. @brief Verify equivalence of combinational networks.
  217. @details The two networks are supposed to have the same names for
  218. inputs and outputs. The only exception is that the second network
  219. may miss output buffers that are present in the first network. This
  220. function tries to match both the output and the input of the buffer.
  221. @return 1 if successful and if the networks are equivalent; -1 if
  222. successful, but the networks are not equivalent; 0 otherwise.
  223. @sideeffect None
  224. */
  225. int
  226. Ntr_VerifyEquivalence(
  227. DdManager * dd,
  228. BnetNetwork * net1,
  229. BnetNetwork * net2,
  230. NtrOptions * option)
  231. {
  232. BnetNode *node;
  233. char *oname;
  234. DdNode *odd1, *odd2;
  235. int i;
  236. int pr;
  237. (void) printf("Testing equivalence\n");
  238. if (net2->noutputs != net1->noutputs) {
  239. (void) printf("The two networks have different number of outputs\n");
  240. (void) printf(" %s has %d outputs\n %s has %d outputs\n",
  241. net1->name, net1->noutputs, net2->name, net2->noutputs);
  242. return(-1);
  243. }
  244. if (net2->nlatches != net1->nlatches) {
  245. (void) printf("The two networks have different number of latches\n");
  246. (void) printf(" %s has %d latches\n %s has %d latches\n",
  247. net1->name, net1->nlatches, net2->name, net2->nlatches);
  248. return(-1);
  249. }
  250. pr = option->verb;
  251. for (i = 0; i < net1->noutputs; i++) {
  252. oname = net1->outputs[i];
  253. if (!st_lookup(net1->hash,oname,(void **)&node)) {
  254. return(0);
  255. }
  256. odd1 = node->dd;
  257. (void) printf("%s", oname);
  258. Cudd_PrintDebug(dd, node->dd, Cudd_ReadSize(dd), pr);
  259. if (!st_lookup(net2->hash,oname,(void **)&node)) {
  260. BnetNode *inpnd;
  261. if ((inpnd = ntrNodeIsBuffer(node,net1->hash)) == NULL ||
  262. !st_lookup(net2->hash,inpnd->name,(void **)&node)) {
  263. (void) printf("Output %s missing from network %s\n",
  264. oname, net2->name);
  265. return(-1);
  266. } else {
  267. odd2 = inpnd->dd;
  268. }
  269. } else {
  270. odd2 = node->dd;
  271. }
  272. if (odd1 != odd2) {
  273. (void) printf("Output %s is not equivalent\n", oname);
  274. return(-1);
  275. }
  276. }
  277. return(1);
  278. } /* end of Ntr_VerifyEquivalence */
  279. /**
  280. @brief Tests %BDD cofactor estimate functions.
  281. @return 1 if successful; 0 otherwise.
  282. @sideeffect None
  283. */
  284. int
  285. Ntr_TestCofactorEstimate(
  286. DdManager * dd,
  287. BnetNetwork * net,
  288. NtrOptions * option)
  289. {
  290. DdNode *f;
  291. BnetNode *node;
  292. int i;
  293. int result;
  294. if (option->cofest == FALSE) return(1);
  295. (void) printf("Testing BDD cofactor estimation algorithms\n");
  296. if (option->node == NULL) {
  297. for (i = 0; i < net->noutputs; i++) {
  298. if (!st_lookup(net->hash,net->outputs[i],(void **)&node)) {
  299. return(0);
  300. }
  301. f = node->dd;
  302. if (f == NULL) return(0);
  303. result = ntrTestCofEstAux(dd,net,f,node->name,option);
  304. if (result == 0) return(0);
  305. }
  306. } else {
  307. if (!st_lookup(net->hash,option->node,(void **)&node)) {
  308. return(0);
  309. }
  310. f = node->dd;
  311. if (f == NULL) return(0);
  312. result = ntrTestCofEstAux(dd,net,f,option->node,option);
  313. if (result == 0) return(0);
  314. }
  315. return(1);
  316. } /* end of Ntr_TestCofactorEstimate */
  317. /**
  318. @brief Tests %BDD clipping functions.
  319. @return 1 if successful; 0 otherwise.
  320. @sideeffect None
  321. */
  322. int
  323. Ntr_TestClipping(
  324. DdManager * dd,
  325. BnetNetwork * net1,
  326. BnetNetwork * net2,
  327. NtrOptions * option)
  328. {
  329. DdNode *f;
  330. DdNode *g = NULL;
  331. char *gname = NULL;
  332. BnetNode *node;
  333. int i;
  334. int result;
  335. int nsize, gsize;
  336. if (option->clip < 0.0) return(1);
  337. (void) printf("Testing BDD clipping algorithms\n");
  338. /* Use largest output of second network as second operand. */
  339. gsize = -1;
  340. for (i = 0; i < net2->noutputs; i++) {
  341. if (!st_lookup(net2->hash,net2->outputs[i],(void **)&node)) {
  342. return(0);
  343. }
  344. nsize = Cudd_DagSize(node->dd);
  345. if (nsize > gsize) {
  346. g = node->dd;
  347. gname = node->name;
  348. gsize = nsize;
  349. }
  350. }
  351. if (g == NULL || gname == NULL) return(0);
  352. (void) printf("TEST-CLIP: Second operand (%s) %d nodes\n",
  353. gname, Cudd_DagSize(g));
  354. if (option->node == NULL) {
  355. for (i = 0; i < net1->noutputs; i++) {
  356. if (!st_lookup(net1->hash,net1->outputs[i],(void **)&node)) {
  357. return(0);
  358. }
  359. f = node->dd;
  360. if (f == NULL) return(0);
  361. result = ntrTestClippingAux(dd,net1,f,node->name,g,gname,option);
  362. if (result == 0) return(0);
  363. }
  364. } else {
  365. if (!st_lookup(net1->hash,option->node,(void **)&node)) {
  366. return(0);
  367. }
  368. f = node->dd;
  369. if (f == NULL) return(0);
  370. result = ntrTestClippingAux(dd,net1,f,option->node,g,gname,option);
  371. if (result == 0) return(0);
  372. }
  373. return(1);
  374. } /* end of Ntr_TestClipping */
  375. /**
  376. @brief Tests %BDD equivalence and containment with don't cares.
  377. @details Tests functions for %BDD equivalence and containment
  378. with don't cares, including Cudd_EquivDC and Cudd_bddLeqUnless. This
  379. function uses as care set the first output of net2 and checkes
  380. equivalence and containment for of all the output pairs of net1.
  381. @return 1 if successful; 0 otherwise.
  382. @sideeffect None
  383. */
  384. int
  385. Ntr_TestEquivAndContain(
  386. DdManager *dd,
  387. BnetNetwork *net1,
  388. BnetNetwork *net2,
  389. NtrOptions *option)
  390. {
  391. DdNode *f, *g;
  392. DdNode *d = NULL;
  393. char *dname = NULL;
  394. BnetNode *node1, *node2;
  395. int i, j;
  396. int result;
  397. int nsize, dsize;
  398. if (option->dontcares == FALSE) return(1);
  399. (void) printf("Testing BDD equivalence and containment algorithms\n");
  400. /* Use largest output of second network as constraint. */
  401. dsize = -1;
  402. for (i = 0; i < net2->noutputs; i++) {
  403. if (!st_lookup(net2->hash,net2->outputs[i],(void **)&node1)) {
  404. return(0);
  405. }
  406. nsize = Cudd_DagSize(node1->dd);
  407. if (nsize > dsize) {
  408. d = node1->dd;
  409. dname = node1->name;
  410. dsize = nsize;
  411. }
  412. }
  413. if (d == NULL || dname == NULL) return(0);
  414. (void) printf("TEST-DC: Don't care set (%s) %d nodes\n",
  415. dname, Cudd_DagSize(d));
  416. if (option->node == NULL) {
  417. for (i = 0; i < net1->noutputs; i++) {
  418. if (!st_lookup(net1->hash,net1->outputs[i],(void **)&node1)) {
  419. return(0);
  420. }
  421. f = node1->dd;
  422. if (f == NULL) return(0);
  423. for (j = 0; j < net1->noutputs; j++) {
  424. if (!st_lookup(net1->hash,net1->outputs[j],(void **)&node2)) {
  425. return(0);
  426. }
  427. g = node2->dd;
  428. if (g == NULL) return(0);
  429. result = ntrTestEquivAndContainAux(dd,net1,f,node1->name,g,
  430. node2->name,d,dname,option);
  431. if (result == 0) return(0);
  432. }
  433. }
  434. } else {
  435. if (!st_lookup(net1->hash,option->node,(void **)&node1)) {
  436. return(0);
  437. }
  438. f = node1->dd;
  439. if (f == NULL) return(0);
  440. for (j = 0; j < net1->noutputs; j++) {
  441. if (!st_lookup(net1->hash,net1->outputs[j],(void **)&node2)) {
  442. return(0);
  443. }
  444. g = node2->dd;
  445. if (g == NULL) return(0);
  446. result = ntrTestEquivAndContainAux(dd,net1,f,option->node,
  447. g,node2->name,d,dname,option);
  448. if (result == 0) return(0);
  449. }
  450. }
  451. return(1);
  452. } /* end of Ntr_TestEquivAndContain */
  453. /**
  454. @brief Tests the Cudd_bddClosestCube function.
  455. @return 1 if successful; 0 otherwise.
  456. @sideeffect None
  457. */
  458. int
  459. Ntr_TestClosestCube(
  460. DdManager * dd,
  461. BnetNetwork * net,
  462. NtrOptions * option)
  463. {
  464. DdNode *f, *g;
  465. BnetNode *node1, *node2;
  466. int i, j, nvars;
  467. int result;
  468. DdNode **vars;
  469. double calls;
  470. if (option->closestCube == FALSE) return(1);
  471. (void) printf("Testing Cudd_bddClosestCube\n");
  472. nvars = Cudd_ReadSize(dd);
  473. vars = ALLOC(DdNode *, nvars);
  474. if (vars == NULL) return(0);
  475. for (i = 0; i < nvars; i++) {
  476. vars[i] = Cudd_bddIthVar(dd,i);
  477. }
  478. calls = Cudd_ReadRecursiveCalls(dd);
  479. if (option->node == NULL) {
  480. for (i = 0; i < net->noutputs; i++) {
  481. if (!st_lookup(net->hash,net->outputs[i],(void **)&node1)) {
  482. FREE(vars);
  483. return(0);
  484. }
  485. f = node1->dd;
  486. if (f == NULL) {
  487. FREE(vars);
  488. return(0);
  489. }
  490. for (j = 0; j < net->noutputs; j++) {
  491. if (!st_lookup(net->hash,net->outputs[j],(void **)&node2)) {
  492. FREE(vars);
  493. return(0);
  494. }
  495. g = node2->dd;
  496. if (g == NULL) {
  497. FREE(vars);
  498. return(0);
  499. }
  500. result = ntrTestClosestCubeAux(dd,net,f,node1->name,g,
  501. node2->name,vars,option);
  502. if (result == 0) {
  503. FREE(vars);
  504. return(0);
  505. }
  506. }
  507. }
  508. } else {
  509. if (!st_lookup(net->hash,option->node,(void **)&node1)) {
  510. FREE(vars);
  511. return(0);
  512. }
  513. f = node1->dd;
  514. if (f == NULL) {
  515. FREE(vars);
  516. return(0);
  517. }
  518. for (j = 0; j < net->noutputs; j++) {
  519. if (!st_lookup(net->hash,net->outputs[j],(void **)&node2)) {
  520. FREE(vars);
  521. return(0);
  522. }
  523. g = node2->dd;
  524. if (g == NULL) {
  525. FREE(vars);
  526. return(0);
  527. }
  528. result = ntrTestClosestCubeAux(dd,net,f,option->node,g,
  529. node2->name,vars,option);
  530. if (result == 0) {
  531. FREE(vars);
  532. return(0);
  533. }
  534. }
  535. }
  536. (void) printf("End of test. Performed %.0f recursive calls.\n",
  537. Cudd_ReadRecursiveCalls(dd) - calls);
  538. FREE(vars);
  539. return(1);
  540. } /* end of Ntr_TestClosestCube */
  541. /**
  542. @brief Tests extraction of two-literal clauses.
  543. @return 1 if successful; 0 otherwise.
  544. @sideeffect None
  545. */
  546. int
  547. Ntr_TestTwoLiteralClauses(
  548. DdManager * dd,
  549. BnetNetwork * net1,
  550. NtrOptions * option)
  551. {
  552. DdNode *f;
  553. BnetNode *node;
  554. int result;
  555. char **inames = NULL;
  556. int i;
  557. if (option->clauses == FALSE) return(1);
  558. /* Initialize data structures. */
  559. inames = ALLOC(char *,Cudd_ReadSize(dd));
  560. if (inames == NULL) return(0);
  561. for (i = 0; i < Cudd_ReadSize(dd); i++) {
  562. inames[i] = NULL;
  563. }
  564. /* Find the input names. */
  565. for (i = 0; i < net1->ninputs; i++) {
  566. if (!st_lookup(net1->hash,net1->inputs[i],(void **)&node)) {
  567. FREE(inames);
  568. return(0);
  569. }
  570. inames[node->var] = net1->inputs[i];
  571. }
  572. for (i = 0; i < net1->nlatches; i++) {
  573. if (!st_lookup(net1->hash,net1->latches[i][1],(void **)&node)) {
  574. FREE(inames);
  575. return(0);
  576. }
  577. inames[node->var] = net1->latches[i][1];
  578. }
  579. (void) printf("Testing extraction of two literal clauses\n");
  580. if (option->node == NULL) {
  581. for (i = 0; i < net1->noutputs; i++) {
  582. if (!st_lookup(net1->hash,net1->outputs[i],(void **)&node)) {
  583. return(0);
  584. }
  585. f = node->dd;
  586. if (f == NULL) {
  587. FREE(inames);
  588. return(0);
  589. }
  590. (void) printf("*** %s ***\n", net1->outputs[i]);
  591. result = Cudd_PrintTwoLiteralClauses(dd, f, inames, NULL);
  592. if (result == 0) {
  593. FREE(inames);
  594. return(0);
  595. }
  596. }
  597. } else {
  598. if (!st_lookup(net1->hash,option->node,(void **)&node)) {
  599. return(0);
  600. }
  601. f = node->dd;
  602. if (f == NULL) {
  603. FREE(inames);
  604. return(0);
  605. }
  606. (void) printf("*** %s ***\n", option->node);
  607. result = Cudd_PrintTwoLiteralClauses(dd, f, inames, NULL);
  608. if (result == 0) {
  609. FREE(inames);
  610. return(0);
  611. }
  612. }
  613. FREE(inames);
  614. return(1);
  615. } /* end of Ntr_TestTwoLiteralClauses */
  616. /**
  617. @brief Test char-to-vect conversion.
  618. @return 1 if successful; 0 otherwise.
  619. @sideeffect None
  620. */
  621. int
  622. Ntr_TestCharToVect(
  623. DdManager * dd,
  624. BnetNetwork * net1,
  625. NtrOptions * option)
  626. {
  627. DdNode *f;
  628. int result;
  629. BnetNode *node;
  630. int i;
  631. if (option->char2vect == FALSE) return(1);
  632. (void) printf("Testing char-to-vect\n");
  633. if (net1->nlatches > 0) {
  634. NtrPartTR *T;
  635. T = Ntr_buildTR(dd,net1,option,NTR_IMAGE_MONO);
  636. result = ntrTestCharToVect(dd,T->part[0],option);
  637. Ntr_freeTR(dd,T);
  638. } else if (option->node == NULL) {
  639. result = 1;
  640. for (i = 0; i < net1->noutputs; i++) {
  641. if (!st_lookup(net1->hash,net1->outputs[i],(void **)&node)) {
  642. return(0);
  643. }
  644. f = node->dd;
  645. if (f == NULL) return(0);
  646. (void) printf("*** %s ***\n", net1->outputs[i]);
  647. result = ntrTestCharToVect(dd,f,option);
  648. if (result == 0) return(0);
  649. }
  650. } else {
  651. if (!st_lookup(net1->hash,option->node,(void **)&node)) {
  652. return(0);
  653. }
  654. f = node->dd;
  655. if (f == NULL) return(0);
  656. result = ntrTestCharToVect(dd,f,option);
  657. }
  658. return(result);
  659. } /* end of Ntr_TestCharToVect */
  660. /*---------------------------------------------------------------------------*/
  661. /* Definition of internal functions */
  662. /*---------------------------------------------------------------------------*/
  663. /*---------------------------------------------------------------------------*/
  664. /* Definition of static functions */
  665. /*---------------------------------------------------------------------------*/
  666. /**
  667. @brief Processes one %BDD for Ntr_TestMinimization.
  668. @return 1 if successful; 0 otherwise.
  669. @sideeffect None
  670. @see Ntr_TestMinimization
  671. */
  672. static int
  673. ntrTestMinimizationAux(
  674. DdManager * dd,
  675. BnetNetwork * net1,
  676. DdNode * f,
  677. char * name,
  678. DdNode * c,
  679. char * cname,
  680. NtrOptions * option)
  681. {
  682. DdNode *com1, *com0, *min1, *min0, *sq1, *sq0;
  683. DdNode *rs1, *rs0, *cs1, *cs0, *na1, *na0, *a1, *a0;
  684. DdNode *g, *u1, *l1, *u0, *l0;
  685. int pr, nvars;
  686. int sizeF, sizeMin1, sizeMin0, sizeSq1, sizeSq0, sizeCom1, sizeCom0;
  687. int sizeRs1, sizeRs0, sizeCs1, sizeCs0, sizeNa1, sizeNa0, sizeA1, sizeA0;
  688. static char *onames[11];
  689. DdNode *outputs[11];
  690. DdNode *fc[2];
  691. pr = option->verb;
  692. fc[0] = f; fc[1] = c;
  693. nvars = Cudd_VectorSupportSize(dd,fc,2);
  694. if (nvars == CUDD_OUT_OF_MEM) return(0);
  695. (void) printf("TEST-MINI:: %s\n", name);
  696. (void) printf("T-M ");
  697. Cudd_PrintDebug(dd, f, nvars, pr);
  698. sizeF = Cudd_DagSize(f);
  699. /* Compute positive generalized cofactor. */
  700. com1 = Cudd_bddLICompaction(dd, f, c);
  701. if (com1 == NULL) {
  702. (void) printf("TEST-MINI: LI-compaction failed (1).\n");
  703. return(0);
  704. }
  705. Cudd_Ref(com1);
  706. (void) printf("T-M L1 ");
  707. Cudd_PrintDebug(dd, com1, nvars, pr);
  708. sizeCom1 = Cudd_DagSize(com1);
  709. if (sizeCom1 > sizeF) {
  710. (void) printf("TEST-MINI: LI-compaction not safe (1).\n");
  711. return(0);
  712. }
  713. min1 = Cudd_bddMinimize(dd, f, c);
  714. if (min1 == NULL) {
  715. (void) printf("TEST-MINI: minimize failed (1).\n");
  716. return(0);
  717. }
  718. Cudd_Ref(min1);
  719. (void) printf("T-M M1 ");
  720. Cudd_PrintDebug(dd, min1, nvars, pr);
  721. sizeMin1 = Cudd_DagSize(min1);
  722. if (sizeMin1 > sizeF) {
  723. (void) printf("TEST-MINI: minimize not safe (1).\n");
  724. return(0);
  725. }
  726. rs1 = Cudd_bddRestrict(dd, f, c);
  727. if (rs1 == NULL) {
  728. (void) printf("TEST-MINI: restrict failed (1).\n");
  729. return(0);
  730. }
  731. Cudd_Ref(rs1);
  732. (void) printf("T-M R1 ");
  733. Cudd_PrintDebug(dd, rs1, nvars, pr);
  734. sizeRs1 = Cudd_DagSize(rs1);
  735. cs1 = Cudd_bddConstrain(dd, f, c);
  736. if (cs1 == NULL) {
  737. (void) printf("TEST-MINI: constrain failed (1).\n");
  738. return(0);
  739. }
  740. Cudd_Ref(cs1);
  741. (void) printf("T-M C1 ");
  742. Cudd_PrintDebug(dd, cs1, nvars, pr);
  743. sizeCs1 = Cudd_DagSize(cs1);
  744. l1 = Cudd_bddAnd(dd, f, c);
  745. if (l1 == NULL) {
  746. (void) printf("TEST-MINI: lower bound failed (1).\n");
  747. return(0);
  748. }
  749. Cudd_Ref(l1);
  750. u1 = Cudd_bddOr(dd, f, Cudd_Not(c));
  751. if (u1 == NULL) {
  752. (void) printf("TEST-MINI: upper bound failed (1).\n");
  753. return(0);
  754. }
  755. Cudd_Ref(u1);
  756. (void) printf("TEST-MINI: (lb,ub) : (%d,%d) nodes\n",
  757. Cudd_DagSize(l1), Cudd_DagSize(u1));
  758. sq1 = Cudd_bddSqueeze(dd, l1, u1);
  759. if (sq1 == NULL) {
  760. (void) printf("TEST-MINI: squeezing failed (1).\n");
  761. return(0);
  762. }
  763. Cudd_Ref(sq1);
  764. sizeSq1 = Cudd_DagSize(sq1);
  765. if (sizeSq1 > sizeF) {
  766. Cudd_RecursiveDeref(dd,sq1);
  767. sq1 = f;
  768. Cudd_Ref(sq1);
  769. sizeSq1 = sizeF;
  770. }
  771. (void) printf("T-M S1 ");
  772. Cudd_PrintDebug(dd, sq1, nvars, pr);
  773. na1 = Cudd_bddNPAnd(dd, f, c);
  774. if (na1 == NULL) {
  775. (void) printf("TEST-MINI: NPand failed (1).\n");
  776. return(0);
  777. }
  778. Cudd_Ref(na1);
  779. (void) printf("T-M N1 ");
  780. Cudd_PrintDebug(dd, na1, nvars, pr);
  781. sizeNa1 = Cudd_DagSize(na1);
  782. a1 = Cudd_bddAnd(dd, f, c);
  783. if (a1 == NULL) {
  784. (void) printf("TEST-MINI: and failed (1).\n");
  785. return(0);
  786. }
  787. Cudd_Ref(a1);
  788. (void) printf("T-M A1 ");
  789. Cudd_PrintDebug(dd, a1, nvars, pr);
  790. sizeA1 = Cudd_DagSize(a1);
  791. (void) printf("TEST-MINI: f %d comp %d mini %d rest %d cons %d sque %d na %d and %d\n",
  792. sizeF, sizeCom1, sizeMin1, sizeRs1, sizeCs1, sizeSq1, sizeNa1, sizeA1);
  793. if (option->bdddump) {
  794. onames[0] = name; outputs[0] = f;
  795. onames[1] = cname; outputs[1] = c;
  796. onames[2] = (char *) "cons"; outputs[2] = cs1;
  797. onames[3] = (char *) "rest"; outputs[3] = rs1;
  798. onames[4] = (char *) "comp"; outputs[4] = com1;
  799. onames[5] = (char *) "mini"; outputs[5] = min1;
  800. onames[6] = (char *) "sqee"; outputs[6] = sq1;
  801. onames[7] = (char *) "lb"; outputs[7] = l1;
  802. onames[8] = (char *) "ub"; outputs[8] = u1;
  803. onames[9] = (char *) "na"; outputs[9] = na1;
  804. onames[10] = (char *) "and"; outputs[10] = a1;
  805. if (!Bnet_bddArrayDump(dd, net1, option->dumpfile, outputs, onames,
  806. 11, option->dumpFmt))
  807. return(0);
  808. }
  809. Cudd_RecursiveDeref(dd,l1);
  810. Cudd_RecursiveDeref(dd,u1);
  811. /* Compute negative generalized cofactor. */
  812. (void) printf("TEST-MINI:: %s\n", name);
  813. (void) printf("T-M ");
  814. Cudd_PrintDebug(dd, f, nvars, pr);
  815. com0 = Cudd_bddLICompaction(dd, f, Cudd_Not(c));
  816. if (com0 == NULL) {
  817. (void) printf("TEST-MINI: LI-compaction failed (2).\n");
  818. return(0);
  819. }
  820. Cudd_Ref(com0);
  821. (void) printf("T-M L0 ");
  822. Cudd_PrintDebug(dd, com0, nvars, pr);
  823. sizeCom0 = Cudd_DagSize(com0);
  824. if (sizeCom0 > sizeF) {
  825. (void) printf("TEST-MINI: LI-compaction not safe (2).\n");
  826. return(0);
  827. }
  828. min0 = Cudd_bddMinimize(dd, f, Cudd_Not(c));
  829. if (min0 == NULL) {
  830. (void) printf("TEST-MINI: minimize failed (2).\n");
  831. return(0);
  832. }
  833. Cudd_Ref(min0);
  834. (void) printf("T-M M0 ");
  835. Cudd_PrintDebug(dd, min0, nvars, pr);
  836. sizeMin0 = Cudd_DagSize(min0);
  837. if (sizeMin0 > sizeF) {
  838. (void) printf("TEST-MINI: minimize not safe (2).\n");
  839. return(0);
  840. }
  841. rs0 = Cudd_bddRestrict(dd, f, Cudd_Not(c));
  842. if (rs0 == NULL) {
  843. (void) printf("TEST-MINI: restrict failed (2).\n");
  844. return(0);
  845. }
  846. Cudd_Ref(rs0);
  847. (void) printf("T-M R0 ");
  848. Cudd_PrintDebug(dd, rs0, nvars, pr);
  849. sizeRs0 = Cudd_DagSize(rs0);
  850. cs0 = Cudd_bddConstrain(dd, f, Cudd_Not(c));
  851. if (cs0 == NULL) {
  852. (void) printf("TEST-MINI: constrain failed (2).\n");
  853. return(0);
  854. }
  855. Cudd_Ref(cs0);
  856. (void) printf("T-M C0 ");
  857. Cudd_PrintDebug(dd, cs0, nvars, pr);
  858. sizeCs0 = Cudd_DagSize(cs0);
  859. l0 = Cudd_bddAnd(dd, f, Cudd_Not(c));
  860. if (l0 == NULL) {
  861. (void) printf("TEST-MINI: lower bound failed (2).\n");
  862. return(0);
  863. }
  864. Cudd_Ref(l0);
  865. u0 = Cudd_bddOr(dd, f, c);
  866. if (u0 == NULL) {
  867. (void) printf("TEST-MINI: upper bound failed (2).\n");
  868. return(0);
  869. }
  870. Cudd_Ref(u0);
  871. (void) printf("TEST-MINI: (lb,ub) : (%d,%d) nodes\n",
  872. Cudd_DagSize(l0), Cudd_DagSize(u0));
  873. sq0 = Cudd_bddSqueeze(dd, l0, u0);
  874. if (sq0 == NULL) {
  875. (void) printf("TEST-MINI: squeezing failed (2).\n");
  876. return(0);
  877. }
  878. Cudd_Ref(sq0);
  879. Cudd_RecursiveDeref(dd,l0);
  880. Cudd_RecursiveDeref(dd,u0);
  881. sizeSq0 = Cudd_DagSize(sq0);
  882. if (sizeSq0 > sizeF) {
  883. Cudd_RecursiveDeref(dd,sq0);
  884. sq0 = f;
  885. Cudd_Ref(sq0);
  886. sizeSq0 = sizeF;
  887. }
  888. (void) printf("T-M S0 ");
  889. Cudd_PrintDebug(dd, sq0, nvars, pr);
  890. na0 = Cudd_bddNPAnd(dd, f, Cudd_Not(c));
  891. if (na0 == NULL) {
  892. (void) printf("TEST-MINI: NPand failed (2).\n");
  893. return(0);
  894. }
  895. Cudd_Ref(na0);
  896. (void) printf("T-M N0 ");
  897. Cudd_PrintDebug(dd, na0, nvars, pr);
  898. sizeNa0 = Cudd_DagSize(na0);
  899. a0 = Cudd_bddAnd(dd, f, Cudd_Not(c));
  900. if (a0 == NULL) {
  901. (void) printf("TEST-MINI: and failed (2).\n");
  902. return(0);
  903. }
  904. Cudd_Ref(a0);
  905. (void) printf("T-M A0 ");
  906. Cudd_PrintDebug(dd, a0, nvars, pr);
  907. sizeA0 = Cudd_DagSize(a0);
  908. (void) printf("TEST-MINI: f %d comp %d mini %d rest %d cons %d sque %d na %d, and %d\n",
  909. sizeF, sizeCom0, sizeMin0, sizeRs0, sizeCs0, sizeSq0, sizeNa0, sizeA0);
  910. /* Check fundamental identity. */
  911. g = Cudd_bddIte(dd,c,com1,com0);
  912. if (g == NULL) {
  913. (void) printf("TEST-MINI: LI-compaction failed (3).\n");
  914. return(0);
  915. }
  916. Cudd_Ref(g);
  917. if (g != f) {
  918. (void) printf("TEST-MINI: LI-compaction failed (4).\n");
  919. return(0);
  920. }
  921. Cudd_RecursiveDeref(dd,com1);
  922. Cudd_RecursiveDeref(dd,com0);
  923. Cudd_RecursiveDeref(dd,g);
  924. g = Cudd_bddIte(dd,c,min1,min0);
  925. if (g == NULL) {
  926. (void) printf("TEST-MINI: minimize failed (3).\n");
  927. return(0);
  928. }
  929. Cudd_Ref(g);
  930. if (g != f) {
  931. (void) printf("TEST-MINI: minimize failed (4).\n");
  932. return(0);
  933. }
  934. Cudd_RecursiveDeref(dd,min1);
  935. Cudd_RecursiveDeref(dd,min0);
  936. Cudd_RecursiveDeref(dd,g);
  937. g = Cudd_bddIte(dd,c,sq1,sq0);
  938. if (g == NULL) {
  939. (void) printf("TEST-MINI: squeezing failed (3).\n");
  940. return(0);
  941. }
  942. Cudd_Ref(g);
  943. if (g != f) {
  944. (void) printf("TEST-MINI: squeezing failed (4).\n");
  945. return(0);
  946. }
  947. Cudd_RecursiveDeref(dd,sq1);
  948. Cudd_RecursiveDeref(dd,sq0);
  949. Cudd_RecursiveDeref(dd,g);
  950. g = Cudd_bddIte(dd,c,rs1,rs0);
  951. if (g == NULL) {
  952. (void) printf("TEST-MINI: restrict failed (3).\n");
  953. return(0);
  954. }
  955. Cudd_Ref(g);
  956. if (g != f) {
  957. (void) printf("TEST-MINI: restrict failed (4).\n");
  958. return(0);
  959. }
  960. Cudd_RecursiveDeref(dd,rs1);
  961. Cudd_RecursiveDeref(dd,rs0);
  962. Cudd_RecursiveDeref(dd,g);
  963. g = Cudd_bddIte(dd,c,cs1,cs0);
  964. if (g == NULL) {
  965. (void) printf("TEST-MINI: constrain failed (3).\n");
  966. return(0);
  967. }
  968. Cudd_Ref(g);
  969. if (g != f) {
  970. (void) printf("TEST-MINI: constrain failed (4).\n");
  971. return(0);
  972. }
  973. Cudd_RecursiveDeref(dd,cs1);
  974. Cudd_RecursiveDeref(dd,cs0);
  975. Cudd_RecursiveDeref(dd,g);
  976. g = Cudd_bddIte(dd,c,na1,na0);
  977. if (g == NULL) {
  978. (void) printf("TEST-MINI: NPand failed (3).\n");
  979. return(0);
  980. }
  981. Cudd_Ref(g);
  982. if (g != f) {
  983. (void) printf("TEST-MINI: NPand failed (4).\n");
  984. return(0);
  985. }
  986. Cudd_RecursiveDeref(dd,na1);
  987. Cudd_RecursiveDeref(dd,na0);
  988. Cudd_RecursiveDeref(dd,g);
  989. g = Cudd_bddIte(dd,c,a1,a0);
  990. if (g == NULL) {
  991. (void) printf("TEST-MINI: and failed (3).\n");
  992. return(0);
  993. }
  994. Cudd_Ref(g);
  995. if (g != f) {
  996. (void) printf("TEST-MINI: and failed (4).\n");
  997. return(0);
  998. }
  999. Cudd_RecursiveDeref(dd,a1);
  1000. Cudd_RecursiveDeref(dd,a0);
  1001. Cudd_RecursiveDeref(dd,g);
  1002. return(1);
  1003. } /* end of ntrTestMinimizationAux */
  1004. /**
  1005. @brief Processes one %BDD for Ntr_TestDensity.
  1006. @return 1 if successful; 0 otherwise.
  1007. @sideeffect None
  1008. @see Ntr_TestDensity ntrCompress1
  1009. */
  1010. static int
  1011. ntrTestDensityAux(
  1012. DdManager * dd,
  1013. BnetNetwork * net,
  1014. DdNode * f,
  1015. char * name,
  1016. NtrOptions * option)
  1017. {
  1018. DdNode *s, *b, *hb, *sp, *ua, *c1, *c2;
  1019. int pr;
  1020. int result;
  1021. int nvars;
  1022. int size, sizeS;
  1023. double densityF, densityB, densityS, densityHB, densitySP, densityUA;
  1024. double densityC1, densityC2;
  1025. char *onames[8];
  1026. DdNode *outputs[8];
  1027. result = 1;
  1028. pr = option->verb;
  1029. nvars = Cudd_SupportSize(dd,f);
  1030. if (nvars == CUDD_OUT_OF_MEM) return(0);
  1031. densityF = Cudd_Density(dd,f,nvars);
  1032. (void) printf("TEST-DENSITY:: %s (%d variables)\n", name, nvars);
  1033. if (pr > 0) {
  1034. (void) printf("T-D (%g)", densityF);
  1035. Cudd_PrintDebug(dd, f, nvars, pr);
  1036. (void) printf("T-D APA ");
  1037. if (!Cudd_ApaPrintMinterm(stdout, dd, f, nvars))
  1038. result = 0;
  1039. }
  1040. /* Test remapping underapproximation. */
  1041. /* s = Cudd_SubsetRemap(dd,f); */
  1042. s = Cudd_RemapUnderApprox(dd,f,nvars,0,option->quality);
  1043. if (s == NULL) {
  1044. (void) printf("TEST-DENSITY: computation failed\n");
  1045. return(0);
  1046. }
  1047. Cudd_Ref(s);
  1048. sizeS = Cudd_DagSize(s);
  1049. densityS = Cudd_Density(dd,s,nvars);
  1050. if (pr > 0) {
  1051. (void) printf("T-D ID (%g)", densityS);
  1052. Cudd_PrintDebug(dd, s, nvars, pr);
  1053. }
  1054. if (!Cudd_bddLeq(dd,s,f)) {
  1055. (void) printf("TEST-DENSITY: result not a subset\n");
  1056. result = 0;
  1057. }
  1058. if (densityF > densityS) {
  1059. (void) printf("TEST-DENSITY: result less dense\n");
  1060. /* result = 0; */
  1061. }
  1062. size = sizeS;
  1063. /* Test biased underapproximation. */
  1064. b = Cudd_BiasedUnderApprox(dd,f,Cudd_Not(s),nvars,0,
  1065. option->quality*1.1,option->quality*0.5);
  1066. if (b == NULL) {
  1067. (void) printf("TEST-DENSITY: computation failed\n");
  1068. return(0);
  1069. }
  1070. Cudd_Ref(b);
  1071. densityB = Cudd_Density(dd,b,nvars);
  1072. if (pr > 0) {
  1073. (void) printf("T-D BU (%g)", densityB);
  1074. Cudd_PrintDebug(dd, b, nvars, pr);
  1075. }
  1076. if (!Cudd_bddLeq(dd,b,f)) {
  1077. (void) printf("TEST-DENSITY: result not a subset\n");
  1078. result = 0;
  1079. }
  1080. if (densityF > densityB) {
  1081. (void) printf("TEST-DENSITY: result less dense\n");
  1082. /* result = 0; */
  1083. }
  1084. /* Test heavy-branch subsetting. */
  1085. hb = Cudd_SubsetHeavyBranch(dd, f, nvars, size);
  1086. if (hb == NULL) {
  1087. (void) printf("TEST-DENSITY: HB computation failed\n");
  1088. Cudd_RecursiveDeref(dd,s);
  1089. return(0);
  1090. }
  1091. Cudd_Ref(hb);
  1092. densityHB = Cudd_Density(dd,hb,nvars);
  1093. if (pr > 0) {
  1094. (void) printf("T-D HB (%g)", densityHB);
  1095. Cudd_PrintDebug(dd, hb, nvars, pr);
  1096. }
  1097. if (!Cudd_bddLeq(dd,hb,f)) {
  1098. (void) printf("TEST-DENSITY: HB not a subset\n");
  1099. result = 0;
  1100. }
  1101. /* Test short paths subsetting. */
  1102. sp = Cudd_SubsetShortPaths(dd, f, nvars, size, 0);
  1103. if (sp == NULL) {
  1104. (void) printf("TEST-DENSITY: SP computation failed\n");
  1105. Cudd_RecursiveDeref(dd,s);
  1106. Cudd_RecursiveDeref(dd,hb);
  1107. return(0);
  1108. }
  1109. Cudd_Ref(sp);
  1110. densitySP = Cudd_Density(dd,sp,nvars);
  1111. if (pr > 0) {
  1112. (void) printf("T-D SP (%g)", densitySP);
  1113. Cudd_PrintDebug(dd, sp, nvars, pr);
  1114. }
  1115. if (!Cudd_bddLeq(dd,sp,f)) {
  1116. (void) printf("TEST-DENSITY: SP not a subset\n");
  1117. result = 0;
  1118. }
  1119. /* Test underapproximation. */
  1120. ua = Cudd_UnderApprox(dd,f,nvars,0,FALSE,option->quality);
  1121. if (ua == NULL) {
  1122. (void) printf("TEST-DENSITY: computation failed\n");
  1123. Cudd_RecursiveDeref(dd,s);
  1124. Cudd_RecursiveDeref(dd,hb);
  1125. Cudd_RecursiveDeref(dd,sp);
  1126. return(0);
  1127. }
  1128. Cudd_Ref(ua);
  1129. densityUA = Cudd_Density(dd,ua,nvars);
  1130. if (pr > 0) {
  1131. (void) printf("T-D UA (%g)", densityUA);
  1132. Cudd_PrintDebug(dd, ua, nvars, pr);
  1133. }
  1134. if (!Cudd_bddLeq(dd,ua,f)) {
  1135. (void) printf("TEST-DENSITY: result not a subset\n");
  1136. result = 0;
  1137. }
  1138. if (densityF > densityUA) {
  1139. (void) printf("TEST-DENSITY: result less dense\n");
  1140. }
  1141. /* Test compress 2 method. */
  1142. c1 = ntrCompress2(dd, f, nvars, size);
  1143. if (c1 == NULL) {
  1144. (void) printf("TEST-DENSITY: C1 computation failed\n");
  1145. Cudd_RecursiveDeref(dd,s);
  1146. Cudd_RecursiveDeref(dd,hb);
  1147. Cudd_RecursiveDeref(dd,sp);
  1148. Cudd_RecursiveDeref(dd,ua);
  1149. return(0);
  1150. }
  1151. densityC1 = Cudd_Density(dd,c1,nvars);
  1152. if (pr > 0) {
  1153. (void) printf("T-D C1 (%g)", densityC1);
  1154. Cudd_PrintDebug(dd, c1, nvars, pr);
  1155. }
  1156. if (!Cudd_bddLeq(dd,c1,f)) {
  1157. (void) printf("TEST-DENSITY: C1 not a subset\n");
  1158. result = 0;
  1159. }
  1160. /* Test compress subsetting. */
  1161. c2 = Cudd_SubsetCompress(dd, f, nvars, size);
  1162. if (c2 == NULL) {
  1163. (void) printf("TEST-DENSITY: C2 computation failed\n");
  1164. Cudd_RecursiveDeref(dd,s);
  1165. Cudd_RecursiveDeref(dd,hb);
  1166. Cudd_RecursiveDeref(dd,sp);
  1167. Cudd_RecursiveDeref(dd,ua);
  1168. Cudd_RecursiveDeref(dd,c1);
  1169. return(0);
  1170. }
  1171. Cudd_Ref(c2);
  1172. densityC2 = Cudd_Density(dd,c2,nvars);
  1173. if (pr > 0) {
  1174. (void) printf("T-D C2 (%g)", densityC2);
  1175. Cudd_PrintDebug(dd, c2, nvars, pr);
  1176. }
  1177. if (!Cudd_bddLeq(dd,c2,f)) {
  1178. (void) printf("TEST-DENSITY: C2 not a subset\n");
  1179. result = 0;
  1180. }
  1181. /* Dump results if so requested. */
  1182. if (option->bdddump) {
  1183. onames[0] = name; outputs[0] = f;
  1184. onames[1] = (char *) "id"; outputs[1] = s;
  1185. onames[2] = (char *) "bu"; outputs[2] = b;
  1186. onames[3] = (char *) "hb"; outputs[3] = hb;
  1187. onames[4] = (char *) "sp"; outputs[4] = sp;
  1188. onames[5] = (char *) "ua"; outputs[5] = ua;
  1189. onames[6] = (char *) "c1"; outputs[6] = c1;
  1190. onames[7] = (char *) "c2"; outputs[7] = c2;
  1191. result &= Bnet_bddArrayDump(dd, net, option->dumpfile, outputs,
  1192. onames, 8, option->dumpFmt);
  1193. }
  1194. Cudd_RecursiveDeref(dd,s);
  1195. Cudd_RecursiveDeref(dd,b);
  1196. Cudd_RecursiveDeref(dd,hb);
  1197. Cudd_RecursiveDeref(dd,sp);
  1198. Cudd_RecursiveDeref(dd,ua);
  1199. Cudd_RecursiveDeref(dd,c1);
  1200. Cudd_RecursiveDeref(dd,c2);
  1201. return(result);
  1202. } /* end of ntrTestDensityAux */
  1203. /**
  1204. @brief Processes one %BDD for Ntr_TestDecomp.
  1205. @return 1 if successful; 0 otherwise.
  1206. @sideeffect None
  1207. @see Ntr_TestDecomp
  1208. */
  1209. static int
  1210. ntrTestDecompAux(
  1211. DdManager * dd,
  1212. BnetNetwork * net,
  1213. DdNode * f,
  1214. char * name,
  1215. NtrOptions * option)
  1216. {
  1217. DdNode *one, *g, *h, *product;
  1218. DdNode **A, **I, **G, **V;
  1219. int pr;
  1220. int i, result;
  1221. int nA, nI, nG, nV;
  1222. int nvars;
  1223. int sizeSa;
  1224. int sizeSi, sizeSg, sizeSv;
  1225. char *onames[9];
  1226. DdNode *outputs[9];
  1227. result = 1;
  1228. pr = option->verb;
  1229. nvars = Cudd_SupportSize(dd,f);
  1230. if (nvars == CUDD_OUT_OF_MEM) return(0);
  1231. (void) printf("TEST-DECOMP:: %s (%d variables)\n", name, nvars);
  1232. if (pr > 0) {
  1233. (void) printf("T-d ");
  1234. Cudd_PrintDebug(dd, f, nvars, pr);
  1235. }
  1236. one = Cudd_ReadOne(dd);
  1237. /* Test Cudd_bddApproxConjDecomp */
  1238. nA = Cudd_bddApproxConjDecomp(dd,f,&A);
  1239. if (nA == 0) {
  1240. (void) printf("TEST-DECOMP: computation failed\n");
  1241. return(0);
  1242. }
  1243. g = A[0];
  1244. h = (nA == 2) ? A[1] : one;
  1245. sizeSa = Cudd_SharingSize(A,nA);
  1246. if (pr > 0) {
  1247. (void) printf("T-d SS : %d nodes\n", sizeSa);
  1248. (void) printf("T-d GS ");
  1249. Cudd_PrintDebug(dd, g, nvars, pr);
  1250. (void) printf("T-d HS ");
  1251. Cudd_PrintDebug(dd, h, nvars, pr);
  1252. }
  1253. product = Cudd_bddAnd(dd,g,h);
  1254. if (product == NULL) {
  1255. (void) printf("TEST-DECOMP: computation failed\n");
  1256. return(0);
  1257. }
  1258. Cudd_Ref(product);
  1259. if (product != f) {
  1260. (void) printf("TEST-DECOMP: result not a decomposition\n");
  1261. result = 0;
  1262. }
  1263. Cudd_RecursiveDeref(dd,product);
  1264. /* Test Cudd_bddIterConjDecomp */
  1265. nI = Cudd_bddIterConjDecomp(dd,f,&I);
  1266. if (nI == 0) {
  1267. (void) printf("TEST-DECOMP: computation failed\n");
  1268. return(0);
  1269. }
  1270. g = I[0];
  1271. h = (nI == 2) ? I[1] : one;
  1272. sizeSi = Cudd_SharingSize(I,nI);
  1273. if (pr > 0) {
  1274. (void) printf("T-d SI : %d nodes\n", sizeSi);
  1275. (void) printf("T-d GI ");
  1276. Cudd_PrintDebug(dd, g, nvars, pr);
  1277. (void) printf("T-d HI ");
  1278. Cudd_PrintDebug(dd, h, nvars, pr);
  1279. }
  1280. product = Cudd_bddAnd(dd,g,h);
  1281. if (product == NULL) {
  1282. (void) printf("TEST-DECOMP: computation failed\n");
  1283. return(0);
  1284. }
  1285. Cudd_Ref(product);
  1286. if (product != f) {
  1287. (void) printf("TEST-DECOMP: result not a decomposition\n");
  1288. result = 0;
  1289. }
  1290. Cudd_RecursiveDeref(dd,product);
  1291. /* Test Cudd_bddGenConjDecomp */
  1292. nG = Cudd_bddGenConjDecomp(dd,f,&G);
  1293. if (nG == 0) {
  1294. (void) printf("TEST-DECOMP: computation failed\n");
  1295. return(0);
  1296. }
  1297. g = G[0];
  1298. h = (nG == 2) ? G[1] : one;
  1299. sizeSg = Cudd_SharingSize(G,nG);
  1300. if (pr > 0) {
  1301. (void) printf("T-d SD : %d nodes\n", sizeSg);
  1302. (void) printf("T-d GD ");
  1303. Cudd_PrintDebug(dd, g, nvars, pr);
  1304. (void) printf("T-d HD ");
  1305. Cudd_PrintDebug(dd, h, nvars, pr);
  1306. }
  1307. product = Cudd_bddAnd(dd,g,h);
  1308. if (product == NULL) {
  1309. (void) printf("TEST-DECOMP: computation failed\n");
  1310. return(0);
  1311. }
  1312. Cudd_Ref(product);
  1313. if (product != f) {
  1314. (void) printf("TEST-DECOMP: result not a decomposition\n");
  1315. result = 0;
  1316. }
  1317. Cudd_RecursiveDeref(dd,product);
  1318. /* Test Cudd_bddVarConjDecomp */
  1319. nV = Cudd_bddVarConjDecomp(dd,f,&V);
  1320. if (nV == 0) {
  1321. (void) printf("TEST-DECOMP: computation failed\n");
  1322. return(0);
  1323. }
  1324. g = V[0];
  1325. h = (nV == 2) ? V[1] : one;
  1326. sizeSv = Cudd_SharingSize(V,nV);
  1327. if (pr > 0) {
  1328. (void) printf("T-d SQ : %d nodes\n", sizeSv);
  1329. (void) printf("T-d GQ ");
  1330. Cudd_PrintDebug(dd, g, nvars, pr);
  1331. (void) printf("T-d HQ ");
  1332. Cudd_PrintDebug(dd, h, nvars, pr);
  1333. }
  1334. product = Cudd_bddAnd(dd,g,h);
  1335. if (product == NULL) {
  1336. (void) printf("TEST-DECOMP: computation failed\n");
  1337. return(0);
  1338. }
  1339. Cudd_Ref(product);
  1340. if (product != f) {
  1341. (void) printf("TEST-DECOMP: result not a decomposition\n");
  1342. result = 0;
  1343. }
  1344. Cudd_RecursiveDeref(dd,product);
  1345. /* Dump to file if requested. */
  1346. if (option->bdddump) {
  1347. onames[0] = name; outputs[0] = f;
  1348. onames[1] = (char *) "ga"; outputs[1] = A[0];
  1349. onames[2] = (char *) "ha"; outputs[2] = (nA == 2) ? A[1] : one;
  1350. onames[3] = (char *) "gi"; outputs[3] = I[0];
  1351. onames[4] = (char *) "hi"; outputs[4] = (nI == 2) ? I[1] : one;
  1352. onames[5] = (char *) "gg"; outputs[5] = G[0];
  1353. onames[6] = (char *) "hg"; outputs[6] = (nG == 2) ? G[1] : one;
  1354. onames[7] = (char *) "gv"; outputs[7] = V[0];
  1355. onames[8] = (char *) "hv"; outputs[8] = (nV == 2) ? V[1] : one;
  1356. result &= Bnet_bddArrayDump(dd, net, option->dumpfile, outputs,
  1357. onames, 9, option->dumpFmt);
  1358. }
  1359. /* Clean up. */
  1360. for (i = 0; i < nA; i++) {
  1361. Cudd_RecursiveDeref(dd,A[i]);
  1362. }
  1363. for (i = 0; i < nI; i++) {
  1364. Cudd_RecursiveDeref(dd,I[i]);
  1365. }
  1366. for (i = 0; i < nG; i++) {
  1367. Cudd_RecursiveDeref(dd,G[i]);
  1368. }
  1369. for (i = 0; i < nV; i++) {
  1370. Cudd_RecursiveDeref(dd,V[i]);
  1371. }
  1372. FREE(A);
  1373. FREE(I);
  1374. FREE(G);
  1375. FREE(V);
  1376. return(result);
  1377. } /* end of ntrTestDecompAux */
  1378. /**
  1379. @brief Processes one %BDD for Ntr_TestCofactorEstimate.
  1380. @return 1 if successful; 0 otherwise.
  1381. @sideeffect None
  1382. */
  1383. static int
  1384. ntrTestCofEstAux(
  1385. DdManager * dd,
  1386. BnetNetwork * net,
  1387. DdNode * f,
  1388. char * name,
  1389. NtrOptions * option)
  1390. {
  1391. DdNode *support, *scan, *cof;
  1392. int pr;
  1393. int nvars;
  1394. int exactSize, estimate, estimateS;
  1395. int totalExactSize = 0;
  1396. int totalEstimate = 0;
  1397. int totalEstimateS = 0;
  1398. int largestError = -1;
  1399. int largestErrorS = -1;
  1400. DdNode *errorVar = NULL;
  1401. pr = option->verb;
  1402. support = Cudd_Support(dd,f);
  1403. if (support == NULL) return(0);
  1404. Cudd_Ref(support);
  1405. nvars = Cudd_DagSize(support) - 1;
  1406. scan = support;
  1407. while (!Cudd_IsConstant(scan)) {
  1408. DdNode *var = Cudd_bddIthVar(dd,scan->index);
  1409. cof = Cudd_Cofactor(dd,f,var);
  1410. if (cof == NULL) return(0);
  1411. Cudd_Ref(cof);
  1412. exactSize = Cudd_DagSize(cof);
  1413. totalExactSize += exactSize;
  1414. estimate = Cudd_EstimateCofactor(dd,f,scan->index,1);
  1415. totalEstimate += estimate;
  1416. if (estimate < exactSize)
  1417. (void) printf("Optimistic estimate!\n");
  1418. if (estimate - exactSize > largestError) {
  1419. largestError = estimate - exactSize;
  1420. errorVar = var;
  1421. }
  1422. estimateS = Cudd_EstimateCofactorSimple(f,scan->index);
  1423. totalEstimateS += estimateS;
  1424. if (estimateS < exactSize)
  1425. (void) printf("Optimistic estimateS!\n");
  1426. if (estimateS - exactSize > largestErrorS)
  1427. largestErrorS = estimateS - exactSize;
  1428. Cudd_RecursiveDeref(dd,cof);
  1429. scan = cuddT(scan);
  1430. }
  1431. Cudd_RecursiveDeref(dd,support);
  1432. (void) printf("TEST-COF:: %s (%d vars)", name, nvars);
  1433. Cudd_PrintDebug(dd, f, nvars, pr);
  1434. (void) printf("T-c : %d\n", totalExactSize);
  1435. (void) printf("T-c E : %d %d\n", totalEstimate, largestError);
  1436. (void) printf("T-c S : %d %d\n", totalEstimateS, largestErrorS);
  1437. /* Dump to file if requested. */
  1438. if (option->bdddump) {
  1439. char *onames[3];
  1440. DdNode *outputs[3];
  1441. int result;
  1442. cof = Cudd_Cofactor(dd,f,errorVar);
  1443. if (cof == NULL) return(0);
  1444. Cudd_Ref(cof);
  1445. onames[0] = name; outputs[0] = f;
  1446. onames[1] = (char *) "var"; outputs[1] = errorVar;
  1447. onames[2] = (char *) "cof"; outputs[2] = cof;
  1448. result = Bnet_bddArrayDump(dd, net, option->dumpfile, outputs,
  1449. onames, 3, option->dumpFmt);
  1450. Cudd_RecursiveDeref(dd,cof);
  1451. if (result == 0) return(0);
  1452. }
  1453. return(1);
  1454. } /* end of ntrTestCofEstAux */
  1455. /**
  1456. @brief Processes one %BDD for Ntr_TestClipping.
  1457. @details It checks whether clipping was correct.
  1458. @return 1 if successful; 0 otherwise.
  1459. @sideeffect None
  1460. @see Ntr_TestClipping
  1461. */
  1462. static int
  1463. ntrTestClippingAux(
  1464. DdManager * dd,
  1465. BnetNetwork * net1,
  1466. DdNode * f,
  1467. char * name,
  1468. DdNode * g,
  1469. char * gname,
  1470. NtrOptions * option)
  1471. {
  1472. DdNode *prod, *sub, *sup;
  1473. DdNode *subF, *subG, *psub;
  1474. DdNode *supF, *supG, *psup;
  1475. int pr, nvars, depth;
  1476. int sizeProd, sizeSub, sizeSup;
  1477. static char *onames[7];
  1478. DdNode *outputs[7];
  1479. DdNode *operands[2];
  1480. int retval = 1;
  1481. int threshold = (option->threshold < 0) ? 0 : option->threshold;
  1482. pr = option->verb;
  1483. operands[0] = f; operands[1] = g;
  1484. nvars = Cudd_VectorSupportSize(dd,operands,2);
  1485. if (nvars == CUDD_OUT_OF_MEM) return(0);
  1486. depth = (int) ((double) nvars * option->clip);
  1487. (void) printf("TEST-CLIP:: %s depth = %d\n", name, depth);
  1488. (void) printf("T-C ");
  1489. Cudd_PrintDebug(dd, f, nvars, pr);
  1490. /* Compute product. */
  1491. prod = Cudd_bddAnd(dd, f, g);
  1492. if (prod == NULL) {
  1493. (void) printf("TEST-CLIP: product failed.\n");
  1494. return(0);
  1495. }
  1496. Cudd_Ref(prod);
  1497. (void) printf("T-C P= ");
  1498. Cudd_PrintDebug(dd, prod, nvars, pr);
  1499. sizeProd = Cudd_DagSize(prod);
  1500. /* Compute subset of product. */
  1501. sub = Cudd_bddClippingAnd(dd, f, g, depth, 0);
  1502. if (sub == NULL) {
  1503. (void) printf("TEST-CLIP: subsetting product failed.\n");
  1504. return(0);
  1505. }
  1506. Cudd_Ref(sub);
  1507. (void) printf("T-C P- ");
  1508. Cudd_PrintDebug(dd, sub, nvars, pr);
  1509. sizeSub = Cudd_DagSize(sub);
  1510. if (sizeSub > sizeProd) {
  1511. (void) printf("TEST-CLIP: subsetting product not safe.\n");
  1512. }
  1513. /* Compute product of subsets. */
  1514. subF = Cudd_RemapUnderApprox(dd,f,nvars,threshold,option->quality);
  1515. if (subF == NULL) {
  1516. (void) printf("TEST-CLIP: subsetting of f failed.\n");
  1517. return(0);
  1518. }
  1519. Cudd_Ref(subF);
  1520. subG = Cudd_RemapUnderApprox(dd,g,nvars,threshold,option->quality);
  1521. if (subF == NULL) {
  1522. (void) printf("TEST-CLIP: subsetting of g failed.\n");
  1523. return(0);
  1524. }
  1525. Cudd_Ref(subG);
  1526. psub = Cudd_bddAnd(dd,subF,subG);
  1527. if (psub == NULL) {
  1528. (void) printf("TEST-CLIP: product of subsets failed.\n");
  1529. return(0);
  1530. }
  1531. Cudd_Ref(psub);
  1532. Cudd_RecursiveDeref(dd,subF);
  1533. Cudd_RecursiveDeref(dd,subG);
  1534. (void) printf("T-C P< ");
  1535. Cudd_PrintDebug(dd, psub, nvars, pr);
  1536. /* Compute superset of product. */
  1537. sup = Cudd_bddClippingAnd(dd, f, g, depth, 1);
  1538. if (sup == NULL) {
  1539. (void) printf("TEST-CLIP: supersetting product failed.\n");
  1540. return(0);
  1541. }
  1542. Cudd_Ref(sup);
  1543. (void) printf("T-C P+ ");
  1544. Cudd_PrintDebug(dd, sup, nvars, pr);
  1545. sizeSup = Cudd_DagSize(sup);
  1546. if (sizeSup > sizeProd) {
  1547. (void) printf("TEST-CLIP: supersetting product not safe.\n");
  1548. }
  1549. /* Compute product of supersets. */
  1550. supF = Cudd_RemapOverApprox(dd,f,nvars,threshold,option->quality);
  1551. if (supF == NULL) {
  1552. (void) printf("TEST-CLIP: supersetting of f failed.\n");
  1553. return(0);
  1554. }
  1555. Cudd_Ref(supF);
  1556. supG = Cudd_RemapOverApprox(dd,g,nvars,threshold,option->quality);
  1557. if (supF == NULL) {
  1558. (void) printf("TEST-CLIP: supersetting of g failed.\n");
  1559. return(0);
  1560. }
  1561. Cudd_Ref(supG);
  1562. psup = Cudd_bddAnd(dd,supF,supG);
  1563. if (psup == NULL) {
  1564. (void) printf("TEST-CLIP: product of supersets failed.\n");
  1565. return(0);
  1566. }
  1567. Cudd_Ref(psup);
  1568. Cudd_RecursiveDeref(dd,supF);
  1569. Cudd_RecursiveDeref(dd,supG);
  1570. (void) printf("T-C P> ");
  1571. Cudd_PrintDebug(dd, psup, nvars, pr);
  1572. if (option->bdddump) {
  1573. onames[0] = name; outputs[0] = f;
  1574. onames[1] = gname; outputs[1] = g;
  1575. onames[2] = (char *) "prod"; outputs[2] = prod;
  1576. onames[3] = (char *) "sub"; outputs[3] = sub;
  1577. onames[4] = (char *) "sup"; outputs[4] = sup;
  1578. onames[5] = (char *) "psub"; outputs[5] = psub;
  1579. onames[6] = (char *) "psup"; outputs[6] = psup;
  1580. retval &= Bnet_bddArrayDump(dd, net1, option->dumpfile, outputs,
  1581. onames, 7, option->dumpFmt);
  1582. }
  1583. /* Check correctness. */
  1584. if (!Cudd_bddLeq(dd,sub,prod)) {
  1585. (void) printf("TEST-CLIP: subsetting product not a subset.\n");
  1586. return(0);
  1587. }
  1588. if (!Cudd_bddLeq(dd,prod,sup)) {
  1589. (void) printf("TEST-CLIP: supersetting product not a superset.\n");
  1590. return(0);
  1591. }
  1592. if (!Cudd_bddLeq(dd,psub,prod)) {
  1593. (void) printf("TEST-CLIP: product of subsets not a subset.\n");
  1594. return(0);
  1595. }
  1596. if (!Cudd_bddLeq(dd,prod,psup)) {
  1597. (void) printf("TEST-CLIP: product of supersets not a superset.\n");
  1598. return(0);
  1599. }
  1600. Cudd_RecursiveDeref(dd,prod);
  1601. Cudd_RecursiveDeref(dd,sub);
  1602. Cudd_RecursiveDeref(dd,sup);
  1603. Cudd_RecursiveDeref(dd,psub);
  1604. Cudd_RecursiveDeref(dd,psup);
  1605. return(retval);
  1606. } /* end of ntrTestClippingAux */
  1607. /**
  1608. @brief Processes one triplet of BDDs for Ntr_TestEquivAndContain.
  1609. @return 1 if successful; 0 otherwise.
  1610. @sideeffect None
  1611. @see Ntr_TestEquivAndContain
  1612. */
  1613. static int
  1614. ntrTestEquivAndContainAux(
  1615. DdManager *dd,
  1616. BnetNetwork *net1,
  1617. DdNode *f,
  1618. char *fname,
  1619. DdNode *g,
  1620. char *gname,
  1621. DdNode *d,
  1622. char *dname,
  1623. NtrOptions *option)
  1624. {
  1625. DdNode *xor_, *diff, *ndiff;
  1626. int pr, nvars;
  1627. int equiv, implies;
  1628. static char *onames[6];
  1629. DdNode *outputs[6];
  1630. DdNode *fgd[3];
  1631. pr = option->verb;
  1632. fgd[0] = f; fgd[1] = g; fgd[2] = d;
  1633. nvars = Cudd_VectorSupportSize(dd,fgd,3);
  1634. if (nvars == CUDD_OUT_OF_MEM) return(0);
  1635. (void) printf("TEST-DC:: %s [=<]= %s unless %s\n", fname, gname, dname);
  1636. (void) printf("T-F ");
  1637. Cudd_PrintDebug(dd, f, nvars, pr);
  1638. (void) printf("T-G ");
  1639. Cudd_PrintDebug(dd, g, nvars, pr);
  1640. (void) printf("T-D ");
  1641. Cudd_PrintDebug(dd, d, nvars, pr);
  1642. /* Check equivalence unless don't cares. */
  1643. xor_ = Cudd_bddXor(dd, f, g);
  1644. if (xor_ == NULL) {
  1645. (void) printf("TEST-DC: XOR computation failed (1).\n");
  1646. return(0);
  1647. }
  1648. Cudd_Ref(xor_);
  1649. equiv = Cudd_EquivDC(dd, f, g, d);
  1650. if (equiv != Cudd_bddLeq(dd,xor_,d)) {
  1651. (void) printf("TEST-DC: EquivDC computation incorrect (1).\n");
  1652. (void) printf(" EquivDC states that %s and %s are %s\n",
  1653. fname, gname, equiv ? "equivalent" : "not equivalent");
  1654. (void) printf("T-X ");
  1655. Cudd_PrintDebug(dd, xor_, nvars, pr);
  1656. return(0);
  1657. }
  1658. equiv = Cudd_EquivDC(dd, f, g, Cudd_Not(d));
  1659. if (equiv != Cudd_bddLeq(dd,xor_,Cudd_Not(d))) {
  1660. (void) printf("TEST-DC: EquivDC computation incorrect (2).\n");
  1661. (void) printf(" EquivDC states that %s and %s are %s\n",
  1662. fname, gname, equiv ? "equivalent" : "not equivalent");
  1663. (void) printf("T-X ");
  1664. Cudd_PrintDebug(dd, xor_, nvars, pr);
  1665. return(0);
  1666. }
  1667. equiv = Cudd_EquivDC(dd, f, Cudd_Not(g), d);
  1668. if (equiv != Cudd_bddLeq(dd,Cudd_Not(xor_),d)) {
  1669. (void) printf("TEST-DC: EquivDC computation incorrect (3).\n");
  1670. (void) printf(" EquivDC states that %s and not %s are %s\n",
  1671. fname, gname, equiv ? "equivalent" : "not equivalent");
  1672. (void) printf("T-X ");
  1673. Cudd_PrintDebug(dd, Cudd_Not(xor_), nvars, pr);
  1674. return(0);
  1675. }
  1676. equiv = Cudd_EquivDC(dd, f, Cudd_Not(g), Cudd_Not(d));
  1677. if (equiv != Cudd_bddLeq(dd,d,xor_)) {
  1678. (void) printf("TEST-DC: EquivDC computation incorrect (4).\n");
  1679. (void) printf(" EquivDC states that %s and not %s are %s\n",
  1680. fname, gname, equiv ? "equivalent" : "not equivalent");
  1681. (void) printf("T-X ");
  1682. Cudd_PrintDebug(dd, Cudd_Not(xor_), nvars, pr);
  1683. return(0);
  1684. }
  1685. /* Check containment unless don't cares. */
  1686. diff = Cudd_bddAnd(dd, f, Cudd_Not(g));
  1687. if (diff == NULL) {
  1688. (void) printf("TEST-DC: AND/NOT computation failed (1).\n");
  1689. return(0);
  1690. }
  1691. Cudd_Ref(diff);
  1692. implies = Cudd_bddLeqUnless(dd, f, g, d);
  1693. if (implies != Cudd_bddLeq(dd,diff,d)) {
  1694. (void) printf("TEST-DC: LeqUnless computation incorrect (1).\n");
  1695. (void) printf(" LeqUnless states that %s %s %s\n",
  1696. fname, implies ? "implies" : "does not imply", gname);
  1697. (void) printf("T-I ");
  1698. Cudd_PrintDebug(dd, diff, nvars, pr);
  1699. return(0);
  1700. }
  1701. implies = Cudd_bddLeqUnless(dd, f, g, Cudd_Not(d));
  1702. if (implies != Cudd_bddLeq(dd,diff,Cudd_Not(d))) {
  1703. (void) printf("TEST-DC: LeqUnless computation incorrect (2).\n");
  1704. (void) printf(" LeqUnless states that %s %s %s\n",
  1705. fname, implies ? "implies" : "does not imply", gname);
  1706. (void) printf("T-I ");
  1707. Cudd_PrintDebug(dd, diff, nvars, pr);
  1708. return(0);
  1709. }
  1710. ndiff = Cudd_bddAnd(dd, f, g);
  1711. if (ndiff == NULL) {
  1712. (void) printf("TEST-DC: AND computation failed (3).\n");
  1713. return(0);
  1714. }
  1715. Cudd_Ref(ndiff);
  1716. implies = Cudd_bddLeqUnless(dd, f, Cudd_Not(g), d);
  1717. if (implies != Cudd_bddLeq(dd,ndiff,d)) {
  1718. (void) printf("TEST-DC: LeqUnless computation incorrect (3).\n");
  1719. (void) printf(" LeqUnless states that %s %s not(%s)\n",
  1720. fname, implies ? "implies" : "does not imply", gname);
  1721. (void) printf("T-I ");
  1722. Cudd_PrintDebug(dd, ndiff, nvars, pr);
  1723. return(0);
  1724. }
  1725. implies = Cudd_bddLeqUnless(dd, f, Cudd_Not(g), Cudd_Not(d));
  1726. if (implies != Cudd_bddLeq(dd,ndiff,Cudd_Not(d))) {
  1727. (void) printf("TEST-DC: LeqUnless computation incorrect (3).\n");
  1728. (void) printf(" LeqUnless states that %s %s not(%s)\n",
  1729. fname, implies ? "implies" : "does not imply", gname);
  1730. (void) printf("T-I ");
  1731. Cudd_PrintDebug(dd, ndiff, nvars, pr);
  1732. return(0);
  1733. }
  1734. if (option->bdddump) {
  1735. onames[0] = fname; outputs[0] = f;
  1736. onames[1] = gname; outputs[1] = g;
  1737. onames[2] = dname; outputs[2] = d;
  1738. onames[3] = (char *) "xor"; outputs[3] = xor_;
  1739. onames[4] = (char *) "diff"; outputs[4] = diff;
  1740. onames[5] = (char *) "ndiff"; outputs[5] = ndiff;
  1741. if (!Bnet_bddArrayDump(dd, net1, option->dumpfile, outputs, onames,
  1742. 6, option->dumpFmt))
  1743. return(0);
  1744. }
  1745. Cudd_RecursiveDeref(dd,xor_);
  1746. Cudd_RecursiveDeref(dd,diff);
  1747. Cudd_RecursiveDeref(dd,ndiff);
  1748. return(1);
  1749. } /* end of ntrTestEquivAndContainAux */
  1750. /**
  1751. @brief Processes one pair of BDDs for Ntr_TestClosestCube.
  1752. @return 1 if successful; 0 otherwise.
  1753. @sideeffect None
  1754. @see Ntr_TestClosestCube
  1755. */
  1756. static int
  1757. ntrTestClosestCubeAux(
  1758. DdManager *dd,
  1759. BnetNetwork *net,
  1760. DdNode *f,
  1761. char *fname,
  1762. DdNode *g,
  1763. char *gname,
  1764. DdNode **vars,
  1765. NtrOptions *option)
  1766. {
  1767. DdNode *cube, *cubeN;
  1768. int distance, pr, nvars;
  1769. DdNode *fg[2];
  1770. static char *onames[4];
  1771. DdNode *outputs[4];
  1772. pr = option->verb;
  1773. fg[0] = f; fg[1] = g;
  1774. nvars = Cudd_VectorSupportSize(dd,fg,2);
  1775. if (nvars == CUDD_OUT_OF_MEM) return(0);
  1776. (void) printf("TEST-CC:: H(%s, %s)\n", fname, gname);
  1777. (void) printf("T-F ");
  1778. Cudd_PrintDebug(dd, f, nvars, pr);
  1779. (void) printf("T-G ");
  1780. Cudd_PrintDebug(dd, g, nvars, pr);
  1781. cube = Cudd_bddClosestCube(dd, f, g, &distance);
  1782. if (cube == NULL) {
  1783. (void) printf("TEST-CC: computation failed (1).\n");
  1784. return(0);
  1785. }
  1786. Cudd_Ref(cube);
  1787. (void) printf("T-C (%d) ", distance);
  1788. Cudd_PrintDebug(dd, cube, nvars, pr);
  1789. if (distance == 0) {
  1790. if (!Cudd_bddLeq(dd,cube,g)) {
  1791. (void) printf("TEST-CC: distance-0 cube not in g (2).\n");
  1792. return(0);
  1793. }
  1794. }
  1795. (void) printf("T-GN ");
  1796. Cudd_PrintDebug(dd, Cudd_Not(g), nvars, pr);
  1797. cubeN = Cudd_bddClosestCube(dd, f, Cudd_Not(g), &distance);
  1798. if (cubeN == NULL) {
  1799. (void) printf("TEST-CC: computation failed (3).\n");
  1800. return(0);
  1801. }
  1802. Cudd_Ref(cubeN);
  1803. (void) printf("T-N (%d) ", distance);
  1804. Cudd_PrintDebug(dd, cubeN, nvars, pr);
  1805. if (distance == 0) {
  1806. if (!Cudd_bddLeq(dd,cubeN,Cudd_Not(g))) {
  1807. (void) printf("TEST-CC: distance-0 cube not in not(g) (4).\n");
  1808. return(0);
  1809. }
  1810. } else {
  1811. int d, *minterm;
  1812. int numvars = Cudd_ReadSize(dd);
  1813. DdNode *scan, *zero;
  1814. DdNode *minBdd = Cudd_bddPickOneMinterm(dd,cubeN,vars,numvars);
  1815. if (minBdd == NULL) {
  1816. (void) printf("TEST-CC: minterm selection failed (5).\n");
  1817. return(0);
  1818. }
  1819. Cudd_Ref(minBdd);
  1820. minterm = ALLOC(int,numvars);
  1821. if (minterm == NULL) {
  1822. (void) printf("TEST-CC: allocation failed (6).\n");
  1823. Cudd_RecursiveDeref(dd,minBdd);
  1824. return(0);
  1825. }
  1826. scan = minBdd;
  1827. zero = Cudd_Not(DD_ONE(dd));
  1828. while (!Cudd_IsConstant(scan)) {
  1829. DdNode *R = Cudd_Regular(scan);
  1830. DdNode *T = Cudd_T(R);
  1831. DdNode *E = Cudd_E(R);
  1832. if (R != scan) {
  1833. T = Cudd_Not(T);
  1834. E = Cudd_Not(E);
  1835. }
  1836. if (T == zero) {
  1837. minterm[Cudd_NodeReadIndex(R)] = 0;
  1838. scan = E;
  1839. } else {
  1840. minterm[Cudd_NodeReadIndex(R)] = 1;
  1841. scan = T;
  1842. }
  1843. }
  1844. Cudd_RecursiveDeref(dd,minBdd);
  1845. d = Cudd_MinHammingDist(dd,Cudd_Not(g),minterm,numvars);
  1846. FREE(minterm);
  1847. if (d != distance) {
  1848. (void) printf("TEST-CC: distance disagreement (7).\n");
  1849. return(0);
  1850. }
  1851. }
  1852. if (option->bdddump) {
  1853. onames[0] = fname; outputs[0] = f;
  1854. onames[1] = gname; outputs[1] = g;
  1855. onames[2] = (char *) "cube"; outputs[2] = cube;
  1856. onames[3] = (char *) "cubeN"; outputs[3] = cubeN;
  1857. if (!Bnet_bddArrayDump(dd, net, option->dumpfile, outputs, onames,
  1858. 4, option->dumpFmt))
  1859. return(0);
  1860. }
  1861. Cudd_RecursiveDeref(dd,cube);
  1862. Cudd_RecursiveDeref(dd,cubeN);
  1863. return(1);
  1864. } /* end of ntrTestClosestCubeAux */
  1865. /**
  1866. @brief Processes one BDDs for Ntr_TestCharToVect.
  1867. @return 1 if successful; 0 otherwise.
  1868. @sideeffect None
  1869. @see Ntr_TestCharToVect
  1870. */
  1871. static int
  1872. ntrTestCharToVect(
  1873. DdManager * dd,
  1874. DdNode * f,
  1875. NtrOptions *option)
  1876. {
  1877. DdNode **vector;
  1878. int sharingSize;
  1879. DdNode *verify;
  1880. int pr = option->verb;
  1881. int i;
  1882. (void) fprintf(stdout,"f");
  1883. Cudd_PrintDebug(dd, f, Cudd_ReadSize(dd), 1);
  1884. if (pr > 1) {
  1885. Cudd_bddPrintCover(dd, f, f);
  1886. }
  1887. vector = Cudd_bddCharToVect(dd,f);
  1888. if (vector == NULL) return(0);
  1889. sharingSize = Cudd_SharingSize(vector, Cudd_ReadSize(dd));
  1890. (void) fprintf(stdout, "Vector Size: %d components %d nodes\n",
  1891. Cudd_ReadSize(dd), sharingSize);
  1892. for (i = 0; i < Cudd_ReadSize(dd); i++) {
  1893. (void) fprintf(stdout,"v[%d]",i);
  1894. Cudd_PrintDebug(dd, vector[i], Cudd_ReadSize(dd), 1);
  1895. if (pr > 1) {
  1896. Cudd_bddPrintCover(dd, vector[i], vector[i]);
  1897. }
  1898. }
  1899. verify = Cudd_bddVectorCompose(dd,f,vector);
  1900. if (verify != Cudd_ReadOne(dd)) {
  1901. (void) fprintf(stdout, "Verification failed!\n");
  1902. return(0);
  1903. }
  1904. Cudd_Ref(verify);
  1905. Cudd_IterDerefBdd(dd, verify);
  1906. for (i = 0; i < Cudd_ReadSize(dd); i++) {
  1907. Cudd_IterDerefBdd(dd, vector[i]);
  1908. }
  1909. FREE(vector);
  1910. return(1);
  1911. } /* end of ntrTestCharToVect */
  1912. #if 0
  1913. /**
  1914. @brief Try hard to squeeze a %BDD.
  1915. @return a pointer to the squeezed %BDD if successful; NULL otherwise.
  1916. @sideeffect None
  1917. @see ntrTestDensityAux Cudd_SubsetCompress
  1918. */
  1919. static DdNode *
  1920. ntrCompress1(
  1921. DdManager * dd,
  1922. DdNode * f,
  1923. int nvars,
  1924. int threshold)
  1925. {
  1926. DdNode *res, *tmp1, *tmp2;
  1927. int sizeI, size;
  1928. tmp1 = Cudd_RemapUnderApprox(dd,f,nvars,0,1.0);
  1929. if (tmp1 == NULL) return(NULL);
  1930. Cudd_Ref(tmp1);
  1931. sizeI = Cudd_DagSize(tmp1);
  1932. size = (sizeI < threshold) ? sizeI : threshold;
  1933. tmp2 = Cudd_SubsetShortPaths(dd, tmp1, nvars, size, 0);
  1934. if (tmp2 == NULL) {
  1935. Cudd_RecursiveDeref(dd,tmp1);
  1936. return(NULL);
  1937. }
  1938. Cudd_Ref(tmp2);
  1939. Cudd_RecursiveDeref(dd,tmp1);
  1940. res = Cudd_bddSqueeze(dd,tmp2,f);
  1941. if (res == NULL) {
  1942. Cudd_RecursiveDeref(dd,tmp2);
  1943. return(NULL);
  1944. }
  1945. Cudd_Ref(res);
  1946. Cudd_RecursiveDeref(dd,tmp2);
  1947. return(res);
  1948. } /* end of ntrCompress1 */
  1949. #endif
  1950. /**
  1951. @brief Try hard to squeeze a %BDD.
  1952. @return a pointer to the squeezed %BDD if successful; NULL otherwise.
  1953. @sideeffect None
  1954. @see ntrTestDensityAux Cudd_SubsetCompress
  1955. */
  1956. static DdNode *
  1957. ntrCompress2(
  1958. DdManager * dd,
  1959. DdNode * f,
  1960. int nvars,
  1961. int threshold)
  1962. {
  1963. DdNode *res, *tmp1, *tmp2;
  1964. int sizeI;
  1965. tmp1 = Cudd_RemapUnderApprox(dd,f,nvars,0,1.0);
  1966. if (tmp1 == NULL) return(NULL);
  1967. Cudd_Ref(tmp1);
  1968. sizeI = Cudd_DagSize(tmp1);
  1969. if (sizeI > threshold) {
  1970. tmp2 = Cudd_SubsetShortPaths(dd, tmp1, nvars, threshold, 0);
  1971. if (tmp2 == NULL) {
  1972. Cudd_RecursiveDeref(dd,tmp1);
  1973. return(NULL);
  1974. }
  1975. Cudd_Ref(tmp2);
  1976. Cudd_RecursiveDeref(dd,tmp1);
  1977. } else {
  1978. tmp2 = tmp1;
  1979. }
  1980. res = Cudd_bddSqueeze(dd,tmp2,f);
  1981. if (res == NULL) {
  1982. Cudd_RecursiveDeref(dd,tmp2);
  1983. return(NULL);
  1984. }
  1985. Cudd_Ref(res);
  1986. if (Cudd_Density(dd,res,nvars) < Cudd_Density(dd,tmp2,nvars)) {
  1987. Cudd_RecursiveDeref(dd,res);
  1988. return(tmp2);
  1989. } else {
  1990. Cudd_RecursiveDeref(dd,tmp2);
  1991. return(res);
  1992. }
  1993. } /* end of ntrCompress2 */
  1994. /**
  1995. @brief Checks whether node is a buffer.
  1996. @return a pointer to the input node if nd is a buffer; NULL
  1997. otherwise.
  1998. @sideeffect None
  1999. */
  2000. static BnetNode *
  2001. ntrNodeIsBuffer(
  2002. BnetNode *nd,
  2003. st_table *hash)
  2004. {
  2005. BnetNode *inpnd;
  2006. if (nd->ninp != 1) return(0);
  2007. if (!st_lookup(hash, nd->inputs[0], (void **) &inpnd)) return(0);
  2008. return(nd->dd == inpnd->dd ? inpnd : NULL);
  2009. } /* end of ntrNodeIsBuffer */