X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=src%2Fcsolver.cc;h=448fb9a7304e6b38a4b891883d151ff805d6a5d2;hb=d483537108b69a82887604f7bad1987e0096f263;hp=3c8fffa510f16b01b6be889703e84ea83a5b7972;hpb=ab88f3e4fab3b0823ff6c6bc908921af554e4155;p=satune.git diff --git a/src/csolver.cc b/src/csolver.cc index 3c8fffa..448fb9a 100644 --- a/src/csolver.cc +++ b/src/csolver.cc @@ -29,17 +29,22 @@ #include "varorderingopt.h" #include #include -#include "alloyenc.h" +#include "alloyinterpreter.h" +#include "smtinterpreter.h" +#include "mathsatinterpreter.h" +#include "smtratinterpreter.h" CSolver::CSolver() : boolTrue(BooleanEdge(new BooleanConst(true))), boolFalse(boolTrue.negate()), unsat(false), booleanVarUsed(false), + incrementalMode(false), + optimizationsOff(false), tuner(NULL), elapsedTime(0), satsolverTimeout(NOTIMEOUT), - alloyEncoder(NULL) + interpreter(NULL) { satEncoder = new SATEncoder(this); } @@ -83,6 +88,10 @@ CSolver::~CSolver() { delete allFunctions.get(i); } + if (interpreter != NULL) { + delete interpreter; + } + delete boolTrue.getBoolean(); delete satEncoder; } @@ -132,6 +141,7 @@ void CSolver::resetSolver() { allOrders.clear(); allFunctions.clear(); constraints.reset(); + encodedConstraints.reset(); activeOrders.reset(); boolMap.reset(); elemMap.reset(); @@ -158,9 +168,9 @@ CSolver *CSolver::clone() { return copy; } -CSolver *CSolver::deserialize(const char *file) { +CSolver *CSolver::deserialize(const char *file, InterpreterType itype) { model_print("deserializing %s ...\n", file); - Deserializer deserializer(file); + Deserializer deserializer(file, itype); return deserializer.deserialize(); } @@ -233,6 +243,17 @@ void CSolver::mustHaveValue(Element *element) { element->anyValue = true; } +void CSolver::freezeElementsVariables() { + + for (uint i = 0; i < allElements.getSize(); i++) { + Element *e = allElements.get(i); + if (e->frozen) { + satEncoder->freezeElementVariables(&e->encoding); + } + } +} + + Set *CSolver::getElementRange (Element *element) { return element->getRange(); } @@ -257,7 +278,6 @@ Element *CSolver::getElementConst(VarType type, uint64_t value) { Element *CSolver::applyFunction(Function *function, Element **array, uint numArrays, BooleanEdge overflowstatus) { - ASSERT(numArrays == 2); Element *element = new ElementFunction(function,array,numArrays,overflowstatus); Element *e = elemMap.get(element); if (e == NULL) { @@ -312,7 +332,7 @@ Function *CSolver::completeTable(Table *table, UndefinedBehavior behavior) { BooleanEdge CSolver::getBooleanVar(VarType type) { Boolean *boolean = new BooleanVar(type); allBooleans.push(boolean); - if(!booleanVarUsed) + if (!booleanVarUsed) booleanVarUsed = true; return BooleanEdge(boolean); } @@ -389,8 +409,30 @@ BooleanEdge CSolver::rewriteLogicalOperation(LogicOp op, BooleanEdge *array, uin return applyLogicalOperation(op, newarray, asize); } +BooleanEdge CSolver::applyAtMostOneConstraint (BooleanEdge *array, uint asize) { + if(asize == 0 || asize == 1){ + return getBooleanTrue(); + } + BooleanEdge newarray[asize*(asize-1)]; + uint newsize = 0; + for (uint i = 0; i < asize -1; i++) { + for(uint j = i +1; j < asize; j++){ + BooleanEdge oprand1 = array[i]; + BooleanEdge oprand2 = applyLogicalOperation(SATC_NOT, array[j]); + newarray[newsize++] = applyLogicalOperation(SATC_IMPLIES, oprand1, oprand2); + } + } + return applyLogicalOperation(SATC_AND, newarray, newsize); +} + +BooleanEdge CSolver::applyExactlyOneConstraint (BooleanEdge *array, uint asize) { + BooleanEdge atleastOne = applyLogicalOperation(SATC_OR, array, asize); + BooleanEdge atmostOne = applyAtMostOneConstraint (array, asize); + return applyLogicalOperation(SATC_AND, atleastOne, atmostOne); +} + BooleanEdge CSolver::applyLogicalOperation(LogicOp op, BooleanEdge *array, uint asize) { - if(!useAlloyCompiler()){ + if (!useInterpreter() && !optimizationsOff) { BooleanEdge newarray[asize]; switch (op) { case SATC_NOT: { @@ -453,7 +495,7 @@ BooleanEdge CSolver::applyLogicalOperation(LogicOp op, BooleanEdge *array, uint return applyLogicalOperation(SATC_OR, applyLogicalOperation(SATC_NOT, array[0]), array[1]); } } - + ASSERT(asize != 0); Boolean *boolean = new BooleanLogic(this, op, array, asize); Boolean *b = boolMap.get(boolean); @@ -471,7 +513,7 @@ BooleanEdge CSolver::applyLogicalOperation(LogicOp op, BooleanEdge *array, uint Boolean *boolean = new BooleanLogic(this, op, array, asize); allBooleans.push(boolean); return BooleanEdge(boolean); - + } } @@ -490,7 +532,7 @@ BooleanEdge CSolver::orderConstraint(Order *order, uint64_t first, uint64_t seco } } Boolean *constraint = new BooleanOrder(order, first, second); - if (!useAlloyCompiler() ){ + if (!useInterpreter() && !optimizationsOff ) { Boolean *b = boolMap.get(constraint); if (b == NULL) { @@ -527,7 +569,7 @@ BooleanEdge CSolver::orderConstraint(Order *order, uint64_t first, uint64_t seco } void CSolver::addConstraint(BooleanEdge constraint) { - if(!useAlloyCompiler()){ + if (!useInterpreter() && !optimizationsOff) { if (isTrue(constraint)) return; else if (isFalse(constraint)) { @@ -565,7 +607,7 @@ void CSolver::addConstraint(BooleanEdge constraint) { replaceBooleanWithTrueNoRemove(constraint); constraint->parents.clear(); } - } else{ + } else { constraints.add(constraint); constraint->parents.clear(); } @@ -597,7 +639,79 @@ void CSolver::inferFixedOrders() { } } +int CSolver::solveIncremental() { + if (isUnSAT()) { + return IS_UNSAT; + } + + + long long startTime = getTimeNano(); + bool deleteTuner = false; + if (tuner == NULL) { + tuner = new DefaultTuner(); + deleteTuner = true; + } + int result = IS_INDETER; + ASSERT (!useInterpreter()); + if(!optimizationsOff){ + computePolarities(this); + } +// long long time1 = getTimeNano(); +// model_print("Polarity time: %f\n", (time1 - startTime) / NANOSEC); +// Preprocess pp(this); +// pp.doTransform(); +// long long time2 = getTimeNano(); +// model_print("Preprocess time: %f\n", (time2 - time1) / NANOSEC); + +// DecomposeOrderTransform dot(this); +// dot.doTransform(); +// time1 = getTimeNano(); +// model_print("Decompose Order: %f\n", (time1 - time2) / NANOSEC); + +// IntegerEncodingTransform iet(this); +// iet.doTransform(); + + //Doing element optimization on new constraints +// ElementOpt eop(this); +// eop.doTransform(); + + //Since no new element is added, we assuming adding new constraint + //has no impact on previous encoding decisions +// EncodingGraph eg(this); +// eg.encode(); + + naiveEncodingDecision(this); + // eg.validate(); + //Order of sat solver variables don't change! +// VarOrderingOpt bor(this, satEncoder); +// bor.doTransform(); + + long long time2 = getTimeNano(); + //Encoding newly added constraints + satEncoder->encodeAllSATEncoder(this); + long long time1 = getTimeNano(); + + model_print("Elapse Encode time: %f\n", (time1 - startTime) / NANOSEC); + + model_print("Is problem UNSAT after encoding: %d\n", unsat); + + result = unsat ? IS_UNSAT : satEncoder->solve(satsolverTimeout); + model_print("Result Computed in SAT solver:\t%s\n", result == IS_SAT ? "SAT" : result == IS_INDETER ? "INDETERMINATE" : " UNSAT"); + time2 = getTimeNano(); + elapsedTime = time2 - startTime; + model_print("CSOLVER solve time: %f\n", elapsedTime / NANOSEC); + + if (deleteTuner) { + delete tuner; + tuner = NULL; + } + return result; +} + int CSolver::solve() { + if (isUnSAT()) { + return IS_UNSAT; + } long long startTime = getTimeNano(); bool deleteTuner = false; if (tuner == NULL) { @@ -605,12 +719,12 @@ int CSolver::solve() { deleteTuner = true; } int result = IS_INDETER; - if(useAlloyCompiler()){ - alloyEncoder->encode(); - model_print("Problem encoded in Alloy\n"); - result = alloyEncoder->solve(); - model_print("Problem solved by Alloy\n"); - } else{ + if (useInterpreter()) { + interpreter->encode(); + model_print("Problem encoded in Interpreter\n"); + result = interpreter->solve(); + model_print("Problem solved by Interpreter\n"); + } else { { SetIteratorOrder *orderit = activeOrders.iterator(); @@ -623,36 +737,39 @@ int CSolver::solve() { } delete orderit; } + long long time1, time2; + computePolarities(this); - long long time1 = getTimeNano(); - model_print("Polarity time: %f\n", (time1 - startTime) / NANOSEC); - Preprocess pp(this); - pp.doTransform(); - long long time2 = getTimeNano(); - model_print("Preprocess time: %f\n", (time2 - time1) / NANOSEC); - - DecomposeOrderTransform dot(this); - dot.doTransform(); time1 = getTimeNano(); - model_print("Decompose Order: %f\n", (time1 - time2) / NANOSEC); + model_print("Polarity time: %f\n", (time1 - startTime) / NANOSEC); + if(!optimizationsOff){ + Preprocess pp(this); + pp.doTransform(); + time2 = getTimeNano(); + model_print("Preprocess time: %f\n", (time2 - time1) / NANOSEC); - IntegerEncodingTransform iet(this); - iet.doTransform(); + DecomposeOrderTransform dot(this); + dot.doTransform(); + time1 = getTimeNano(); + model_print("Decompose Order: %f\n", (time1 - time2) / NANOSEC); - ElementOpt eop(this); - eop.doTransform(); + IntegerEncodingTransform iet(this); + iet.doTransform(); - EncodingGraph eg(this); - eg.encode(); + ElementOpt eop(this); + eop.doTransform(); + EncodingGraph eg(this); + eg.encode(); + } naiveEncodingDecision(this); - // eg.validate(); - - VarOrderingOpt bor(this, satEncoder); - bor.doTransform(); - - time2 = getTimeNano(); - model_print("Encoding Graph Time: %f\n", (time2 - time1) / NANOSEC); + // eg.validate(); + if(!optimizationsOff){ + VarOrderingOpt bor(this, satEncoder); + bor.doTransform(); + time2 = getTimeNano(); + model_print("Encoding Graph Time: %f\n", (time2 - time1) / NANOSEC); + } satEncoder->encodeAllSATEncoder(this); time1 = getTimeNano(); @@ -660,7 +777,7 @@ int CSolver::solve() { model_print("Elapse Encode time: %f\n", (time1 - startTime) / NANOSEC); model_print("Is problem UNSAT after encoding: %d\n", unsat); - + result = unsat ? IS_UNSAT : satEncoder->solve(satsolverTimeout); model_print("Result Computed in SAT solver:\t%s\n", result == IS_SAT ? "SAT" : result == IS_INDETER ? "INDETERMINATE" : " UNSAT"); @@ -675,8 +792,30 @@ int CSolver::solve() { return result; } -void CSolver::setAlloyEncoder(){ - alloyEncoder = new AlloyEnc(this); +void CSolver::setInterpreter(InterpreterType type) { + if (interpreter == NULL) { + switch (type) { + case SATUNE: + break; + case ALLOY: { + interpreter = new AlloyInterpreter(this); + break; + } case Z3: { + interpreter = new SMTInterpreter(this); + break; + } + case MATHSAT: { + interpreter = new MathSATInterpreter(this); + break; + } + case SMTRAT: { + interpreter = new SMTRatInterpreter(this); + break; + } + default: + ASSERT(0); + } + } } void CSolver::printConstraints() { @@ -697,20 +836,27 @@ uint64_t CSolver::getElementValue(Element *element) { case ELEMSET: case ELEMCONST: case ELEMFUNCRETURN: - return useAlloyCompiler()? alloyEncoder->getValue(element): - getElementValueSATTranslator(this, element); + return useInterpreter() ? interpreter->getValue(element) : + getElementValueSATTranslator(this, element); default: ASSERT(0); } exit(-1); } +void CSolver::freezeElement(Element *e) { + e->freezeElement(); + if (!incrementalMode) { + incrementalMode = true; + } +} + bool CSolver::getBooleanValue(BooleanEdge bedge) { Boolean *boolean = bedge.getBoolean(); switch (boolean->type) { case BOOLEANVAR: - return useAlloyCompiler()? alloyEncoder->getBooleanValue(boolean): - getBooleanVariableValueSATTranslator(this, boolean); + return useInterpreter() ? interpreter->getBooleanValue(boolean) : + getBooleanVariableValueSATTranslator(this, boolean); default: ASSERT(0); }