abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddInteract.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddInteract.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Functions to manipulate the variable interaction matrix.]
8 
9  Description [Internal procedures included in this file:
10  <ul>
11  <li> cuddSetInteract()
12  <li> cuddTestInteract()
13  <li> cuddInitInteract()
14  </ul>
15  Static procedures included in this file:
16  <ul>
17  <li> ddSuppInteract()
18  <li> ddClearLocal()
19  <li> ddUpdateInteract()
20  <li> ddClearGlobal()
21  </ul>
22  The interaction matrix tells whether two variables are
23  both in the support of some function of the DD. The main use of the
24  interaction matrix is in the in-place swapping. Indeed, if two
25  variables do not interact, there is no arc connecting the two layers;
26  therefore, the swap can be performed in constant time, without
27  scanning the subtables. Another use of the interaction matrix is in
28  the computation of the lower bounds for sifting. Finally, the
29  interaction matrix can be used to speed up aggregation checks in
30  symmetric and group sifting.<p>
31  The computation of the interaction matrix is done with a series of
32  depth-first searches. The searches start from those nodes that have
33  only external references. The matrix is stored as a packed array of bits;
34  since it is symmetric, only the upper triangle is kept in memory.
35  As a final remark, we note that there may be variables that do
36  intercat, but that for a given variable order have no arc connecting
37  their layers when they are adjacent.]
38 
39  SeeAlso []
40 
41  Author [Fabio Somenzi]
42 
43  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
44 
45  All rights reserved.
46 
47  Redistribution and use in source and binary forms, with or without
48  modification, are permitted provided that the following conditions
49  are met:
50 
51  Redistributions of source code must retain the above copyright
52  notice, this list of conditions and the following disclaimer.
53 
54  Redistributions in binary form must reproduce the above copyright
55  notice, this list of conditions and the following disclaimer in the
56  documentation and/or other materials provided with the distribution.
57 
58  Neither the name of the University of Colorado nor the names of its
59  contributors may be used to endorse or promote products derived from
60  this software without specific prior written permission.
61 
62  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
63  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
64  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
65  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
66  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
67  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
68  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
70  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
72  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
73  POSSIBILITY OF SUCH DAMAGE.]
74 
75 ******************************************************************************/
76 
77 #include "misc/util/util_hack.h"
78 #include "cuddInt.h"
79 
81 
82 
83 
84 /*---------------------------------------------------------------------------*/
85 /* Constant declarations */
86 /*---------------------------------------------------------------------------*/
87 
88 #if SIZEOF_LONG == 8
89 #define BPL 64
90 #define LOGBPL 6
91 #else
92 #define BPL 32
93 #define LOGBPL 5
94 #endif
95 
96 /*---------------------------------------------------------------------------*/
97 /* Stucture declarations */
98 /*---------------------------------------------------------------------------*/
99 
100 
101 /*---------------------------------------------------------------------------*/
102 /* Type declarations */
103 /*---------------------------------------------------------------------------*/
104 
105 
106 /*---------------------------------------------------------------------------*/
107 /* Variable declarations */
108 /*---------------------------------------------------------------------------*/
109 
110 #ifndef lint
111 static char rcsid[] DD_UNUSED = "$Id: cuddInteract.c,v 1.12 2004/08/13 18:04:49 fabio Exp $";
112 #endif
113 
114 /*---------------------------------------------------------------------------*/
115 /* Macro declarations */
116 /*---------------------------------------------------------------------------*/
117 
118 
119 /**AutomaticStart*************************************************************/
120 
121 /*---------------------------------------------------------------------------*/
122 /* Static function prototypes */
123 /*---------------------------------------------------------------------------*/
124 
125 static void ddSuppInteract (DdNode *f, int *support);
126 static void ddClearLocal (DdNode *f);
127 static void ddUpdateInteract (DdManager *table, int *support);
128 static void ddClearGlobal (DdManager *table);
129 
130 /**AutomaticEnd***************************************************************/
131 
132 
133 /*---------------------------------------------------------------------------*/
134 /* Definition of exported functions */
135 /*---------------------------------------------------------------------------*/
136 
137 
138 /*---------------------------------------------------------------------------*/
139 /* Definition of internal functions */
140 /*---------------------------------------------------------------------------*/
141 
142 
143 /**Function********************************************************************
144 
145  Synopsis [Set interaction matrix entries.]
146 
147  Description [Given a pair of variables 0 <= x < y < table->size,
148  sets the corresponding bit of the interaction matrix to 1.]
149 
150  SideEffects [None]
151 
152  SeeAlso []
153 
154 ******************************************************************************/
155 void
157  DdManager * table,
158  int x,
159  int y)
160 {
161  int posn, word, bit;
162 
163 #ifdef DD_DEBUG
164  assert(x < y);
165  assert(y < table->size);
166  assert(x >= 0);
167 #endif
168 
169  posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1;
170  word = posn >> LOGBPL;
171  bit = posn & (BPL-1);
172  table->interact[word] |= 1L << bit;
173 
174 } /* end of cuddSetInteract */
175 
176 
177 /**Function********************************************************************
178 
179  Synopsis [Test interaction matrix entries.]
180 
181  Description [Given a pair of variables 0 <= x < y < table->size,
182  tests whether the corresponding bit of the interaction matrix is 1.
183  Returns the value of the bit.]
184 
185  SideEffects [None]
186 
187  SeeAlso []
188 
189 ******************************************************************************/
190 int
192  DdManager * table,
193  int x,
194  int y)
195 {
196  int posn, word, bit, result;
197 
198  if (x > y) {
199  int tmp = x;
200  x = y;
201  y = tmp;
202  }
203 #ifdef DD_DEBUG
204  assert(x < y);
205  assert(y < table->size);
206  assert(x >= 0);
207 #endif
208 
209  posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1;
210  word = posn >> LOGBPL;
211  bit = posn & (BPL-1);
212  result = (table->interact[word] >> bit) & 1L;
213  return(result);
214 
215 } /* end of cuddTestInteract */
216 
217 
218 /**Function********************************************************************
219 
220  Synopsis [Initializes the interaction matrix.]
221 
222  Description [Initializes the interaction matrix. The interaction
223  matrix is implemented as a bit vector storing the upper triangle of
224  the symmetric interaction matrix. The bit vector is kept in an array
225  of long integers. The computation is based on a series of depth-first
226  searches, one for each root of the DAG. Two flags are needed: The
227  local visited flag uses the LSB of the then pointer. The global
228  visited flag uses the LSB of the next pointer.
229  Returns 1 if successful; 0 otherwise.]
230 
231  SideEffects [None]
232 
233  SeeAlso []
234 
235 ******************************************************************************/
236 int
238  DdManager * table)
239 {
240  int i,j,k;
241  ABC_UINT64_T words;
242  long *interact;
243  int *support;
244  DdNode *f;
245  DdNode *sentinel = &(table->sentinel);
246  DdNodePtr *nodelist;
247  int slots;
248  int n = table->size;
249 
250  words = ((n * (n-1)) >> (1 + LOGBPL)) + 1;
251  table->interact = interact = ABC_ALLOC(long,(unsigned)words);
252  if (interact == NULL) {
253  table->errorCode = CUDD_MEMORY_OUT;
254  return(0);
255  }
256  for (i = 0; i < words; i++) {
257  interact[i] = 0;
258  }
259 
260  support = ABC_ALLOC(int,n);
261  if (support == NULL) {
262  table->errorCode = CUDD_MEMORY_OUT;
263  ABC_FREE(interact);
264  return(0);
265  }
266 
267  for (i = 0; i < n; i++) {
268  nodelist = table->subtables[i].nodelist;
269  slots = table->subtables[i].slots;
270  for (j = 0; j < slots; j++) {
271  f = nodelist[j];
272  while (f != sentinel) {
273  /* A node is a root of the DAG if it cannot be
274  ** reached by nodes above it. If a node was never
275  ** reached during the previous depth-first searches,
276  ** then it is a root, and we start a new depth-first
277  ** search from it.
278  */
279  if (!Cudd_IsComplement(f->next)) {
280  for (k = 0; k < n; k++) {
281  support[k] = 0;
282  }
283  ddSuppInteract(f,support);
284  ddClearLocal(f);
285  ddUpdateInteract(table,support);
286  }
287  f = Cudd_Regular(f->next);
288  }
289  }
290  }
291  ddClearGlobal(table);
292 
293  ABC_FREE(support);
294  return(1);
295 
296 } /* end of cuddInitInteract */
297 
298 
299 /*---------------------------------------------------------------------------*/
300 /* Definition of static functions */
301 /*---------------------------------------------------------------------------*/
302 
303 
304 /**Function********************************************************************
305 
306  Synopsis [Find the support of f.]
307 
308  Description [Performs a DFS from f. Uses the LSB of the then pointer
309  as visited flag.]
310 
311  SideEffects [Accumulates in support the variables on which f depends.]
312 
313  SeeAlso []
314 
315 ******************************************************************************/
316 static void
318  DdNode * f,
319  int * support)
320 {
321  if (cuddIsConstant(f) || Cudd_IsComplement(cuddT(f))) {
322  return;
323  }
324 
325  support[f->index] = 1;
326  ddSuppInteract(cuddT(f),support);
327  ddSuppInteract(Cudd_Regular(cuddE(f)),support);
328  /* mark as visited */
329  cuddT(f) = Cudd_Complement(cuddT(f));
330  f->next = Cudd_Complement(f->next);
331  return;
332 
333 } /* end of ddSuppInteract */
334 
335 
336 /**Function********************************************************************
337 
338  Synopsis [Performs a DFS from f, clearing the LSB of the then pointers.]
339 
340  Description []
341 
342  SideEffects [None]
343 
344  SeeAlso []
345 
346 ******************************************************************************/
347 static void
349  DdNode * f)
350 {
351  if (cuddIsConstant(f) || !Cudd_IsComplement(cuddT(f))) {
352  return;
353  }
354  /* clear visited flag */
355  cuddT(f) = Cudd_Regular(cuddT(f));
356  ddClearLocal(cuddT(f));
358  return;
359 
360 } /* end of ddClearLocal */
361 
362 
363 /**Function********************************************************************
364 
365  Synopsis [Marks as interacting all pairs of variables that appear in
366  support.]
367 
368  Description [If support[i] == support[j] == 1, sets the (i,j) entry
369  of the interaction matrix to 1.]
370 
371  SideEffects [None]
372 
373  SeeAlso []
374 
375 ******************************************************************************/
376 static void
378  DdManager * table,
379  int * support)
380 {
381  int i,j;
382  int n = table->size;
383 
384  for (i = 0; i < n-1; i++) {
385  if (support[i] == 1) {
386  for (j = i+1; j < n; j++) {
387  if (support[j] == 1) {
388  cuddSetInteract(table,i,j);
389  }
390  }
391  }
392  }
393 
394 } /* end of ddUpdateInteract */
395 
396 
397 /**Function********************************************************************
398 
399  Synopsis [Scans the DD and clears the LSB of the next pointers.]
400 
401  Description [The LSB of the next pointers are used as markers to tell
402  whether a node was reached by at least one DFS. Once the interaction
403  matrix is built, these flags are reset.]
404 
405  SideEffects [None]
406 
407  SeeAlso []
408 
409 ******************************************************************************/
410 static void
412  DdManager * table)
413 {
414  int i,j;
415  DdNode *f;
416  DdNode *sentinel = &(table->sentinel);
417  DdNodePtr *nodelist;
418  int slots;
419 
420  for (i = 0; i < table->size; i++) {
421  nodelist = table->subtables[i].nodelist;
422  slots = table->subtables[i].slots;
423  for (j = 0; j < slots; j++) {
424  f = nodelist[j];
425  while (f != sentinel) {
426  f->next = Cudd_Regular(f->next);
427  f = f->next;
428  }
429  }
430  }
431 
432 } /* end of ddClearGlobal */
433 
434 
436 
437 
Definition: cudd.h:278
static char rcsid[] DD_UNUSED
Definition: cuddInteract.c:111
int size
Definition: cuddInt.h:361
#define Cudd_Regular(node)
Definition: cudd.h:397
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdSubtable * subtables
Definition: cuddInt.h:365
#define Cudd_IsComplement(node)
Definition: cudd.h:425
DdNode sentinel
Definition: cuddInt.h:344
DdNode * next
Definition: cudd.h:281
unsigned __int64 word
DECLARATIONS ///.
Definition: kitPerm.c:36
long * interact
Definition: cuddInt.h:394
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define cuddIsConstant(node)
Definition: cuddInt.h:620
static void ddClearLocal(DdNode *f)
Definition: cuddInteract.c:348
DdNode ** nodelist
Definition: cuddInt.h:327
int cuddInitInteract(DdManager *table)
Definition: cuddInteract.c:237
static int size
Definition: cuddSign.c:86
#define Cudd_Complement(node)
Definition: cudd.h:411
#define cuddT(node)
Definition: cuddInt.h:636
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
static void ddSuppInteract(DdNode *f, int *support)
Definition: cuddInteract.c:317
static void ddClearGlobal(DdManager *table)
Definition: cuddInteract.c:411
#define BPL
Definition: cuddInteract.c:92
void cuddSetInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:156
DdHalfWord index
Definition: cudd.h:279
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned int slots
Definition: cuddInt.h:329
#define cuddE(node)
Definition: cuddInt.h:652
static void ddUpdateInteract(DdManager *table, int *support)
Definition: cuddInteract.c:377
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:191
#define assert(ex)
Definition: util_old.h:213
static int result
Definition: cuddGenetic.c:125
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
#define LOGBPL
Definition: cuddInteract.c:93