Esempio n. 1
0
/**Function*************************************************************

  Synopsis    [Computes the transition relation of the network.]

  Description [Assumes that the global BDDs are computed.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * Abc_NtkTransitionRelation( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose )
{
    DdNode * bRel, * bTemp, * bProd, * bVar, * bInputs;
    Abc_Obj_t * pNode;
    int fReorder = 1;
    int i;

    // extand the BDD manager to represent NS variables
    assert( dd->size == Abc_NtkCiNum(pNtk) );
    Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + Abc_NtkLatchNum(pNtk) - 1 );

    // enable reordering
    if ( fReorder )
        Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
    else
        Cudd_AutodynDisable( dd );

    // compute the transition relation
    bRel = b1;   Cudd_Ref( bRel );
    Abc_NtkForEachLatch( pNtk, pNode, i )
    {
        bVar  = Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + i );
//        bProd = Cudd_bddXnor( dd, bVar, pNtk->vFuncsGlob->pArray[i] );  Cudd_Ref( bProd );
        bProd = Cudd_bddXnor( dd, bVar, Abc_ObjGlobalBdd(Abc_ObjFanin0(pNode)) );  Cudd_Ref( bProd );
        bRel  = Cudd_bddAnd( dd, bTemp = bRel, bProd );                 Cudd_Ref( bRel );
        Cudd_RecursiveDeref( dd, bTemp ); 
        Cudd_RecursiveDeref( dd, bProd ); 
    }
Esempio n. 2
0
static YAP_Bool init_bdd(void) {
  mgr_ex = (DdManager **)realloc(mgr_ex, (ex + 1) * sizeof(DdManager *));
  mgr_ex[ex] = Cudd_Init(0, 0, UNIQUE_SLOTS, CACHE_SLOTS, 5120);
  Cudd_AutodynEnable(mgr_ex[ex], CUDD_REORDER_GROUP_SIFT);
  Cudd_SetMaxCacheHard(mgr_ex[ex], 0);
  Cudd_SetLooseUpTo(mgr_ex[ex], 0);
  Cudd_SetMinHit(mgr_ex[ex], 15);

  bVar2mVar_ex = (int **)realloc(bVar2mVar_ex, (ex + 1) * sizeof(int *));
  bVar2mVar_ex[ex] = NULL;

  vars_ex = (variable **)realloc(vars_ex, (ex + 1) * sizeof(variable *));
  vars_ex[ex] = NULL;

  nVars_ex = (int *)realloc(nVars_ex, (ex + 1) * sizeof(int));
  nVars_ex[ex] = 0;

  probs_ex = (double **)realloc(probs_ex, (ex + 1) * sizeof(double *));
  probs_ex[ex] = NULL;

  boolVars_ex = (int *)realloc(boolVars_ex, (ex + 1) * sizeof(int));
  boolVars_ex[ex] = 0;

  return 1;
}
Esempio n. 3
0
static YAP_Bool init_test(void) {
  YAP_Term arg1;

  arg1 = YAP_ARG1;
  nRules = YAP_IntOfTerm(arg1);

  ex = 0;
  mgr_ex = (DdManager **)malloc((ex + 1) * sizeof(DdManager *));
  mgr_ex[ex] = Cudd_Init(0, 0, UNIQUE_SLOTS, CACHE_SLOTS, 5120);
  Cudd_AutodynEnable(mgr_ex[ex], CUDD_REORDER_GROUP_SIFT);
  Cudd_SetMaxCacheHard(mgr_ex[ex], 0);
  Cudd_SetLooseUpTo(mgr_ex[ex], 0);
  Cudd_SetMinHit(mgr_ex[ex], 15);

  bVar2mVar_ex = (int **)malloc((ex + 1) * sizeof(int *));
  bVar2mVar_ex[ex] = NULL;

  vars_ex = (variable **)malloc((ex + 1) * sizeof(variable *));
  vars_ex[ex] = NULL;

  nVars_ex = (int *)malloc((ex + 1) * sizeof(int));
  nVars_ex[ex] = 0;

  probs_ex = (double **)malloc((ex + 1) * sizeof(double *));
  probs_ex[ex] = NULL;

  boolVars_ex = (int *)malloc((ex + 1) * sizeof(int));
  boolVars_ex[ex] = 0;

  rules = (int *)malloc(nRules * sizeof(int));

  return 1;
}
Esempio n. 4
0
/**
 * Creates a new BDDManager.
 *
 * @param maxMemoryInMB The amount of memory to be used. Must be <4096 as CUDD does not support more
 * @param reorderingMaxBlowup The maximal allowed blowup during sifting steps in the reordering algorithm. Standard is 1.2 - use 1.1 to have less reordering done. A value of 1.0 results in greedy reordering.
 * @author ehlers
 */
BFBddManager::BFBddManager(unsigned int maxMemoryInMB, float reorderingMaxBlowup) {

	mgr = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, (long) maxMemoryInMB * 1024UL * 1024UL);

	// Configuring the manager
	Cudd_AutodynEnable(mgr, CUDD_REORDER_SIFT);
	Cudd_SetMaxGrowth(mgr, reorderingMaxBlowup);
	Cudd_SetMinHit(mgr, 1);
	setAutomaticOptimisation(true);
}
Esempio n. 5
0
/**Function********************************************************************

  Synopsis    [Starts the CUDD manager with the desired options.]

  Description [Starts the CUDD manager with the desired options.
  We start with 0 variables, because Ntr_buildDDs will create new
  variables rather than using whatever already exists.]

  SideEffects [None]

  SeeAlso     []

*****************************************************************************/
static DdManager *
startCudd(
  NtrOptions * option,
  int  nvars)
{
    DdManager *dd;
    int result;

    dd = Cudd_Init(0, 0, option->slots, option->cacheSize, option->maxMemory);
    if (dd == NULL) return(NULL);

    if (option->maxMemHard != 0) {
	Cudd_SetMaxMemory(dd,option->maxMemHard);
    }
    Cudd_SetMaxLive(dd,option->maxLive);
    Cudd_SetGroupcheck(dd,option->groupcheck);
    if (option->autoDyn & 1) {
	Cudd_AutodynEnable(dd,option->autoMethod);
    }
    dd->nextDyn = option->firstReorder;
    dd->countDead = (option->countDead == FALSE) ? ~0 : 0;
    dd->maxGrowth = 1.0 + ((float) option->maxGrowth / 100.0);
    dd->recomb = option->recomb;
    dd->arcviolation = option->arcviolation;
    dd->symmviolation = option->symmviolation;
    dd->populationSize = option->populationSize;
    dd->numberXovers = option->numberXovers;
    result = ntrReadTree(dd,option->treefile,nvars);
    if (result == 0) {
	Cudd_Quit(dd);
	return(NULL);
    }
#ifndef DD_STATS
    result = Cudd_EnableReorderingReporting(dd);
    if (result == 0) {
	(void) fprintf(stderr,
		       "Error reported by Cudd_EnableReorderingReporting\n");
	Cudd_Quit(dd);
	return(NULL);
    }
#endif

    return(dd);

} /* end of startCudd */
Esempio n. 6
0
void  initc(int reorder)
{
    int intBits;

    nVars=0;
    boolVars=0;
    mgr=Cudd_Init(nVars,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0);

    if (reorder != CUDD_REORDER_NONE)
        Cudd_AutodynEnable(mgr,reorder);

    vars= (variable *) malloc(nVars * sizeof(variable));
    probs=(double *) malloc(0);
    intBits=sizeof(unsigned int)*8;
    dividend=-1;
    /* dividend is a global variable used by my_hash
       it is equal to an unsigned int with binary representation 11..1 */
}
Esempio n. 7
0
/**Function*************************************************************

  Synopsis    [Recursively computes global BDDs for the AIG in the manager.]

  Description [On exit, BDDs are stored in the pNode->pData fields.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
DdManager * Aig_ManComputeGlobalBdds( Aig_Man_t * p, int nBddSizeMax, int fDropInternal, int fReorder, int fVerbose )
{
    ProgressBar * pProgress = NULL;
    Aig_Obj_t * pObj;
    DdManager * dd;
    DdNode * bFunc;
    int i, Counter;
    // start the manager
    dd = Cudd_Init( Aig_ManCiNum(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
    // set reordering
    if ( fReorder )
        Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
    // prepare to construct global BDDs
    Aig_ManCleanData( p );
    // assign the constant node BDD
    Aig_ObjSetGlobalBdd( Aig_ManConst1(p), dd->one );   Cudd_Ref( dd->one );
    // set the elementary variables
    Aig_ManForEachCi( p, pObj, i )
    {
        Aig_ObjSetGlobalBdd( pObj, dd->vars[i] );  Cudd_Ref( dd->vars[i] );
    }
Esempio n. 8
0
BddBuilder::BddBuilder(){
	__pddWireHead = __pddWireTail = NULL;
	__pddOutputWireHead = __pddOutputWireTail = NULL;
	__pddOutputNodes = NULL;
	__pddGateHead = __pddGateTail = NULL;
	__pddInputNodes = NULL;

	__pddManager = Cudd_Init(0, 0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS , 0);
	Cudd_ReduceHeap(__pddManager,CUDD_REORDER_RANDOM_PIVOT,0);
	Cudd_AutodynEnable(__pddManager,CUDD_REORDER_RANDOM_PIVOT);
	__Vcc = Cudd_ReadOne(__pddManager);
	__GND = Cudd_ReadLogicZero(__pddManager);
	
	char * name_vcc = new char[4];
	char * name_gnd = new char[4];

	sprintf(name_vcc, "Vcc");
	sprintf(name_gnd, "GND");

	__VccWire = new DdWire(__pddManager, name_vcc, 0, 0);
	__GNDWire = new DdWire(__pddManager, name_gnd, 0, 0);
	__VccWire->setDdNode(__Vcc);
	__GNDWire->setDdNode(__GND);

	Cudd_Ref(__Vcc);
	Cudd_Ref(__GND);

	if(__pddManager == NULL){
		perror("DdManager initializing error.");
	}

	//__inputWireCnt = 2; // Vcc & GND
	__inputWireCnt = -1;
	__outputWireCnt = -1;

	__pddInputWireHead = __VccWire;
	__VccWire->setInputListNext(__GNDWire);
	__pddInputWireTail = __GNDWire;
}
Esempio n. 9
0
/**Function********************************************************************

  Synopsis    [Main function for testcudd.]

  Description []

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
int
main(int argc, char **argv)
{
    FILE *fp;           /* pointer to input file */
    char *file = (char *) "";	/* input file name */
    FILE *dfp = NULL;	/* pointer to dump file */
    char *dfile;	/* file for DD dump */
    DdNode *dfunc[2];	/* addresses of the functions to be dumped */
    DdManager *dd;	/* pointer to DD manager */
    DdNode *_true;	/* fast access to constant function */
    DdNode *M;
    DdNode **x;		/* pointers to variables */
    DdNode **y;		/* pointers to variables */
    DdNode **xn;       	/* complements of row variables */
    DdNode **yn_;      	/* complements of column variables */
    DdNode **xvars;
    DdNode **yvars;
    DdNode *C;		/* result of converting from ADD to BDD */
    DdNode *ess;	/* cube of essential variables */
    DdNode *shortP;	/* BDD cube of shortest path */
    DdNode *largest;	/* BDD of largest cube */
    DdNode *shortA;	/* ADD cube of shortest path */
    DdNode *constN;	/* value returned by evaluation of ADD */
    DdNode *ycube;	/* cube of the negated y vars for c-proj */
    DdNode *CP;		/* C-Projection of C */
    DdNode *CPr;	/* C-Selection of C */
    int    length;	/* length of the shortest path */
    int    nx;			/* number of variables */
    int    ny;
    int    maxnx;
    int    maxny;
    int    m;
    int    n;
    int    N;
    int    cmu;			/* use CMU multiplication */
    int    pr;			/* verbose printout level */
    int    harwell;
    int    multiple;		/* read multiple matrices */
    int    ok;
    int    c;			/* variable to read in options */
    int    approach;		/* reordering approach */
    int    autodyn;		/* automatic reordering */
    int    groupcheck;		/* option for group sifting */
    int    profile;		/* print heap profile if != 0 */
    int    keepperm;		/* keep track of permutation */
    int    clearcache;		/* clear the cache after each matrix */
    int    blifOrDot;		/* dump format: 0 -> dot, 1 -> blif, ... */
    int    retval;		/* return value */
    int    i;			/* loop index */
    long   startTime;		/* initial time */
    long   lapTime;
    int    size;
    unsigned int cacheSize, maxMemory;
    unsigned int nvars,nslots;

    startTime = util_cpu_time();

    approach = CUDD_REORDER_NONE;
    autodyn = 0;
    pr = 0;
    harwell = 0;
    multiple = 0;
    profile = 0;
    keepperm = 0;
    cmu = 0;
    N = 4;
    nvars = 4;
    cacheSize = 127;
    maxMemory = 0;
    nslots = CUDD_UNIQUE_SLOTS;
    clearcache = 0;
    groupcheck = CUDD_GROUP_CHECK7;
    dfile = NULL;
    blifOrDot = 0; /* dot format */

    /* Parse command line. */
    while ((c = util_getopt(argc, argv, (char *) "CDHMPS:a:bcd:g:hkmn:p:v:x:X:"))
	   != EOF) {
	switch(c) {
	case 'C':
	    cmu = 1;
	    break;
	case 'D':
	    autodyn = 1;
	    break;
	case 'H':
	    harwell = 1;
	    break;
	case 'M':
#ifdef MNEMOSYNE
	    (void) mnem_setrecording(0);
#endif
	    break;
	case 'P':
	    profile = 1;
	    break;
	case 'S':
	    nslots = atoi(util_optarg);
	    break;
	case 'X':
	    maxMemory = atoi(util_optarg);
	    break;
	case 'a':
	    approach = atoi(util_optarg);
	    break;
	case 'b':
	    blifOrDot = 1; /* blif format */
	    break;
	case 'c':
	    clearcache = 1;
	    break;
	case 'd':
	    dfile = util_optarg;
	    break;
	case 'g':
	    groupcheck = atoi(util_optarg);
	    break;
	case 'k':
	    keepperm = 1;
	    break;
	case 'm':
	    multiple = 1;
	    break;
	case 'n':
	    N = atoi(util_optarg);
	    break;
	case 'p':
	    pr = atoi(util_optarg);
	    break;
	case 'v':
	    nvars = atoi(util_optarg);
	    break;
	case 'x':
	    cacheSize = atoi(util_optarg);
	    break;
	case 'h':
	default:
	    usage(argv[0]);
	    break;
	}
    }

    if (argc - util_optind == 0) {
	file = (char *) "-";
    } else if (argc - util_optind == 1) {
	file = argv[util_optind];
    } else {
	usage(argv[0]);
    }
    if ((approach<0) || (approach>17)) {
	(void) fprintf(stderr,"Invalid approach: %d \n",approach);
	usage(argv[0]);
    }

    if (pr >= 0) {
	(void) printf("# %s\n", TESTCUDD_VERSION);
	/* Echo command line and arguments. */
	(void) printf("#");
	for (i = 0; i < argc; i++) {
	    (void) printf(" %s", argv[i]);
	}
	(void) printf("\n");
	(void) fflush(stdout);
    }

    /* Initialize manager and provide easy reference to terminals. */
    dd = Cudd_Init(nvars,0,nslots,cacheSize,maxMemory);
    _true = DD_TRUE(dd);
    dd->groupcheck = (Cudd_AggregationType) groupcheck;
    if (autodyn) Cudd_AutodynEnable(dd,CUDD_REORDER_SAME);

    /* Open input file. */
    fp = open_file(file, "r");

    /* Open dump file if requested */
    if (dfile != NULL) {
	dfp = open_file(dfile, "w");
    }

    x = y = xn = yn_ = NULL;
    do {
	/* We want to start anew for every matrix. */
	maxnx = maxny = 0;
	nx = maxnx; ny = maxny;
	if (pr>0) lapTime = util_cpu_time();
	if (harwell) {
	    if (pr >= 0) (void) printf(":name: ");
	    ok = Cudd_addHarwell(fp, dd, &M, &x, &y, &xn, &yn_, &nx, &ny,
	    &m, &n, 0, 2, 1, 2, pr);
	} else {
	    ok = Cudd_addRead(fp, dd, &M, &x, &y, &xn, &yn_, &nx, &ny,
	    &m, &n, 0, 2, 1, 2);
	    if (pr >= 0)
		(void) printf(":name: %s: %d rows %d columns\n", file, m, n);
	}
	if (!ok) {
	    (void) fprintf(stderr, "Error reading matrix\n");
	    exit(1);
	}

	if (nx > maxnx) maxnx = nx;
	if (ny > maxny) maxny = ny;

	/* Build cube of negated y's. */
	ycube = DD_TRUE(dd);
	Cudd_Ref(ycube);
	for (i = maxny - 1; i >= 0; i--) {
	    DdNode *tmpp;
	    tmpp = Cudd_bddAnd(dd,Cudd_Not(dd->vars[y[i]->index]),ycube);
	    if (tmpp == NULL) exit(2);
	    Cudd_Ref(tmpp);
	    Cudd_RecursiveDeref(dd,ycube);
	    ycube = tmpp;
	}
	/* Initialize vectors of BDD variables used by priority func. */
	xvars = ALLOC(DdNode *, nx);
	if (xvars == NULL) exit(2);
	for (i = 0; i < nx; i++) {
	    xvars[i] = dd->vars[x[i]->index];
	}
	yvars = ALLOC(DdNode *, ny);
	if (yvars == NULL) exit(2);
	for (i = 0; i < ny; i++) {
	    yvars[i] = dd->vars[y[i]->index];
	}

	/* Clean up */
	for (i=0; i < maxnx; i++) {
	    Cudd_RecursiveDeref(dd, x[i]);
	    Cudd_RecursiveDeref(dd, xn[i]);
	}
	FREE(x);
	FREE(xn);
	for (i=0; i < maxny; i++) {
	    Cudd_RecursiveDeref(dd, y[i]);
	    Cudd_RecursiveDeref(dd, yn_[i]);
	}
	FREE(y);
	FREE(yn_);

	if (pr>0) {(void) printf(":1: M"); Cudd_PrintDebug(dd,M,nx+ny,pr);}

	if (pr>0) (void) printf(":2: time to read the matrix = %s\n",
		    util_print_time(util_cpu_time() - lapTime));

	C = Cudd_addBddPattern(dd, M);
	if (C == 0) exit(2);
	Cudd_Ref(C);
	if (pr>0) {(void) printf(":3: C"); Cudd_PrintDebug(dd,C,nx+ny,pr);}

	/* Test iterators. */
	retval = testIterators(dd,M,C,pr);
	if (retval == 0) exit(2);

	cuddCacheProfile(dd,stdout);

	/* Test XOR */
	retval = testXor(dd,C,pr,nx+ny);
	if (retval == 0) exit(2);

	/* Test Hamming distance functions. */
	retval = testHamming(dd,C,pr);
	if (retval == 0) exit(2);

	/* Test selection functions. */
	CP = Cudd_CProjection(dd,C,ycube);
	if (CP == NULL) exit(2);
	Cudd_Ref(CP);
	if (pr>0) {(void) printf("ycube"); Cudd_PrintDebug(dd,ycube,nx+ny,pr);}
	if (pr>0) {(void) printf("CP"); Cudd_PrintDebug(dd,CP,nx+ny,pr);}

	if (nx == ny) {
	    CPr = Cudd_PrioritySelect(dd,C,xvars,yvars,(DdNode **)NULL,
		(DdNode *)NULL,ny,Cudd_Xgty);
	    if (CPr == NULL) exit(2);
	    Cudd_Ref(CPr);
	    if (pr>0) {(void) printf(":4: CPr"); Cudd_PrintDebug(dd,CPr,nx+ny,pr);}
	    if (CP != CPr) {
		(void) printf("CP != CPr!\n");
	    }
	    Cudd_RecursiveDeref(dd, CPr);
	}
	FREE(xvars); FREE(yvars);

	Cudd_RecursiveDeref(dd, CP);
	Cudd_RecursiveDeref(dd, ycube);

	/* Test functions for essential variables. */
	ess = Cudd_FindEssential(dd,C);
	if (ess == NULL) exit(2);
	Cudd_Ref(ess);
	if (pr>0) {(void) printf(":4: ess"); Cudd_PrintDebug(dd,ess,nx+ny,pr);}
	Cudd_RecursiveDeref(dd, ess);

	/* Test functions for shortest paths. */
	shortP = Cudd_ShortestPath(dd, M, NULL, NULL, &length);
	if (shortP == NULL) exit(2);
	Cudd_Ref(shortP);
	if (pr>0) {
	    (void) printf(":5: shortP"); Cudd_PrintDebug(dd,shortP,nx+ny,pr);
	}
	/* Test functions for largest cubes. */
	largest = Cudd_LargestCube(dd, Cudd_Not(C), &length);
	if (largest == NULL) exit(2);
	Cudd_Ref(largest);
	if (pr>0) {
	    (void) printf(":5b: largest");
	    Cudd_PrintDebug(dd,largest,nx+ny,pr);
	}
	Cudd_RecursiveDeref(dd, largest);

	/* Test Cudd_addEvalConst and Cudd_addIteConstant. */
	shortA = Cudd_BddToAdd(dd,shortP);
	if (shortA == NULL) exit(2);
	Cudd_Ref(shortA);
	Cudd_RecursiveDeref(dd, shortP);
	constN = Cudd_addEvalConst(dd,shortA,M);
	if (constN == DD_NON_CONSTANT) exit(2);
	if (Cudd_addIteConstant(dd,shortA,M,constN) != constN) exit(2);
	if (pr>0) {(void) printf("The value of M along the chosen shortest path is %g\n", cuddV(constN));}
	Cudd_RecursiveDeref(dd, shortA);

	shortP = Cudd_ShortestPath(dd, C, NULL, NULL, &length);
	if (shortP == NULL) exit(2);
	Cudd_Ref(shortP);
	if (pr>0) {
	    (void) printf(":6: shortP"); Cudd_PrintDebug(dd,shortP,nx+ny,pr);
	}

	/* Test Cudd_bddIteConstant and Cudd_bddLeq. */
	if (!Cudd_bddLeq(dd,shortP,C)) exit(2);
	if (Cudd_bddIteConstant(dd,Cudd_Not(shortP),_true,C) != _true) exit(2);
	Cudd_RecursiveDeref(dd, shortP);

	if (profile) {
	    retval = cuddHeapProfile(dd);
	}

	size = dd->size;

	if (pr>0) {
	    (void) printf("Average distance: %g\n", Cudd_AverageDistance(dd));
	}

	/* Reorder if so requested. */
        if (approach != CUDD_REORDER_NONE) {
#ifndef DD_STATS
	    retval = Cudd_EnableReorderingReporting(dd);
	    if (retval == 0) {
		(void) fprintf(stderr,"Error reported by Cudd_EnableReorderingReporting\n");
		exit(3);
	    }
#endif
#ifdef DD_DEBUG
	    retval = Cudd_DebugCheck(dd);
	    if (retval != 0) {
		(void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n");
		exit(3);
	    }
	    retval = Cudd_CheckKeys(dd);
	    if (retval != 0) {
		(void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n");
		exit(3);
	    }
#endif
	    retval = Cudd_ReduceHeap(dd,(Cudd_ReorderingType)approach,5);
	    if (retval == 0) {
		(void) fprintf(stderr,"Error reported by Cudd_ReduceHeap\n");
		exit(3);
	    }
#ifndef DD_STATS
	    retval = Cudd_DisableReorderingReporting(dd);
	    if (retval == 0) {
		(void) fprintf(stderr,"Error reported by Cudd_DisableReorderingReporting\n");
		exit(3);
	    }
#endif
#ifdef DD_DEBUG
	    retval = Cudd_DebugCheck(dd);
	    if (retval != 0) {
		(void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n");
		exit(3);
	    }
	    retval = Cudd_CheckKeys(dd);
	    if (retval != 0) {
		(void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n");
		exit(3);
	    }
#endif
	    if (approach == CUDD_REORDER_SYMM_SIFT ||
	    approach == CUDD_REORDER_SYMM_SIFT_CONV) {
		Cudd_SymmProfile(dd,0,dd->size-1);
	    }

	    if (pr>0) {
		(void) printf("Average distance: %g\n", Cudd_AverageDistance(dd));
	    }

	    if (keepperm) {
		/* Print variable permutation. */
		(void) printf("Variable Permutation:");
		for (i=0; i<size; i++) {
		    if (i%20 == 0) (void) printf("\n");
		    (void) printf("%d ", dd->invperm[i]);
		}
		(void) printf("\n");
		(void) printf("Inverse Permutation:");
		for (i=0; i<size; i++) {
		    if (i%20 == 0) (void) printf("\n");
		    (void) printf("%d ", dd->perm[i]);
		}
		(void) printf("\n");
	    }

	    if (pr>0) {(void) printf("M"); Cudd_PrintDebug(dd,M,nx+ny,pr);}

	    if (profile) {
		retval = cuddHeapProfile(dd);
	    }

	}

	/* Dump DDs of C and M if so requested. */
	if (dfile != NULL) {
	    dfunc[0] = C;
	    dfunc[1] = M;
	    if (blifOrDot == 1) {
		/* Only dump C because blif cannot handle ADDs */
		retval = Cudd_DumpBlif(dd,1,dfunc,NULL,(char **)onames,
				       NULL,dfp);
	    } else {
		retval = Cudd_DumpDot(dd,2,dfunc,NULL,(char **)onames,dfp);
	    }
	    if (retval != 1) {
		(void) fprintf(stderr,"abnormal termination\n");
		exit(2);
	    }
	}

	Cudd_RecursiveDeref(dd, C);
	Cudd_RecursiveDeref(dd, M);

	if (clearcache) {
	    if (pr>0) {(void) printf("Clearing the cache... ");}
	    for (i = dd->cacheSlots - 1; i>=0; i--) {
		dd->cache[i].data = NIL(DdNode);
	    }
	    if (pr>0) {(void) printf("done\n");}
	}
	if (pr>0) {
	    (void) printf("Number of variables = %6d\t",dd->size);
	    (void) printf("Number of slots     = %6d\n",dd->slots);
	    (void) printf("Number of keys      = %6d\t",dd->keys);
	    (void) printf("Number of min dead  = %6d\n",dd->minDead);
	}

    } while (multiple && !feof(fp));

    fclose(fp);
    if (dfile != NULL) {
	fclose(dfp);
    }

    /* Second phase: experiment with Walsh matrices. */
    if (!testWalsh(dd,N,cmu,approach,pr)) {
	exit(2);
    }

    /* Check variable destruction. */
    assert(cuddDestroySubtables(dd,3));
    assert(Cudd_DebugCheck(dd) == 0);
    assert(Cudd_CheckKeys(dd) == 0);

    retval = Cudd_CheckZeroRef(dd);
    ok = retval != 0;  /* ok == 0 means O.K. */
    if (retval != 0) {
	(void) fprintf(stderr,
	    "%d non-zero DD reference counts after dereferencing\n", retval);
    }

    if (pr >= 0) {
	(void) Cudd_PrintInfo(dd,stdout);
    }

    Cudd_Quit(dd);

#ifdef MNEMOSYNE
    mnem_writestats();
#endif

    if (pr>0) (void) printf("total time = %s\n",
		util_print_time(util_cpu_time() - startTime));

    if (pr >= 0) util_print_cpu_stats(stdout);
    exit(ok);
    /* NOTREACHED */

} /* end of main */
Esempio n. 10
0
int main( int argc, char **argv )
{
    FILE *fp;
    FILE *stdin_backup = NULL;
    bool help_flag = False;
    bool ptdump_flag = False;
    bool logging_flag = False;
    unsigned char verbose = 0;
    int input_index = -1;
    int output_file_index = -1;  /* For command-line flag "-o". */
    char dumpfilename[64];

    int i, j, var_index;
    ptree_t *tmppt;  /* General purpose temporary ptree pointer */
    int horizon = -1;

    DdNode *W, *etrans, *strans, **sgoals, **egoals;

    DdManager *manager;
    DdNode *T = NULL;
    anode_t *strategy = NULL;
    int num_env, num_sys;
    int original_num_env, original_num_sys;

    int max_sim_it;  /* Number of simulation iterations */
    anode_t *play;
    vartype *init_state;
    int *init_state_ints = NULL;
    char *all_vars = NULL, *metric_vars = NULL;
    int *offw, num_vars;
    int init_state_acc;  /* Accumulate components of initial state
                            before expanding into a (bool) bitvector. */

    /* Look for flags in command-line arguments. */
    for (i = 1; i < argc; i++) {
        if (argv[i][0] == '-') {
            if (argv[i][1] == 'h') {
                help_flag = True;
            } else if (argv[i][1] == 'V') {
                printf( "grjit (experiment-related program, distributed with"
                        " gr1c v" GR1C_VERSION ")\n\n" GR1C_COPYRIGHT "\n" );
                return 0;
            } else if (argv[i][1] == 'v') {
                verbose = 1;
                j = 2;
                /* Only support up to "level 2" of verbosity */
                while (argv[i][j] == 'v' && j <= 2) {
                    verbose++;
                    j++;
                }
            } else if (argv[i][1] == 'l') {
                logging_flag = True;
            } else if (argv[i][1] == 'p') {
                ptdump_flag = True;
            } else if (argv[i][1] == 'm') {
                if (i == argc-1) {
                    fprintf( stderr, "Invalid flag given. Try \"-h\".\n" );
                    return 1;
                }
                all_vars = strtok( argv[i+1], "," );
                max_sim_it = strtol( all_vars, NULL, 10 );
                all_vars = strtok( NULL, "," );
                if (all_vars == NULL) {
                    fprintf( stderr, "Invalid use of -m flag.\n" );
                    return 1;
                }
                metric_vars = strdup( all_vars );
                if (max_sim_it >= 0) {
                    all_vars = strtok( NULL, "," );
                    if (all_vars == NULL) {
                        fprintf( stderr, "Invalid use of -m flag.\n" );
                        return 1;
                    }
                    init_state_acc = read_state_str( all_vars,
                                                     &init_state_ints, -1 );
                    all_vars = strtok( NULL, "," );
                    if (all_vars == NULL) {
                        horizon = -1;  /* The horizon was not given. */
                    } else {
                        horizon = strtol( all_vars, NULL, 10 );
                        if (horizon < 1) {
                            fprintf( stderr,
                                     "Invalid use of -m flag.  Horizon must"
                                     " be positive.\n" );
                            return 1;
                        }
                    }
                }
                all_vars = NULL;
                i++;
            } else if (argv[i][1] == 'o') {
                if (i == argc-1) {
                    fprintf( stderr, "Invalid flag given. Try \"-h\".\n" );
                    return 1;
                }
                output_file_index = i+1;
                i++;
            } else {
                fprintf( stderr, "Invalid flag given. Try \"-h\".\n" );
                return 1;
            }
        } else if (input_index < 0) {
            /* Use first non-flag argument as filename whence to read
               specification. */
            input_index = i;
        }
    }

    if (help_flag) {
        /* Split among printf() calls to conform with ISO C90 string length */
        printf( "Usage: %s [-hVvlp] [-m ARG1,ARG2,...] [-o FILE] [FILE]\n\n"
                "  -h          this help message\n"
                "  -V          print version and exit\n"
                "  -v          be verbose; use -vv to be more verbose\n"
                "  -l          enable logging\n"
                "  -p          dump parse trees to DOT files, and echo formulas to screen\n"
                "  -o FILE     output results to FILE, rather than stdout (default)\n", argv[0] );
        printf( "  -m ARG1,... run simulation using comma-separated list of arguments:\n"
                "                ARG1 is the max simulation duration; -1 to only compute horizon;\n"
                "                ARG2 is a space-separated list of metric variables;\n"
                "                ARG3 is a space-separated list of initial values;\n"
                "                    ARG3 is ignored and may be omitted if ARG1 equals -1.\n"
                "                ARG4 is the horizon, if provided; otherwise compute it.\n" );
        return 1;
    }

    if (logging_flag) {
        openlogfile( NULL );  /* Use default filename prefix */
        /* Only change verbosity level if user did not specify it */
        if (verbose == 0)
            verbose = 1;
    } else {
        setlogstream( stdout );
        setlogopt( LOGOPT_NOTIME );
    }
    if (verbose > 0)
        logprint( "Running with verbosity level %d.", verbose );

    /* If filename for specification given at command-line, then use
       it.  Else, read from stdin. */
    if (input_index > 0) {
        fp = fopen( argv[input_index], "r" );
        if (fp == NULL) {
            perror( "grjit, fopen" );
            return -1;
        }
        stdin_backup = stdin;
        stdin = fp;
    }

    /* Parse the specification. */
    if (verbose)
        logprint( "Parsing input..." );
    SPC_INIT( spc );
    if (yyparse())
        return -1;
    if (verbose)
        logprint( "Done." );
    if (stdin_backup != NULL) {
        stdin = stdin_backup;
    }

    /* Close input file, if opened. */
    if (input_index > 0)
        fclose( fp );

    /* Treat deterministic problem in which ETRANS or EINIT is omitted. */
    if (spc.evar_list == NULL) {
        if (spc.et_array_len == 0) {
            spc.et_array_len = 1;
            spc.env_trans_array = malloc( sizeof(ptree_t *) );
            if (spc.env_trans_array == NULL) {
                perror( "gr1c, malloc" );
                return -1;
            }
            *spc.env_trans_array = init_ptree( PT_CONSTANT, NULL, 1 );
        }
        if (spc.env_init == NULL)
            spc.env_init = init_ptree( PT_CONSTANT, NULL, 1 );
    }

    /* Number of variables, before expansion of those that are nonboolean */
    original_num_env = tree_size( spc.evar_list );
    original_num_sys = tree_size( spc.svar_list );

    /* Build list of variable names if needed for simulation, storing
       the result as a string in all_vars */
    if (max_sim_it >= 0) {
        /* At this point, init_state_acc should contain the number of
           integers read by read_state_str() during
           command-line argument parsing. */
        if (init_state_acc != original_num_env+original_num_sys) {
            fprintf( stderr,
                     "Number of initial values given does not match number"
                     " of problem variables.\n" );
            return 1;
        }

        num_vars = 0;
        tmppt = spc.evar_list;
        while (tmppt) {
            num_vars += strlen( tmppt->name )+1;
            tmppt = tmppt->left;
        }
        tmppt = spc.svar_list;
        while (tmppt) {
            num_vars += strlen( tmppt->name )+1;
            tmppt = tmppt->left;
        }
        all_vars = malloc( num_vars*sizeof(char) );
        if (all_vars == NULL) {
            perror( "main, malloc" );
            return -1;
        }
        i = 0;
        tmppt = spc.evar_list;
        while (tmppt) {
            strncpy( all_vars+i, tmppt->name, num_vars-i );
            i += strlen( tmppt->name )+1;
            *(all_vars+i-1) = ' ';
            tmppt = tmppt->left;
        }
        tmppt = spc.svar_list;
        while (tmppt) {
            strncpy( all_vars+i, tmppt->name, num_vars-i );
            i += strlen( tmppt->name )+1;
            *(all_vars+i-1) = ' ';
            tmppt = tmppt->left;
        }
        *(all_vars+i-1) = '\0';
        if (verbose)
            logprint( "String of all variables found to be \"%s\"", all_vars );
    }


    if (ptdump_flag) {
        tree_dot_dump( spc.env_init, "env_init_ptree.dot" );
        tree_dot_dump( spc.sys_init, "sys_init_ptree.dot" );

        for (i = 0; i < spc.et_array_len; i++) {
            snprintf( dumpfilename, sizeof(dumpfilename),
                      "env_trans%05d_ptree.dot", i );
            tree_dot_dump( *(spc.env_trans_array+i), dumpfilename );
        }
        for (i = 0; i < spc.st_array_len; i++) {
            snprintf( dumpfilename, sizeof(dumpfilename),
                      "sys_trans%05d_ptree.dot", i );
            tree_dot_dump( *(spc.sys_trans_array+i), dumpfilename );
        }

        if (spc.num_egoals > 0) {
            for (i = 0; i < spc.num_egoals; i++) {
                snprintf( dumpfilename, sizeof(dumpfilename),
                         "env_goal%05d_ptree.dot", i );
                tree_dot_dump( *(spc.env_goals+i), dumpfilename );
            }
        }
        if (spc.num_sgoals > 0) {
            for (i = 0; i < spc.num_sgoals; i++) {
                snprintf( dumpfilename, sizeof(dumpfilename),
                         "sys_goal%05d_ptree.dot", i );
                tree_dot_dump( *(spc.sys_goals+i), dumpfilename );
            }
        }

        var_index = 0;
        printf( "Environment variables (indices; domains): " );
        if (spc.evar_list == NULL) {
            printf( "(none)" );
        } else {
            tmppt = spc.evar_list;
            while (tmppt) {
                if (tmppt->value == 0) {  /* Boolean */
                    if (tmppt->left == NULL) {
                        printf( "%s (%d; bool)", tmppt->name, var_index );
                    } else {
                        printf( "%s (%d; bool), ", tmppt->name, var_index);
                    }
                } else {
                    if (tmppt->left == NULL) {
                        printf( "%s (%d; {0..%d})",
                                tmppt->name, var_index, tmppt->value );
                    } else {
                        printf( "%s (%d; {0..%d}), ",
                                tmppt->name, var_index, tmppt->value );
                    }
                }
                tmppt = tmppt->left;
                var_index++;
            }
        }
        printf( "\n\n" );

        printf( "System variables (indices; domains): " );
        if (spc.svar_list == NULL) {
            printf( "(none)" );
        } else {
            tmppt = spc.svar_list;
            while (tmppt) {
                if (tmppt->value == 0) {  /* Boolean */
                    if (tmppt->left == NULL) {
                        printf( "%s (%d; bool)", tmppt->name, var_index );
                    } else {
                        printf( "%s (%d; bool), ", tmppt->name, var_index );
                    }
                } else {
                    if (tmppt->left == NULL) {
                        printf( "%s (%d; {0..%d})",
                                tmppt->name, var_index, tmppt->value );
                    } else {
                        printf( "%s (%d; {0..%d}), ",
                                tmppt->name, var_index, tmppt->value );
                    }
                }
                tmppt = tmppt->left;
                var_index++;
            }
        }
        printf( "\n\n" );

        print_GR1_spec( spc.evar_list, spc.svar_list, spc.env_init, spc.sys_init,
                        spc.env_trans_array, spc.et_array_len,
                        spc.sys_trans_array, spc.st_array_len,
                        spc.env_goals, spc.num_egoals, spc.sys_goals, spc.num_sgoals, stdout );
    }

    if (expand_nonbool_GR1( spc.evar_list, spc.svar_list, &spc.env_init, &spc.sys_init,
                            &spc.env_trans_array, &spc.et_array_len,
                            &spc.sys_trans_array, &spc.st_array_len,
                            &spc.env_goals, spc.num_egoals, &spc.sys_goals, spc.num_sgoals,
                            verbose ) < 0)
        return -1;
    spc.nonbool_var_list = expand_nonbool_variables( &spc.evar_list, &spc.svar_list,
                                                     verbose );

    if (spc.et_array_len > 1) {
        spc.env_trans = merge_ptrees( spc.env_trans_array, spc.et_array_len, PT_AND );
    } else if (spc.et_array_len == 1) {
        spc.env_trans = *spc.env_trans_array;
    } else {
        fprintf( stderr,
                 "Syntax error: GR(1) specification is missing environment"
                 " transition rules.\n" );
        return -1;
    }
    if (spc.st_array_len > 1) {
        spc.sys_trans = merge_ptrees( spc.sys_trans_array, spc.st_array_len, PT_AND );
    } else if (spc.st_array_len == 1) {
        spc.sys_trans = *spc.sys_trans_array;
    } else {
        fprintf( stderr,
                 "Syntax error: GR(1) specification is missing system"
                 " transition rules.\n" );
        return -1;
    }

    if (verbose > 1)
        /* Dump the spec to show results of conversion (if any). */
        print_GR1_spec( spc.evar_list, spc.svar_list, spc.env_init, spc.sys_init,
                        spc.env_trans_array, spc.et_array_len,
                        spc.sys_trans_array, spc.st_array_len,
                        spc.env_goals, spc.num_egoals, spc.sys_goals, spc.num_sgoals, NULL );


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

    manager = Cudd_Init( 2*(num_env+num_sys),
                         0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
    Cudd_SetMaxCacheHard( manager, (unsigned int)-1 );
    Cudd_AutodynEnable( manager, CUDD_REORDER_SAME );

    T = check_realizable( manager, EXIST_SYS_INIT, verbose );
    if (verbose) {
        if (T != NULL) {
            logprint( "Realizable." );
        } else {
            logprint( "Not realizable." );
        }
    }

    if (T != NULL) { /* Print measure data and simulate. */
        if (horizon < 0) {
            if (verbose)
                logprint( "Computing horizon with metric variables: %s",
                          metric_vars );
            horizon = compute_horizon( manager, &W, &etrans, &strans, &sgoals,
                                       metric_vars, verbose );
            logprint( "horizon: %d", horizon );
            if (getlogstream() != stdout)
                printf( "horizon: %d\n", horizon );
        } else {
            W = compute_winning_set_saveBDDs( manager, &etrans, &strans,
                                              &egoals, &sgoals, verbose );
            if (verbose)
                logprint( "Using given horizon: %d", horizon );
        }

        if (max_sim_it >= 0 && horizon > -1) {
            /* Compute variable offsets and use it to get the initial
               state as a bitvector */
            offw = get_offsets( all_vars, &num_vars );
            if (num_vars != original_num_env+original_num_sys) {
                fprintf( stderr,
                         "Error while computing bitwise variable offsets.\n" );
                return -1;
            }
            free( all_vars );
            init_state_acc = 0;
            if (verbose) {
                logprint_startline();
                logprint_raw( "initial state for simulation:" );
            }
            for (i = 0; i < original_num_env+original_num_sys; i++) {
                if (verbose)
                    logprint_raw( " %d", *(init_state_ints+i) );
                init_state_acc += *(init_state_ints+i) << *(offw + 2*i);
            }
            if (verbose)
                logprint_endline();
            free( offw );
            init_state = int_to_bitvec( init_state_acc, num_env+num_sys );
            if (init_state == NULL)
                return -1;

            play = sim_rhc( manager, W, etrans, strans, sgoals, metric_vars,
                            horizon, init_state, max_sim_it, verbose );
            if (play == NULL) {
                fprintf( stderr,
                         "Error while attempting receding horizon"
                         " simulation.\n" );
                return -1;
            }
            free( init_state );
            logprint( "play length: %d", aut_size( play ) );
            tmppt = spc.nonbool_var_list;
            while (tmppt) {
                aut_compact_nonbool( play, spc.evar_list, spc.svar_list,
                                     tmppt->name, tmppt->value );
                tmppt = tmppt->left;
            }

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

            /* Open output file if specified; else point to stdout. */
            if (output_file_index >= 0) {
                fp = fopen( argv[output_file_index], "w" );
                if (fp == NULL) {
                    perror( "grjit, fopen" );
                    return -1;
                }
            } else {
                fp = stdout;
            }

            /* Print simulation trace */
            dump_simtrace( play, spc.evar_list, spc.svar_list, fp );
            if (fp != stdout)
                fclose( fp );
        }


        Cudd_RecursiveDeref( manager, W );
        Cudd_RecursiveDeref( manager, etrans );
        Cudd_RecursiveDeref( manager, strans );
    }

    /* Clean-up */
    free( metric_vars );
    delete_tree( spc.evar_list );
    delete_tree( spc.svar_list );
    delete_tree( spc.env_init );
    delete_tree( spc.sys_init );
    delete_tree( spc.env_trans );
    delete_tree( spc.sys_trans );
    for (i = 0; i < spc.num_egoals; i++)
        delete_tree( *(spc.env_goals+i) );
    if (spc.num_egoals > 0)
        free( spc.env_goals );
    for (i = 0; i < spc.num_sgoals; i++)
        delete_tree( *(spc.sys_goals+i) );
    if (spc.num_sgoals > 0)
        free( spc.sys_goals );
    if (T != NULL)
        Cudd_RecursiveDeref( manager, T );
    if (strategy)
        delete_aut( strategy );
    if (verbose > 1)
        logprint( "Cudd_CheckZeroRef -> %d", Cudd_CheckZeroRef( manager ) );
    Cudd_Quit(manager);
    if (logging_flag)
        closelogfile();

    /* Return 0 if realizable, -1 if not realizable. */
    if (T != NULL) {
        return 0;
    } else {
        return -1;
    }

    return 0;
}
Esempio n. 11
0
anode_t *synthesize( DdManager *manager,  unsigned char init_flags,
                     unsigned char verbose )
{
    anode_t *strategy = NULL;
    anode_t *this_node_stack = NULL;
    anode_t *node, *new_node;
    bool initial;
    vartype *state;
    vartype **env_moves;
    int emoves_len;

    ptree_t *var_separator;
    DdNode *W;
    DdNode *strans_into_W;

    DdNode *einit, *sinit, *etrans, *strans, **egoals, **sgoals;

    DdNode *ddval;  /* Store result of evaluating a BDD */
    DdNode ***Y = NULL;
    DdNode *Y_i_primed;
    int *num_sublevels;
    DdNode ****X_ijr = NULL;

    DdNode *tmp, *tmp2;
    int i, j, r, k;  /* Generic counters */
    int offset;
    bool env_nogoal_flag = False;  /* Indicate environment has no goals */
    int loop_mode;
    int next_mode;

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

    /* Variables used during CUDD generation (state enumeration). */
    DdGen *gen;
    CUDD_VALUE_TYPE gvalue;
    int *gcube;

    /* Set environment goal to True (i.e., any state) if none was
       given. This simplifies the implementation below. */
    if (spc.num_egoals == 0) {
        env_nogoal_flag = True;
        spc.num_egoals = 1;
        spc.env_goals = malloc( sizeof(ptree_t *) );
        *spc.env_goals = init_ptree( PT_CONSTANT, NULL, 1 );
    }

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

    /* State vector (i.e., valuation of the variables) */
    state = malloc( sizeof(vartype)*(num_env+num_sys) );
    if (state == NULL) {
        perror( __FILE__ ",  malloc" );
        exit(-1);
    }

    /* 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);
    }

    /* Chain together environment and system variable lists for
       working with BDD library. */
    if (spc.evar_list == NULL) {
        var_separator = NULL;
        spc.evar_list = spc.svar_list;  /* that this is the deterministic case
                                           is indicated by var_separator = NULL. */
    } else {
        var_separator = get_list_item( spc.evar_list, -1 );
        if (var_separator == NULL) {
            fprintf( stderr,
                     "Error: get_list_item failed on environment variables"
                     " list.\n" );
            free( state );
            free( cube );
            return NULL;
        }
        var_separator->left = spc.svar_list;
    }

    /* Generate BDDs for the various parse trees from the problem spec. */
    if (spc.env_init != NULL) {
        einit = ptree_BDD( spc.env_init, spc.evar_list, manager );
    } else {
        einit = Cudd_ReadOne( manager );
        Cudd_Ref( einit );
    }
    if (spc.sys_init != NULL) {
        sinit = ptree_BDD( spc.sys_init, spc.evar_list, manager );
    } else {
        sinit = Cudd_ReadOne( manager );
        Cudd_Ref( sinit );
    }
    if (verbose > 1)
        logprint( "Building environment transition BDD..." );
    etrans = ptree_BDD( spc.env_trans, spc.evar_list, manager );
    if (verbose > 1) {
        logprint( "Done." );
        logprint( "Building system transition BDD..." );
    }
    strans = ptree_BDD( spc.sys_trans, spc.evar_list, manager );
    if (verbose > 1)
        logprint( "Done." );

    /* Build goal BDDs, if present. */
    if (spc.num_egoals > 0) {
        egoals = malloc( spc.num_egoals*sizeof(DdNode *) );
        for (i = 0; i < spc.num_egoals; i++)
            *(egoals+i) = ptree_BDD( *(spc.env_goals+i), spc.evar_list, manager );
    } else {
        egoals = NULL;
    }
    if (spc.num_sgoals > 0) {
        sgoals = malloc( spc.num_sgoals*sizeof(DdNode *) );
        for (i = 0; i < spc.num_sgoals; i++)
            *(sgoals+i) = ptree_BDD( *(spc.sys_goals+i), spc.evar_list, manager );
    } else {
        sgoals = NULL;
    }

    if (var_separator == NULL) {
        spc.evar_list = NULL;
    } else {
        var_separator->left = NULL;
    }

    W = compute_winning_set_BDD( manager, etrans, strans, egoals, sgoals,
                                 verbose );
    if (W == NULL) {
        fprintf( stderr,
                 "Error synthesize: failed to construct winning set.\n" );
        free( state );
        free( cube );
        return NULL;
    }
    Y = compute_sublevel_sets( manager, W, etrans, strans,
                               egoals, spc.num_egoals,
                               sgoals, spc.num_sgoals,
                               &num_sublevels, &X_ijr, verbose );
    if (Y == NULL) {
        fprintf( stderr,
                 "Error synthesize: failed to construct sublevel sets.\n" );
        free( state );
        free( cube );
        return NULL;
    }

    /* The sublevel sets are exactly as resulting from the vanilla
       fixed point formula.  Thus for each system goal i, Y_0 = \emptyset,
       and Y_1 is a union of i-goal states and environment-blocking states.

       For the purpose of synthesis, it is enough to delete Y_0 and
       replace Y_1 with the intersection of i-goal states and the
       winning set, and then shift the indices down (so that Y_1 is
       now called Y_0, Y_2 is now called Y_1, etc.) */
    for (i = 0; i < spc.num_sgoals; i++) {
        Cudd_RecursiveDeref( manager, *(*(Y+i)) );
        Cudd_RecursiveDeref( manager, *(*(Y+i)+1) );
        for (r = 0; r < spc.num_egoals; r++)
            Cudd_RecursiveDeref( manager, *(*(*(X_ijr+i))+r) );
        free( *(*(X_ijr+i)) );

        *(*(Y+i)+1) = Cudd_bddAnd( manager, *(sgoals+i), W );
        Cudd_Ref( *(*(Y+i)+1) );

        (*(num_sublevels+i))--;
        for (j = 0; j < *(num_sublevels+i); j++) {
            *(*(Y+i)+j) = *(*(Y+i)+j+1);
            *(*(X_ijr+i)+j) = *(*(X_ijr+i)+j+1);
        }

        assert( *(num_sublevels+i) > 0 );
        *(Y+i) = realloc( *(Y+i), (*(num_sublevels+i))*sizeof(DdNode *) );
        *(X_ijr+i) = realloc( *(X_ijr+i),
                              (*(num_sublevels+i))*sizeof(DdNode **) );
        if (*(Y+i) == NULL || *(X_ijr+i) == NULL) {
            perror( __FILE__ ",  realloc" );
            exit(-1);
        }
    }

    /* Make primed form of W and take conjunction with system
       transition (safety) formula, for use while stepping down Y_i
       sets.  Note that we assume the variable map has been
       appropriately defined in the CUDD manager, after the call to
       compute_winning_set_BDD above. */
    tmp = Cudd_bddVarMap( manager, W );
    if (tmp == NULL) {
        fprintf( stderr,
                 "Error synthesize: Error in swapping variables with primed"
                 " forms.\n" );
        free( state );
        free( cube );
        return NULL;
    }
    Cudd_Ref( tmp );
    strans_into_W = Cudd_bddAnd( manager, strans, tmp );
    Cudd_Ref( strans_into_W );
    Cudd_RecursiveDeref( manager, tmp );

    /* From each initial state, build strategy by propagating forward
       toward the next goal (current target goal specified by "mode"
       of a state), and iterating until every reached state and mode
       combination has already been encountered (whence the
       strategy already built). */
    if (init_flags == ALL_INIT
        || (init_flags == ONE_SIDE_INIT && spc.sys_init == NULL)) {
        if (init_flags == ALL_INIT) {
            if (verbose > 1)
                logprint( "Enumerating initial states, given init_flags ="
                          " ALL_INIT" );
            tmp = Cudd_bddAnd( manager, einit, sinit );
        } else {
            if (verbose > 1)
                logprint( "Enumerating initial states, given init_flags ="
                          " ONE_SIDE_INIT and empty SYSINIT" );
            tmp = einit;
            Cudd_Ref( tmp );
        }
        Cudd_Ref( tmp );
        Cudd_AutodynDisable( manager );
        Cudd_ForeachCube( manager, tmp, gen, gcube, gvalue ) {
            initialize_cube( state, gcube, num_env+num_sys );
            while (!saturated_cube( state, gcube, num_env+num_sys )) {
                this_node_stack = insert_anode( this_node_stack, 0, -1, False,
                                                state, num_env+num_sys );
                if (this_node_stack == NULL) {
                    fprintf( stderr,
                             "Error synthesize: building list of initial"
                             " states.\n" );
                    return NULL;
                }
                increment_cube( state, gcube, num_env+num_sys );
            }
            this_node_stack = insert_anode( this_node_stack, 0, -1, False,
                                            state, num_env+num_sys );
            if (this_node_stack == NULL) {
                fprintf( stderr,
                         "Error synthesize: building list of initial"
                         " states.\n" );
                return NULL;
            }
        }
        Cudd_AutodynEnable( manager, CUDD_REORDER_SAME );
        Cudd_RecursiveDeref( manager, tmp );

    } else if (init_flags == ALL_ENV_EXIST_SYS_INIT) {
Esempio n. 12
0
static int compute_prob(void)
/* this is the function that implements the compute_prob predicate used in pp.pl
*/
{
    YAP_Term out,arg1,arg2,arg3,arg4;
    variables  vars;
    expr expression;
    DdNode * function;
    DdManager * mgr;
    int nBVar,i,intBits,create_dot;
    FILE * file;
    DdNode * array[1];
    double prob;
    char * onames[1];
    char inames[1000][20];
    char * names[1000];
    tablerow * nodes;

    arg1=YAP_ARG1;
    arg2=YAP_ARG2;
    arg3=YAP_ARG3;
    arg4=YAP_ARG4;

    mgr=Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0);
    create_dot=YAP_IntOfTerm(arg4);
    vars=createVars(arg1,mgr,create_dot,inames);

    //Cudd_PrintInfo(mgr,stderr);

    /* automatic variable reordering, default method CUDD_REORDER_SIFT used */
    //printf("status %d\n",Cudd_ReorderingStatus(mgr,&order));
    //printf("order %d\n",order);

    Cudd_AutodynEnable(mgr,CUDD_REORDER_SAME);
    /*   Cudd_AutodynEnable(mgr, CUDD_REORDER_RANDOM_PIVOT);
      printf("status %d\n",Cudd_ReorderingStatus(mgr,&order));
            printf("order %d\n",order);
      printf("%d",CUDD_REORDER_RANDOM_PIVOT);
    */


    expression=createExpression(arg2);

    function=retFunction(mgr,expression,vars);

    /* the BDD build by retFunction is converted to an ADD (algebraic decision diagram)
    because it is easier to interpret and to print */
    //add=Cudd_BddToAdd(mgr,function);
    //Cudd_PrintInfo(mgr,stderr);

    if (create_dot)
        /* if specified by the user, a dot file for the BDD is written to cpl.dot */
    {
        nBVar=vars.nBVar;
        for(i=0; i<nBVar; i++)
            names[i]=inames[i];
        array[0]=function;
        onames[0]="Out";
        file = open_file("cpl.dot", "w");
        Cudd_DumpDot(mgr,1,array,names,onames,file);
        fclose(file);
    }
    nodes=init_table(vars.nBVar);
    intBits=sizeof(unsigned int)*8;
    prob=Prob(function,vars,nodes);
    out=YAP_MkFloatTerm(prob);
    destroy_table(nodes,vars.nBVar);

    Cudd_Quit(mgr);
    for(i=0; i<vars.nVar; i++)
    {
        free(vars.varar[i].probabilities);
        free(vars.varar[i].booleanVars);
    }
    free(vars.varar);
    free(vars.bVar2mVar);
    for(i=0; i<expression.nTerms; i++)
    {
        free(expression.terms[i].factors);
    }
    free(expression.terms);
    return(YAP_Unify(out,arg3));
}
Esempio n. 13
0
/**
 * A function for switching automatic BDD optimisation (variable reordering) on and off
 *
 * @param enable Whether automatic optimisation should be enabled or not
 * @author ehlers
 */
void BFBddManager::setAutomaticOptimisation(bool enable) {
	if (enable)
		Cudd_AutodynEnable(mgr, CUDD_REORDER_SAME);
	else
		Cudd_AutodynDisable(mgr);
}
Esempio n. 14
0
static int compute_prob(void)
/* this is the function that implements the compute_prob predicate used in pp.pl
*/
{
	YAP_Term out,arg1,arg2,arg3,arg4;
	array_t * variables,* expression, * bVar2mVar;
	DdNode * function, * add;
	DdManager * mgr;
	int nBVar,i,j,intBits,create_dot;
        FILE * file;
        DdNode * array[1];
        char * onames[1];
        char inames[1000][20];
	char * names[1000];
	GHashTable  * nodes; /* hash table that associates nodes with their probability if already 
				computed, it is defined in glib */
	Cudd_ReorderingType order;
	arg1=YAP_ARG1;
	arg2=YAP_ARG2;
	arg3=YAP_ARG3;
	arg4=YAP_ARG4;

  	mgr=Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0);
	variables=array_alloc(variable,0);
	bVar2mVar=array_alloc(int,0);
	create_dot=YAP_IntOfTerm(arg4);
	createVars(variables,arg1,mgr,bVar2mVar,create_dot,inames);
        //Cudd_PrintInfo(mgr,stderr);

	/* automatic variable reordering, default method CUDD_REORDER_SIFT used */
	//printf("status %d\n",Cudd_ReorderingStatus(mgr,&order));
	//printf("order %d\n",order);

	Cudd_AutodynEnable(mgr,CUDD_REORDER_SAME); 
/*	 Cudd_AutodynEnable(mgr, CUDD_REORDER_RANDOM_PIVOT);
	printf("status %d\n",Cudd_ReorderingStatus(mgr,&order));
        printf("order %d\n",order);
	printf("%d",CUDD_REORDER_RANDOM_PIVOT);
*/


	expression=array_alloc(array_t *,0);
	createExpression(expression,arg2);	

	function=retFunction(mgr,expression,variables);
	/* the BDD build by retFunction is converted to an ADD (algebraic decision diagram)
	because it is easier to interpret and to print */
	add=Cudd_BddToAdd(mgr,function);
	//Cudd_PrintInfo(mgr,stderr);

	if (create_dot)
	/* if specified by the user, a dot file for the BDD is written to cpl.dot */
	{	
		nBVar=array_n(bVar2mVar);
		for(i=0;i<nBVar;i++)
		   names[i]=inames[i];
	  	array[0]=add;
		onames[0]="Out";
		file = open_file("cpl.dot", "w");
		Cudd_DumpDot(mgr,1,array,names,onames,file);
  		fclose(file);
	}
	
	nodes=g_hash_table_new(my_hash,my_equal);
	intBits=sizeof(unsigned int)*8;
	/* dividend is a global variable used by my_hash 
	   it is equal to an unsigned int with binary representation 11..1 */ 
	dividend=1;
	for(j=1;j<intBits;j++)
	{
		dividend=(dividend<<1)+1;
	}
	out=YAP_MkFloatTerm(Prob(add,variables,bVar2mVar,nodes));
	g_hash_table_foreach (nodes,dealloc,NULL);
	g_hash_table_destroy(nodes);
	Cudd_Quit(mgr);
	array_free(variables);
 	array_free(bVar2mVar);
	array_free(expression);
    	return(YAP_Unify(out,arg3));
}