abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddMatMult.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddMatMult.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Matrix multiplication functions.]
8 
9  Description [External procedures included in this module:
10  <ul>
11  <li> Cudd_addMatrixMultiply()
12  <li> Cudd_addTimesPlus()
13  <li> Cudd_addTriangle()
14  <li> Cudd_addOuterSum()
15  </ul>
16  Static procedures included in this module:
17  <ul>
18  <li> addMMRecur()
19  <li> addTriangleRecur()
20  <li> cuddAddOuterSumRecur()
21  </ul>]
22 
23  Author [Fabio Somenzi]
24 
25  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
26 
27  All rights reserved.
28 
29  Redistribution and use in source and binary forms, with or without
30  modification, are permitted provided that the following conditions
31  are met:
32 
33  Redistributions of source code must retain the above copyright
34  notice, this list of conditions and the following disclaimer.
35 
36  Redistributions in binary form must reproduce the above copyright
37  notice, this list of conditions and the following disclaimer in the
38  documentation and/or other materials provided with the distribution.
39 
40  Neither the name of the University of Colorado nor the names of its
41  contributors may be used to endorse or promote products derived from
42  this software without specific prior written permission.
43 
44  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
45  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
46  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
47  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
48  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
49  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
50  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
52  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
54  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55  POSSIBILITY OF SUCH DAMAGE.]
56 
57 ******************************************************************************/
58 
59 #include "misc/util/util_hack.h"
60 #include "cuddInt.h"
61 
63 
64 
65 
66 
67 /*---------------------------------------------------------------------------*/
68 /* Constant declarations */
69 /*---------------------------------------------------------------------------*/
70 
71 
72 /*---------------------------------------------------------------------------*/
73 /* Stucture declarations */
74 /*---------------------------------------------------------------------------*/
75 
76 
77 /*---------------------------------------------------------------------------*/
78 /* Type declarations */
79 /*---------------------------------------------------------------------------*/
80 
81 
82 /*---------------------------------------------------------------------------*/
83 /* Variable declarations */
84 /*---------------------------------------------------------------------------*/
85 
86 #ifndef lint
87 static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.17 2004/08/13 18:04:50 fabio Exp $";
88 #endif
89 
90 /*---------------------------------------------------------------------------*/
91 /* Macro declarations */
92 /*---------------------------------------------------------------------------*/
93 
94 
95 /**AutomaticStart*************************************************************/
96 
97 /*---------------------------------------------------------------------------*/
98 /* Static function prototypes */
99 /*---------------------------------------------------------------------------*/
100 
101 static DdNode * addMMRecur (DdManager *dd, DdNode *A, DdNode *B, int topP, int *vars);
102 static DdNode * addTriangleRecur (DdManager *dd, DdNode *f, DdNode *g, int *vars, DdNode *cube);
103 static DdNode * cuddAddOuterSumRecur (DdManager *dd, DdNode *M, DdNode *r, DdNode *c);
104 
105 /**AutomaticEnd***************************************************************/
106 
107 
108 /*---------------------------------------------------------------------------*/
109 /* Definition of exported functions */
110 /*---------------------------------------------------------------------------*/
111 
112 /**Function********************************************************************
113 
114  Synopsis [Calculates the product of two matrices represented as
115  ADDs.]
116 
117  Description [Calculates the product of two matrices, A and B,
118  represented as ADDs. This procedure implements the quasiring multiplication
119  algorithm. A is assumed to depend on variables x (rows) and z
120  (columns). B is assumed to depend on variables z (rows) and y
121  (columns). The product of A and B then depends on x (rows) and y
122  (columns). Only the z variables have to be explicitly identified;
123  they are the "summation" variables. Returns a pointer to the
124  result if successful; NULL otherwise.]
125 
126  SideEffects [None]
127 
128  SeeAlso [Cudd_addTimesPlus Cudd_addTriangle Cudd_bddAndAbstract]
129 
130 ******************************************************************************/
131 DdNode *
133  DdManager * dd,
134  DdNode * A,
135  DdNode * B,
136  DdNode ** z,
137  int nz)
138 {
139  int i, nvars, *vars;
140  DdNode *res;
141 
142  /* Array vars says what variables are "summation" variables. */
143  nvars = dd->size;
144  vars = ABC_ALLOC(int,nvars);
145  if (vars == NULL) {
147  return(NULL);
148  }
149  for (i = 0; i < nvars; i++) {
150  vars[i] = 0;
151  }
152  for (i = 0; i < nz; i++) {
153  vars[z[i]->index] = 1;
154  }
155 
156  do {
157  dd->reordered = 0;
158  res = addMMRecur(dd,A,B,-1,vars);
159  } while (dd->reordered == 1);
160  ABC_FREE(vars);
161  return(res);
162 
163 } /* end of Cudd_addMatrixMultiply */
164 
165 
166 /**Function********************************************************************
167 
168  Synopsis [Calculates the product of two matrices represented as
169  ADDs.]
170 
171  Description [Calculates the product of two matrices, A and B,
172  represented as ADDs, using the CMU matrix by matrix multiplication
173  procedure by Clarke et al.. Matrix A has x's as row variables and z's
174  as column variables, while matrix B has z's as row variables and y's
175  as column variables. Returns the pointer to the result if successful;
176  NULL otherwise. The resulting matrix has x's as row variables and y's
177  as column variables.]
178 
179  SideEffects [None]
180 
181  SeeAlso [Cudd_addMatrixMultiply]
182 
183 ******************************************************************************/
184 DdNode *
186  DdManager * dd,
187  DdNode * A,
188  DdNode * B,
189  DdNode ** z,
190  int nz)
191 {
192  DdNode *w, *cube, *tmp, *res;
193  int i;
194  tmp = Cudd_addApply(dd,Cudd_addTimes,A,B);
195  if (tmp == NULL) return(NULL);
196  Cudd_Ref(tmp);
197  Cudd_Ref(cube = DD_ONE(dd));
198  for (i = nz-1; i >= 0; i--) {
199  w = Cudd_addIte(dd,z[i],cube,DD_ZERO(dd));
200  if (w == NULL) {
201  Cudd_RecursiveDeref(dd,tmp);
202  return(NULL);
203  }
204  Cudd_Ref(w);
205  Cudd_RecursiveDeref(dd,cube);
206  cube = w;
207  }
208  res = Cudd_addExistAbstract(dd,tmp,cube);
209  if (res == NULL) {
210  Cudd_RecursiveDeref(dd,tmp);
211  Cudd_RecursiveDeref(dd,cube);
212  return(NULL);
213  }
214  Cudd_Ref(res);
215  Cudd_RecursiveDeref(dd,cube);
216  Cudd_RecursiveDeref(dd,tmp);
217  Cudd_Deref(res);
218  return(res);
219 
220 } /* end of Cudd_addTimesPlus */
221 
222 
223 /**Function********************************************************************
224 
225  Synopsis [Performs the triangulation step for the shortest path
226  computation.]
227 
228  Description [Implements the semiring multiplication algorithm used in
229  the triangulation step for the shortest path computation. f
230  is assumed to depend on variables x (rows) and z (columns). g is
231  assumed to depend on variables z (rows) and y (columns). The product
232  of f and g then depends on x (rows) and y (columns). Only the z
233  variables have to be explicitly identified; they are the
234  "abstraction" variables. Returns a pointer to the result if
235  successful; NULL otherwise. ]
236 
237  SideEffects [None]
238 
239  SeeAlso [Cudd_addMatrixMultiply Cudd_bddAndAbstract]
240 
241 ******************************************************************************/
242 DdNode *
244  DdManager * dd,
245  DdNode * f,
246  DdNode * g,
247  DdNode ** z,
248  int nz)
249 {
250  int i, nvars, *vars;
251  DdNode *res, *cube;
252 
253  nvars = dd->size;
254  vars = ABC_ALLOC(int, nvars);
255  if (vars == NULL) {
257  return(NULL);
258  }
259  for (i = 0; i < nvars; i++) vars[i] = -1;
260  for (i = 0; i < nz; i++) vars[z[i]->index] = i;
261  cube = Cudd_addComputeCube(dd, z, NULL, nz);
262  if (cube == NULL) {
263  ABC_FREE(vars);
264  return(NULL);
265  }
266  cuddRef(cube);
267 
268  do {
269  dd->reordered = 0;
270  res = addTriangleRecur(dd, f, g, vars, cube);
271  } while (dd->reordered == 1);
272  if (res != NULL) cuddRef(res);
273  Cudd_RecursiveDeref(dd,cube);
274  if (res != NULL) cuddDeref(res);
275  ABC_FREE(vars);
276  return(res);
277 
278 } /* end of Cudd_addTriangle */
279 
280 
281 /**Function********************************************************************
282 
283  Synopsis [Takes the minimum of a matrix and the outer sum of two vectors.]
284 
285  Description [Takes the pointwise minimum of a matrix and the outer
286  sum of two vectors. This procedure is used in the Floyd-Warshall
287  all-pair shortest path algorithm. Returns a pointer to the result if
288  successful; NULL otherwise.]
289 
290  SideEffects [None]
291 
292  SeeAlso []
293 
294 ******************************************************************************/
295 DdNode *
297  DdManager *dd,
298  DdNode *M,
299  DdNode *r,
300  DdNode *c)
301 {
302  DdNode *res;
303 
304  do {
305  dd->reordered = 0;
306  res = cuddAddOuterSumRecur(dd, M, r, c);
307  } while (dd->reordered == 1);
308  return(res);
309 
310 } /* end of Cudd_addOuterSum */
311 
312 
313 /*---------------------------------------------------------------------------*/
314 /* Definition of internal functions */
315 /*---------------------------------------------------------------------------*/
316 
317 
318 /*---------------------------------------------------------------------------*/
319 /* Definition of static functions */
320 /*---------------------------------------------------------------------------*/
321 
322 /**Function********************************************************************
323 
324  Synopsis [Performs the recursive step of Cudd_addMatrixMultiply.]
325 
326  Description [Performs the recursive step of Cudd_addMatrixMultiply.
327  Returns a pointer to the result if successful; NULL otherwise.]
328 
329  SideEffects [None]
330 
331 ******************************************************************************/
332 static DdNode *
334  DdManager * dd,
335  DdNode * A,
336  DdNode * B,
337  int topP,
338  int * vars)
339 {
340  DdNode *zero,
341  *At, /* positive cofactor of first operand */
342  *Ae, /* negative cofactor of first operand */
343  *Bt, /* positive cofactor of second operand */
344  *Be, /* negative cofactor of second operand */
345  *t, /* positive cofactor of result */
346  *e, /* negative cofactor of result */
347  *scaled, /* scaled result */
348  *add_scale, /* ADD representing the scaling factor */
349  *res;
350  int i; /* loop index */
351  double scale; /* scaling factor */
352  int index; /* index of the top variable */
354  unsigned int topA, topB, topV;
355  DD_CTFP cacheOp;
356 
357  statLine(dd);
358  zero = DD_ZERO(dd);
359 
360  if (A == zero || B == zero) {
361  return(zero);
362  }
363 
364  if (cuddIsConstant(A) && cuddIsConstant(B)) {
365  /* Compute the scaling factor. It is 2^k, where k is the
366  ** number of summation variables below the current variable.
367  ** Indeed, these constants represent blocks of 2^k identical
368  ** constant values in both A and B.
369  */
370  value = cuddV(A) * cuddV(B);
371  for (i = 0; i < dd->size; i++) {
372  if (vars[i]) {
373  if (dd->perm[i] > topP) {
374  value *= (CUDD_VALUE_TYPE) 2;
375  }
376  }
377  }
378  res = cuddUniqueConst(dd, value);
379  return(res);
380  }
381 
382  /* Standardize to increase cache efficiency. Clearly, A*B != B*A
383  ** in matrix multiplication. However, which matrix is which is
384  ** determined by the variables appearing in the ADDs and not by
385  ** which one is passed as first argument.
386  */
387  if (A > B) {
388  DdNode *tmp = A;
389  A = B;
390  B = tmp;
391  }
392 
393  topA = cuddI(dd,A->index); topB = cuddI(dd,B->index);
394  topV = ddMin(topA,topB);
395 
396  cacheOp = (DD_CTFP) addMMRecur;
397  res = cuddCacheLookup2(dd,cacheOp,A,B);
398  if (res != NULL) {
399  /* If the result is 0, there is no need to normalize.
400  ** Otherwise we count the number of z variables between
401  ** the current depth and the top of the ADDs. These are
402  ** the missing variables that determine the size of the
403  ** constant blocks.
404  */
405  if (res == zero) return(res);
406  scale = 1.0;
407  for (i = 0; i < dd->size; i++) {
408  if (vars[i]) {
409  if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) {
410  scale *= 2;
411  }
412  }
413  }
414  if (scale > 1.0) {
415  cuddRef(res);
416  add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale);
417  if (add_scale == NULL) {
418  Cudd_RecursiveDeref(dd, res);
419  return(NULL);
420  }
421  cuddRef(add_scale);
422  scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale);
423  if (scaled == NULL) {
424  Cudd_RecursiveDeref(dd, add_scale);
425  Cudd_RecursiveDeref(dd, res);
426  return(NULL);
427  }
428  cuddRef(scaled);
429  Cudd_RecursiveDeref(dd, add_scale);
430  Cudd_RecursiveDeref(dd, res);
431  res = scaled;
432  cuddDeref(res);
433  }
434  return(res);
435  }
436 
437  /* compute the cofactors */
438  if (topV == topA) {
439  At = cuddT(A);
440  Ae = cuddE(A);
441  } else {
442  At = Ae = A;
443  }
444  if (topV == topB) {
445  Bt = cuddT(B);
446  Be = cuddE(B);
447  } else {
448  Bt = Be = B;
449  }
450 
451  t = addMMRecur(dd, At, Bt, (int)topV, vars);
452  if (t == NULL) return(NULL);
453  cuddRef(t);
454  e = addMMRecur(dd, Ae, Be, (int)topV, vars);
455  if (e == NULL) {
456  Cudd_RecursiveDeref(dd, t);
457  return(NULL);
458  }
459  cuddRef(e);
460 
461  index = dd->invperm[topV];
462  if (vars[index] == 0) {
463  /* We have split on either the rows of A or the columns
464  ** of B. We just need to connect the two subresults,
465  ** which correspond to two submatrices of the result.
466  */
467  res = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
468  if (res == NULL) {
469  Cudd_RecursiveDeref(dd, t);
470  Cudd_RecursiveDeref(dd, e);
471  return(NULL);
472  }
473  cuddRef(res);
474  cuddDeref(t);
475  cuddDeref(e);
476  } else {
477  /* we have simultaneously split on the columns of A and
478  ** the rows of B. The two subresults must be added.
479  */
480  res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e);
481  if (res == NULL) {
482  Cudd_RecursiveDeref(dd, t);
483  Cudd_RecursiveDeref(dd, e);
484  return(NULL);
485  }
486  cuddRef(res);
487  Cudd_RecursiveDeref(dd, t);
488  Cudd_RecursiveDeref(dd, e);
489  }
490 
491  cuddCacheInsert2(dd,cacheOp,A,B,res);
492 
493  /* We have computed (and stored in the computed table) a minimal
494  ** result; that is, a result that assumes no summation variables
495  ** between the current depth of the recursion and its top
496  ** variable. We now take into account the z variables by properly
497  ** scaling the result.
498  */
499  if (res != zero) {
500  scale = 1.0;
501  for (i = 0; i < dd->size; i++) {
502  if (vars[i]) {
503  if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) {
504  scale *= 2;
505  }
506  }
507  }
508  if (scale > 1.0) {
509  add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale);
510  if (add_scale == NULL) {
511  Cudd_RecursiveDeref(dd, res);
512  return(NULL);
513  }
514  cuddRef(add_scale);
515  scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale);
516  if (scaled == NULL) {
517  Cudd_RecursiveDeref(dd, res);
518  Cudd_RecursiveDeref(dd, add_scale);
519  return(NULL);
520  }
521  cuddRef(scaled);
522  Cudd_RecursiveDeref(dd, add_scale);
523  Cudd_RecursiveDeref(dd, res);
524  res = scaled;
525  }
526  }
527  cuddDeref(res);
528  return(res);
529 
530 } /* end of addMMRecur */
531 
532 
533 /**Function********************************************************************
534 
535  Synopsis [Performs the recursive step of Cudd_addTriangle.]
536 
537  Description [Performs the recursive step of Cudd_addTriangle. Returns
538  a pointer to the result if successful; NULL otherwise.]
539 
540  SideEffects [None]
541 
542 ******************************************************************************/
543 static DdNode *
545  DdManager * dd,
546  DdNode * f,
547  DdNode * g,
548  int * vars,
549  DdNode *cube)
550 {
551  DdNode *fv, *fvn, *gv, *gvn, *t, *e, *res;
553  int top, topf, topg, index;
554 
555  statLine(dd);
556  if (f == DD_PLUS_INFINITY(dd) || g == DD_PLUS_INFINITY(dd)) {
557  return(DD_PLUS_INFINITY(dd));
558  }
559 
560  if (cuddIsConstant(f) && cuddIsConstant(g)) {
561  value = cuddV(f) + cuddV(g);
562  res = cuddUniqueConst(dd, value);
563  return(res);
564  }
565  if (f < g) {
566  DdNode *tmp = f;
567  f = g;
568  g = tmp;
569  }
570 
571  if (f->ref != 1 || g->ref != 1) {
572  res = cuddCacheLookup(dd, DD_ADD_TRIANGLE_TAG, f, g, cube);
573  if (res != NULL) {
574  return(res);
575  }
576  }
577 
578  topf = cuddI(dd,f->index); topg = cuddI(dd,g->index);
579  top = ddMin(topf,topg);
580 
581  if (top == topf) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;}
582  if (top == topg) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;}
583 
584  t = addTriangleRecur(dd, fv, gv, vars, cube);
585  if (t == NULL) return(NULL);
586  cuddRef(t);
587  e = addTriangleRecur(dd, fvn, gvn, vars, cube);
588  if (e == NULL) {
589  Cudd_RecursiveDeref(dd, t);
590  return(NULL);
591  }
592  cuddRef(e);
593 
594  index = dd->invperm[top];
595  if (vars[index] < 0) {
596  res = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
597  if (res == NULL) {
598  Cudd_RecursiveDeref(dd, t);
599  Cudd_RecursiveDeref(dd, e);
600  return(NULL);
601  }
602  cuddDeref(t);
603  cuddDeref(e);
604  } else {
605  res = cuddAddApplyRecur(dd,Cudd_addMinimum,t,e);
606  if (res == NULL) {
607  Cudd_RecursiveDeref(dd, t);
608  Cudd_RecursiveDeref(dd, e);
609  return(NULL);
610  }
611  cuddRef(res);
612  Cudd_RecursiveDeref(dd, t);
613  Cudd_RecursiveDeref(dd, e);
614  cuddDeref(res);
615  }
616 
617  if (f->ref != 1 || g->ref != 1) {
618  cuddCacheInsert(dd, DD_ADD_TRIANGLE_TAG, f, g, cube, res);
619  }
620 
621  return(res);
622 
623 } /* end of addTriangleRecur */
624 
625 
626 /**Function********************************************************************
627 
628  Synopsis [Performs the recursive step of Cudd_addOuterSum.]
629 
630  Description [Performs the recursive step of Cudd_addOuterSum.
631  Returns a pointer to the result if successful; NULL otherwise.]
632 
633  SideEffects [None]
634 
635  SeeAlso []
636 
637 ******************************************************************************/
638 static DdNode *
640  DdManager *dd,
641  DdNode *M,
642  DdNode *r,
643  DdNode *c)
644 {
645  DdNode *P, *R, *Mt, *Me, *rt, *re, *ct, *ce, *Rt, *Re;
646  int topM, topc, topr;
647  int v, index;
648 
649  statLine(dd);
650  /* Check special cases. */
651  if (r == DD_PLUS_INFINITY(dd) || c == DD_PLUS_INFINITY(dd)) return(M);
652 
653  if (cuddIsConstant(c) && cuddIsConstant(r)) {
654  R = cuddUniqueConst(dd,Cudd_V(c)+Cudd_V(r));
655  cuddRef(R);
656  if (cuddIsConstant(M)) {
657  if (cuddV(R) <= cuddV(M)) {
658  cuddDeref(R);
659  return(R);
660  } else {
661  Cudd_RecursiveDeref(dd,R);
662  return(M);
663  }
664  } else {
665  P = Cudd_addApply(dd,Cudd_addMinimum,R,M);
666  cuddRef(P);
667  Cudd_RecursiveDeref(dd,R);
668  cuddDeref(P);
669  return(P);
670  }
671  }
672 
673  /* Check the cache. */
674  R = cuddCacheLookup(dd,DD_ADD_OUT_SUM_TAG,M,r,c);
675  if (R != NULL) return(R);
676 
677  topM = cuddI(dd,M->index); topr = cuddI(dd,r->index);
678  topc = cuddI(dd,c->index);
679  v = ddMin(topM,ddMin(topr,topc));
680 
681  /* Compute cofactors. */
682  if (topM == v) { Mt = cuddT(M); Me = cuddE(M); } else { Mt = Me = M; }
683  if (topr == v) { rt = cuddT(r); re = cuddE(r); } else { rt = re = r; }
684  if (topc == v) { ct = cuddT(c); ce = cuddE(c); } else { ct = ce = c; }
685 
686  /* Recursively solve. */
687  Rt = cuddAddOuterSumRecur(dd,Mt,rt,ct);
688  if (Rt == NULL) return(NULL);
689  cuddRef(Rt);
690  Re = cuddAddOuterSumRecur(dd,Me,re,ce);
691  if (Re == NULL) {
692  Cudd_RecursiveDeref(dd, Rt);
693  return(NULL);
694  }
695  cuddRef(Re);
696  index = dd->invperm[v];
697  R = (Rt == Re) ? Rt : cuddUniqueInter(dd,index,Rt,Re);
698  if (R == NULL) {
699  Cudd_RecursiveDeref(dd, Rt);
700  Cudd_RecursiveDeref(dd, Re);
701  return(NULL);
702  }
703  cuddDeref(Rt);
704  cuddDeref(Re);
705 
706  /* Store the result in the cache. */
708 
709  return(R);
710 
711 } /* end of cuddAddOuterSumRecur */
712 
713 
715 
DdHalfWord ref
Definition: cudd.h:280
#define cuddRef(n)
Definition: cuddInt.h:584
#define DD_ADD_TRIANGLE_TAG
Definition: cuddInt.h:189
#define DD_ADD_OUT_SUM_TAG
Definition: cuddInt.h:187
#define cuddDeref(n)
Definition: cuddInt.h:604
DdNode * Cudd_addOuterSum(DdManager *dd, DdNode *M, DdNode *r, DdNode *c)
Definition: cuddMatMult.c:296
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
Definition: cuddTable.c:1450
static byte P[256]
Definition: kitPerm.c:76
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
DdNode * Cudd_addComputeCube(DdManager *dd, DdNode **vars, int *phase, int n)
Definition: cuddUtil.c:2246
int size
Definition: cuddInt.h:361
DdNode * cuddAddApplyRecur(DdManager *dd, DD_AOP op, DdNode *f, DdNode *g)
Definition: cuddAddApply.c:809
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:321
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdNode * Cudd_addApply(DdManager *dd, DdNode *(*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g)
word M(word f1, word f2, int n)
Definition: kitPerm.c:240
#define statLine(dd)
Definition: cuddInt.h:1037
#define cuddV(node)
Definition: cuddInt.h:668
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
int reordered
Definition: cuddInt.h:409
static DdNode * addTriangleRecur(DdManager *dd, DdNode *f, DdNode *g, int *vars, DdNode *cube)
Definition: cuddMatMult.c:544
static DdNode * cuddAddOuterSumRecur(DdManager *dd, DdNode *M, DdNode *r, DdNode *c)
Definition: cuddMatMult.c:639
DdNode * Cudd_addMatrixMultiply(DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz)
Definition: cuddMatMult.c:132
DdNode * Cudd_addPlus(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:168
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define cuddIsConstant(node)
Definition: cuddInt.h:620
DdNode * Cudd_addTriangle(DdManager *dd, DdNode *f, DdNode *g, DdNode **z, int nz)
Definition: cuddMatMult.c:243
#define ddMin(x, y)
Definition: cuddInt.h:818
#define cuddT(node)
Definition: cuddInt.h:636
#define Cudd_V(node)
Definition: cudd.h:470
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
DdNode * Cudd_addTimesPlus(DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz)
Definition: cuddMatMult.c:185
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdNode * Cudd_addIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddAddIte.c:129
#define CUDD_VALUE_TYPE
Definition: cudd.h:94
DdHalfWord index
Definition: cudd.h:279
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_PLUS_INFINITY(dd)
Definition: cuddInt.h:941
int value
int * invperm
Definition: cuddInt.h:388
static DdNode * addMMRecur(DdManager *dd, DdNode *A, DdNode *B, int topP, int *vars)
Definition: cuddMatMult.c:333
DdNode * Cudd_addExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddAddAbs.c:129
static ABC_NAMESPACE_IMPL_START char rcsid[] DD_UNUSED
Definition: cuddMatMult.c:87
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * Cudd_addTimes(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:208
DdNode * Cudd_addMinimum(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:385
int * perm
Definition: cuddInt.h:386
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:369
#define DD_ZERO(dd)
Definition: cuddInt.h:927