#include "../includes/globals.h" #include "dpll.h" #include #include #include void checkStructure(); void buildSupportStructures(){ int i; int j; DPLL_LITERAL* dpll_literals = (DPLL_LITERAL*) malloc(sizeof(DPLL_LITERAL)* numberOfLiterals); srandom(RAND_SEED); emptyClauses = NULL; singleVariableClauses = NULL; unsatisfiedClauses = numberOfClauses; for(i=0;idata; CLAUSE_ENCLOSER* cl = (CLAUSE_ENCLOSER*) malloc(sizeof(CLAUSE_ENCLOSER)); cl->clause = &clauses[i]; if(clauses[i].literals[j] > 0){ cl->next = thisLiteralData->positiveClauses; thisLiteralData->positiveClauses = cl; } else{ cl->next = thisLiteralData->negativeClauses; thisLiteralData->negativeClauses = cl; } dpll_clauses[i].currentLiterals[j]=clauses[i].literals[j]; } if(dpll_clauses[i].currentLiteralCount == 0){ CLAUSE_ENCLOSER* c1 = (CLAUSE_ENCLOSER*) malloc(sizeof(CLAUSE_ENCLOSER)); c1->clause = &clauses[i]; c1->next = emptyClauses; emptyClauses = c1; } else if(dpll_clauses[i].currentLiteralCount == 1){ CLAUSE_ENCLOSER* c1 = (CLAUSE_ENCLOSER*) malloc(sizeof(CLAUSE_ENCLOSER)); c1->clause = &clauses[i]; c1->next = singleVariableClauses; singleVariableClauses = c1; } } //checkStructure(); } void checkStructure(){ int i; int j; for(i=0;idata))->positiveClauses; while(c1 != NULL){ printf("CHECK %d\n",c1->clause); c1 = c1->next; } } } void printLiteralState(){ int j; int i; printf("***** DUMPING LITERAL STATE ******\n"); for(i=0;icurrentLiteralCount;j++){ printf("%d ",dl->currentLiterals[j]); } printf("\n IS SATISFIED: %d at DEPTH %d\n",dl->isSatisfied, dl->depthSatisfied); } printf("\n\n"); } void satisfyClauses(int literal, int depth){ LITERAL* l = getLiteral(abs(literal)); CLAUSE_ENCLOSER* clEn; if(literal > 0){ clEn = ((DPLL_LITERAL*)(l->data))->positiveClauses; } else{ clEn = ((DPLL_LITERAL*)(l->data))->negativeClauses; } while(clEn != NULL){ CLAUSE* cl = clEn->clause; DPLL_CLAUSE* dl = (DPLL_CLAUSE*) cl->data; if(dl->isSatisfied == 0){ int i; dl->isSatisfied = 1; dl->depthSatisfied = depth; for(i=0;icurrentLiteralCount;i++){ if(dl->currentLiterals[i]>0){ getLiteral(dl->currentLiterals[i])->countTrueClauses--; } else{ getLiteral(-dl->currentLiterals[i])->countFalseClauses--; } } unsatisfiedClauses--; } clEn = clEn->next; } } int allSatisfied(){ if(unsatisfiedClauses == 0){ return 1; } return 0; } void shortenClauses(int literal, int depth){ LITERAL* l = getLiteral(abs(literal)); CLAUSE_ENCLOSER* clEn; if(literal > 0){ clEn = ((DPLL_LITERAL*)(l->data))->positiveClauses; } else{ clEn = ((DPLL_LITERAL*)(l->data))->negativeClauses; } while(clEn != NULL){ CLAUSE* cl = clEn->clause; DPLL_CLAUSE* dl = (DPLL_CLAUSE*) cl->data; int i; int j=0; for(i=0;icurrentLiteralCount;i++){ if(dl->currentLiterals[i]!=literal){ dl->currentLiterals[j++]=dl->currentLiterals[i]; } } assert(jcurrentLiteralCount); dl->currentLiteralCount=j; if(dl->isSatisfied == 0){ if(dl->currentLiteralCount == 0){ CLAUSE_ENCLOSER* ce = (CLAUSE_ENCLOSER*) malloc(sizeof(CLAUSE_ENCLOSER)); ce->clause = cl; ce->next = emptyClauses; emptyClauses = ce; } else if(dl->currentLiteralCount == 1){ CLAUSE_ENCLOSER* ce = (CLAUSE_ENCLOSER*) malloc(sizeof(CLAUSE_ENCLOSER)); ce->clause = cl; ce->next = singleVariableClauses; singleVariableClauses = ce; } } clEn = clEn->next; } } int hasEmptyClause(){ if(emptyClauses == NULL){ return 0; } else{ while(emptyClauses != NULL){ CLAUSE* cl = emptyClauses->clause; DPLL_CLAUSE* dl = (DPLL_CLAUSE*) cl->data; if(dl->currentLiteralCount!=0){ CLAUSE_ENCLOSER* clen = emptyClauses; emptyClauses = emptyClauses->next; free(clen); } else{ break; } } if(emptyClauses != NULL){ return 1; } return 0; } } int getUnitLiteral(){ while(singleVariableClauses != NULL){ DPLL_CLAUSE* dl = (DPLL_CLAUSE*) singleVariableClauses->clause->data; if(dl->isSatisfied == 0 && dl->currentLiteralCount == 1){ return dl->currentLiterals[0]; } else{ CLAUSE_ENCLOSER* old = singleVariableClauses; singleVariableClauses = singleVariableClauses->next; free(old); } } return 0; } int getPureLiteral(){ int i; for(i=0;i 0){ return -literals[i].literalNumber; } else if(literals[i].countFalseClauses == 0 && literals[i].countTrueClauses > 0){ return literals[i].literalNumber; } } } return 0; } void cleanUp(int literal, int depth){ LITERAL* l = getLiteral(abs(literal)); l->value = 0; CLAUSE_ENCLOSER* clEn; CLAUSE_ENCLOSER* clEnAddLiteral; if(literal > 0){ clEn = ((DPLL_LITERAL*)(l->data))->positiveClauses; clEnAddLiteral = ((DPLL_LITERAL*)(l->data))->negativeClauses; } else{ clEn = ((DPLL_LITERAL*)(l->data))->negativeClauses; clEnAddLiteral = ((DPLL_LITERAL*)(l->data))->positiveClauses; } //printf("Starting cleanup\n"); while(clEn != NULL){ CLAUSE* cl = clEn->clause; /*if(cl != NULL){ printf("NN %d\n",cl); } else{ printf("c1 is null\n"); }*/ DPLL_CLAUSE* dl = (DPLL_CLAUSE*) cl->data; if(dl->isSatisfied == 1 && dl->depthSatisfied == depth){ int i; dl->isSatisfied = 0; dl->depthSatisfied = -1; for(i=0;icurrentLiteralCount;i++){ if(dl->currentLiterals[i]>0){ getLiteral(dl->currentLiterals[i])->countTrueClauses++; } else{ getLiteral(-(dl->currentLiterals[i]))->countFalseClauses++; } } unsatisfiedClauses++; } clEn = clEn->next; } while(clEnAddLiteral != NULL){ CLAUSE* cl; DPLL_CLAUSE* dl; cl = clEnAddLiteral->clause; dl = (DPLL_CLAUSE*) (cl->data); //if(dl->depthSatisfied >= depth){ int item = dl->currentLiteralCount; dl->currentLiterals[item]=-literal; dl->currentLiteralCount=item+1; assert(item + 1 <= maxLiteralsPerClause); //} clEnAddLiteral = clEnAddLiteral->next; } } int getUnsatisfiedVariable(){ //TODO: replace by a better algorithm... int direction = 1; #ifdef RANDOMIZED_DIRECTION if(random()%2 == 0){ direction = -1; } #endif #ifdef RANDOMIZED_EXPLORE int i; int count = 0; int selected=0; for(i = 0; i max){ selected = literals[i].literalNumber; max = literals[i].countTrueClauses; } if(literals[i].countFalseClauses > max){ selected = -literals[i].literalNumber; max = literals[i].countFalseClauses; } } } return selected; #else #ifdef GREEDY_SELECT_2 int i; int selected=0; int min = 10000000; for(i = 0; ivalue == 0); if(literal > 0){ currentLiteral->value=1; } else{ currentLiteral->value=-1; } ((DPLL_LITERAL*)(currentLiteral->data))->depthSatisfied=depth; satisfyClauses(literal,depth); if(allSatisfied()){ return 1; } else{ //printf( "Shortening %d\n",literal); shortenClauses(-literal, depth); } } if(hasEmptyClause()){ #ifdef DPLL_DEBUG printf("Has Empty Clause\n"); #endif return 0; } int unitLiteral = getUnitLiteral(); if(unitLiteral != 0){ #ifdef DPLL_DEBUG printf("Accepting Unit Literal %d\n",unitLiteral); #endif return dpllStepWithCleanUp(unitLiteral, depth+1); } int pureLiteral = getPureLiteral(); if(pureLiteral != 0){ #ifdef DPLL_DEBUG printf("Accepting Pure Literal %d\n",pureLiteral); #endif return dpllStepWithCleanUp(pureLiteral, depth+1); } int selectVariable = getUnsatisfiedVariable(); if(selectVariable == 0){ return 0; } #ifdef DPLL_DEBUG printf("Selecting Variable %d\n",selectVariable); #endif if(dpllStepWithCleanUp(selectVariable, depth+1)){ return 1; } else{ statistics.backTracks++; #ifdef DPLL_DEBUG printf("Selecting Variable %d\n",-selectVariable); #endif return dpllStepWithCleanUp(-selectVariable, depth+1); } }