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); } }
// this prints the clauses to be read by the CNF solver void printClausesLinked(char *fileName,indexList *varList,linkedList clauseList){ FILE *file = fopen(fileName,"w"); int numVar = sizeVarList(varList); int numClause = sizeLinked(clauseList); fprintf(file,"p cnf %i %i\n",numVar,numClause); linkedList clause; while((clause = popLinked(clauseList))){ clauseVarData *var; while((var = popLinked(clause))){ varData *data = var->data; int printInt = data->value; if(var->negate) printInt = -printInt; fprintf(file,"%i ",printInt); Free(var); } fprintf(file,"0\n"); destroyLinked(clause,NULL); } fclose(file); }
// clause contains list of clauseVar int addClause(linkedList clauseList,linkedList clause){ // sometimes adding a clause is not to the global clauseList // but to a clause list that will be added to the global clauseList later if(clauseList != clauseListGlobal){ addTailLinked(clauseList,clause); return 0; } assert(tempClausesFileGlobal,"temp clause file"); clauseVarData *var; while((var = popLinked(clause))){ varData *data = var->data; int printInt = data->value; if(var->negate) printInt = -printInt; fprintf(tempClausesFileGlobal,"%i ",printInt); Free(var); } fprintf(tempClausesFileGlobal,"0\n"); destroyLinked(clause,NULL); numClausesGlobal++; return 0; }
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); }
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 *nameNode(int tok,treeNode *stagesNode,int nameId,int objId,treeNode *set) { nodeType type; switch(tok) { case OBJECT: type = objType; break; case DESOBJECT: type = desObjType; if(!nameId) nameId = inventName("DesObj"); break; case REQUIRE: type = reqType; if(!nameId) nameId = inventName("Req"); break; case OPTION: type = optType; if(!nameId) nameId = addSymbol("+NoNameOpt+"); break; case START: type = startType; break; case END: type = endType; break; case SYMBOLS: type = symType; break; default: assert(NULL,"No Token"); } startSetData *notParsed = set->data; nameData *name = Malloc(sizeof(nameData)); name->nameId = nameId; name->objId = objId; name->elabNum = 0; name->set = createSet(notParsed); treeNode *newNode = Malloc(sizeof(treeNode)); newNode->type = type; newNode->data = name; newNode->stages = NULL; if(stagesNode) { newNode->stages = stagesNode->data; Free(stagesNode); } destroyLinked(set->spaces,singleFree); Free(set); return newNode; }
treeNode *transNode(int type,treeNode *stagesNode,int transId,int objId,treeNode *startSet,treeNode *endSet){ treeNode *newNode = Malloc(sizeof(treeNode)); newNode->stages = NULL; transData *data = Malloc(sizeof(transData)); if(stagesNode){ newNode->stages = stagesNode->data; Free(stagesNode); } if(!transId) transId = inventName("Trans"); data->transId = transId; data->objId = objId; startSetData *notParsedStart = startSet->data; startSetData *notParsedEnd = endSet->data; data->startData = createSet(notParsedStart); data->endData = createSet(notParsedEnd); // either Trans, TransSim, or TransLock if(type == TRANSFORM) newNode->type = transType; else if(type == TRANSFORMSIM) newNode->type = transSimType; else if(type == TRANSFORMLOCK) newNode->type = transLockType; newNode->data = data; destroyLinked(startSet->spaces,singleFree); destroyLinked(endSet->spaces,singleFree); Free(startSet); Free(endSet); return newNode; }
int main(int argc,char **argv){ tempClausesFileGlobal = NULL; numClausesGlobal = 0; if(argc == 1){ endHelp(); } sabrDirGlobal = getDir(argv[0]); // current argument int a = processFlags(argc,argv); if(a >= argc || !atoi(argv[a])){ endErrorMsg("Positive Integer Number Of Levels Must Be Input First"); } curLineNumGlobal = 1; numStagesGlobal = atoi(argv[a]); inventNameNumGlobal = 0; endFileGlobal = 0; a++; if(a >= argc){ endErrorMsg("Must Enter Source File"); } char *file = argv[a]; fileRead(file); a++; if(a != argc){ endErrorMsg("Too Many Arguments"); } initSym(); yyparse(); destroyLinked(symTableGlobal,freeSyms); // could use Malloc-L, Free-L and MemInfo to show no memory lost // should say: "Leak Size: 0" return 0; }
setData *createSet(startSetData *notParsed){ linkedList list = notParsed->set; int height = notParsed->numLines; int width = notParsed->maxWidth; void **set = Malloc(sizeof(void*)*height*width); int x = 0; int y = 0; int i; for(i=0;i<width*height;i++) set[i] = NULL; void *var = popLinked(list); while(var) { if(var == ENDLINE){ x=0; y++; } else{ set[y*width+x] = var; x++; } var = popLinked(list); } setData *data = Malloc(sizeof(setData)); data->height = height; data->width = width; data->setVars = set; // free startSetData, nothing in it destroyLinked(notParsed->set,NULL); Free(notParsed); return data; }
int main(int argc,char **argv) { if(argc < 2 || !atoi(argv[1])) { printf("Error: Positive Integer Number Of Levels Must Be Input.\n"); exit(0); } if(argc == 2) command = COMMAND_NONE; else if(argc == 3 && strcmp(argv[2],"-initial") == 0) command = COMMAND_INITIAL; else if(argc == 3 && strcmp(argv[2],"-debug") == 0) command = COMMAND_DEBUG; else if(argc == 3 && strcmp(argv[2],"-result") == 0) command = COMMAND_RESULT; else if(argc == 3 && strcmp(argv[2],"-all") == 0) command = COMMAND_ALL; else { printf("Error: Invalid Input.\n"); exit(0); } curLineNum = 1; numStages = atoi(argv[1]); inventNameNum = 0; endFile = 0; initSym(); printf("Start\n"); yyparse(); destroyLinked(symTable,freeSyms); // could use Malloc-L, Free-L and MemInfo to show no memory lost // should say: "Leak Size: 0" return 0; }
void destroyVarIndex(indexList *ind){ destroySkip(ind->keyList,delSkip); destroyLinked(ind->fullList,delLink); Free(ind); }
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); }
// 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); } } } }
// 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); } } } }