コード例 #1
0
ファイル: bdd.c プロジェクト: dkudrow/cs267
/* recursively convert an AST expression into a BDD */
DdNode* bdd_expr(DdManager* m, symbol** symtab, ast_node* expr) {
    int i;
    DdNode* ret, *tmp1, *tmp2;
    switch (expr->tag) {
    case _id_expr:                     /* simply return that variable's BDD */
        if ((i = symtab_lookup(symtab, expr->name)) < 0) {
            printf("Error: variable '%s' not found in symbol table\n", expr->name);
            exit(1);
        }
        ret = Cudd_bddIthVar(m, symtab_lookup(symtab, expr->name));
        break;
    case _lit_expr:                    /* return a BDD 1 or 0 */
        ret = expr->val ? Cudd_ReadOne(m) : Cudd_ReadLogicZero(m);
        break;
    case _not_expr:                    /* return complement BDD */
        tmp1 = bdd_expr(m, symtab, expr->children[EXPR1]);
        ret = Cudd_Not(tmp1);
        Cudd_Ref(ret);
        Cudd_RecursiveDeref(m, tmp1);
        break;
    case _and_expr:                    /* return logical AND */
        tmp1 = bdd_expr(m, symtab, expr->children[EXPR1]);
        tmp2 = bdd_expr(m, symtab, expr->children[EXPR2]);
        ret = Cudd_bddAnd(m, tmp1, tmp2);
        Cudd_Ref(ret);
        Cudd_RecursiveDeref(m, tmp1);
        Cudd_RecursiveDeref(m, tmp2);
        break;
    case _or_expr:                     /* return logical OR */
        tmp1 = bdd_expr(m, symtab, expr->children[EXPR1]);
        tmp2 = bdd_expr(m, symtab, expr->children[EXPR2]);
        ret = Cudd_bddOr(m, tmp1, tmp2);
        Cudd_Ref(ret);
        Cudd_RecursiveDeref(m, tmp1);
        Cudd_RecursiveDeref(m, tmp2);
        break;
    case _eq_expr:                     /* check for equality, return 1 or 0 */
        tmp1 = bdd_expr(m, symtab, expr->children[EXPR1]);
        tmp2 = bdd_expr(m, symtab, expr->children[EXPR2]);
        if (Cudd_EquivDC(m, tmp1, tmp2, Cudd_ReadLogicZero(m)))
            ret = Cudd_ReadOne(m);
        else
            ret = Cudd_ReadLogicZero(m);
        Cudd_RecursiveDeref(m, tmp1);
        Cudd_RecursiveDeref(m, tmp2);
        break;
    case _impl_expr:                   /* return logical implication (!a|b) */
        tmp1 = Cudd_Not(bdd_expr(m, symtab, expr->children[EXPR1]));
        tmp2 = bdd_expr(m, symtab, expr->children[EXPR2]);
        ret = Cudd_bddOr(m, tmp1, tmp2);
        Cudd_Ref(ret);
        Cudd_RecursiveDeref(m, tmp1);
        Cudd_RecursiveDeref(m, tmp2);
        break;
    default:
        printf("Error: invalid expression\n");
        exit(1);
    }
    return ret;
}
コード例 #2
0
ファイル: pita_lib.c プロジェクト: jianqiao/code
int orc(int nodea, int nodeb)
{
    DdNode * node1,*node2,*nodeout;

    node1=(DdNode *)nodea;
    node2=(DdNode *)nodeb;
    nodeout=Cudd_bddOr(mgr,node1,node2);
    Cudd_Ref(nodeout);
    return (int)nodeout;
}
コード例 #3
0
ファイル: bdd.c プロジェクト: dkudrow/cs267
DdNode* compute_EF(DdManager* m, pos* postab, DdNode* R, DdNode* p) {
    DdNode* last = Cudd_ReadOne(m);
    DdNode* current = p;
    while (!Cudd_EquivDC(m, last, current, Cudd_ReadLogicZero(m))) {
//       printf("iterating\n");
        last = Cudd_bddAnd(m, current, Cudd_ReadOne(m));
        current = Cudd_bddOr(m, p, compute_EX(m, postab, R, current));
    }
    return current;
}
コード例 #4
0
ファイル: bddem.c プロジェクト: gokhansolak/yap-6.3
static YAP_Bool or (void) {
  YAP_Term arg1, arg2, arg3, out;
  DdNode *node1, *node2, *nodeout;

  arg1 = YAP_ARG1;
  arg2 = YAP_ARG2;
  arg3 = YAP_ARG3;
  node1 = (DdNode *)YAP_IntOfTerm(arg1);
  node2 = (DdNode *)YAP_IntOfTerm(arg2);
  nodeout = Cudd_bddOr(mgr_ex[ex], node1, node2);
  Cudd_Ref(nodeout);
  out = YAP_MkIntTerm((YAP_Int)nodeout);
  return (YAP_Unify(out, arg3));
}
コード例 #5
0
ファイル: DdGate.cpp プロジェクト: HosukChoi/ECO
DdNode * DdGate::gateFuncElem(DdManager * pDdManager, DdNode * pa, DdNode * pb){
	switch(__gate){
		case AND:
			return Cudd_bddAnd(pDdManager, pa, pb);
		case NAND:
			return Cudd_bddNand(pDdManager, pa, pb);
		case OR:
			return Cudd_bddOr(pDdManager, pa, pb);
		case NOR:
			return Cudd_bddNor(pDdManager, pa, pb);
		case XOR:
			return Cudd_bddXor(pDdManager, pa, pb);
		case XNOR:
			return Cudd_bddXnor(pDdManager, pa, pb);
		case NOT:
			return Cudd_bddNand(pDdManager, pa, pa);
		default:
			return NULL;
	}
}
コード例 #6
0
ファイル: bdd.c プロジェクト: dkudrow/cs267
/* wrap the CFG to BDD conversion */
DdNode* encode_prog(DdManager* m, pos* postab, cfg_node* proc_list_head) {
    DdNode* tmp, *proc, *init;
    DdNode* R = Cudd_ReadLogicZero(m);
    Cudd_Ref(R);
    cfg_node* next = proc_list_head;
    int proc_no = 0;                     /* all process begin with an 'init' */
    while (next) {                       /* skip node that has id = 0 */
//     init = Cudd_ReadOne(m);
//     init = bdd_encode_pc(m, init, postab->pc, postab->pc_size, proc_no, 0);
        init = bdd_mk_skip(m, postab, 0, proc_no);
        proc = bdd_convert_cfg(m, postab, proc_list_head, proc_no, init, R, 0);
        tmp = Cudd_bddOr(m, R, proc);      /* add process to transition relation */
        Cudd_Ref(tmp);
        Cudd_RecursiveDeref(m, R);
        Cudd_RecursiveDeref(m, proc);
        R = tmp;
        next = next->next_proc;            /* next process */
        ++proc_no;
    }
    return R;                            /* return complete transition relation */
}
コード例 #7
0
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_MvRead( Mv_Man_t * p )
{
    FILE * pFile;
    char Buffer[1000], * pLine;
    DdNode * bCube, * bTemp, * bProd, * bVar0, * bVar1, * bCubeSum;
    int i, v;

    // start the cube
    bCubeSum = Cudd_ReadLogicZero(p->dd);  Cudd_Ref( bCubeSum );

    // start the values
    for ( i = 0; i < 15; i++ )
    for ( v = 0; v < 4; v++ )
    {
        p->bValues[i][v]   = Cudd_ReadLogicZero(p->dd);  Cudd_Ref( p->bValues[i][v] );
        p->bValueDcs[i][v] = Cudd_ReadLogicZero(p->dd);  Cudd_Ref( p->bValueDcs[i][v] );
    }

    // read the file
    pFile = fopen( "input.pla", "r" );
    while ( fgets( Buffer, 1000, pFile ) )
    {
        if ( Buffer[0] == '#' )
            continue;
        if ( Buffer[0] == '.' )
        {
            if ( Buffer[1] == 'e' )
                break;
            continue;
        }

        // get the cube 
        bCube = Abc_MvReadCube( p->dd, Buffer, 18 );  Cudd_Ref( bCube );

        // add it to the values of the output functions
        pLine = Buffer + 19;
        for ( i = 0; i < 15; i++ )
        {
            if ( pLine[2*i] == '-' && pLine[2*i+1] == '-' )
            {
                for ( v = 0; v < 4; v++ )
                {
                    p->bValueDcs[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValueDcs[i][v], bCube );  Cudd_Ref( p->bValueDcs[i][v] );
                    Cudd_RecursiveDeref( p->dd, bTemp );
                }
                continue;
            }
            else if ( pLine[2*i] == '0' && pLine[2*i+1] == '0' ) // 0
                v = 0;
            else if ( pLine[2*i] == '1' && pLine[2*i+1] == '0' ) // 1
                v = 1;
            else if ( pLine[2*i] == '0' && pLine[2*i+1] == '1' ) // 2
                v = 2;
            else if ( pLine[2*i] == '1' && pLine[2*i+1] == '1' ) // 3
                v = 3;
            else assert( 0 );
            // add the value
            p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], bCube );  Cudd_Ref( p->bValues[i][v] );
            Cudd_RecursiveDeref( p->dd, bTemp );
        }

        // add the cube
        bCubeSum = Cudd_bddOr( p->dd, bTemp = bCubeSum, bCube );  Cudd_Ref( bCubeSum );
        Cudd_RecursiveDeref( p->dd, bTemp );
        Cudd_RecursiveDeref( p->dd, bCube );
    }

    // add the complement of the domain to all values
    for ( i = 0; i < 15; i++ )
        for ( v = 0; v < 4; v++ )
        {
            if ( p->bValues[i][v] == Cudd_Not(Cudd_ReadOne(p->dd)) )
                continue;
            p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], p->bValueDcs[i][v] );  Cudd_Ref( p->bValues[i][v] );
            Cudd_RecursiveDeref( p->dd, bTemp );
            p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], Cudd_Not(bCubeSum) );  Cudd_Ref( p->bValues[i][v] );
            Cudd_RecursiveDeref( p->dd, bTemp );
        }
    printf( "Domain = %5.2f %%.\n", 100.0*Cudd_CountMinterm(p->dd, bCubeSum, 32)/Cudd_CountMinterm(p->dd, Cudd_ReadOne(p->dd), 32) ); 
    Cudd_RecursiveDeref( p->dd, bCubeSum );

    // create each output function
    for ( i = 0; i < 15; i++ )
    {
        p->bFuncs[i] = Cudd_ReadLogicZero(p->dd);  Cudd_Ref( p->bFuncs[i] );
        for ( v = 0; v < 4; v++ )
        {
            bVar0 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 30), ((v & 1) == 0) );
            bVar1 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 31), ((v & 2) == 0) );
            bCube = Cudd_bddAnd( p->dd, bVar0, bVar1 );             Cudd_Ref( bCube );
            bProd = Cudd_bddAnd( p->dd, p->bValues[i][v], bCube );  Cudd_Ref( bProd );
            Cudd_RecursiveDeref( p->dd, bCube );
            // add the value
            p->bFuncs[i] = Cudd_bddOr( p->dd, bTemp = p->bFuncs[i], bProd );  Cudd_Ref( p->bFuncs[i] );
            Cudd_RecursiveDeref( p->dd, bTemp );
            Cudd_RecursiveDeref( p->dd, bProd );
        }
    }
}
コード例 #8
0
ファイル: bdd.c プロジェクト: dkudrow/cs267
/* traverse a CFG and encode each edge as a BDD */
DdNode* bdd_convert_cfg(DdManager *m, pos* postab, cfg_node* host, int proc,
                        DdNode* current, DdNode* R, int prev) {
    DdNode* branch;                      /* holds branch conditions */
    DdNode* tmp1, *tmp2;                 /* temporary vars for cleanup */
    current = bdd_encode_pc(m, current, postab->pc_, postab->pc_size, proc,
                            host->node->id);
    tmp1 = Cudd_bddOr(m, R, current);    /* add the completed edge to the */
    Cudd_Ref(tmp1);                      /* transistion system by disjuncting */
    Cudd_RecursiveDeref(m, R);
    Cudd_RecursiveDeref(m, current);
    R = tmp1;
    switch (host->node->tag) {
    case _assign_stat:                 /* assignment and skip statements */
    case _skip_stat:                   /* form very similar edges */
        if (host->node->tag == _assign_stat)
            current = bdd_mk_assign(m, postab, host, proc);
        else if (host->node->tag == _skip_stat)
            current = bdd_mk_skip(m, postab, host->node->id,  proc);
        break;
    case _if_then_stat:                /* if a branch is encountered, */
    case _if_else_stat:                /* add the branch condition to the  */
    case _while_stat:                  /* edge's encoding and continue */
        current = bdd_mk_skip(m, postab, host->node->id,  proc);
        tmp1 = bdd_expr(m, postab->vars, host->node->children[EXPR]);
        branch = Cudd_bddAnd(m, tmp1, current);
        Cudd_Ref(branch);                /* conjunct branch condition to branch */
        tmp2 = Cudd_bddAnd(m, Cudd_Not(tmp1), current);
        Cudd_Ref(tmp2);                  /* conjuct complement of the branch */
        Cudd_RecursiveDeref(m, tmp1);    /* condition to current */
        Cudd_RecursiveDeref(m, current);
        current = tmp2;
        if (host->node->id < prev)       /* terminate after back edge */
            return R;
        else {                           /* traverse the 'true' branch */
            tmp1 = bdd_convert_cfg(m, postab, host->succ[CFG_IF | CFG_WHILE], proc,
                                   branch, R, prev);
            Cudd_RecursiveDeref(m, R);
        }
        break;
    case _await_stat:                  /* await is both a branch and a skip */
        tmp1 = bdd_mk_skip(m, postab, host->node->id,  proc);
        tmp2 = bdd_expr(m, postab->vars, host->node->children[EXPR]);
        current = Cudd_bddAnd(m, tmp1, tmp2);
        Cudd_Ref(current);               /* conjunct branch condition to current */
        branch = Cudd_bddAnd(m, tmp1, Cudd_Not(tmp2));
        Cudd_Ref(branch);                /* conjuct complement of the branch */
        Cudd_RecursiveDeref(m, tmp1);    /* condition to branch */
        Cudd_RecursiveDeref(m, tmp2);    /* branch is a self-referential edge */
        branch = bdd_encode_pc(m, branch, postab->pc_, postab->pc_size, proc,
                               host->node->id);
        tmp1 = Cudd_bddOr(m, R, branch);
        Cudd_Ref(tmp1);
        Cudd_RecursiveDeref(m, R);
        Cudd_RecursiveDeref(m, branch);  /* continue edge continues to next node */
        break;
    default:
        printf("Error: invalid statement in CFG\n");
        exit(1);
    }
    if (host->succ[CONTINUE])  {         /* if the node has a successor */
        R = bdd_convert_cfg(m, postab, host->succ[CONTINUE], proc, current,
                            tmp1, host->node->id);
        Cudd_RecursiveDeref(m, tmp1);      /* initiate new edge and call again */
    } else {                             /* if the node terminates a branch */
        current = bdd_encode_pc(m, current, postab->pc_, postab->pc_size, proc,
                                host->node->id);
        R = Cudd_bddOr(m, tmp1, current);
        Cudd_Ref(R);                       /* terminate node with an infinite loop */
        Cudd_RecursiveDeref(m, tmp1);
        Cudd_RecursiveDeref(m, current);
    }
    return R;                            /* return complete transition relation */
}
コード例 #9
0
ファイル: testextra.c プロジェクト: cjdrake/cudd
/**
 * @brief Basic test of timeout handler.
 *
 * @details Sets a short timeout and then tries to build a function
 * with a large BDD.  Strives to avoid leaking nodes.
 *
 * @return 0 if successful; -1 otherwise.
 */
static int
testTimeout(int verbosity)
{
    DdManager *dd;
    /* Declare these "volatile" to prevent clobbering by longjmp. */
    DdNode * volatile f;
    DdNode * volatile clause = NULL;
    DdNode * var1, * var2;
    int i, ret, count;
    int const N = 20; /* half the number of variables in f */
    unsigned long timeout = 100UL; /* in milliseconds */
    jmp_buf timeoutEnv;

    dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
    if (!dd) {
        if (verbosity) {
            printf("initialization failed\n");
        }
        return -1;
    }

    /* Set up timeout handling. */
    if (setjmp(timeoutEnv) > 0) {
        if (verbosity) {
            printf("caught timeout\n");
        }
        /* The nodes of clause may be leaked if the timeout was
         * detected while conjoining the clause to f.  We set
         * clause to NULL when it's not in use to be able to
         * detect this case.
         */
        if (clause)
            Cudd_RecursiveDeref(dd, clause);
        goto finally;
    }
    (void) Cudd_RegisterTimeoutHandler(dd, timeoutHandler, (void *) &timeoutEnv);
    (void) Cudd_SetTimeLimit(dd, timeout);

    /* Try to build function.  This is expected to run out of time. */
    f = Cudd_ReadOne(dd);
    Cudd_Ref(f);
    for (i = 0; i < N; i++) {
        DdNode * tmp;
        var1 = Cudd_bddIthVar(dd, i);
        if (!var1) {
            if (verbosity) {
                printf("computation failed\n");
                return -1;
            }
        }
        var2 = Cudd_bddIthVar(dd, i+N);
        if (!var2) {
            if (verbosity) {
                printf("computation failed\n");
                return -1;
            }
        }
        clause = Cudd_bddOr(dd, var1, var2);
        if (!clause) {
            if (verbosity) {
                printf("computation failed\n");
            }
            return -1;
        }
        Cudd_Ref(clause);
        tmp = Cudd_bddAnd(dd, f, clause);
        if (!tmp) {
            if (verbosity) {
                printf("computation failed\n");
            }
            return -1;
        }
        Cudd_Ref(tmp);
        Cudd_RecursiveDeref(dd, clause);
        clause = NULL;
        Cudd_RecursiveDeref(dd, f);
        f = tmp;
    }
    if (verbosity > 1) {
        Cudd_bddPrintCover(dd, f, f);
    }

finally:
    if (verbosity) {
        printf("so far");
        Cudd_PrintSummary(dd, f, 2*N, 0);
    }
    count = 0;
    for (i = 0; i < N-1; i += 2) {
        var1 = Cudd_bddIthVar(dd, i);
        if (!var1) {
            printf("computation failed\n");
            return -1;
        }
        var2 = Cudd_bddIthVar(dd, i+1);
        if (!var2) {
            printf("computation failed\n");
            return -1;
        }
        clause = Cudd_bddOr(dd, var1, var2);
        if (!clause) {
            printf("computation failed\n");
            return -1;
        }
        Cudd_Ref(clause);
        if (Cudd_bddLeq(dd, f, clause)) {
            count++;
        }
        Cudd_RecursiveDeref(dd, clause);
    }
    if (verbosity) {
        printf("f implies %d clauses\n", count);
    }
    Cudd_RecursiveDeref(dd, f);
    ret = Cudd_CheckZeroRef(dd);
    if (verbosity) {
        Cudd_PrintInfo(dd, stdout);
        if (ret != 0) {
            printf("%d non-zero references\n", ret);
        }
    }
    Cudd_Quit(dd);
    return 0;
}
コード例 #10
0
ファイル: testextra.c プロジェクト: cjdrake/cudd
/**
 * @brief Basic test of long double and EPD minterm computation.
 * @return 0 if successful; -1 otherwise.
 */
static int
testLdbl(int verbosity)
{
    DdManager *dd;
    DdNode *f, *g;
    int i, ret;
    int const N = 12; /* half the number of variables */
    long double cnt;

    dd = Cudd_Init(2*N, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
    if (!dd) {
        if (verbosity) {
            printf("initialization failed\n");
        }
        return -1;
    }
    f = g = Cudd_ReadOne(dd);
    Cudd_Ref(f);
    Cudd_Ref(g);
    for (i = 0; i < N; i++) {
        DdNode *var1, *var2, *clause, *tmp;
        var1 = Cudd_bddIthVar(dd, i);
        var2 = Cudd_bddIthVar(dd, i+N);
        clause = Cudd_bddOr(dd, var1, var2);
        if (!clause) {
            Cudd_Quit(dd);
            return -1;
        }
        Cudd_Ref(clause);
        tmp = Cudd_bddAnd(dd, f, clause);
        if (!tmp) {
            Cudd_Quit(dd);
            return -1;
        }
        Cudd_Ref(tmp);
        Cudd_RecursiveDeref(dd, clause);
        Cudd_RecursiveDeref(dd, f);
        f = tmp;
        clause = Cudd_bddOr(dd, Cudd_Not(var1), Cudd_Not(var2));
        if (!clause) {
            Cudd_Quit(dd);
            return -1;
        }
        Cudd_Ref(clause);
        tmp = Cudd_bddAnd(dd, g, clause);
        if (!tmp) {
            Cudd_Quit(dd);
            return -1;
        }
        Cudd_Ref(tmp);
        Cudd_RecursiveDeref(dd, clause);
        Cudd_RecursiveDeref(dd, g);
        g = tmp;
    }
    if (verbosity) {
        printf("f");
        Cudd_PrintSummary(dd, f, 2*N, 0);
    }
    cnt = Cudd_LdblCountMinterm(dd, f, 2*N);
    if (verbosity) {
        printf("f has %Lg minterms\n", cnt);
    }
    if (verbosity) {
        printf("EPD count for f = ");
        ret = Cudd_EpdPrintMinterm(dd, f, 2*N);
        printf("\n");
        if (!ret) {
            printf("problem with EPD\n");
        }
    }
    Cudd_RecursiveDeref(dd, f);
    if (verbosity) {
        printf("g");
        Cudd_PrintSummary(dd, g, 2*N, 0);
    }
    cnt = Cudd_LdblCountMinterm(dd, g, 2*N);
    if (verbosity) {
        printf("g has %Lg minterms\n", cnt);
    }
    if (verbosity) {
        printf("EPD count for g = ");
        ret = Cudd_EpdPrintMinterm(dd, g, 2*N);
        printf("\n");
        if (!ret) {
            printf("problem with EPD\n");
        }
    }
    Cudd_RecursiveDeref(dd, g);
    ret = Cudd_CheckZeroRef(dd);
    if (verbosity && ret != 0) {
        printf("%d non-zero references\n", ret);
    }
    Cudd_Quit(dd);
    return 0;
}
コード例 #11
0
ファイル: solve_operators.c プロジェクト: tulip-control/gr1c
DdNode *compute_winning_set_BDD( DdManager *manager,
                                 DdNode *etrans, DdNode *strans,
                                 DdNode **egoals, DdNode **sgoals,
                                 unsigned char verbose )
{
    DdNode *X = NULL, *X_prev = NULL;
    DdNode *Y = NULL, *Y_exmod = NULL, *Y_prev = NULL;
    DdNode **Z = NULL, **Z_prev = NULL;
    bool Z_changed;  /* Use to detect occurrence of fixpoint for all Z_i */

    /* Fixpoint iteration counters */
    int num_it_Z, num_it_Y, num_it_X;

    DdNode *tmp, *tmp2;
    int i, j;  /* Generic counters */

    DdNode **vars, **pvars;
    int num_env, num_sys;
    int *cube;  /* length will be twice total number of variables (to
                   account for both variables and their primes). */

    num_env = tree_size( spc.evar_list );
    num_sys = tree_size( spc.svar_list );

    /* Allocate cube array, used later for quantifying over variables. */
    cube = (int *)malloc( sizeof(int)*2*(num_env+num_sys) );
    if (cube == NULL) {
        perror( __FILE__ ",  malloc" );
        exit(-1);
    }

    /* Define a map in the manager to easily swap variables with their
       primed selves. */
    vars = malloc( (num_env+num_sys)*sizeof(DdNode *) );
    pvars = malloc( (num_env+num_sys)*sizeof(DdNode *) );
    for (i = 0; i < num_env+num_sys; i++) {
        *(vars+i) = Cudd_bddIthVar( manager, i );
        *(pvars+i) = Cudd_bddIthVar( manager, i+num_env+num_sys );
    }
    if (!Cudd_SetVarMap( manager, vars, pvars, num_env+num_sys )) {
        fprintf( stderr,
                 "Error: failed to define variable map in CUDD manager.\n" );
        free( cube );
        return NULL;
    }
    free( vars );
    free( pvars );

    if (spc.num_sgoals > 0) {
        Z = malloc( spc.num_sgoals*sizeof(DdNode *) );
        Z_prev = malloc( spc.num_sgoals*sizeof(DdNode *) );
        for (i = 0; i < spc.num_sgoals; i++) {
            *(Z+i) = NULL;
            *(Z_prev+i) = NULL;
        }
    }

    /* Initialize */
    for (i = 0; i < spc.num_sgoals; i++) {
        *(Z+i) = Cudd_ReadOne( manager );
        Cudd_Ref( *(Z+i) );
    }

    num_it_Z = 0;
    do {
        num_it_Z++;
        if (verbose > 1) {
            logprint( "Z iteration %d", num_it_Z );
            logprint( "Cudd_ReadMemoryInUse (bytes): %d",
                      Cudd_ReadMemoryInUse( manager ) );
        }

        for (i = 0; i < spc.num_sgoals; i++) {
            if (*(Z_prev+i) != NULL)
                Cudd_RecursiveDeref( manager, *(Z_prev+i) );
            *(Z_prev+i) = *(Z+i);
        }

        for (i = 0; i < spc.num_sgoals; i++) {
            if (i == spc.num_sgoals-1) {
                *(Z+i) = compute_existsmodal( manager, *Z_prev, etrans, strans,
                                              num_env, num_sys, cube );
            } else {
                *(Z+i) = compute_existsmodal( manager, *(Z_prev+i+1),
                                              etrans, strans, num_env, num_sys,
                                              cube );
            }
            if (*(Z+i) == NULL) {
                /* fatal error */
                return NULL;
            }

            /* (Re)initialize Y */
            if (Y != NULL)
                Cudd_RecursiveDeref( manager, Y );
            Y = Cudd_Not( Cudd_ReadOne( manager ) );
            Cudd_Ref( Y );

            num_it_Y = 0;
            do {
                num_it_Y++;
                if (verbose > 1) {
                    logprint( "\tY iteration %d", num_it_Y );
                    logprint( "\tCudd_ReadMemoryInUse (bytes): %d",
                              Cudd_ReadMemoryInUse( manager ) );
                }

                if (Y_prev != NULL)
                    Cudd_RecursiveDeref( manager, Y_prev );
                Y_prev = Y;
                if (Y_exmod != NULL)
                    Cudd_RecursiveDeref( manager, Y_exmod );
                Y_exmod = compute_existsmodal( manager, Y_prev, etrans, strans,
                                               num_env, num_sys, cube );
                if (Y_exmod == NULL) {
                    /* fatal error */
                    return NULL;
                }

                Y = Cudd_Not( Cudd_ReadOne( manager ) );
                Cudd_Ref( Y );
                for (j = 0; j < spc.num_egoals; j++) {

                    /* (Re)initialize X */
                    if (X != NULL)
                        Cudd_RecursiveDeref( manager, X );
                    X = Cudd_ReadOne( manager );
                    Cudd_Ref( X );

                    /* Greatest fixpoint for X, for this env goal */
                    num_it_X = 0;
                    do {
                        num_it_X++;
                        if (verbose > 1) {
                            logprint( "\t\tX iteration %d", num_it_X );
                            logprint( "\t\tCudd_ReadMemoryInUse (bytes): %d",
                                      Cudd_ReadMemoryInUse( manager ) );
                        }

                        if (X_prev != NULL)
                            Cudd_RecursiveDeref( manager, X_prev );
                        X_prev = X;
                        X = compute_existsmodal( manager, X_prev,
                                                 etrans, strans,
                                                 num_env, num_sys, cube );
                        if (X == NULL) {
                            /* fatal error */
                            return NULL;
                        }

                        tmp = Cudd_bddAnd( manager, *(sgoals+i), *(Z+i) );
                        Cudd_Ref( tmp );
                        tmp2 = Cudd_bddOr( manager, tmp, Y_exmod );
                        Cudd_Ref( tmp2 );
                        Cudd_RecursiveDeref( manager, tmp );

                        tmp = Cudd_bddAnd( manager,
                                           X, Cudd_Not( *(egoals+j) ) );
                        Cudd_Ref( tmp );
                        Cudd_RecursiveDeref( manager, X );

                        X = Cudd_bddOr( manager, tmp2, tmp );
                        Cudd_Ref( X );
                        Cudd_RecursiveDeref( manager, tmp );
                        Cudd_RecursiveDeref( manager, tmp2 );

                        tmp = X;
                        X = Cudd_bddAnd( manager, X, X_prev );
                        Cudd_Ref( X );
                        Cudd_RecursiveDeref( manager, tmp );

                    } while (!Cudd_bddLeq( manager, X, X_prev )
                             || !Cudd_bddLeq( manager, X_prev, X ));

                    tmp = Y;
                    Y = Cudd_bddOr( manager, Y, X );
                    Cudd_Ref( Y );
                    Cudd_RecursiveDeref( manager, tmp );

                    Cudd_RecursiveDeref( manager, X );
                    X = NULL;
                    Cudd_RecursiveDeref( manager, X_prev );
                    X_prev = NULL;
                }

                tmp2 = Y;
                Y = Cudd_bddOr( manager, Y, Y_prev );
                Cudd_Ref( Y );
                Cudd_RecursiveDeref( manager, tmp2 );

            } while (!Cudd_bddLeq( manager, Y, Y_prev )
                     || !Cudd_bddLeq( manager, Y_prev, Y ));

            Cudd_RecursiveDeref( manager, *(Z+i) );
            *(Z+i) = Cudd_bddAnd( manager, Y, *(Z_prev+i) );
            Cudd_Ref( *(Z+i) );

            Cudd_RecursiveDeref( manager, Y );
            Y = NULL;
            Cudd_RecursiveDeref( manager, Y_prev );
            Y_prev = NULL;
            Cudd_RecursiveDeref( manager, Y_exmod );
            Y_exmod = NULL;

        }

        Z_changed = False;
        for (i = 0; i < spc.num_sgoals; i++) {
            if (!Cudd_bddLeq( manager, *(Z+i), *(Z_prev+i) )
                || !Cudd_bddLeq( manager, *(Z_prev+i), *(Z+i) )) {
                Z_changed = True;
                break;
            }
        }
    } while (Z_changed);

    /* Pre-exit clean-up */
    tmp = *Z;
    Cudd_RecursiveDeref( manager, *Z_prev );
    for (i = 1; i < spc.num_sgoals; i++) {
        Cudd_RecursiveDeref( manager, *(Z+i) );
        Cudd_RecursiveDeref( manager, *(Z_prev+i) );
    }
    free( Z );
    free( Z_prev );
    free( cube );

    return tmp;
}
コード例 #12
0
ファイル: expr.cpp プロジェクト: cambridgehackers/atomicc
static DdNode *tree2BDD(DdManager *mgr, ACCExpr *expr, VarMap &varMap)
{
    std::string op = expr->value;
    DdNode *ret = nullptr;
    if (op == "&&")
        op = "&";
    else if (op == "||")
        op = "|";
    if (checkInteger(expr, "1"))
        ret = Cudd_ReadOne(mgr);
    else if (checkInteger(expr, "0"))
        ret = Cudd_ReadLogicZero(mgr);
    else if (op == "!")
        return Cudd_Not(tree2BDD(mgr, expr->operands.front(), varMap)); // Not passes through ref count
    else if (op != "&" && op != "|" && op != "^") {
        if ((op == "!=" || op == "==")) {
            ACCExpr *lhs = getRHS(expr, 0);
            if (boolPossible(lhs) && boolPossible(getRHS(expr,1)))
                goto next; // we can analyze relops on booleans
            if (trace_bool)
                printf("[%s:%d] boolnot %d %d = %s\n", __FUNCTION__, __LINE__, boolPossible(getRHS(expr,0)), boolPossible(getRHS(expr,1)), tree2str(expr).c_str());
            if (isIdChar(lhs->value[0])) {
                if (trace_bool)
                    printf("[%s:%d] name %s type %s\n", __FUNCTION__, __LINE__, lhs->value.c_str(), refList[lhs->value].type.c_str());
            }
        }
        if (op == "!=")    // normalize comparison strings
            expr->value = "==";
        std::string name = "( " + tree2str(expr) + " )";
        if (!varMap[name]) {
            varMap[name] = new MapItem;
            varMap[name]->index = varMap.size();
            varMap[name]->node = Cudd_bddIthVar(mgr, varMap[name]->index);
        }
        ret = varMap[name]->node;
        if (op == "!=") {   // normalize comparison strings
            expr->value = op; // restore
            ret = Cudd_Not(ret);
        }
    }
    if (ret) {
        Cudd_Ref(ret);
        return ret;
    }
next:;
    for (auto item: expr->operands) {
         DdNode *operand = tree2BDD(mgr, item, varMap), *next;
         if (!ret)
             ret = operand;
         else {
             if (op == "&")
                 next = Cudd_bddAnd(mgr, ret, operand);
             else if (op == "|")
                 next = Cudd_bddOr(mgr, ret, operand);
             else if (op == "^" || op == "!=")
                 next = Cudd_bddXor(mgr, ret, operand);
             else if (op == "==")
                 next = Cudd_bddXnor(mgr, ret, operand);
             else {
                 printf("[%s:%d] unknown operator\n", __FUNCTION__, __LINE__);
                 exit(-1);
             }
             Cudd_Ref(next);
             Cudd_RecursiveDeref(mgr, operand);
             Cudd_RecursiveDeref(mgr, ret);
             ret = next;
         }
    }
    return ret;
}