ASSERT(encoding->type == BINARYVAL);
allocElementConstraintVariables(encoding, encoding->numBits);
getArrayNewVarsSATEncoder(encoding->numVars, encoding->variables);
+ if(encoding->anyValue)
+ generateAnyValueBinaryValueEncoding(encoding);
}
void SATEncoder::generateBinaryIndexEncodingVars(ElementEncoding *encoding) {
ASSERT(encoding->type == BINARYINDEX);
allocElementConstraintVariables(encoding, NUMBITS(encoding->encArraySize - 1));
getArrayNewVarsSATEncoder(encoding->numVars, encoding->variables);
+ if(encoding->anyValue)
+ generateAnyValueBinaryIndexEncoding(encoding);
}
void SATEncoder::generateOneHotEncodingVars(ElementEncoding *encoding) {
}
}
addConstraintCNF(cnf, constraintOR(cnf, encoding->numVars, encoding->variables));
+ if(encoding->anyValue)
+ generateAnyValueOneHotEncoding(encoding);
}
void SATEncoder::generateUnaryEncodingVars(ElementEncoding *encoding) {
for (uint i = 1; i < encoding->numVars; i++) {
addConstraintCNF(cnf, constraintOR2(cnf, encoding->variables[i - 1], constraintNegate(encoding->variables[i])));
}
+ if(encoding->anyValue)
+ generateAnyValueUnaryEncoding(encoding);
}
void SATEncoder::generateElementEncoding(Element *element) {
}
}
+void SATEncoder::generateAnyValueOneHotEncoding(ElementEncoding *encoding){
+ if(encoding->numVars == 0)
+ return;
+ Edge carray[encoding->numVars];
+ int size = 0;
+ for (uint i = 0; i < encoding->encArraySize; i++) {
+ if (encoding->isinUseElement(i)){
+ carray[size++] = encoding->variables[i];
+ }
+ }
+ if(size > 0){
+ addConstraintCNF(cnf, constraintOR(cnf, size, carray));
+ }
+}
+
+void SATEncoder::generateAnyValueUnaryEncoding(ElementEncoding *encoding){
+ if (encoding->numVars == 0)
+ return;
+ Edge carray[encoding->numVars];
+ int size = 0;
+ for (uint i = 0; i < encoding->encArraySize; i++) {
+ if (encoding->isinUseElement(i)) {
+ if (i == 0)
+ carray[size++] = constraintNegate(encoding->variables[0]);
+ else if ((i + 1) == encoding->encArraySize)
+ carray[size++] = encoding->variables[i - 1];
+ else
+ carray[size++] = constraintAND2(cnf, encoding->variables[i - 1], constraintNegate(encoding->variables[i]));
+ }
+ }
+ if(size > 0){
+ addConstraintCNF(cnf, constraintOR(cnf, size, carray));
+ }
+}
+
+void SATEncoder::generateAnyValueBinaryIndexEncoding(ElementEncoding *encoding){
+ if(encoding->numVars == 0)
+ return;
+ Edge carray[encoding->numVars];
+ int size = 0;
+ int index = -1;
+ for(uint i= encoding->encArraySize-1; i>=0; i--){
+ if(encoding->isinUseElement(i)){
+ if(i+1 < encoding->encArraySize){
+ index = i+1;
+ }
+ break;
+ }
+ }
+ if( index != -1 ){
+ carray[size++] = generateLTValueConstraint(cnf, encoding->numVars, encoding->variables, index);
+ }
+ index = index == -1? encoding->encArraySize-1 : index-1;
+ for(int i= index; i>=0; i--){
+ if (!encoding->isinUseElement(i)){
+ carray[size++] = constraintNegate( generateBinaryConstraint(cnf, encoding->numVars, encoding->variables, i));
+ }
+ }
+ if(size > 0){
+ addConstraintCNF(cnf, constraintAND(cnf, size, carray));
+ }
+}
+
+void SATEncoder::generateAnyValueBinaryValueEncoding(ElementEncoding *encoding){
+ uint64_t minvalueminusoffset = encoding->low - encoding->offset;
+ uint64_t maxvalueminusoffset = encoding->high - encoding->offset;
+ model_print("This is minvalueminus offset: %lu", minvalueminusoffset);
+ Edge lowerbound = generateLTValueConstraint(cnf, encoding->numVars, encoding->variables, maxvalueminusoffset);
+ Edge upperbound = constraintNegate(generateLTValueConstraint(cnf, encoding->numVars, encoding->variables, minvalueminusoffset));
+ addConstraintCNF(cnf, constraintAND2(cnf, lowerbound, upperbound));
+}
+
--- /dev/null
+#include "csolver.h"
+
+
+int main(int numargs, char **argv) {
+ CSolver *solver = new CSolver();
+ uint64_t set1[] = {10, 8, 18};
+ uint64_t set2[] = {10, 13, 7};
+ Set *s1 = solver->createSet(0, set1, 3);
+ Set *s2 = solver->createSet(1, set2, 3);
+ Element *e1 = solver->getElementVar(s1);
+ Element *e2 = solver->getElementVar(s2);
+ solver->mustHaveValue(e1);
+ solver->mustHaveValue(e2);
+
+ Set *domain[] = {s1, s2};
+ Predicate *equals = solver->createPredicateOperator(SATC_EQUALS, domain, 2);
+ Element *inputs[] = {e1, e2};
+ BooleanEdge b = solver->applyPredicate(equals, inputs, 2);
+ b = solver->applyLogicalOperation(SATC_NOT, b);
+ solver->addConstraint(b);
+
+ if (solver->solve() == 1)
+ printf("e1=%" PRIu64 "e2=%" PRIu64 "\n", solver->getElementValue(e1), solver->getElementValue(e2));
+ else
+ printf("UNSAT\n");
+ delete solver;
+}
return element;
}
+void CSolver::mustHaveValue(Element *element){
+ element->getElementEncoding()->anyValue = true;
+}
+
Set *CSolver::getElementRange (Element *element) {
return element->getRange();
}
return applyLogicalOperation(op, array, 1);
}
-static int ptrcompares(const void *p1, const void *p2) {
- uintptr_t b1 = *(uintptr_t const *) p1;
- uintptr_t b2 = *(uintptr_t const *) p2;
+static int booleanEdgeCompares(const void *p1, const void *p2) {
+ BooleanEdge be1 = *(BooleanEdge const *) p1;
+ BooleanEdge be2 = *(BooleanEdge const *) p2;
+ uint64_t b1 = be1->id;
+ uint64_t b2 = be2->id;
if (b1 < b2)
return -1;
else if (b1 == b2)
} else if (newindex == 1) {
return newarray[0];
} else {
- bsdqsort(newarray, newindex, sizeof(BooleanEdge), ptrcompares);
+ bsdqsort(newarray, newindex, sizeof(BooleanEdge), booleanEdgeCompares);
array = newarray;
asize = newindex;
}