void stdInfraTrans(rootData *rdata,indexList *varList,linkedList clauseList,linkedList fullTransNodes,int allowBlankTrans){ int i,n; // at most, least one trans/stage int transWidth = sizeLinked(fullTransNodes); tempTransVar **transArray = toArrayLinked(fullTransNodes); // can have an empty state with zero transitions // at most one for(n=0;n<numStagesGlobal-1;n++){ linkedList *lockedTransList = createLinked(Malloc,Free); linkedList *transList = createLinked(Malloc,Free); for(i=0;i<transWidth;i++){ tempTransVar *tv = transArray[i]; int desObjId = tv->desObjId; int transId = tv->transId; nodeStages *stages = tv->stages; // stages are inclusive between start and end for both int start = stages->start; int end = stages->end; if(n<start || n>=end-1) continue; varData *var = getTransVar(varList,transId,desObjId,n); assert(var,"Trans Failed"); // multiple transitions can happen simultaneously, so don't // need to be in atMostOne if(!(tv->isSim)) addTailLinked(transList,var); // if it is locked, atLeastOne Trans must occur if(tv->isLocked) addTailLinked(lockedTransList,var); } if(!allowBlankTrans) atLeastOne(transList,clauseList); if(sizeLinked(lockedTransList) > 0) atLeastOne(lockedTransList,clauseList); // possible to have a stage with no trans if allowBlankTrans is 0 atMostOne(transList,clauseList); destroyLinked(transList,NULL); destroyLinked(lockedTransList,NULL); } }
treeNode *setVarNode(int tok,int varId,treeNode *varList){ if(tok == CHARVAR){ return setCommaNode(tok,varId,NULL); } if(tok == MANYVAR){ return setCommaNode(tok,varId,NULL); } if(tok == ELABNEG){ return setCommaNode(tok,varId,NULL); } if(tok == MANYBRACK){ return varList; } if(tok == ELABPAREN){ elabData *ed = varList->data; ed->tempVarName = 0; return varList; } // only elabtemp and elabcol can create tempvars if(tok == ELABCOL){ elabData *ed = varList->data; ed->tempVarName = varId; return varList; } if(tok == ELABTEMP){ elabData *elab = Malloc(sizeof(elabData)); elab->tempVarName = varId; elab->isAny = 0; elab->negVars = createLinked(Malloc,Free); elab->posVars = createLinked(Malloc,Free); varList = Malloc(sizeof(treeNode)); varList->type = elabType; varList->data = elab; return varList; } if(tok == ELABQUEST){ elabData *elab = Malloc(sizeof(elabData)); elab->tempVarName = 0; elab->isAny = 1; elab->negVars = NULL; elab->posVars = NULL; varList = Malloc(sizeof(treeNode)); varList->type = elabType; varList->data = elab; return varList; } // error return NULL; }
treeNode *makeRoot() { treeNode *root = Malloc(sizeof(treeNode)); rootData *data = Malloc(sizeof(rootData)); data->objNodes = createLinked(Malloc,Free); data->desObjNodes = createLinked(Malloc,Free); data->transNodes = createLinked(Malloc,Free); data->reqNodes = createLinked(Malloc,Free); data->optNodes = createLinked(Malloc,Free); root->type = rootType; root->data = data; return root; }
treeNode *setNode(int tok,treeNode *var,treeNode *set){ if(!set){ startSetData *startData = Malloc(sizeof(startSetData)); startData->numLines = 1; startData->maxWidth = 0; startData->curWidth = 0; startData->set = createLinked(Malloc,Free); set = Malloc(sizeof(treeNode)); set->spaces = createLinked(Malloc,Free); set->type = tempSetType; set->data = startData; } startSetData *sd = set->data; linkedList list = sd->set; if(tok == SPACEVAR){ int *num = peekLinked(set->spaces); *num = *num + 1; return set; } if(tok == SEMI){ pushLinked(list,ENDLINE); sd->numLines++; sd->curWidth = 0; } sd->curWidth++; if(sd->maxWidth < sd->curWidth) sd->maxWidth = sd->curWidth; void *data = var->data; pushLinked(list,data); Free(var); // for space int *num = Malloc(sizeof(int)); *num = 0; pushLinked(set->spaces,num); return set; }
indexList *createVarIndex(){ indexList *retList = Malloc(sizeof(indexList)); retList->keyList = createSkip(Malloc,Free,compGenVar); retList->fullList = createLinked(Malloc,Free); retList->numVar = 0; return retList; }
void advInfraTrans(rootData *rdata,indexList *varList,linkedList clauseList,linkedList fullTransNodes){ int x,i,n; linkedList clause; clauseVarData *clauseVar; // at most, least one trans/stage int transWidth = sizeLinked(fullTransNodes); tempTransVar **transArray = toArrayLinked(fullTransNodes); int logVal = log2Int(transWidth); // can have an empty state with zero transitions // at most one for(i=0;i<transWidth;i++){ tempTransVar *tv = transArray[i]; int desObjId = tv->desObjId; int transId = tv->transId; nodeStages *stages = tv->stages; if(tv->isSim) continue; for(n=0;n<numStagesGlobal-1;n++){ if(n < stages->start || n > stages->end) continue; varData *trans = getTransVar(varList,transId,desObjId,n); assert(trans,"Trans Failed"); int setPart = i+1; // set the vars to the corresponding trans for(x=0;x<=logVal;x++){ clause = createLinked(Malloc,Free); varData *part = getTransPartVar(varList,x,n); if(!part) part = createTransPartVar(varList,x,n); clauseVar = createClauseVar(trans,1); addTailLinked(clause,clauseVar); int isNeg = !(setPart % 2); setPart = setPart >> 1; clauseVar = createClauseVar(part,isNeg); addTailLinked(clause,clauseVar); addClause(clauseList,clause); } } } }
void infraClauses(rootData *rdata,indexList *varList,linkedList clauseList,linkedList fullTransNodes,int allowAdvTrans,int allowBlankTrans){ int y,x,i,n; // clauses from infrastructure // at most, least one symbol/cell/stage treeNode *boardNode = rdata->boardNode; setData *boardSet = boardNode->data; int boardWidth = boardSet->width; int boardHeight = boardSet->height; cellData **boardVars = boardSet->setVars; for(y=0;y<boardHeight;y++){ for(x=0;x<boardWidth;x++){ if(!boardVars[y*boardWidth + x]) continue; cellData *cell = boardVars[y*boardWidth + x]; linkedList symList = cell->symList; int symWidth = sizeLinked(symList); int **symArray = toArrayLinked(symList); for(n=0;n<numStagesGlobal;n++){ if(symWidth > 2){ // at least, most one variable linkedList newVarList = createLinked(Malloc,Free); for(i=0;i<symWidth;i++){ int symId = *symArray[i]; varData *var = getSymCellVar(varList,x,y,symId,n); assert(var,"Var Failed"); addTailLinked(newVarList,var); } atLeastOne(newVarList,clauseList); atMostOne(newVarList,clauseList); destroyLinked(newVarList,NULL); } } } } // in cases where there are a lot of trans, it is faster to change the way at-most-one // is performed to matching each to the equivalent of a binary number (series of TransPartVar) int transWidth = sizeLinked(fullTransNodes); if(transWidth > 64 && allowAdvTrans) advInfraTrans(rdata,varList,clauseList,fullTransNodes); else stdInfraTrans(rdata,varList,clauseList,fullTransNodes,allowBlankTrans); }
treeNode *symNode(treeNode *newSymListNode,treeNode *symLists){ nameData *cur = newSymListNode->data; int curName = cur->nameId; setData *setD = cur->set; int height = setD->height; int width = setD->width; int **set = setD->setVars; if(height > 1){ printf("Error: Symbols Must Be On One Line.\n"); endError(); } linkedList newSymList = createLinked(Malloc,Free); int i; for(i=0;i<width;i++) addTailLinked(newSymList,set[i]); symListInfo *newSym = Malloc(sizeof(symListInfo)); newSym->nameId = curName; newSym->symbols = newSymList; if(!symLists){ symLists = Malloc(sizeof(treeNode)); symLists->data = createLinked(Malloc,Free); } linkedList *lists = symLists->data; addTailLinked(lists,newSym); Free(set); Free(setD); Free(cur); Free(newSymListNode); return symLists; }
// a trans must be created for each desObj that describes it because the board cells change for each desObj linkedList expandTrans(rootData *rdata){ int i,j; linkedList fullTransList = createLinked(Malloc,Free); // trans linkedList transNodes = rdata->transNodes; int transWidth = sizeLinked(transNodes); treeNode **transArray = toArrayLinked(transNodes); // desObj linkedList desObjNodes = rdata->desObjNodes; int desObjWidth = sizeLinked(desObjNodes); treeNode **desObjArray = toArrayLinked(desObjNodes); for(i=0;i<transWidth;i++){ treeNode *trans = transArray[i]; transData *td = trans->data; int transId = td->transId; int transObjId = td->objId; // collect all object descriptions with same object id as this transition for(j=0;j<desObjWidth;j++){ treeNode *desObj = desObjArray[j]; nameData *objData = desObj->data; int desObjId = objData->objId; if(transObjId == desObjId){ tempTransVar *var = Malloc(sizeof(tempTransVar)); var->transId = transId; var->startData = td->startData; var->endData = td->endData; var->objId = objData->objId; var->desObjId = objData->nameId; var->desObjSet = objData->set; var->stages = trans->stages; var->isSim = 0; var->isLocked = 0; if(trans->type == transSimType) var->isSim = 1; if(trans->type == transLockType) var->isLocked = 1; pushLinked(fullTransList,var); } } } return fullTransList; }
void execute(treeNode *root){ tempClausesFileGlobal = NULL; rootData *rdata = root->data; compilerDebug(rdata); postProc(rdata); linkedList fullTransNodes = expandTrans(rdata); indexList *varList = createVarList(rdata,fullTransNodes); linkedList clauseList = createLinked(Malloc,Free); clauseListGlobal = clauseList; // don't need to create clauses if only getting final result if(flagGlobal != FLAG_RESULT){ processAllClauses(rdata,varList,clauseList,fullTransNodes); } if(flagGlobal == FLAG_DEBUG){ printDebugClausesVars(DEBUG_CLAUSE_FILE,varList,clauseList); } if(flagGlobal == FLAG_CNF || flagGlobal == FLAG_DEBUG || flagGlobal == FLAG_RUN){ printClauses(CNF_FILE,varList,clauseList); } if(flagGlobal == FLAG_RUN){ runCnfSolver(); } if(flagGlobal == FLAG_RESULT || flagGlobal == FLAG_RUN){ createSatOut(OUT_VARS_FILE,RESULT_FILE,rdata,varList,fullTransNodes); } if(flagGlobal != FLAG_RESULT){ deleteFile(TEMP_CLAUSE_FILE); } Free(sabrDirGlobal); freeArch(root); destroyLinked(fullTransNodes,singleFree); destroyLinked(clauseList,singleFree); destroyVarIndex(varList); }
// Req and DesObj // Opt and DesObj void reqOptClausesInit(nodeType type,linkedList elabNodes,linkedList desObjNodes,indexList *varList,linkedList clauseList,linkedList optGroupList){ int i; int elabSize = sizeLinked(elabNodes); treeNode **elabArray = toArrayLinked(elabNodes); elabFullData elabTemp; elabFullData *elab = &elabTemp; for(i=0;i<elabSize;i++){ treeNode *elabNode = elabArray[i]; nameData *elabData = elabNode->data; int elabObj = elabData->objId; int elabName = elabData->nameId; setData *elabSet = elabData->set; if(optGroupList){ optGroup *group = getLinked(optGroupList,findGroup,elabNode); if(!group){ group = Malloc(sizeof(optGroup)); group->nameId = elabName; group->objId = elabObj; group->list = createLinked(Malloc,Free); addTailLinked(optGroupList,group); } elabData->elabNum = sizeLinked(group->list); addTailLinked(group->list,elabNode); } elab->type = type; elab->elabId = elabName; elab->elabNum = elabData->elabNum; elab->objId = elabObj; elab->startData = elabSet; elab->endData = NULL; elab->stages = elabNode->stages; elabClauses(elab,desObjNodes,varList,clauseList); } }
int initSym(){ symTableGlobal = createLinked(Malloc,Free); return 0; }
// this sets cellUsedStageN=>N+1 variables when that cell is used in that transition void setUsedClauses(rootData *rdata,indexList *varList,linkedList clauseList,linkedList fullTransNodes){ int i,n; linkedList clause; clauseVarData *clauseVar; // trans int transWidth = sizeLinked(fullTransNodes); tempTransVar **transArray = toArrayLinked(fullTransNodes); // board treeNode *boardNode = rdata->boardNode; setData *boardSet = boardNode->data; int boardWidth = boardSet->width; int boardHeight = boardSet->height; cellData **boardVars = boardSet->setVars; int boardX, boardY; int desObjX, desObjY; // for each cellStage used-var // find all transitions that use that cell, put it into the set for(boardY=0;boardY<boardHeight;boardY++){ for(boardX=0;boardX<boardWidth;boardX++){ if(!boardVars[boardY*boardWidth+boardX]) continue; cellData *boardCell = boardVars[boardY*boardWidth+boardX]; int boardCellName = boardCell->cellName; for(n=0;n<numStagesGlobal-1;n++){ varData *used = getUsedVar(varList,boardX,boardY,n); assert(used,"Used NULL"); // NOT cellUsedStageN=>N+1 OR tran1StageN=>N+1 OR tran2StageN=>N+1 OR ... linkedList transListClause = createLinked(Malloc,Free); // contains varData // this is for saying at most one of these simultaneous trans that use this cell can be used linkedList transSimAtMostList = createLinked(Malloc,Free); // try to find it in trans for(i=0;i<transWidth;i++){ tempTransVar *trans = transArray[i]; // if this trans does not occur at this stage, it is not included in list that would indicate cell is used nodeStages *stages = trans->stages; if(n < stages->start || n > stages->end) continue; varData *tv = getTransVar(varList,trans->transId,trans->desObjId,n); assert(tv,"Trans NULL"); // true if the transition operates on board cell (boardX,boardY) int transUsesBoardCell = 0; // if it is the board, this x,y is used setData *dos = trans->desObjSet; manyData **desObjSet = dos->setVars; int desObjHeight = dos->height; int desObjWidth = dos->width; for(desObjY=0;desObjY<desObjHeight;desObjY++){ for(desObjX=0;desObjX<desObjWidth;desObjX++){ if(!desObjSet[desObjY*desObjWidth + desObjX]) continue; manyData *md = desObjSet[desObjY*desObjWidth + desObjX]; linkedList brackVars = md->brackVars; int *objSymP = peekLinked(brackVars); int desObjCellName = *objSymP; if(boardCellName == desObjCellName){ transUsesBoardCell = 1; } } } // found board cell if(transUsesBoardCell){ clause = createLinked(Malloc,Free); clauseVar = createClauseVar(used,0); addTailLinked(clause,clauseVar); clauseVar = createClauseVar(tv,1); addTailLinked(clause,clauseVar); assertBool(sizeLinked(clause) != 0,"Empty Clause Used"); addClause(clauseList,clause); clauseVar = createClauseVar(tv,0); addTailLinked(transListClause,clauseVar); // if it is not a TransSim it is already in an at-most-one if(trans->isSim){ // varData addTailLinked(transSimAtMostList,tv); } } } // connect this trans to this used cell clauseVar = createClauseVar(used,1); pushLinked(transListClause,clauseVar); addClause(clauseList,transListClause); // for TransSim atMostOne(transSimAtMostList,clauseList); destroyLinked(transSimAtMostList,NULL); } } } }
// may need to create a treeNode to store elab treeNode *setCommaNode(int tok,int varId,treeNode *varList){ if(tok == CHARVAR){ // assert no varlist assertBool(varList == NULL,"Char VarList"); int *dataVar = Malloc(sizeof(int)); *dataVar = varId; varList = Malloc(sizeof(treeNode)); varList->type = charType; varList->data = dataVar; return varList; } if(tok == MANYVAR){ if(!varList){ manyData *many = Malloc(sizeof(manyData)); linkedList brackVars = createLinked(Malloc,Free); many->brackVars = brackVars; varList = Malloc(sizeof(treeNode)); varList->type = manyType; varList->data = many; } manyData *md = varList->data; linkedList list = md->brackVars; int *dataVar = Malloc(sizeof(int)); *dataVar = varId; pushLinked(list,dataVar); return varList; } if(tok == ELABVAR || tok == ELABNEG){ if(!varList){ elabData *elab = Malloc(sizeof(elabData)); linkedList negVars = createLinked(Malloc,Free); linkedList posVars = createLinked(Malloc,Free); elab->tempVarName = 0; elab->isAny = 0; elab->negVars = negVars; elab->posVars = posVars; varList = Malloc(sizeof(treeNode)); varList->type = elabType; varList->data = elab; } elabData *ed = varList->data; linkedList addToList; if(tok == ELABNEG) addToList = ed->negVars; else addToList = ed->posVars; int *dataVar = Malloc(sizeof(int)); *dataVar = varId; pushLinked(addToList,dataVar); return varList; } // error return NULL; }
// this forces the cell to remain the same when cellUsedStageN=>N+1 is not set void usedClauses(rootData *rdata,indexList *varList,linkedList clauseList,linkedList fullTransNodes){ int i,n; linkedList clause; clauseVarData *clauseVar; // board treeNode *boardNode = rdata->boardNode; setData *boardSet = boardNode->data; int boardWidth = boardSet->width; int boardHeight = boardSet->height; cellData **boardVars = boardSet->setVars; int boardX, boardY; // for each cellStage used-var // find all transitions that use that cell, put it into the set for(boardY=0;boardY<boardHeight;boardY++){ for(boardX=0;boardX<boardWidth;boardX++){ if(!boardVars[boardY*boardWidth+boardX]) continue; cellData *cell = boardVars[boardY*boardWidth+boardX]; linkedList symList = cell->symList; int symWidth = sizeLinked(symList); int **symArray = toArrayLinked(symList); for(n=0;n<numStagesGlobal-1;n++){ varData *used = getUsedVar(varList,boardX,boardY,n); assert(used,"No Used\n"); for(i=0;i<symWidth;i++){ int sym = *symArray[i]; // empty transitions // boardCell0UsedStageN=>N+1 OR NOT boardCell0IsSym0StageN OR boardCell0IsSym0StageN+1 // and reverse varData *scv0 = getSymCellVar(varList,boardX,boardY,sym,n); assert(scv0,"No SCV0\n"); varData *scv1 = getSymCellVar(varList,boardX,boardY,sym,n+1); assert(scv1,"No SCV1\n"); clause = createLinked(Malloc,Free); clauseVar = createClauseVar(used,0); addTailLinked(clause,clauseVar); clauseVar = createClauseVar(scv0,1); addTailLinked(clause,clauseVar); clauseVar = createClauseVar(scv1,0); addTailLinked(clause,clauseVar); assertBool(sizeLinked(clause) != 0,"Empty Clause Used"); addClause(clauseList,clause); clause = createLinked(Malloc,Free); clauseVar = createClauseVar(used,0); addTailLinked(clause,clauseVar); clauseVar = createClauseVar(scv1,1); addTailLinked(clause,clauseVar); clauseVar = createClauseVar(scv0,0); addTailLinked(clause,clauseVar); assertBool(sizeLinked(clause) != 0,"Empty Clause Used"); addClause(clauseList,clause); } } } } }
// for all distinct variables void allDifClauses(rootData *rdata,indexList *varList,linkedList clauseList){ int n,c,s,x,y; linkedList allDifNodes = rdata->allDifNodes; int allDifWidth = sizeLinked(allDifNodes); treeNode **allDifArray = toArrayLinked(allDifNodes); for(n=0;n<numStagesGlobal;n++){ for(c=0;c<allDifWidth;c++){ treeNode *allDifNode = allDifArray[c]; nameData *allDifData = allDifNode->data; nodeStages *stages = allDifNode->stages; if(stages != NULL){ // stages are inclusive between start and end for both int start = stages->start; int end = stages->end; if(n < start || n > end) continue; } setData *allDifSet = allDifData->set; manyData **many = allDifSet->setVars; int height = allDifSet->height; int width = allDifSet->width; if(width == 0) return; // these should all have the same symlist manyData *manyThis = many[0]; linkedList symList = manyThis->symList; int symWidth = sizeLinked(symList); int **symArray = toArrayLinked(symList); for(s=0;s<symWidth;s++){ int symId = *symArray[s]; // must be exactly one linkedList singleVars = createLinked(Malloc,Free); int numCells = 0; for(y=0;y<height;y++){ for(x=0;x<width;x++){ manyThis = many[width*y+x]; // may not have rectangle shape if(!manyThis) continue; assertBool(manyThis->symList == symList,"SymList Did Not Match."); linkedList brackVars = manyThis->brackVars; int *boardCellP = peekLinked(brackVars); int boardCell = *boardCellP; varData *v = getSymCellVarByName(varList,boardCell,symId,n); assert(v,"AllDif Variable Not Found."); addTailLinked(singleVars,v); numCells++; } } atMostOne(singleVars,clauseList); if(numCells == symWidth) atLeastOne(singleVars,clauseList); destroyLinked(singleVars,NULL); } } } }
void reqOptClauses(rootData *rdata,indexList *varList,linkedList clauseList){ // req reqOptClausesInit(reqType,rdata->reqNodes,rdata->desObjNodes,varList,clauseList,NULL); // opt linkedList optGroupList = createLinked(Malloc,Free); reqOptClausesInit(optType,rdata->optNodes,rdata->desObjNodes,varList,clauseList,optGroupList); // add that at least one of each opt group must be true int optGroupSize = sizeLinked(optGroupList); optGroup **optGroupArray = toArrayLinked(optGroupList); // desObj linkedList desObjNodes = rdata->desObjNodes; int desObjSize = sizeLinked(desObjNodes); treeNode **desObjArray = toArrayLinked(desObjNodes); // at least one Opt-<Opt>-<Any Number>-DesObj-<DesObj>-Stage<Stage> int n,i,c,x; for(n=0;n<numStagesGlobal;n++){ for(x=0;x<optGroupSize;x++){ optGroup *optGroup = optGroupArray[x]; int optGroupObj = optGroup->objId; int optGroupName = optGroup->nameId; int optSize = sizeLinked(optGroup->list); treeNode **optArray = toArrayLinked(optGroup->list); for(c=0;c<desObjSize;c++){ treeNode *desObjNode = desObjArray[c]; nameData *desObjData = desObjNode->data; int desObjName = desObjData->nameId; int desObjObj = desObjData->objId; if(desObjObj != optGroupObj) continue; linkedList atLeastList = createLinked(Malloc,Free); for(i=0;i<optSize;i++){ treeNode *optNode = optArray[i]; // check if is valid at this stage nodeStages *stages = optNode->stages; if(n < stages->start || n > stages->end) continue; nameData *optData = optNode->data; int optNum = optData->elabNum; // if it was not created, it is not used and so is not needed in atLeastList varData *opt = getOptVar(varList,optGroupName,optNum,desObjName,n); if(!opt) continue; pushLinked(atLeastList,opt); } atLeastOne(atLeastList,clauseList); destroyLinked(atLeastList,NULL); } } } optGroup *rem; while((rem = popLinked(optGroupList))){ destroyLinked(rem->list,NULL); Free(rem); } destroyLinked(optGroupList,NULL); }