CUDD使用非门

时间:2018-12-30 17:15:05

标签: cudd

我正在尝试为单调乘法构建BDD,并且需要使用输入位的取反。

我正在使用以下代码:

DdNode *x[N], *y[N], *nx[N], *ny[N];

gbm = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); /* Initialize a new BDD manager. */

for(k=0;k<N;k++)
{
   x[k] = Cudd_bddNewVar(gbm);
   nx[k] = Cudd_Not(x[k]);  
   y[k] = Cudd_bddNewVar(gbm);
   ny[k] = Cudd_Not(y[k]);  
}

我得到的错误是:

cuddGarbageCollect: problem in table 0
  dead count != deleted
  This problem is often due to a missing call to Cudd_Ref
  or to an extra call to Cudd_RecursiveDeref.
  See the CUDD Programmer's Guide for additional details.Aborted (core dumped)

当我使用

时,乘法器可以编译并运行良好
   x[k] = Cudd_bddNewVar(gbm);
   nx[k] = Cudd_bddNewVar(gbm);  
   y[k] = Cudd_bddNewVar(gbm);
   ny[k] = Cudd_bddNewVar(gbm);  

我该怎么办,该手册无助于参考ref x [k],nx [k] ...

1 个答案:

答案 0 :(得分:1)

每个未引用的BDD节点都可以通过任何Cudd操作删除。如果要确保数组中存储的所有节点都保持有效,则需要在CUDD返回它们后立即Cudd_Ref它们。因此,您需要将代码更正为:

for(k=0;k<N;k++)
{
   x[k] = Cudd_bddNewVar(gbm);
   Cudd_Ref(x[k]);
   nx[k] = Cudd_Not(x[k]);  
   Cudd_Ref(nx[k]);
   y[k] = Cudd_bddNewVar(gbm);
   Cudd_Ref(y[k]);
   ny[k] = Cudd_Not(y[k]);  
   Cudd_Ref(yn[k]);
}

在取消分配Cudd管理器之前,您需要先取消引用节点:

for(k=0;k<N;k++)
{
   Cudd_RecursiveDeref(gbm,x[k]);
   Cudd_RecursiveDeref(gbm,nx[k]);
   Cudd_RecursiveDeref(gbm,y[k]);
   Cudd_RecursiveDeref(gbm,ny[k]);
}

请注意,您的代码在分配更多变量时有效,这一事实并不表明不需要引用。可能仅仅是因为您从未使用过足够多的节点来触发垃圾收集器-并且在此之前,未检测到问题。