emergency commit
[cl-cudd.git] / distr / dddmp / dddmpNodeCnf.c
blobfa61ace695318c1811be5706db2bca68603f6ee2
1 /**CFile**********************************************************************
3 FileName [dddmpNodeCnf.c]
5 PackageName [dddmp]
7 Synopsis [Functions to handle BDD node infos and numbering
8 while storing a CNF formula from a BDD or an array of BDDs]
10 Description [Functions to handle BDD node infos and numbering
11 while storing a CNF formula from a BDD or an array of BDDs.
14 Author [Gianpiero Cabodi and Stefano Quer]
16 Copyright [
17 Copyright (c) 2004 by Politecnico di Torino.
18 All Rights Reserved. This software is for educational purposes only.
19 Permission is given to academic institutions to use, copy, and modify
20 this software and its documentation provided that this introductory
21 message is not removed, that this software and its documentation is
22 used for the institutions' internal research and educational purposes,
23 and that no monies are exchanged. No guarantee is expressed or implied
24 by the distribution of this code.
25 Send bug-reports and/or questions to:
26 {gianpiero.cabodi,stefano.quer}@polito.it.
29 ******************************************************************************/
31 #include "dddmpInt.h"
33 /*---------------------------------------------------------------------------*/
34 /* Stucture declarations */
35 /*---------------------------------------------------------------------------*/
37 /*---------------------------------------------------------------------------*/
38 /* Type declarations */
39 /*---------------------------------------------------------------------------*/
41 /*---------------------------------------------------------------------------*/
42 /* Variable declarations */
43 /*---------------------------------------------------------------------------*/
45 #define DDDMP_DEBUG_CNF 0
47 /*---------------------------------------------------------------------------*/
48 /* Macro declarations */
49 /*---------------------------------------------------------------------------*/
51 /**AutomaticStart*************************************************************/
53 /*---------------------------------------------------------------------------*/
54 /* Static function prototypes */
55 /*---------------------------------------------------------------------------*/
57 static int DddmpWriteNodeIndexCnfWithTerminalCheck(DdNode *f, int *cnfIds, int id);
58 static int DddmpClearVisitedCnfRecur(DdNode *f);
59 static void DddmpClearVisitedCnf(DdNode *f);
60 static int NumberNodeRecurCnf(DdNode *f, int *cnfIds, int id);
61 static void DddmpDdNodesCheckIncomingAndScanPath(DdNode *f, int pathLengthCurrent, int edgeInTh, int pathLengthTh);
62 static int DddmpDdNodesNumberEdgesRecur(DdNode *f, int *cnfIds, int id);
63 static int DddmpDdNodesResetCountRecur(DdNode *f);
64 static int DddmpDdNodesCountEdgesRecur(DdNode *f);
65 static void RemoveFromUniqueRecurCnf(DdManager *ddMgr, DdNode *f);
66 static void RestoreInUniqueRecurCnf(DdManager *ddMgr, DdNode *f);
67 static int DddmpPrintBddAndNextRecur(DdManager *ddMgr, DdNode *f);
69 /**AutomaticEnd***************************************************************/
71 /*---------------------------------------------------------------------------*/
72 /* Definition of exported functions */
73 /*---------------------------------------------------------------------------*/
75 /*---------------------------------------------------------------------------*/
76 /* Definition of internal functions */
77 /*---------------------------------------------------------------------------*/
79 /**Function********************************************************************
81 Synopsis [Removes nodes from unique table and numbers them]
83 Description [Node numbering is required to convert pointers to integers.
84 Since nodes are removed from unique table, no new nodes should
85 be generated before re-inserting nodes in the unique table
86 (DddmpUnnumberDdNodesCnf()).
89 SideEffects [Nodes are temporarily removed from unique table]
91 SeeAlso [RemoveFromUniqueRecurCnf(), NumberNodeRecurCnf(),
92 DddmpUnnumberDdNodesCnf()]
94 ******************************************************************************/
96 int
97 DddmpNumberDdNodesCnf (
98 DdManager *ddMgr /* IN: DD Manager */,
99 DdNode **f /* IN: array of BDDs */,
100 int rootN /* IN: number of BDD roots in the array of BDDs */,
101 int *cnfIds /* OUT: CNF identifiers for variables */,
102 int id /* OUT: number of Temporary Variables Introduced */
105 int i;
107 for (i=0; i<rootN; i++) {
108 RemoveFromUniqueRecurCnf (ddMgr, f[i]);
111 for (i=0; i<rootN; i++) {
112 id = NumberNodeRecurCnf (f[i], cnfIds, id);
115 return (id);
118 /**Function********************************************************************
120 Synopsis [Removes nodes from unique table and numbers each node according
121 to the number of its incoming BDD edges.
124 Description [Removes nodes from unique table and numbers each node according
125 to the number of its incoming BDD edges.
128 SideEffects [Nodes are temporarily removed from unique table]
130 SeeAlso [RemoveFromUniqueRecurCnf()]
132 ******************************************************************************/
135 DddmpDdNodesCountEdgesAndNumber (
136 DdManager *ddMgr /* IN: DD Manager */,
137 DdNode **f /* IN: Array of BDDs */,
138 int rootN /* IN: Number of BDD roots in the array of BDDs */,
139 int edgeInTh /* IN: Max # In-Edges, after a Insert Cut Point */,
140 int pathLengthTh /* IN: Max Path Length (after, Insert a Cut Point) */,
141 int *cnfIds /* OUT: CNF identifiers for variables */,
142 int id /* OUT: Number of Temporary Variables Introduced */
145 int retValue, i;
147 /*-------------------------- Remove From Unique ---------------------------*/
149 for (i=0; i<rootN; i++) {
150 RemoveFromUniqueRecurCnf (ddMgr, f[i]);
153 /*-------------------- Reset Counter and Reset Visited --------------------*/
155 for (i=0; i<rootN; i++) {
156 retValue = DddmpDdNodesResetCountRecur (f[i]);
159 /* Here we must have:
160 * cnfIndex = 0
161 * visitedFlag = 0
162 * FOR ALL nodes
165 #if DDDMP_DEBUG_CNF
166 fprintf (stdout, "###---> BDDs After Count Reset:\n");
167 DddmpPrintBddAndNext (ddMgr, f, rootN);
168 #endif
170 /*----------------------- Count Incoming Edges ----------------------------*/
172 for (i=0; i<rootN; i++) {
173 retValue = DddmpDdNodesCountEdgesRecur (f[i]);
176 /* Here we must have:
177 * cnfIndex = incoming edge count
178 * visitedFlag = 0 (AGAIN ... remains untouched)
179 * FOR ALL nodes
182 #if DDDMP_DEBUG_CNF
183 fprintf (stdout, "###---> BDDs After Count Recur:\n");
184 DddmpPrintBddAndNext (ddMgr, f, rootN);
185 #endif
187 /*------------------------- Count Path Length ----------------------------*/
189 for (i=0; i<rootN; i++) {
190 DddmpDdNodesCheckIncomingAndScanPath (f[i], 0, edgeInTh,
191 pathLengthTh);
194 /* Here we must have:
195 * cnfIndex = 1 if we want to insert there a cut point
196 * 0 if we do NOT want to insert there a cut point
197 * visitedFlag = 1
198 * FOR ALL nodes
201 #if DDDMP_DEBUG_CNF
202 fprintf (stdout, "###---> BDDs After Check Incoming And Scan Path:\n");
203 DddmpPrintBddAndNext (ddMgr, f, rootN);
204 #endif
206 /*-------------------- Number Nodes and Set Visited -----------------------*/
208 for (i=0; i<rootN; i++) {
209 id = DddmpDdNodesNumberEdgesRecur (f[i], cnfIds, id);
212 /* Here we must have:
213 * cnfIndex = CNF auxiliary variable enumeration
214 * visitedFlag = 0
215 * FOR ALL nodes
218 #if DDDMP_DEBUG_CNF
219 fprintf (stdout, "###---> BDDs After Count Edges Recur:\n");
220 DddmpPrintBddAndNext (ddMgr, f, rootN);
221 #endif
223 return (id);
226 /**Function********************************************************************
228 Synopsis [Restores nodes in unique table, loosing numbering]
230 Description [Node indexes are no more needed. Nodes are re-linked in the
231 unique table.
234 SideEffects [None]
236 SeeAlso [DddmpNumberDdNode()]
238 ******************************************************************************/
240 void
241 DddmpUnnumberDdNodesCnf(
242 DdManager *ddMgr /* IN: DD Manager */,
243 DdNode **f /* IN: array of BDDs */,
244 int rootN /* IN: number of BDD roots in the array of BDDs */
247 int i;
249 for (i=0; i<rootN; i++) {
250 RestoreInUniqueRecurCnf (ddMgr, f[i]);
253 return;
256 /**Function********************************************************************
258 Synopsis [Prints debug information]
260 Description [Prints debug information for an array of BDDs on the screen]
262 SideEffects [None]
264 SeeAlso []
266 ******************************************************************************/
269 DddmpPrintBddAndNext (
270 DdManager *ddMgr /* IN: DD Manager */,
271 DdNode **f /* IN: Array of BDDs to be displayed */,
272 int rootN /* IN: Number of BDD roots in the array of BDDs */
275 int i;
277 for (i=0; i<rootN; i++) {
278 fprintf (stdout, "---> Bdd %d:\n", i);
279 fflush (stdout);
280 DddmpPrintBddAndNextRecur (ddMgr, f[i]);
283 return (DDDMP_SUCCESS);
286 /**Function********************************************************************
288 Synopsis [Write index to node]
290 Description [The index of the node is written in the "next" field of
291 a DdNode struct. LSB is not used (set to 0). It is used as
292 "visited" flag in DD traversals.
295 SideEffects [None]
297 SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (),
298 DddmpVisitedCnf ()
301 ******************************************************************************/
304 DddmpWriteNodeIndexCnf (
305 DdNode *f /* IN: BDD node */,
306 int id /* IN: index to be written */
309 if (!Cudd_IsConstant (f)) {
310 f->next = (struct DdNode *)((ptruint)((id)<<1));
313 return (DDDMP_SUCCESS);
316 /**Function********************************************************************
318 Synopsis [Returns true if node is visited]
320 Description [Returns true if node is visited]
322 SideEffects [None]
324 SeeAlso [DddmpSetVisitedCnf (), DddmpClearVisitedCnf ()]
326 ******************************************************************************/
329 DddmpVisitedCnf (
330 DdNode *f /* IN: BDD node to be tested */
333 f = Cudd_Regular(f);
335 return ((int)((ptruint)(f->next)) & (01));
338 /**Function********************************************************************
340 Synopsis [Marks a node as visited]
342 Description [Marks a node as visited]
344 SideEffects [None]
346 SeeAlso [DddmpVisitedCnf (), DddmpClearVisitedCnf ()]
348 ******************************************************************************/
350 void
351 DddmpSetVisitedCnf (
352 DdNode *f /* IN: BDD node to be marked (as visited) */
355 f = Cudd_Regular(f);
357 f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01);
359 return;
362 /**Function********************************************************************
364 Synopsis [Reads the index of a node]
366 Description [Reads the index of a node. LSB is skipped (used as visited
367 flag).
370 SideEffects [None]
372 SeeAlso [DddmpWriteNodeIndexCnf(), DddmpSetVisitedCnf (),
373 DddmpVisitedCnf ()]
375 ******************************************************************************/
378 DddmpReadNodeIndexCnf (
379 DdNode *f /* IN: BDD node */
382 if (!Cudd_IsConstant (f)) {
383 return ((int)(((ptruint)(f->next))>>1));
384 } else {
385 return (1);
389 /*---------------------------------------------------------------------------*/
390 /* Definition of static functions */
391 /*---------------------------------------------------------------------------*/
393 /**Function********************************************************************
395 Synopsis [Write index to node]
397 Description [The index of the node is written in the "next" field of
398 a DdNode struct. LSB is not used (set to 0). It is used as
399 "visited" flag in DD traversals. The index corresponds to
400 the BDD node variable if both the node's children are a
401 constant node, otherwise a new CNF variable is used.
404 SideEffects [None]
406 SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (),
407 DddmpVisitedCnf ()]
409 *****************************************************************************/
411 static int
412 DddmpWriteNodeIndexCnfWithTerminalCheck (
413 DdNode *f /* IN: BDD node */,
414 int *cnfIds /* IN: possible source for the index to be written */,
415 int id /* IN: possible source for the index to be written */
418 if (!Cudd_IsConstant (f)) {
419 if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) {
420 /* If Variable SET ID as Variable ID */
421 f->next = (struct DdNode *)((ptruint)((cnfIds[f->index])<<1));
422 } else {
423 f->next = (struct DdNode *)((ptruint)((id)<<1));
424 id++;
428 return(id);
431 /**Function********************************************************************
433 Synopsis [Mark ALL nodes as not visited]
435 Description [Mark ALL nodes as not visited (it recurs on the node children)]
437 SideEffects [None]
439 SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()]
441 ******************************************************************************/
443 static int
444 DddmpClearVisitedCnfRecur (
445 DdNode *f /* IN: root of the BDD to be marked */
448 int retValue;
450 f = Cudd_Regular(f);
452 if (cuddIsConstant (f)) {
453 return (DDDMP_SUCCESS);
456 if (!DddmpVisitedCnf (f)) {
457 return (DDDMP_SUCCESS);
460 retValue = DddmpClearVisitedCnfRecur (cuddT (f));
461 retValue = DddmpClearVisitedCnfRecur (cuddE (f));
463 DddmpClearVisitedCnf (f);
465 return (DDDMP_SUCCESS);
468 /**Function********************************************************************
470 Synopsis [Marks a node as not visited]
472 Description [Marks a node as not visited]
474 SideEffects [None]
476 SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()]
478 ******************************************************************************/
480 static void
481 DddmpClearVisitedCnf (
482 DdNode *f /* IN: BDD node to be marked (as not visited) */
485 f = Cudd_Regular (f);
487 f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01));
489 return;
492 /**Function********************************************************************
494 Synopsis [Number nodes recursively in post-order]
496 Description [Number nodes recursively in post-order.
497 The "visited" flag is used with inverse polarity, because all nodes
498 were set "visited" when removing them from unique.
501 SideEffects ["visited" flags are reset.]
503 SeeAlso []
505 ******************************************************************************/
507 static int
508 NumberNodeRecurCnf(
509 DdNode *f /* IN: root of the BDD to be numbered */,
510 int *cnfIds /* IN: possible source for numbering */,
511 int id /* IN/OUT: possible source for numbering */
514 f = Cudd_Regular(f);
516 if (!DddmpVisitedCnf (f)) {
517 return (id);
520 if (!cuddIsConstant (f)) {
521 id = NumberNodeRecurCnf (cuddT (f), cnfIds, id);
522 id = NumberNodeRecurCnf (cuddE (f), cnfIds, id);
525 id = DddmpWriteNodeIndexCnfWithTerminalCheck (f, cnfIds, id);
526 DddmpClearVisitedCnf (f);
528 return (id);
531 /**Function********************************************************************
533 Synopsis [Number nodes recursively in post-order]
535 Description [Number nodes recursively in post-order.
536 The "visited" flag is used with the right polarity.
537 The node is assigned to a new CNF variable only if it is a "shared"
538 node (i.e. the number of its incoming edges is greater than 1).
541 SideEffects ["visited" flags are set.]
543 SeeAlso []
545 ******************************************************************************/
547 static void
548 DddmpDdNodesCheckIncomingAndScanPath (
549 DdNode *f /* IN: BDD node to be numbered */,
550 int pathLengthCurrent /* IN: Current Path Length */,
551 int edgeInTh /* IN: Max # In-Edges, after a Insert Cut Point */,
552 int pathLengthTh /* IN: Max Path Length (after, Insert a Cut Point) */
555 int retValue;
557 f = Cudd_Regular(f);
559 if (DddmpVisitedCnf (f)) {
560 return;
563 if (cuddIsConstant (f)) {
564 return;
567 pathLengthCurrent++;
568 retValue = DddmpReadNodeIndexCnf (f);
570 if ( ((edgeInTh >= 0) && (retValue > edgeInTh)) ||
571 ((pathLengthTh >= 0) && (pathLengthCurrent > pathLengthTh))
573 DddmpWriteNodeIndexCnf (f, 1);
574 pathLengthCurrent = 0;
575 } else {
576 DddmpWriteNodeIndexCnf (f, 0);
579 DddmpDdNodesCheckIncomingAndScanPath (cuddT (f), pathLengthCurrent,
580 edgeInTh, pathLengthTh);
581 DddmpDdNodesCheckIncomingAndScanPath (cuddE (f), pathLengthCurrent,
582 edgeInTh, pathLengthTh);
584 DddmpSetVisitedCnf (f);
586 return;
589 /**Function********************************************************************
591 Synopsis [Number nodes recursively in post-order]
593 Description [Number nodes recursively in post-order.
594 The "visited" flag is used with the inverse polarity.
595 Numbering follows the subsequent strategy:
596 * if the index = 0 it remains so
597 * if the index >= 1 it gets enumerated.
598 This implies that the node is assigned to a new CNF variable only if
599 it is not a terminal node otherwise it is assigned the index of
600 the BDD variable.
603 SideEffects ["visited" flags are reset.]
605 SeeAlso []
607 ******************************************************************************/
609 static int
610 DddmpDdNodesNumberEdgesRecur (
611 DdNode *f /* IN: BDD node to be numbered */,
612 int *cnfIds /* IN: possible source for numbering */,
613 int id /* IN/OUT: possible source for numbering */
616 int retValue;
618 f = Cudd_Regular(f);
620 if (!DddmpVisitedCnf (f)) {
621 return (id);
624 if (cuddIsConstant (f)) {
625 return (id);
628 id = DddmpDdNodesNumberEdgesRecur (cuddT (f), cnfIds, id);
629 id = DddmpDdNodesNumberEdgesRecur (cuddE (f), cnfIds, id);
631 retValue = DddmpReadNodeIndexCnf (f);
632 if (retValue >= 1) {
633 id = DddmpWriteNodeIndexCnfWithTerminalCheck (f, cnfIds, id);
634 } else {
635 DddmpWriteNodeIndexCnf (f, 0);
638 DddmpClearVisitedCnf (f);
640 return (id);
643 /**Function********************************************************************
645 Synopsis [Resets counter and visited flag for ALL nodes of a BDD]
647 Description [Resets counter and visited flag for ALL nodes of a BDD (it
648 recurs on the node children). The index field of the node is
649 used as counter.
652 SideEffects []
654 SeeAlso []
656 ******************************************************************************/
658 static int
659 DddmpDdNodesResetCountRecur (
660 DdNode *f /* IN: root of the BDD whose counters are reset */
663 int retValue;
665 f = Cudd_Regular (f);
667 if (!DddmpVisitedCnf (f)) {
668 return (DDDMP_SUCCESS);
671 if (!cuddIsConstant (f)) {
672 retValue = DddmpDdNodesResetCountRecur (cuddT (f));
673 retValue = DddmpDdNodesResetCountRecur (cuddE (f));
676 DddmpWriteNodeIndexCnf (f, 0);
677 DddmpClearVisitedCnf (f);
679 return (DDDMP_SUCCESS);
682 /**Function********************************************************************
684 Synopsis [Counts the number of incoming edges for each node of a BDD]
686 Description [Counts (recursively) the number of incoming edges for each
687 node of a BDD. This number is stored in the index field.
690 SideEffects ["visited" flags remain untouched.]
692 SeeAlso []
694 ******************************************************************************/
696 static int
697 DddmpDdNodesCountEdgesRecur (
698 DdNode *f /* IN: root of the BDD */
701 int indexValue, retValue;
703 f = Cudd_Regular (f);
705 if (cuddIsConstant (f)) {
706 return (DDDMP_SUCCESS);
709 if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) {
710 return (DDDMP_SUCCESS);
713 indexValue = DddmpReadNodeIndexCnf (f);
715 /* IF (first time) THEN recur */
716 if (indexValue == 0) {
717 retValue = DddmpDdNodesCountEdgesRecur (cuddT (f));
718 retValue = DddmpDdNodesCountEdgesRecur (cuddE (f));
721 /* Increment Incoming-Edge Count Flag */
722 indexValue++;
723 DddmpWriteNodeIndexCnf (f, indexValue);
725 return (DDDMP_SUCCESS);
728 /**Function********************************************************************
730 Synopsis [Removes a node from unique table]
732 Description [Removes a node from the unique table by locating the proper
733 subtable and unlinking the node from it. It recurs on on the
734 children of the node. Constants remain untouched.
737 SideEffects [Nodes are left with the "visited" flag true.]
739 SeeAlso [RestoreInUniqueRecurCnf()]
741 ******************************************************************************/
743 static void
744 RemoveFromUniqueRecurCnf (
745 DdManager *ddMgr /* IN: DD Manager */,
746 DdNode *f /* IN: root of the BDD to be extracted */
749 DdNode *node, *last, *next;
750 DdNode *sentinel = &(ddMgr->sentinel);
751 DdNodePtr *nodelist;
752 DdSubtable *subtable;
753 int pos, level;
755 f = Cudd_Regular (f);
757 if (DddmpVisitedCnf (f)) {
758 return;
761 if (!cuddIsConstant (f)) {
763 RemoveFromUniqueRecurCnf (ddMgr, cuddT (f));
764 RemoveFromUniqueRecurCnf (ddMgr, cuddE (f));
766 level = ddMgr->perm[f->index];
767 subtable = &(ddMgr->subtables[level]);
769 nodelist = subtable->nodelist;
771 pos = ddHash (cuddT (f), cuddE (f), subtable->shift);
772 node = nodelist[pos];
773 last = NULL;
774 while (node != sentinel) {
775 next = node->next;
776 if (node == f) {
777 if (last != NULL)
778 last->next = next;
779 else
780 nodelist[pos] = next;
781 break;
782 } else {
783 last = node;
784 node = next;
788 f->next = NULL;
792 DddmpSetVisitedCnf (f);
794 return;
797 /**Function********************************************************************
799 Synopsis [Restores a node in unique table]
801 Description [Restores a node in unique table (recursive)]
803 SideEffects [Nodes are not restored in the same order as before removal]
805 SeeAlso [RemoveFromUnique()]
807 ******************************************************************************/
809 static void
810 RestoreInUniqueRecurCnf (
811 DdManager *ddMgr /* IN: DD Manager */,
812 DdNode *f /* IN: root of the BDD to be restored */
815 DdNodePtr *nodelist;
816 DdNode *T, *E, *looking;
817 DdNodePtr *previousP;
818 DdSubtable *subtable;
819 int pos, level;
820 #ifdef DDDMP_DEBUG
821 DdNode *node;
822 DdNode *sentinel = &(ddMgr->sentinel);
823 #endif
825 f = Cudd_Regular(f);
827 if (!Cudd_IsComplement (f->next)) {
828 return;
831 if (cuddIsConstant (f)) {
832 /* StQ 11.02.2004:
833 Bug fixed --> restore NULL within the next field */
834 /*DddmpClearVisitedCnf (f);*/
835 f->next = NULL;
837 return;
840 RestoreInUniqueRecurCnf (ddMgr, cuddT (f));
841 RestoreInUniqueRecurCnf (ddMgr, cuddE (f));
843 level = ddMgr->perm[f->index];
844 subtable = &(ddMgr->subtables[level]);
846 nodelist = subtable->nodelist;
848 pos = ddHash (cuddT (f), cuddE (f), subtable->shift);
850 #ifdef DDDMP_DEBUG
851 /* verify uniqueness to avoid duplicate nodes in unique table */
852 for (node=nodelist[pos]; node != sentinel; node=node->next)
853 assert(node!=f);
854 #endif
856 T = cuddT (f);
857 E = cuddE (f);
858 previousP = &(nodelist[pos]);
859 looking = *previousP;
861 while (T < cuddT (looking)) {
862 previousP = &(looking->next);
863 looking = *previousP;
866 while (T == cuddT (looking) && E < cuddE (looking)) {
867 previousP = &(looking->next);
868 looking = *previousP;
870 f->next = *previousP;
871 *previousP = f;
873 return;
876 /**Function********************************************************************
878 Synopsis [Prints debug info]
880 Description [Prints debug info for a BDD on the screen. It recurs on
881 node's children.
884 SideEffects []
886 SeeAlso []
888 ******************************************************************************/
890 static int
891 DddmpPrintBddAndNextRecur (
892 DdManager *ddMgr /* IN: DD Manager */,
893 DdNode *f /* IN: root of the BDD to be displayed */
896 int retValue;
897 DdNode *fPtr, *tPtr, *ePtr;
899 fPtr = Cudd_Regular (f);
901 if (Cudd_IsComplement (f)) {
902 fprintf (stdout, "sign=- ptr=%ld ", ((long int) fPtr));
903 } else {
904 fprintf (stdout, "sign=+ ptr=%ld ", ((long int) fPtr));
907 if (cuddIsConstant (fPtr)) {
908 fprintf (stdout, "one\n");
909 fflush (stdout);
910 return (DDDMP_SUCCESS);
913 fprintf (stdout,
914 "thenPtr=%ld elsePtr=%ld BddId=%d CnfId=%d Visited=%d\n",
915 ((long int) cuddT (fPtr)), ((long int) cuddE (fPtr)),
916 fPtr->index, DddmpReadNodeIndexCnf (fPtr),
917 DddmpVisitedCnf (fPtr));
919 tPtr = cuddT (fPtr);
920 ePtr = cuddE (fPtr);
921 if (Cudd_IsComplement (f)) {
922 tPtr = Cudd_Not (tPtr);
923 ePtr = Cudd_Not (ePtr);
926 retValue = DddmpPrintBddAndNextRecur (ddMgr, tPtr);
927 retValue = DddmpPrintBddAndNextRecur (ddMgr, ePtr);
929 return (DDDMP_SUCCESS);