emergency commit
[cl-cudd.git] / distr / dddmp / dddmpDdNodeCnf.c
blob421d920e99df89f7293f1bcca01af6457a284eb7
1 /**CFile**********************************************************************
3 FileName [dddmpDdNodeCnf.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 DddmpWriteNodeIndexCnf(DdNode *f, int *cnfIds, int id);
58 static int DddmpReadNodeIndexCnf(DdNode *f);
59 static int DddmpClearVisitedCnfRecur(DdNode *f);
60 static int DddmpVisitedCnf(DdNode *f);
61 static void DddmpSetVisitedCnf(DdNode *f);
62 static void DddmpClearVisitedCnf(DdNode *f);
63 static int NumberNodeRecurCnf(DdNode *f, int *cnfIds, int id);
64 static void DddmpDdNodesCheckIncomingAndScanPath(DdNode *f, int pathLengthCurrent, int edgeInTh, int pathLengthTh);
65 static int DddmpDdNodesNumberEdgesRecur(DdNode *f, int *cnfIds, int id);
66 static int DddmpDdNodesResetCountRecur(DdNode *f);
67 static int DddmpDdNodesCountEdgesRecur(DdNode *f);
68 static void RemoveFromUniqueRecurCnf(DdManager *ddMgr, DdNode *f);
69 static void RestoreInUniqueRecurCnf(DdManager *ddMgr, DdNode *f);
70 static int DddmpPrintBddAndNextRecur(DdManager *ddMgr, DdNode *f);
72 /**AutomaticEnd***************************************************************/
74 /*---------------------------------------------------------------------------*/
75 /* Definition of exported functions */
76 /*---------------------------------------------------------------------------*/
78 /*---------------------------------------------------------------------------*/
79 /* Definition of internal functions */
80 /*---------------------------------------------------------------------------*/
82 /**Function********************************************************************
84 Synopsis [Removes nodes from unique table and numbers them]
86 Description [Node numbering is required to convert pointers to integers.
87 Since nodes are removed from unique table, no new nodes should
88 be generated before re-inserting nodes in the unique table
89 (DddmpUnnumberDdNodesCnf()).
92 SideEffects [Nodes are temporarily removed from unique table]
94 SeeAlso [RemoveFromUniqueRecurCnf(), NumberNodeRecurCnf(),
95 DddmpUnnumberDdNodesCnf()]
97 ******************************************************************************/
99 int
100 DddmpNumberDdNodesCnf (
101 DdManager *ddMgr /* IN: DD Manager */,
102 DdNode **f /* IN: array of BDDs */,
103 int rootN /* IN: number of BDD roots in the array of BDDs */,
104 int *cnfIds /* OUT: CNF identifiers for variables */,
105 int id /* OUT: number of Temporary Variables Introduced */
108 int i;
110 for (i=0; i<rootN; i++) {
111 RemoveFromUniqueRecurCnf (ddMgr, f[i]);
114 for (i=0; i<rootN; i++) {
115 id = NumberNodeRecurCnf (f[i], cnfIds, id);
118 return (id);
121 /**Function********************************************************************
123 Synopsis [Removes nodes from unique table and numbers each node according
124 to the number of its incoming BDD edges.
127 Description [Removes nodes from unique table and numbers each node according
128 to the number of its incoming BDD edges.
131 SideEffects [Nodes are temporarily removed from unique table]
133 SeeAlso [RemoveFromUniqueRecurCnf()]
135 ******************************************************************************/
138 DddmpDdNodesCountEdgesAndNumber (
139 DdManager *ddMgr /* IN: DD Manager */,
140 DdNode **f /* IN: Array of BDDs */,
141 int rootN /* IN: Number of BDD roots in the array of BDDs */,
142 int edgeInTh /* IN: Max # In-Edges, after a Insert Cut Point */,
143 int pathLengthTh /* IN: Max Path Length (after, Insert a Cut Point) */,
144 int *cnfIds /* OUT: CNF identifiers for variables */,
145 int id /* OUT: Number of Temporary Variables Introduced */
148 int retValue, i;
150 /*-------------------------- Remove From Unique ---------------------------*/
152 for (i=0; i<rootN; i++) {
153 RemoveFromUniqueRecurCnf (ddMgr, f[i]);
156 /*-------------------- Reset Counter and Reset Visited --------------------*/
158 for (i=0; i<rootN; i++) {
159 retValue = DddmpDdNodesResetCountRecur (f[i]);
162 /* Here we must have:
163 * cnfIndex = 0
164 * visitedFlag = 0
165 * FOR ALL nodes
168 #if DDDMP_DEBUG_CNF
169 fprintf (stdout, "###---> BDDs After Count Reset:\n");
170 DddmpPrintBddAndNext (ddMgr, f, rootN);
171 #endif
173 /*----------------------- Count Incoming Edges ----------------------------*/
175 for (i=0; i<rootN; i++) {
176 retValue = DddmpDdNodesCountEdgesRecur (f[i]);
179 /* Here we must have:
180 * cnfIndex = incoming edge count
181 * visitedFlag = 0 (AGAIN ... remains untouched)
182 * FOR ALL nodes
185 #if DDDMP_DEBUG_CNF
186 fprintf (stdout, "###---> BDDs After Count Recur:\n");
187 DddmpPrintBddAndNext (ddMgr, f, rootN);
188 #endif
190 /*------------------------- Count Path Length ----------------------------*/
192 for (i=0; i<rootN; i++) {
193 DddmpDdNodesCheckIncomingAndScanPath (f[i], 0, edgeInTh,
194 pathLengthTh);
197 /* Here we must have:
198 * cnfIndex = 1 if we want to insert there a cut point
199 * 0 if we do NOT want to insert there a cut point
200 * visitedFlag = 1
201 * FOR ALL nodes
204 #if DDDMP_DEBUG_CNF
205 fprintf (stdout, "###---> BDDs After Check Incoming And Scan Path:\n");
206 DddmpPrintBddAndNext (ddMgr, f, rootN);
207 #endif
209 /*-------------------- Number Nodes and Set Visited -----------------------*/
211 for (i=0; i<rootN; i++) {
212 id = DddmpDdNodesNumberEdgesRecur (f[i], cnfIds, id);
215 /* Here we must have:
216 * cnfIndex = CNF auxiliary variable enumeration
217 * visitedFlag = 0
218 * FOR ALL nodes
221 #if DDDMP_DEBUG_CNF
222 fprintf (stdout, "###---> BDDs After Count Edges Recur:\n");
223 DddmpPrintBddAndNext (ddMgr, f, rootN);
224 #endif
226 /*---------------------------- Clear Visited ------------------------------*/
228 #if DDDMP_DEBUG_CNF
229 for (i=0; i<rootN; i++) {
230 retValue = DddmpClearVisitedCnfRecur (f[i]);
233 #if DDDMP_DEBUG_CNF
234 fprintf (stdout, "###---> BDDs After All Numbering Process:\n");
235 DddmpPrintBddAndNext (ddMgr, f, rootN);
236 #endif
237 #endif
239 return (id);
242 /**Function********************************************************************
244 Synopsis [Restores nodes in unique table, loosing numbering]
246 Description [Node indexes are no more needed. Nodes are re-linked in the
247 unique table.
250 SideEffects [None]
252 SeeAlso [DddmpNumberDdNode()]
254 ******************************************************************************/
256 void
257 DddmpUnnumberDdNodesCnf(
258 DdManager *ddMgr /* IN: DD Manager */,
259 DdNode **f /* IN: array of BDDs */,
260 int rootN /* IN: number of BDD roots in the array of BDDs */
263 int i;
265 for (i=0; i<rootN; i++) {
266 RestoreInUniqueRecurCnf (ddMgr, f[i]);
269 return;
272 /**Function********************************************************************
274 Synopsis [Prints debug information]
276 Description [Prints debug information for an array of BDDs on the screen]
278 SideEffects [None]
280 SeeAlso []
282 ******************************************************************************/
285 DddmpPrintBddAndNext (
286 DdManager *ddMgr /* IN: DD Manager */,
287 DdNode **f /* IN: Array of BDDs to be displayed */,
288 int rootN /* IN: Number of BDD roots in the array of BDDs */
291 int i;
293 for (i=0; i<rootN; i++) {
294 fprintf (stdout, "---> Bdd %d:\n", i);
295 fflush (stdout);
296 DddmpPrintBddAndNextRecur (ddMgr, f[i]);
299 return (DDDMP_SUCCESS);
302 /**Function********************************************************************
304 Synopsis [Write index to node]
306 Description [The index of the node is written in the "next" field of
307 a DdNode struct. LSB is not used (set to 0). It is used as
308 "visited" flag in DD traversals.
311 SideEffects [None]
313 SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (),
314 DddmpVisitedCnf ()
317 ******************************************************************************/
320 DddmpWriteNodeIndexCnfBis (
321 DdNode *f /* IN: BDD node */,
322 int id /* IN: index to be written */
325 if (!Cudd_IsConstant (f)) {
326 f->next = (struct DdNode *)((ptruint)((id)<<1));
329 return (DDDMP_SUCCESS);
332 /*---------------------------------------------------------------------------*/
333 /* Definition of static functions */
334 /*---------------------------------------------------------------------------*/
336 /**Function********************************************************************
338 Synopsis [Write index to node]
340 Description [The index of the node is written in the "next" field of
341 a DdNode struct. LSB is not used (set to 0). It is used as
342 "visited" flag in DD traversals. The index corresponds to
343 the BDD node variable if both the node's children are a
344 constant node, otherwise a new CNF variable is used.
347 SideEffects [None]
349 SeeAlso [DddmpReadNodeIndexCnf(), DddmpSetVisitedCnf (),
350 DddmpVisitedCnf ()]
352 *****************************************************************************/
354 static int
355 DddmpWriteNodeIndexCnf (
356 DdNode *f /* IN: BDD node */,
357 int *cnfIds /* IN: possible source for the index to be written */,
358 int id /* IN: possible source for the index to be written */
361 if (!Cudd_IsConstant (f)) {
362 if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) {
363 /* If Variable SET ID as Variable ID */
364 f->next = (struct DdNode *)((ptruint)((cnfIds[f->index])<<1));
365 } else {
366 f->next = (struct DdNode *)((ptruint)((id)<<1));
367 id++;
371 return(id);
374 /**Function********************************************************************
376 Synopsis [Reads the index of a node]
378 Description [Reads the index of a node. LSB is skipped (used as visited
379 flag).
382 SideEffects [None]
384 SeeAlso [DddmpWriteNodeIndexCnf(), DddmpSetVisitedCnf (),
385 DddmpVisitedCnf ()]
387 ******************************************************************************/
389 static int
390 DddmpReadNodeIndexCnf (
391 DdNode *f /* IN: BDD node */
394 if (!Cudd_IsConstant (f)) {
395 return ((int)(((ptruint)(f->next))>>1));
396 } else {
397 return (1);
401 /**Function********************************************************************
403 Synopsis [Mark ALL nodes as not visited]
405 Description [Mark ALL nodes as not visited (it recurs on the node children)]
407 SideEffects [None]
409 SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()]
411 ******************************************************************************/
413 static int
414 DddmpClearVisitedCnfRecur (
415 DdNode *f /* IN: root of the BDD to be marked */
418 int retValue;
420 f = Cudd_Regular(f);
422 if (cuddIsConstant (f)) {
423 return (DDDMP_SUCCESS);
426 if (!DddmpVisitedCnf (f)) {
427 return (DDDMP_SUCCESS);
430 retValue = DddmpClearVisitedCnfRecur (cuddT (f));
431 retValue = DddmpClearVisitedCnfRecur (cuddE (f));
433 DddmpClearVisitedCnf (f);
435 return (DDDMP_SUCCESS);
438 /**Function********************************************************************
440 Synopsis [Returns true if node is visited]
442 Description [Returns true if node is visited]
444 SideEffects [None]
446 SeeAlso [DddmpSetVisitedCnf (), DddmpClearVisitedCnf ()]
448 ******************************************************************************/
450 static int
451 DddmpVisitedCnf (
452 DdNode *f /* IN: BDD node to be tested */
455 f = Cudd_Regular(f);
457 return ((int)((ptruint)(f->next)) & (01));
460 /**Function********************************************************************
462 Synopsis [Marks a node as visited]
464 Description [Marks a node as visited]
466 SideEffects [None]
468 SeeAlso [DddmpVisitedCnf (), DddmpClearVisitedCnf ()]
470 ******************************************************************************/
472 static void
473 DddmpSetVisitedCnf (
474 DdNode *f /* IN: BDD node to be marked (as visited) */
477 f = Cudd_Regular(f);
479 f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next))|01);
481 return;
484 /**Function********************************************************************
486 Synopsis [Marks a node as not visited]
488 Description [Marks a node as not visited]
490 SideEffects [None]
492 SeeAlso [DddmpVisitedCnf (), DddmpSetVisitedCnf ()]
494 ******************************************************************************/
496 static void
497 DddmpClearVisitedCnf (
498 DdNode *f /* IN: BDD node to be marked (as not visited) */
501 f = Cudd_Regular (f);
503 f->next = (DdNode *)(ptruint)((int)((ptruint)(f->next)) & (~01));
505 return;
508 /**Function********************************************************************
510 Synopsis [Number nodes recursively in post-order]
512 Description [Number nodes recursively in post-order.
513 The "visited" flag is used with inverse polarity, because all nodes
514 were set "visited" when removing them from unique.
517 SideEffects ["visited" flags are reset.]
519 SeeAlso []
521 ******************************************************************************/
523 static int
524 NumberNodeRecurCnf(
525 DdNode *f /* IN: root of the BDD to be numbered */,
526 int *cnfIds /* IN: possible source for numbering */,
527 int id /* IN/OUT: possible source for numbering */
530 f = Cudd_Regular(f);
532 if (!DddmpVisitedCnf (f)) {
533 return (id);
536 if (!cuddIsConstant (f)) {
537 id = NumberNodeRecurCnf (cuddT (f), cnfIds, id);
538 id = NumberNodeRecurCnf (cuddE (f), cnfIds, id);
541 id = DddmpWriteNodeIndexCnf (f, cnfIds, id);
542 DddmpClearVisitedCnf (f);
544 return (id);
547 /**Function********************************************************************
549 Synopsis [Number nodes recursively in post-order]
551 Description [Number nodes recursively in post-order.
552 The "visited" flag is used with the right polarity.
553 The node is assigned to a new CNF variable only if it is a "shared"
554 node (i.e. the number of its incoming edges is greater than 1).
557 SideEffects ["visited" flags are set.]
559 SeeAlso []
561 ******************************************************************************/
563 static void
564 DddmpDdNodesCheckIncomingAndScanPath (
565 DdNode *f /* IN: BDD node to be numbered */,
566 int pathLengthCurrent /* IN: Current Path Length */,
567 int edgeInTh /* IN: Max # In-Edges, after a Insert Cut Point */,
568 int pathLengthTh /* IN: Max Path Length (after, Insert a Cut Point) */
571 int retValue;
573 f = Cudd_Regular(f);
575 if (DddmpVisitedCnf (f)) {
576 return;
579 if (cuddIsConstant (f)) {
580 return;
583 pathLengthCurrent++;
584 retValue = DddmpReadNodeIndexCnf (f);
586 if ( ((edgeInTh >= 0) && (retValue > edgeInTh)) ||
587 ((pathLengthTh >= 0) && (pathLengthCurrent > pathLengthTh))
589 DddmpWriteNodeIndexCnfBis (f, 1);
590 pathLengthCurrent = 0;
591 } else {
592 DddmpWriteNodeIndexCnfBis (f, 0);
595 DddmpDdNodesCheckIncomingAndScanPath (cuddT (f), pathLengthCurrent,
596 edgeInTh, pathLengthTh);
597 DddmpDdNodesCheckIncomingAndScanPath (cuddE (f), pathLengthCurrent,
598 edgeInTh, pathLengthTh);
600 DddmpSetVisitedCnf (f);
602 return;
605 /**Function********************************************************************
607 Synopsis [Number nodes recursively in post-order]
609 Description [Number nodes recursively in post-order.
610 The "visited" flag is used with the inverse polarity.
611 Numbering follows the subsequent strategy:
612 * if the index = 0 it remains so
613 * if the index >= 1 it gets enumerated.
614 This implies that the node is assigned to a new CNF variable only if
615 it is not a terminal node otherwise it is assigned the index of
616 the BDD variable.
619 SideEffects ["visited" flags are reset.]
621 SeeAlso []
623 ******************************************************************************/
625 static int
626 DddmpDdNodesNumberEdgesRecur (
627 DdNode *f /* IN: BDD node to be numbered */,
628 int *cnfIds /* IN: possible source for numbering */,
629 int id /* IN/OUT: possible source for numbering */
632 int retValue;
634 f = Cudd_Regular(f);
636 if (!DddmpVisitedCnf (f)) {
637 return (id);
640 if (cuddIsConstant (f)) {
641 return (id);
644 id = DddmpDdNodesNumberEdgesRecur (cuddT (f), cnfIds, id);
645 id = DddmpDdNodesNumberEdgesRecur (cuddE (f), cnfIds, id);
647 retValue = DddmpReadNodeIndexCnf (f);
648 if (retValue >= 1) {
649 id = DddmpWriteNodeIndexCnf (f, cnfIds, id);
650 } else {
651 DddmpWriteNodeIndexCnfBis (f, 0);
654 DddmpClearVisitedCnf (f);
656 return (id);
659 /**Function********************************************************************
661 Synopsis [Resets counter and visited flag for ALL nodes of a BDD]
663 Description [Resets counter and visited flag for ALL nodes of a BDD (it
664 recurs on the node children). The index field of the node is
665 used as counter.
668 SideEffects []
670 SeeAlso []
672 ******************************************************************************/
674 static int
675 DddmpDdNodesResetCountRecur (
676 DdNode *f /* IN: root of the BDD whose counters are reset */
679 int retValue;
681 f = Cudd_Regular (f);
683 if (!DddmpVisitedCnf (f)) {
684 return (DDDMP_SUCCESS);
687 if (!cuddIsConstant (f)) {
688 retValue = DddmpDdNodesResetCountRecur (cuddT (f));
689 retValue = DddmpDdNodesResetCountRecur (cuddE (f));
692 DddmpWriteNodeIndexCnfBis (f, 0);
693 DddmpClearVisitedCnf (f);
695 return (DDDMP_SUCCESS);
698 /**Function********************************************************************
700 Synopsis [Counts the number of incoming edges for each node of a BDD]
702 Description [Counts (recursively) the number of incoming edges for each
703 node of a BDD. This number is stored in the index field.
706 SideEffects ["visited" flags remain untouched.]
708 SeeAlso []
710 ******************************************************************************/
712 static int
713 DddmpDdNodesCountEdgesRecur (
714 DdNode *f /* IN: root of the BDD */
717 int indexValue, retValue;
719 f = Cudd_Regular (f);
721 if (cuddIsConstant (f)) {
722 return (DDDMP_SUCCESS);
725 if (Cudd_IsConstant (cuddT (f)) && Cudd_IsConstant (cuddE (f))) {
726 return (DDDMP_SUCCESS);
729 indexValue = DddmpReadNodeIndexCnf (f);
731 /* IF (first time) THEN recur */
732 if (indexValue == 0) {
733 retValue = DddmpDdNodesCountEdgesRecur (cuddT (f));
734 retValue = DddmpDdNodesCountEdgesRecur (cuddE (f));
737 /* Increment Incoming-Edge Count Flag */
738 indexValue++;
739 DddmpWriteNodeIndexCnfBis (f, indexValue);
741 return (DDDMP_SUCCESS);
744 /**Function********************************************************************
746 Synopsis [Removes a node from unique table]
748 Description [Removes a node from the unique table by locating the proper
749 subtable and unlinking the node from it. It recurs on son nodes.
752 SideEffects [Nodes are left with the "visited" flag true.]
754 SeeAlso [RestoreInUniqueRecurCnf()]
756 ******************************************************************************/
758 static void
759 RemoveFromUniqueRecurCnf (
760 DdManager *ddMgr /* IN: DD Manager */,
761 DdNode *f /* IN: root of the BDD to be extracted */
764 DdNode *node, *last, *next;
765 DdNode *sentinel = &(ddMgr->sentinel);
766 DdNodePtr *nodelist;
767 DdSubtable *subtable;
768 int pos, level;
770 f = Cudd_Regular (f);
772 if (DddmpVisitedCnf (f)) {
773 return;
776 if (!cuddIsConstant (f)) {
778 RemoveFromUniqueRecurCnf (ddMgr, cuddT (f));
779 RemoveFromUniqueRecurCnf (ddMgr, cuddE (f));
781 level = ddMgr->perm[f->index];
782 subtable = &(ddMgr->subtables[level]);
784 nodelist = subtable->nodelist;
786 pos = ddHash (cuddT (f), cuddE (f), subtable->shift);
787 node = nodelist[pos];
788 last = NULL;
789 while (node != sentinel) {
790 next = node->next;
791 if (node == f) {
792 if (last != NULL)
793 last->next = next;
794 else
795 nodelist[pos] = next;
796 break;
797 } else {
798 last = node;
799 node = next;
803 f->next = NULL;
807 DddmpSetVisitedCnf (f);
809 return;
812 /**Function********************************************************************
814 Synopsis [Restores a node in unique table]
816 Description [Restores a node in unique table (recursive)]
818 SideEffects [Nodes are not restored in the same order as before removal]
820 SeeAlso [RemoveFromUnique()]
822 ******************************************************************************/
824 static void
825 RestoreInUniqueRecurCnf (
826 DdManager *ddMgr /* IN: DD Manager */,
827 DdNode *f /* IN: root of the BDD to be restored */
830 DdNodePtr *nodelist;
831 DdNode *T, *E, *looking;
832 DdNodePtr *previousP;
833 DdSubtable *subtable;
834 int pos, level;
835 #ifdef DDDMP_DEBUG
836 DdNode *node;
837 DdNode *sentinel = &(ddMgr->sentinel);
838 #endif
840 f = Cudd_Regular(f);
842 if (!Cudd_IsComplement (f->next)) {
843 return;
846 if (cuddIsConstant (f)) {
847 DddmpClearVisitedCnf (f);
848 /*f->next = NULL;*/
849 return;
852 RestoreInUniqueRecurCnf (ddMgr, cuddT (f));
853 RestoreInUniqueRecurCnf (ddMgr, cuddE (f));
855 level = ddMgr->perm[f->index];
856 subtable = &(ddMgr->subtables[level]);
858 nodelist = subtable->nodelist;
860 pos = ddHash (cuddT (f), cuddE (f), subtable->shift);
862 #ifdef DDDMP_DEBUG
863 /* verify uniqueness to avoid duplicate nodes in unique table */
864 for (node=nodelist[pos]; node != sentinel; node=node->next)
865 assert(node!=f);
866 #endif
868 T = cuddT (f);
869 E = cuddE (f);
870 previousP = &(nodelist[pos]);
871 looking = *previousP;
873 while (T < cuddT (looking)) {
874 previousP = &(looking->next);
875 looking = *previousP;
878 while (T == cuddT (looking) && E < cuddE (looking)) {
879 previousP = &(looking->next);
880 looking = *previousP;
882 f->next = *previousP;
883 *previousP = f;
885 return;
888 /**Function********************************************************************
890 Synopsis [Prints debug info]
892 Description [Prints debug info for a BDD on the screen. It recurs on
893 node's children.
896 SideEffects []
898 SeeAlso []
900 ******************************************************************************/
902 static int
903 DddmpPrintBddAndNextRecur (
904 DdManager *ddMgr /* IN: DD Manager */,
905 DdNode *f /* IN: root of the BDD to be displayed */
908 int retValue;
909 DdNode *fPtr, *tPtr, *ePtr;
911 fPtr = Cudd_Regular (f);
913 if (Cudd_IsComplement (f)) {
914 fprintf (stdout, "sign=- ptr=%ld ", ((long int) fPtr));
915 } else {
916 fprintf (stdout, "sign=+ ptr=%ld ", ((long int) fPtr));
919 if (cuddIsConstant (fPtr)) {
920 fprintf (stdout, "one\n");
921 fflush (stdout);
922 return (DDDMP_SUCCESS);
925 fprintf (stdout,
926 "thenPtr=%ld elsePtr=%ld BddId=%d CnfId=%d Visited=%d\n",
927 ((long int) cuddT (fPtr)), ((long int) cuddE (fPtr)),
928 fPtr->index, DddmpReadNodeIndexCnf (fPtr),
929 DddmpVisitedCnf (fPtr));
931 tPtr = cuddT (fPtr);
932 ePtr = cuddE (fPtr);
933 if (Cudd_IsComplement (f)) {
934 tPtr = Cudd_Not (tPtr);
935 ePtr = Cudd_Not (ePtr);
938 retValue = DddmpPrintBddAndNextRecur (ddMgr, tPtr);
939 retValue = DddmpPrintBddAndNextRecur (ddMgr, ePtr);
941 return (DDDMP_SUCCESS);