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.

1084 lines
29 KiB

2 months ago
  1. /**CFile**********************************************************************
  2. FileName [dddmpLoadCnf.c]
  3. PackageName [dddmp]
  4. Synopsis [Functions to read in CNF from file as BDDs.]
  5. Description [Functions to read in CNF from file as BDDs.
  6. ]
  7. Author [Gianpiero Cabodi and Stefano Quer]
  8. Copyright [
  9. Copyright (c) 2004 by Politecnico di Torino.
  10. All Rights Reserved. This software is for educational purposes only.
  11. Permission is given to academic institutions to use, copy, and modify
  12. this software and its documentation provided that this introductory
  13. message is not removed, that this software and its documentation is
  14. used for the institutions' internal research and educational purposes,
  15. and that no monies are exchanged. No guarantee is expressed or implied
  16. by the distribution of this code.
  17. Send bug-reports and/or questions to:
  18. {gianpiero.cabodi,stefano.quer}@polito.it.
  19. ]
  20. ******************************************************************************/
  21. #include "dddmpInt.h"
  22. /*---------------------------------------------------------------------------*/
  23. /* Constant declarations */
  24. /*---------------------------------------------------------------------------*/
  25. #define DDDMP_MAX_CNF_ROW_LENGTH 1000
  26. #define DDDMP_DEBUG_CNF 0
  27. /*---------------------------------------------------------------------------*/
  28. /* Stucture declarations */
  29. /*---------------------------------------------------------------------------*/
  30. /*---------------------------------------------------------------------------*/
  31. /* Type declarations */
  32. /*---------------------------------------------------------------------------*/
  33. /*---------------------------------------------------------------------------*/
  34. /* Variable declarations */
  35. /*---------------------------------------------------------------------------*/
  36. /*---------------------------------------------------------------------------*/
  37. /* Macro declarations */
  38. /*---------------------------------------------------------------------------*/
  39. #define matchkeywd(str,key) (strncmp(str,key,strlen(key))==0)
  40. /**AutomaticStart*************************************************************/
  41. /*---------------------------------------------------------------------------*/
  42. /* Static function prototypes */
  43. /*---------------------------------------------------------------------------*/
  44. static int DddmpCuddDdArrayLoadCnf(DdManager *ddMgr, Dddmp_RootMatchType rootmatchmode, char **rootmatchnames, Dddmp_VarMatchType varmatchmode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***rootsPtrPtr, int *nRoots);
  45. static Dddmp_Hdr_t * DddmpBddReadHeaderCnf(char *file, FILE *fp);
  46. static void DddmpFreeHeaderCnf(Dddmp_Hdr_t *Hdr);
  47. static int DddmpReadCnfClauses(Dddmp_Hdr_t *Hdr, int ***cnfTable, FILE *fp);
  48. static int DddmpCnfClauses2Bdd(Dddmp_Hdr_t *Hdr, DdManager *ddMgr, int **cnfTable, int mode, DdNode ***rootsPtrPtr);
  49. /**AutomaticEnd***************************************************************/
  50. /*---------------------------------------------------------------------------*/
  51. /* Definition of exported functions */
  52. /*---------------------------------------------------------------------------*/
  53. /**Function********************************************************************
  54. Synopsis [Reads a dump file in a CNF format.]
  55. Description [Reads a dump file representing the argument BDD in a
  56. CNF formula.
  57. Dddmp_cuddBddArrayLoadCnf is used through a dummy array.
  58. The results is returned in different formats depending on the
  59. mode selection:
  60. IFF mode == 0 Return the Clauses without Conjunction
  61. IFF mode == 1 Return the sets of BDDs without Quantification
  62. IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification
  63. ]
  64. SideEffects [A vector of pointers to DD nodes is allocated and freed.]
  65. SeeAlso [Dddmp_cuddBddLoad, Dddmp_cuddBddArrayLoad]
  66. ******************************************************************************/
  67. int
  68. Dddmp_cuddBddLoadCnf (
  69. DdManager *ddMgr /* IN: DD Manager */,
  70. Dddmp_VarMatchType varmatchmode /* IN: storing mode selector */,
  71. char **varmatchnames /* IN: array of variable names, by IDs */,
  72. int *varmatchauxids /* IN: array of variable auxids, by IDs */,
  73. int *varcomposeids /* IN: array of new ids accessed, by IDs */,
  74. int mode /* IN: computation mode */,
  75. char *file /* IN: file name */,
  76. FILE *fp /* IN: file pointer */,
  77. DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots */,
  78. int *nRoots /* OUT: number of BDDs returned */
  79. )
  80. {
  81. int i, retValue;
  82. retValue = Dddmp_cuddBddArrayLoadCnf (ddMgr, DDDMP_ROOT_MATCHLIST, NULL,
  83. varmatchmode, varmatchnames, varmatchauxids, varcomposeids, mode,
  84. file, fp, rootsPtrPtr, nRoots);
  85. if (retValue == DDDMP_FAILURE) {
  86. return (DDDMP_FAILURE);
  87. }
  88. if (*nRoots > 1) {
  89. fprintf (stderr,
  90. "Warning: %d BDD roots found in file. Only first retrieved.\n",
  91. *nRoots);
  92. for (i=1; i<*nRoots; i++) {
  93. Cudd_RecursiveDeref (ddMgr, *rootsPtrPtr[i]);
  94. }
  95. }
  96. return (DDDMP_SUCCESS);
  97. }
  98. /**Function********************************************************************
  99. Synopsis [Reads a dump file in a CNF format.]
  100. Description [Reads a dump file representing the argument BDD in a
  101. CNF formula.
  102. ]
  103. SideEffects [A vector of pointers to DD nodes is allocated and freed.]
  104. SeeAlso [Dddmp_cuddBddArrayLoad]
  105. ******************************************************************************/
  106. int
  107. Dddmp_cuddBddArrayLoadCnf (
  108. DdManager *ddMgr /* IN: DD Manager */,
  109. Dddmp_RootMatchType rootmatchmode/* IN: storing mode selector */,
  110. char **rootmatchnames /* IN: sorted names for loaded roots */,
  111. Dddmp_VarMatchType varmatchmode /* IN: storing mode selector */,
  112. char **varmatchnames /* IN: array of variable names, by IDs */,
  113. int *varmatchauxids /* IN: array of variable auxids, by IDs */,
  114. int *varcomposeids /* IN: array of new ids, by IDs */,
  115. int mode /* IN: computation Mode */,
  116. char *file /* IN: file name */,
  117. FILE *fp /* IN: file pointer */,
  118. DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots */,
  119. int *nRoots /* OUT: number of BDDs returned */
  120. )
  121. {
  122. int retValue;
  123. #ifdef DDDMP_DEBUG
  124. #ifndef __alpha__
  125. int retValueBis;
  126. retValueBis = Cudd_DebugCheck (ddMgr);
  127. if (retValueBis == 1) {
  128. fprintf (stderr, "Inconsistency Found During CNF Load.\n");
  129. fflush (stderr);
  130. } else {
  131. if (retValueBis == CUDD_OUT_OF_MEM) {
  132. fprintf (stderr, "Out of Memory During CNF Load.\n");
  133. fflush (stderr);
  134. }
  135. }
  136. #endif
  137. #endif
  138. retValue = DddmpCuddDdArrayLoadCnf (ddMgr, rootmatchmode,
  139. rootmatchnames, varmatchmode, varmatchnames, varmatchauxids,
  140. varcomposeids, mode, file, fp, rootsPtrPtr, nRoots);
  141. #ifdef DDDMP_DEBUG
  142. #ifndef __alpha__
  143. retValueBis = Cudd_DebugCheck (ddMgr);
  144. if (retValueBis == 1) {
  145. fprintf (stderr, "Inconsistency Found During CNF Load.\n");
  146. fflush (stderr);
  147. } else {
  148. if (retValueBis == CUDD_OUT_OF_MEM) {
  149. fprintf (stderr, "Out of Memory During CNF Load.\n");
  150. fflush (stderr);
  151. }
  152. }
  153. #endif
  154. #endif
  155. return (retValue);
  156. }
  157. /**Function********************************************************************
  158. Synopsis [Reads the header of a dump file representing the argument BDDs]
  159. Description [Reads the header of a dump file representing the argument BDDs.
  160. Returns main information regarding DD type stored in the file,
  161. the variable ordering used, the number of variables, etc.
  162. It reads only the header of the file NOT the BDD/ADD section.
  163. ]
  164. SideEffects []
  165. SeeAlso [Dddmp_cuddBddArrayLoad]
  166. ******************************************************************************/
  167. int
  168. Dddmp_cuddHeaderLoadCnf (
  169. int *nVars /* OUT: number of DD variables */,
  170. int *nsuppvars /* OUT: number of support variables */,
  171. char ***suppVarNames /* OUT: array of support variable names */,
  172. char ***orderedVarNames /* OUT: array of variable names */,
  173. int **varIds /* OUT: array of variable ids */,
  174. int **varComposeIds /* OUT: array of permids ids */,
  175. int **varAuxIds /* OUT: array of variable aux ids */,
  176. int *nRoots /* OUT: number of root in the file */,
  177. char *file /* IN: file name */,
  178. FILE *fp /* IN: file pointer */
  179. )
  180. {
  181. Dddmp_Hdr_t *Hdr;
  182. int i, fileToClose;
  183. char **tmpOrderedVarNames = NULL;
  184. char **tmpSuppVarNames = NULL;
  185. int *tmpVarIds = NULL;
  186. int *tmpVarComposeIds = NULL;
  187. int *tmpVarAuxIds = NULL;
  188. fileToClose = 0;
  189. if (fp == NULL) {
  190. fp = fopen (file, "r");
  191. Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.",
  192. failure);
  193. fileToClose = 1;
  194. }
  195. Hdr = DddmpBddReadHeaderCnf (NULL, fp);
  196. Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.",
  197. failure);
  198. /*
  199. * Number of variables (tot and support)
  200. */
  201. *nVars = Hdr->nVars;
  202. *nsuppvars = Hdr->nsuppvars;
  203. /*
  204. * Support Varnames
  205. */
  206. if (Hdr->suppVarNames != NULL) {
  207. tmpSuppVarNames = DDDMP_ALLOC (char *, *nsuppvars);
  208. Dddmp_CheckAndGotoLabel (tmpSuppVarNames==NULL, "Error allocating memory.",
  209. failure);
  210. for (i=0; i<*nsuppvars; i++) {
  211. tmpSuppVarNames[i] = DDDMP_ALLOC (char,
  212. (strlen (Hdr->suppVarNames[i]) + 1));
  213. Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL,
  214. "Support Variable Name Missing in File.", failure);
  215. strcpy (tmpSuppVarNames[i], Hdr->suppVarNames[i]);
  216. }
  217. *suppVarNames = tmpSuppVarNames;
  218. } else {
  219. *suppVarNames = NULL;
  220. }
  221. /*
  222. * Ordered Varnames
  223. */
  224. if (Hdr->orderedVarNames != NULL) {
  225. tmpOrderedVarNames = DDDMP_ALLOC (char *, *nVars);
  226. Dddmp_CheckAndGotoLabel (tmpOrderedVarNames==NULL,
  227. "Error allocating memory.", failure);
  228. for (i=0; i<*nVars; i++) {
  229. tmpOrderedVarNames[i] = DDDMP_ALLOC (char,
  230. (strlen (Hdr->orderedVarNames[i]) + 1));
  231. Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames[i]==NULL,
  232. "Support Variable Name Missing in File.", failure);
  233. strcpy (tmpOrderedVarNames[i], Hdr->orderedVarNames[i]);
  234. }
  235. *orderedVarNames = tmpOrderedVarNames;
  236. } else {
  237. *orderedVarNames = NULL;
  238. }
  239. /*
  240. * Variable Ids
  241. */
  242. if (Hdr->ids != NULL) {
  243. tmpVarIds = DDDMP_ALLOC (int, *nsuppvars);
  244. Dddmp_CheckAndGotoLabel (tmpVarIds==NULL, "Error allocating memory.",
  245. failure);
  246. for (i=0; i<*nsuppvars; i++) {
  247. tmpVarIds[i] = Hdr->ids[i];
  248. }
  249. *varIds = tmpVarIds;
  250. } else {
  251. *varIds = NULL;
  252. }
  253. /*
  254. * Variable Compose Ids
  255. */
  256. if (Hdr->permids != NULL) {
  257. tmpVarComposeIds = DDDMP_ALLOC (int, *nsuppvars);
  258. Dddmp_CheckAndGotoLabel (tmpVarComposeIds==NULL,
  259. "Error allocating memory.", failure);
  260. for (i=0; i<*nsuppvars; i++) {
  261. tmpVarComposeIds[i] = Hdr->permids[i];
  262. }
  263. *varComposeIds = tmpVarComposeIds;
  264. } else {
  265. *varComposeIds = NULL;
  266. }
  267. /*
  268. * Variable Auxiliary Ids
  269. */
  270. if (Hdr->auxids != NULL) {
  271. tmpVarAuxIds = DDDMP_ALLOC (int, *nsuppvars);
  272. Dddmp_CheckAndGotoLabel (tmpVarAuxIds==NULL,
  273. "Error allocating memory.", failure);
  274. for (i=0; i<*nsuppvars; i++) {
  275. tmpVarAuxIds[i] = Hdr->auxids[i];
  276. }
  277. *varAuxIds = tmpVarAuxIds;
  278. } else {
  279. *varAuxIds = NULL;
  280. }
  281. /*
  282. * Number of roots
  283. */
  284. *nRoots = Hdr->nRoots;
  285. /*
  286. * Free and Return
  287. */
  288. if (fileToClose == 1) {
  289. fclose (fp);
  290. }
  291. DddmpFreeHeaderCnf (Hdr);
  292. return (DDDMP_SUCCESS);
  293. failure:
  294. return (DDDMP_FAILURE);
  295. }
  296. /*---------------------------------------------------------------------------*/
  297. /* Definition of internal functions */
  298. /*---------------------------------------------------------------------------*/
  299. /*---------------------------------------------------------------------------*/
  300. /* Definition of static functions */
  301. /*---------------------------------------------------------------------------*/
  302. /**Function********************************************************************
  303. Synopsis [Reads a dump file representing the argument BDDs in CNF
  304. format.
  305. ]
  306. Description [Reads a dump file representing the argument BDDs in CNF
  307. format.
  308. IFF mode == 0 Return the Clauses without Conjunction
  309. IFF mode == 1 Return the sets of BDDs without Quantification
  310. IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification
  311. ]
  312. SideEffects [A vector of pointers to DD nodes is allocated and freed.]
  313. SeeAlso [Dddmp_cuddBddArrayLoad]
  314. ******************************************************************************/
  315. static int
  316. DddmpCuddDdArrayLoadCnf (
  317. DdManager *ddMgr /* IN: DD Manager */,
  318. Dddmp_RootMatchType rootmatchmode/* IN: storing mode selector */,
  319. char **rootmatchnames /* IN: sorted names for loaded roots */,
  320. Dddmp_VarMatchType varmatchmode /* IN: storing mode selector */,
  321. char **varmatchnames /* IN: array of variable names, by ids */,
  322. int *varmatchauxids /* IN: array of variable auxids, by ids */,
  323. int *varcomposeids /* IN: array of new ids, by ids */,
  324. int mode /* IN: computation mode */,
  325. char *file /* IN: file name */,
  326. FILE *fp /* IN: file pointer */,
  327. DdNode ***rootsPtrPtr /* OUT: array of BDD roots */,
  328. int *nRoots /* OUT: number of BDDs returned */
  329. )
  330. {
  331. Dddmp_Hdr_t *Hdr = NULL;
  332. int **cnfTable = NULL;
  333. int fileToClose = 0;
  334. int retValue, i;
  335. (void) rootmatchmode; /* avoid warning */
  336. (void) rootmatchnames; /* avoid warning */
  337. (void) varmatchmode; /* avoid warning */
  338. (void) varmatchnames; /* avoid warning */
  339. (void) varmatchauxids; /* avoid warning */
  340. (void) varcomposeids; /* avoid warning */
  341. fileToClose = 0;
  342. *rootsPtrPtr = NULL;
  343. if (fp == NULL) {
  344. fp = fopen (file, "r");
  345. Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.",
  346. failure);
  347. fileToClose = 1;
  348. }
  349. /*--------------------------- Read the Header -----------------------------*/
  350. Hdr = DddmpBddReadHeaderCnf (NULL, fp);
  351. Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.",
  352. failure);
  353. /*------------------------ Read the CNF Clauses ---------------------------*/
  354. retValue = DddmpReadCnfClauses (Hdr, &cnfTable, fp);
  355. Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE,
  356. "Read CNF Clauses Failure.", failure);
  357. /*------------------------- From Clauses to BDDs --------------------------*/
  358. retValue = DddmpCnfClauses2Bdd (Hdr, ddMgr, cnfTable, mode, rootsPtrPtr);
  359. Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE,
  360. "CNF Clauses To BDDs Failure.", failure);
  361. *nRoots = Hdr->nRoots;
  362. if (fileToClose) {
  363. fclose (fp);
  364. }
  365. for (i=0; i<Hdr->nClausesCnf; i++) {
  366. DDDMP_FREE (cnfTable[i]);
  367. }
  368. DDDMP_FREE (cnfTable);
  369. DddmpFreeHeaderCnf (Hdr);
  370. return (DDDMP_SUCCESS);
  371. /*
  372. * Failure Condition
  373. */
  374. failure:
  375. if (fileToClose) {
  376. fclose (fp);
  377. }
  378. for (i=0; i<Hdr->nClausesCnf; i++) {
  379. DDDMP_FREE (cnfTable[i]);
  380. }
  381. DDDMP_FREE (cnfTable);
  382. DddmpFreeHeaderCnf (Hdr);
  383. /* return 0 on error ! */
  384. nRoots = 0;
  385. return (DDDMP_FAILURE);
  386. }
  387. /**Function********************************************************************
  388. Synopsis [Reads a the header of a dump file representing the argument
  389. BDDs.
  390. ]
  391. Description [Reads the header of a dump file. Builds a Dddmp_Hdr_t struct
  392. containing all infos in the header, for next manipulations.
  393. ]
  394. SideEffects [none]
  395. SeeAlso []
  396. ******************************************************************************/
  397. static Dddmp_Hdr_t *
  398. DddmpBddReadHeaderCnf (
  399. char *file /* IN: file name */,
  400. FILE *fp /* IN: file pointer */
  401. )
  402. {
  403. Dddmp_Hdr_t *Hdr = NULL;
  404. char buf[DDDMP_MAXSTRLEN];
  405. int nv, nc, retValue, fileToClose = 0;
  406. char *fgetsRet;
  407. if (fp == NULL) {
  408. fp = fopen (file, "r");
  409. Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.",
  410. failure);
  411. fileToClose = 1;
  412. }
  413. /* Start Header */
  414. Hdr = DDDMP_ALLOC (Dddmp_Hdr_t, 1);
  415. if (Hdr == NULL) {
  416. return NULL;
  417. }
  418. Hdr->ver = NULL;
  419. Hdr->mode = 0;
  420. Hdr->ddType = DDDMP_CNF;
  421. Hdr->varinfo = DDDMP_VARIDS;
  422. Hdr->dd = NULL;
  423. Hdr->nnodes = 0;
  424. Hdr->nVars = 0;
  425. Hdr->nsuppvars = 0;
  426. Hdr->orderedVarNames = NULL;
  427. Hdr->suppVarNames = NULL;
  428. Hdr->ids = NULL;
  429. Hdr->permids = NULL;
  430. Hdr->auxids = NULL;
  431. Hdr->cnfids = NULL;
  432. Hdr->nRoots = 0;
  433. Hdr->rootids = NULL;
  434. Hdr->rootnames = NULL;
  435. Hdr->nAddedCnfVar = 0;
  436. Hdr->nVarsCnf = 0;
  437. Hdr->nClausesCnf = 0;
  438. while (fscanf (fp, "%s", buf) != EOF) {
  439. /* Init Problem Line */
  440. if (buf[0] == 'p') {
  441. retValue = fscanf (fp, "%*s %d %d", &nv, &nc);
  442. Dddmp_CheckAndGotoLabel (retValue!=2, "Error reading problem line.",
  443. failure);
  444. Hdr->nVarsCnf = nv;
  445. Hdr->nClausesCnf = nc;
  446. break;
  447. }
  448. /* CNF Comment Line */
  449. if (buf[0] == 'c') {
  450. if (fscanf (fp, "%s", buf) == EOF) {
  451. break;
  452. }
  453. }
  454. /* Skip Comment? */
  455. if (buf[0] != '.') {
  456. fgetsRet = fgets (buf, DDDMP_MAXSTRLEN, fp);
  457. Dddmp_CheckAndGotoLabel (!fgetsRet, "Error reading comment.", failure);
  458. continue;
  459. }
  460. if (matchkeywd (buf, ".ver")) {
  461. /* this not checked so far: only read */
  462. retValue = fscanf (fp, "%s", buf);
  463. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading from file.",
  464. failure);
  465. Hdr->ver=DddmpStrDup(buf);
  466. Dddmp_CheckAndGotoLabel (Hdr->ver==NULL,
  467. "Error allocating memory.", failure);
  468. continue;
  469. }
  470. if (matchkeywd (buf, ".dd")) {
  471. retValue = fscanf (fp, "%s", buf);
  472. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.",
  473. failure);
  474. Hdr->dd = DddmpStrDup (buf);
  475. Dddmp_CheckAndGotoLabel (Hdr->dd==NULL, "Error allocating memory.",
  476. failure);
  477. continue;
  478. }
  479. if (matchkeywd (buf, ".nnodes")) {
  480. retValue = fscanf (fp, "%d", &(Hdr->nnodes));
  481. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.",
  482. failure);
  483. continue;
  484. }
  485. if (matchkeywd (buf, ".nvars")) {
  486. retValue = fscanf (fp, "%d", &(Hdr->nVars));
  487. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.",
  488. failure);
  489. continue;
  490. }
  491. if (matchkeywd (buf, ".nsuppvars")) {
  492. retValue = fscanf (fp, "%d", &(Hdr->nsuppvars));
  493. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.",
  494. failure);
  495. continue;
  496. }
  497. if (matchkeywd (buf, ".orderedvarnames")) {
  498. Hdr->orderedVarNames = DddmpStrArrayRead (fp, Hdr->nVars);
  499. Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames==NULL,
  500. "Error allocating memory.", failure);
  501. continue;
  502. }
  503. if (matchkeywd (buf, ".suppvarnames")) {
  504. Hdr->suppVarNames = DddmpStrArrayRead (fp, Hdr->nsuppvars);
  505. Dddmp_CheckAndGotoLabel (Hdr->suppVarNames==NULL,
  506. "Error allocating memory.", failure);
  507. continue;
  508. }
  509. if matchkeywd (buf, ".ids") {
  510. Hdr->ids = DddmpIntArrayRead(fp,Hdr->nsuppvars);
  511. Dddmp_CheckAndGotoLabel (Hdr->ids==NULL,
  512. "Error allocating memory.", failure);
  513. continue;
  514. }
  515. if (matchkeywd (buf, ".permids")) {
  516. Hdr->permids = DddmpIntArrayRead(fp,Hdr->nsuppvars);
  517. Dddmp_CheckAndGotoLabel (Hdr->permids==NULL,
  518. "Error allocating memory.", failure);
  519. continue;
  520. }
  521. if (matchkeywd (buf, ".auxids")) {
  522. Hdr->auxids = DddmpIntArrayRead(fp,Hdr->nsuppvars);
  523. Dddmp_CheckAndGotoLabel (Hdr->auxids==NULL,
  524. "Error allocating memory.", failure);
  525. continue;
  526. }
  527. if (matchkeywd (buf, ".cnfids")) {
  528. Hdr->cnfids = DddmpIntArrayRead (fp, Hdr->nsuppvars);
  529. Dddmp_CheckAndGotoLabel (Hdr->cnfids==NULL,
  530. "Error allocating memory.", failure);
  531. continue;
  532. }
  533. if (matchkeywd (buf, ".nroots")) {
  534. retValue = fscanf (fp, "%d", &(Hdr->nRoots));
  535. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.",
  536. failure);
  537. continue;
  538. }
  539. if (matchkeywd (buf, ".rootids")) {
  540. Hdr->rootids = DddmpIntArrayRead(fp,Hdr->nRoots);
  541. Dddmp_CheckAndGotoLabel (Hdr->rootids==NULL,
  542. "Error allocating memory.", failure);
  543. continue;
  544. }
  545. if (matchkeywd (buf, ".rootnames")) {
  546. Hdr->rootnames = DddmpStrArrayRead(fp,Hdr->nRoots);
  547. Dddmp_CheckAndGotoLabel (Hdr->rootnames==NULL,
  548. "Error allocating memory.", failure);
  549. continue;
  550. }
  551. if (matchkeywd (buf, ".nAddedCnfVar")) {
  552. retValue = fscanf (fp, "%d", &(Hdr->nAddedCnfVar));
  553. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.",
  554. failure);
  555. continue;
  556. }
  557. }
  558. /* END HEADER */
  559. return (Hdr);
  560. failure:
  561. if (fileToClose == 1) {
  562. fclose (fp);
  563. }
  564. DddmpFreeHeaderCnf (Hdr);
  565. return (NULL);
  566. }
  567. /**Function********************************************************************
  568. Synopsis [Frees the internal header structure.]
  569. Description [Frees the internal header structure by freeing all internal
  570. fields first.
  571. ]
  572. SideEffects []
  573. SeeAlso []
  574. ******************************************************************************/
  575. static void
  576. DddmpFreeHeaderCnf (
  577. Dddmp_Hdr_t *Hdr /* IN: pointer to header */
  578. )
  579. {
  580. if (Hdr==NULL) {
  581. return;
  582. }
  583. DDDMP_FREE (Hdr->ver);
  584. DDDMP_FREE (Hdr->dd);
  585. DddmpStrArrayFree (Hdr->orderedVarNames, Hdr->nVars);
  586. DddmpStrArrayFree (Hdr->suppVarNames, Hdr->nsuppvars);
  587. DDDMP_FREE (Hdr->ids);
  588. DDDMP_FREE (Hdr->permids);
  589. DDDMP_FREE (Hdr->auxids);
  590. DDDMP_FREE (Hdr->cnfids);
  591. DDDMP_FREE (Hdr->rootids);
  592. DddmpStrArrayFree (Hdr->rootnames, Hdr->nRoots);
  593. DDDMP_FREE (Hdr);
  594. return;
  595. }
  596. /**Function********************************************************************
  597. Synopsis [Read the CNF clauses from the file in the standard DIMACS
  598. format.
  599. ]
  600. Description [Read the CNF clauses from the file in the standard DIMACS
  601. format. Store all the clauses in an internal structure for
  602. future transformation into BDDs.
  603. ]
  604. SideEffects []
  605. SeeAlso []
  606. ******************************************************************************/
  607. static int
  608. DddmpReadCnfClauses (
  609. Dddmp_Hdr_t *Hdr /* IN: file header */,
  610. int ***cnfTable /* OUT: CNF table for clauses */,
  611. FILE *fp /* IN: source file */
  612. )
  613. {
  614. char word[DDDMP_MAX_CNF_ROW_LENGTH];
  615. int i, j, var;
  616. int **cnfTableLocal = NULL;
  617. int *clause = NULL;
  618. char *fgetsRet;
  619. cnfTableLocal = DDDMP_ALLOC (int *, Hdr->nClausesCnf);
  620. clause = DDDMP_ALLOC (int, 2*Hdr->nVarsCnf+1);
  621. for (i=0; i<Hdr->nClausesCnf; i++) {
  622. cnfTableLocal[i] = NULL;
  623. }
  624. for (i=0; i<=2*Hdr->nVarsCnf; i++) {
  625. clause[i] = 0;
  626. }
  627. i = j = 0;
  628. do {
  629. if (fscanf(fp, "%s", word)==EOF) {
  630. if (j>0) {
  631. /* force last zero */
  632. strcpy(word,"0");
  633. }
  634. else break;
  635. }
  636. /* Check for Comment */
  637. if (word[0] == 'c') {
  638. /* Comment Found: Skip line */
  639. fgetsRet = fgets (word, DDDMP_MAX_CNF_ROW_LENGTH-1, fp);
  640. if (!fgetsRet) return (DDDMP_FAILURE);
  641. break;
  642. }
  643. var = atoi (word);
  644. Dddmp_Assert ((var>=(-Hdr->nVarsCnf))&&(var<=Hdr->nVarsCnf),
  645. "Wrong num found");
  646. clause[j++] = var;
  647. if (var == 0) {
  648. cnfTableLocal[i] = DDDMP_ALLOC (int, j);
  649. while (--j >=0) {
  650. cnfTableLocal[i][j] = clause[j];
  651. }
  652. i++;
  653. j=0;
  654. }
  655. } while (!feof(fp));
  656. Dddmp_Assert (i==Hdr->nClausesCnf,
  657. "Wrong number of clauses in file");
  658. #if DDDMP_DEBUG_CNF
  659. for (i=0; i<Hdr->nClausesCnf; i++) {
  660. fprintf (stdout, "[%4d] ", i);
  661. j=0;
  662. while ((var = cnfTableLocal[i][j++]) != 0) {
  663. fprintf (stdout, "%d ", var);
  664. }
  665. fprintf (stdout, "0\n");
  666. }
  667. #endif
  668. DDDMP_FREE (clause);
  669. *cnfTable = cnfTableLocal;
  670. return (DDDMP_SUCCESS);
  671. }
  672. /**Function********************************************************************
  673. Synopsis [Transforms CNF clauses into BDDs.]
  674. Description [Transforms CNF clauses into BDDs. Clauses are stored in an
  675. internal structure previously read. The results can be given in
  676. different format according to the mode selection:
  677. IFF mode == 0 Return the Clauses without Conjunction
  678. IFF mode == 1 Return the sets of BDDs without Quantification
  679. IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification
  680. ]
  681. SideEffects []
  682. SeeAlso []
  683. ******************************************************************************/
  684. static int
  685. DddmpCnfClauses2Bdd (
  686. Dddmp_Hdr_t *Hdr /* IN: file header */,
  687. DdManager *ddMgr /* IN: DD Manager */,
  688. int **cnfTable /* IN: CNF table for clauses */,
  689. int mode /* IN: computation mode */,
  690. DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots (by reference) */
  691. )
  692. {
  693. DdNode **rel = NULL;
  694. DdNode *lit = NULL;
  695. DdNode *tmp1 = NULL;
  696. DdNode *tmp2 = NULL;
  697. DdNode **rootsPtr = NULL;
  698. DdNode *cubeAllVar = NULL;
  699. DdNode *cubeBddVar = NULL;
  700. DdNode *cubeCnfVar = NULL;
  701. int i, j, k, n, var1, var2, fromLine, toLine;
  702. rootsPtr = NULL;
  703. *rootsPtrPtr = NULL;
  704. /*-------------------------- Read The Clauses -----------------------------*/
  705. rel = DDDMP_ALLOC (DdNode *, Hdr->nClausesCnf);
  706. cubeBddVar = Cudd_ReadOne (ddMgr);
  707. cubeCnfVar = Cudd_ReadOne (ddMgr);
  708. cubeAllVar = Cudd_ReadOne (ddMgr);
  709. Cudd_Ref (cubeBddVar);
  710. Cudd_Ref (cubeCnfVar);
  711. Cudd_Ref (cubeAllVar);
  712. for (i=0; i<Hdr->nClausesCnf; i++) {
  713. rel[i] = Cudd_Not (Cudd_ReadOne (ddMgr));
  714. Cudd_Ref (rel[i]);
  715. j=0;
  716. while ((var1 = cnfTable[i][j++]) != 0) {
  717. /* Deal with the Literal */
  718. var2 = abs (var1);
  719. n = (-1);
  720. for (k=0; k<Hdr->nsuppvars; k++) {
  721. if (Hdr->cnfids[k] == var2) {
  722. n = k;
  723. break;
  724. }
  725. }
  726. if (n == (-1)) {
  727. lit = Cudd_bddIthVar (ddMgr, var2);
  728. /* Create the cubes of CNF Variables */
  729. tmp1 = Cudd_bddAnd (ddMgr, cubeCnfVar, lit);
  730. Cudd_Ref (tmp1);
  731. Cudd_RecursiveDeref (ddMgr, cubeCnfVar);
  732. cubeCnfVar = tmp1;
  733. } else {
  734. lit = Cudd_bddIthVar (ddMgr, Hdr->ids[n]);
  735. /* Create the cubes of BDD Variables */
  736. tmp1 = Cudd_bddAnd (ddMgr, cubeBddVar, lit);
  737. Cudd_Ref (tmp1);
  738. Cudd_RecursiveDeref (ddMgr, cubeBddVar);
  739. cubeBddVar = tmp1;
  740. }
  741. /* Create the cubes of ALL Variables */
  742. tmp1 = Cudd_bddAnd (ddMgr, cubeAllVar, lit);
  743. Cudd_Ref (tmp1);
  744. Cudd_RecursiveDeref (ddMgr, cubeAllVar);
  745. cubeAllVar = tmp1;
  746. /* Deal with Relations */
  747. if (var1<0) {
  748. lit = Cudd_Not (lit);
  749. }
  750. tmp1 = Cudd_bddOr (ddMgr, rel[i], lit);
  751. Cudd_Ref (tmp1);
  752. Cudd_RecursiveDeref (ddMgr, rel[i]);
  753. rel[i] = tmp1;
  754. }
  755. }
  756. /*
  757. * Mode == 0 Return the Clauses without Conjunction
  758. */
  759. if (mode == 0) {
  760. return (DDDMP_SUCCESS);
  761. }
  762. rootsPtr = DDDMP_ALLOC (DdNode *, Hdr->nRoots);
  763. Dddmp_CheckAndGotoLabel (rootsPtr==NULL, "Error allocating memory.",
  764. failure);
  765. for (i=0; i<Hdr->nRoots; i++) {
  766. if (i == (Hdr->nRoots-1)) {
  767. fromLine = Hdr->rootids[i] - 1;
  768. toLine = Hdr->nClausesCnf;
  769. } else {
  770. fromLine = Hdr->rootids[i] - 1;
  771. toLine = Hdr->rootids[i+1];
  772. }
  773. tmp1 = Cudd_ReadOne (ddMgr);
  774. Cudd_Ref (tmp1);
  775. for (j=fromLine; j<toLine; j++) {
  776. tmp2 = Cudd_bddAnd (ddMgr, rel[j], tmp1);
  777. Cudd_Ref (tmp2);
  778. Cudd_RecursiveDeref (ddMgr, tmp1);
  779. Cudd_RecursiveDeref (ddMgr, rel[j]);
  780. tmp1 = tmp2;
  781. }
  782. rootsPtr[i] = tmp1;
  783. }
  784. DDDMP_FREE (rel);
  785. /*
  786. * Mode == 1 Return the sets of BDDs without Quantification
  787. */
  788. if (mode == 1) {
  789. *rootsPtrPtr = rootsPtr;
  790. return (DDDMP_SUCCESS);
  791. }
  792. /*
  793. * Mode == 2 Return the sets of BDDs AFTER Existential Quantification
  794. */
  795. #if DDDMP_DEBUG_CNF
  796. cubeBddVar = Cudd_ReadOne (ddMgr);
  797. Cudd_Ref (cubeBddVar);
  798. for (i=0; i<Hdr->nsuppvars; i++) {
  799. lit = Cudd_bddIthVar (ddMgr, Hdr->ids[i]);
  800. tmp1 = Cudd_bddAnd (ddMgr, cubeBddVar, lit);
  801. Cudd_Ref (tmp1);
  802. Cudd_RecursiveDeref (ddMgr, cubeBddVar);
  803. cubeBddVar = tmp1;
  804. }
  805. cubeCnfVar = Cudd_bddExistAbstract (ddMgr, cubeAllVar, cubeBddVar);
  806. #endif
  807. for (i=0; i<Hdr->nRoots; i++) {
  808. #if DDDMP_DEBUG_CNF
  809. fprintf (stdout, "rootsPtr Before Exist:\n");
  810. Cudd_PrintDebug (ddMgr, rootsPtr[i], 0, 3);
  811. #endif
  812. tmp1 = Cudd_bddExistAbstract (ddMgr, rootsPtr[i], cubeCnfVar);
  813. Cudd_RecursiveDeref (ddMgr, rootsPtr[i]);
  814. rootsPtr[i] = tmp1;
  815. #if DDDMP_DEBUG_CNF
  816. fprintf (stdout, "rootsPtr After Exist:\n");
  817. Cudd_PrintDebug (ddMgr, rootsPtr[i], 0, 3);
  818. #endif
  819. }
  820. #if DDDMP_DEBUG_CNF
  821. fprintf (stdout, "cubeAllVar:\n");
  822. Cudd_PrintDebug (ddMgr, cubeAllVar, 0, 3);
  823. fprintf (stdout, "cubeBddVar:\n");
  824. Cudd_PrintDebug (ddMgr, cubeBddVar, 0, 3);
  825. fprintf (stdout, "cubeCnfVar:\n");
  826. Cudd_PrintDebug (ddMgr, cubeCnfVar, 0, 3);
  827. #endif
  828. Cudd_RecursiveDeref (ddMgr, cubeAllVar);
  829. Cudd_RecursiveDeref (ddMgr, cubeBddVar);
  830. Cudd_RecursiveDeref (ddMgr, cubeCnfVar);
  831. *rootsPtrPtr = rootsPtr;
  832. return (DDDMP_SUCCESS);
  833. /*
  834. * Failure Condition
  835. */
  836. failure:
  837. DDDMP_FREE (rel);
  838. DDDMP_FREE (rootsPtrPtr);
  839. return (DDDMP_FAILURE);
  840. }