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); } }
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); }
/************************** operatorHandling *********************************** Element operatorHandling(Element *pOperand1, Element *pOperand2, Element *pOperator, Customer *pCustomer) Purpose: This function handles an operation of type AND, OR, =, NOTANY, or ONLY on two operands. Parameters: I Element *pOperand1 The first of the two operands. I Element *pOperand2 The second operand. I Element *pOperator The operator element for this operation. I Customer *pCustomer The customer for which the operations need to be true. Notes: Return value: A boolean Element containing the result of the operation. *******************************************************************************/ Element operatorHandling(Element *pOperand1, Element *pOperand2, Element *pOperator, Customer *pCustomer) { Element result; Trait currentTrait; char *szOperatorM[] = {"=", "NOTANY", "ONLY", "AND", "OR"}; int i; for (i = 0; (strcmp(pOperator->szToken, szOperatorM[i]) != 0); i++); //will stop when i = the index of our operator in szOperatorM[] switch (i) { case 0: //= strcpy(currentTrait.szTraitType, pOperand1->szToken); strcpy(currentTrait.szTraitValue, pOperand2->szToken); //store both tokens poped in a trait variable to use in atLeastOne function result.bInclude = atLeastOne(pCustomer, ¤tTrait); break; case 1: //NOTANY strcpy(currentTrait.szTraitType, pOperand1->szToken); strcpy(currentTrait.szTraitValue, pOperand2->szToken); //store both tokens poped in a trait variable to use in notAny function result.bInclude = notAny(pCustomer, ¤tTrait); break; case 2: //ONLY strcpy(currentTrait.szTraitType, pOperand1->szToken); strcpy(currentTrait.szTraitValue, pOperand2->szToken); //store both tokens poped in a trait variable to use in only function result.bInclude = only(pCustomer, ¤tTrait); break; case 3: //AND result.bInclude = and(pOperand1, pOperand2); //call function and if token is AND break; case 4: //OR result.bInclude = or(pOperand1, pOperand2); //call function or if token is OR break; } strcpy(result.szBoolean, "Boolean result of "); strcat(result.szBoolean, pOperator->szToken); //for help in debugging and identifying boolean structs return result; }
/******************************** only ***************************************** int only(Customer *pCustomer, Trait *pTrait) Purpose: Determines whether a customer has a particular trait (type and value) and no other trait of the same type. If he does, only returns TRUE; otherwise, it returns FALSE. Parameters: I Customer pCustomer One customer structure which also contains traits of that customer. I Trait pTrait The trait that we want this customer to have. Notes: Return value: TRUE - customer has the specified trait and no other trait of the same type FALSE - customer didn't have the trait and/or had other traits of the same type *******************************************************************************/ int only(Customer *pCustomer, Trait *pTrait) { if (atLeastOne(pCustomer, pTrait)) //if the customer has the trait { int i; for (i = 0; i < pCustomer->iNumberOfTraits; i++) //go through the customer's trait { if (strcmp(pCustomer->traitM[i].szTraitType, pTrait->szTraitType) == 0 && strcmp(pCustomer->traitM[i].szTraitValue, pTrait->szTraitValue) != 0) { //if we find a trait of same type but different value return FALSE; } } return TRUE; } return FALSE; }
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); } } } }