+++ /dev/null
-#include "boolean.h"
-#include "structs.h"
-#include "csolver.h"
-#include "element.h"
-#include "order.h"
-
-Boolean *allocBooleanVar(VarType t) {
- BooleanVar *This = (BooleanVar *) ourmalloc(sizeof (BooleanVar));
- GETBOOLEANTYPE(This) = BOOLEANVAR;
- GETBOOLEANVALUE(This) = BV_UNDEFINED;
- GETBOOLEANPOLARITY(This) = P_UNDEFINED;
- This->vtype = t;
- This->var = E_NULL;
- initDefVectorBoolean(GETBOOLEANPARENTS(This));
- return &This->base;
-}
-
-Boolean *allocBooleanOrder(Order *order, uint64_t first, uint64_t second) {
- BooleanOrder *This = (BooleanOrder *) ourmalloc(sizeof (BooleanOrder));
- GETBOOLEANTYPE(This) = ORDERCONST;
- GETBOOLEANVALUE(This) = BV_UNDEFINED;
- GETBOOLEANPOLARITY(This) = P_UNDEFINED;
- This->order = order;
- This->first = first;
- This->second = second;
- pushVectorBooleanOrder(&order->constraints, This);
- initDefVectorBoolean(GETBOOLEANPARENTS(This));
- return &This->base;
-}
-
-Boolean *allocBooleanPredicate(Predicate *predicate, Element **inputs, uint numInputs, Boolean *undefinedStatus) {
- BooleanPredicate *This = (BooleanPredicate *) ourmalloc(sizeof(BooleanPredicate));
- GETBOOLEANTYPE(This) = PREDICATEOP;
- GETBOOLEANVALUE(This) = BV_UNDEFINED;
- GETBOOLEANPOLARITY(This) = P_UNDEFINED;
- This->predicate = predicate;
- initArrayInitElement(&This->inputs, inputs, numInputs);
- initDefVectorBoolean(GETBOOLEANPARENTS(This));
-
- for (uint i = 0; i < numInputs; i++) {
- pushVectorASTNode(GETELEMENTPARENTS(inputs[i]), (ASTNode *)This);
- }
- initPredicateEncoding(&This->encoding, (Boolean *) This);
- This->undefStatus = undefinedStatus;
- return &This->base;
-}
-
-Boolean *allocBooleanLogicArray(CSolver *solver, LogicOp op, Boolean **array, uint asize) {
- BooleanLogic *This = ourmalloc(sizeof(BooleanLogic));
- GETBOOLEANTYPE(This) = LOGICOP;
- GETBOOLEANVALUE(This) = BV_UNDEFINED;
- GETBOOLEANPOLARITY(This) = P_UNDEFINED;
- This->op = op;
- initDefVectorBoolean(GETBOOLEANPARENTS(This));
- initArrayInitBoolean(&This->inputs, array, asize);
- pushVectorBoolean(solver->allBooleans, (Boolean *) This);
- return &This->base;
-}
-
-void deleteBoolean(Boolean *This) {
- switch (GETBOOLEANTYPE(This)) {
- case PREDICATEOP: {
- BooleanPredicate *bp = (BooleanPredicate *)This;
- deleteInlineArrayElement(&bp->inputs );
- deleteFunctionEncoding(&bp->encoding);
- break;
- }
- case LOGICOP: {
- BooleanLogic *bl = (BooleanLogic *) This;
- deleteInlineArrayBoolean(&bl->inputs);
- break;
- }
- default:
- break;
- }
- deleteVectorArrayBoolean(GETBOOLEANPARENTS(This));
- ourfree(This);
-}
--- /dev/null
+#include "boolean.h"
+#include "structs.h"
+#include "csolver.h"
+#include "element.h"
+#include "order.h"
+
+Boolean *allocBooleanVar(VarType t) {
+ BooleanVar *This = (BooleanVar *) ourmalloc(sizeof (BooleanVar));
+ GETBOOLEANTYPE(This) = BOOLEANVAR;
+ GETBOOLEANVALUE(This) = BV_UNDEFINED;
+ GETBOOLEANPOLARITY(This) = P_UNDEFINED;
+ This->vtype = t;
+ This->var = E_NULL;
+ initDefVectorBoolean(GETBOOLEANPARENTS(This));
+ return &This->base;
+}
+
+Boolean *allocBooleanOrder(Order *order, uint64_t first, uint64_t second) {
+ BooleanOrder *This = (BooleanOrder *) ourmalloc(sizeof (BooleanOrder));
+ GETBOOLEANTYPE(This) = ORDERCONST;
+ GETBOOLEANVALUE(This) = BV_UNDEFINED;
+ GETBOOLEANPOLARITY(This) = P_UNDEFINED;
+ This->order = order;
+ This->first = first;
+ This->second = second;
+ pushVectorBooleanOrder(&order->constraints, This);
+ initDefVectorBoolean(GETBOOLEANPARENTS(This));
+ return &This->base;
+}
+
+Boolean *allocBooleanPredicate(Predicate *predicate, Element **inputs, uint numInputs, Boolean *undefinedStatus) {
+ BooleanPredicate *This = (BooleanPredicate *) ourmalloc(sizeof(BooleanPredicate));
+ GETBOOLEANTYPE(This) = PREDICATEOP;
+ GETBOOLEANVALUE(This) = BV_UNDEFINED;
+ GETBOOLEANPOLARITY(This) = P_UNDEFINED;
+ This->predicate = predicate;
+ initArrayInitElement(&This->inputs, inputs, numInputs);
+ initDefVectorBoolean(GETBOOLEANPARENTS(This));
+
+ for (uint i = 0; i < numInputs; i++) {
+ pushVectorASTNode(GETELEMENTPARENTS(inputs[i]), (ASTNode *)This);
+ }
+ initPredicateEncoding(&This->encoding, (Boolean *) This);
+ This->undefStatus = undefinedStatus;
+ return &This->base;
+}
+
+Boolean *allocBooleanLogicArray(CSolver *solver, LogicOp op, Boolean **array, uint asize) {
+ BooleanLogic *This = (BooleanLogic *) ourmalloc(sizeof(BooleanLogic));
+ GETBOOLEANTYPE(This) = LOGICOP;
+ GETBOOLEANVALUE(This) = BV_UNDEFINED;
+ GETBOOLEANPOLARITY(This) = P_UNDEFINED;
+ This->op = op;
+ initDefVectorBoolean(GETBOOLEANPARENTS(This));
+ initArrayInitBoolean(&This->inputs, array, asize);
+ pushVectorBoolean(solver->allBooleans, (Boolean *) This);
+ return &This->base;
+}
+
+void deleteBoolean(Boolean *This) {
+ switch (GETBOOLEANTYPE(This)) {
+ case PREDICATEOP: {
+ BooleanPredicate *bp = (BooleanPredicate *)This;
+ deleteInlineArrayElement(&bp->inputs );
+ deleteFunctionEncoding(&bp->encoding);
+ break;
+ }
+ case LOGICOP: {
+ BooleanLogic *bl = (BooleanLogic *) This;
+ deleteInlineArrayBoolean(&bl->inputs);
+ break;
+ }
+ default:
+ break;
+ }
+ deleteVectorArrayBoolean(GETBOOLEANPARENTS(This));
+ ourfree(This);
+}
+++ /dev/null
-#include "element.h"
-#include "structs.h"
-#include "set.h"
-#include "constraint.h"
-#include "function.h"
-#include "table.h"
-
-Element *allocElementSet(Set *s) {
- ElementSet *This = (ElementSet *)ourmalloc(sizeof(ElementSet));
- GETELEMENTTYPE(This) = ELEMSET;
- This->set = s;
- initDefVectorASTNode(GETELEMENTPARENTS(This));
- initElementEncoding(&This->encoding, (Element *) This);
- return &This->base;
-}
-
-Element *allocElementFunction(Function *function, Element **array, uint numArrays, Boolean *overflowstatus) {
- ElementFunction *This = (ElementFunction *) ourmalloc(sizeof(ElementFunction));
- GETELEMENTTYPE(This) = ELEMFUNCRETURN;
- This->function = function;
- ASSERT(GETBOOLEANTYPE(overflowstatus) == BOOLEANVAR);
- This->overflowstatus = overflowstatus;
- initArrayInitElement(&This->inputs, array, numArrays);
- initDefVectorASTNode(GETELEMENTPARENTS(This));
- for (uint i = 0; i < numArrays; i++)
- pushVectorASTNode(GETELEMENTPARENTS(array[i]), (ASTNode *) This);
- initElementEncoding(&This->rangeencoding, (Element *) This);
- initFunctionEncoding(&This->functionencoding, (Element *) This);
- return &This->base;
-}
-
-Element *allocElementConst(uint64_t value, VarType type) {
- ElementConst *This = (ElementConst *)ourmalloc(sizeof(ElementConst));
- GETELEMENTTYPE(This) = ELEMCONST;
- This->value = value;
- This->set = allocSet(type, (uint64_t[]) {value}, 1);
- initDefVectorASTNode(GETELEMENTPARENTS(This));
- initElementEncoding(&This->encoding, (Element *) This);
- return &This->base;
-}
-
-Set *getElementSet(Element *This) {
- switch (GETELEMENTTYPE(This)) {
- case ELEMSET:
- return ((ElementSet *)This)->set;
- case ELEMCONST:
- return ((ElementConst *)This)->set;
- case ELEMFUNCRETURN: {
- Function *func = ((ElementFunction *)This)->function;
- switch (GETFUNCTIONTYPE(func)) {
- case TABLEFUNC:
- return ((FunctionTable *)func)->table->range;
- case OPERATORFUNC:
- return ((FunctionOperator *)func)->range;
- default:
- ASSERT(0);
- }
- }
- default:
- ASSERT(0);
- }
- ASSERT(0);
- return NULL;
-}
-
-void deleteElement(Element *This) {
- switch (GETELEMENTTYPE(This)) {
- case ELEMFUNCRETURN: {
- ElementFunction *ef = (ElementFunction *) This;
- deleteInlineArrayElement(&ef->inputs);
- deleteElementEncoding(&ef->rangeencoding);
- deleteFunctionEncoding(&ef->functionencoding);
- break;
- }
- case ELEMSET: {
- ElementSet *es = (ElementSet *) This;
- deleteElementEncoding(&es->encoding);
- break;
- }
- case ELEMCONST: {
- ElementConst *ec = (ElementConst *) This;
- deleteSet(ec->set);//Client did not create, so we free it
- deleteElementEncoding(&ec->encoding);
- break;
- }
- default:
- ASSERT(0);
- }
- deleteVectorArrayASTNode(GETELEMENTPARENTS(This));
- ourfree(This);
-}
--- /dev/null
+#include "element.h"
+#include "structs.h"
+#include "set.h"
+#include "constraint.h"
+#include "function.h"
+#include "table.h"
+
+Element *allocElementSet(Set *s) {
+ ElementSet *This = (ElementSet *)ourmalloc(sizeof(ElementSet));
+ GETELEMENTTYPE(This) = ELEMSET;
+ This->set = s;
+ initDefVectorASTNode(GETELEMENTPARENTS(This));
+ initElementEncoding(&This->encoding, (Element *) This);
+ return &This->base;
+}
+
+Element *allocElementFunction(Function *function, Element **array, uint numArrays, Boolean *overflowstatus) {
+ ElementFunction *This = (ElementFunction *) ourmalloc(sizeof(ElementFunction));
+ GETELEMENTTYPE(This) = ELEMFUNCRETURN;
+ This->function = function;
+ ASSERT(GETBOOLEANTYPE(overflowstatus) == BOOLEANVAR);
+ This->overflowstatus = overflowstatus;
+ initArrayInitElement(&This->inputs, array, numArrays);
+ initDefVectorASTNode(GETELEMENTPARENTS(This));
+ for (uint i = 0; i < numArrays; i++)
+ pushVectorASTNode(GETELEMENTPARENTS(array[i]), (ASTNode *) This);
+ initElementEncoding(&This->rangeencoding, (Element *) This);
+ initFunctionEncoding(&This->functionencoding, (Element *) This);
+ return &This->base;
+}
+
+Element *allocElementConst(uint64_t value, VarType type) {
+ ElementConst *This = (ElementConst *)ourmalloc(sizeof(ElementConst));
+ GETELEMENTTYPE(This) = ELEMCONST;
+ This->value = value;
+ This->set = allocSet(type, (uint64_t[]) {value}, 1);
+ initDefVectorASTNode(GETELEMENTPARENTS(This));
+ initElementEncoding(&This->encoding, (Element *) This);
+ return &This->base;
+}
+
+Set *getElementSet(Element *This) {
+ switch (GETELEMENTTYPE(This)) {
+ case ELEMSET:
+ return ((ElementSet *)This)->set;
+ case ELEMCONST:
+ return ((ElementConst *)This)->set;
+ case ELEMFUNCRETURN: {
+ Function *func = ((ElementFunction *)This)->function;
+ switch (GETFUNCTIONTYPE(func)) {
+ case TABLEFUNC:
+ return ((FunctionTable *)func)->table->range;
+ case OPERATORFUNC:
+ return ((FunctionOperator *)func)->range;
+ default:
+ ASSERT(0);
+ }
+ }
+ default:
+ ASSERT(0);
+ }
+ ASSERT(0);
+ return NULL;
+}
+
+void deleteElement(Element *This) {
+ switch (GETELEMENTTYPE(This)) {
+ case ELEMFUNCRETURN: {
+ ElementFunction *ef = (ElementFunction *) This;
+ deleteInlineArrayElement(&ef->inputs);
+ deleteElementEncoding(&ef->rangeencoding);
+ deleteFunctionEncoding(&ef->functionencoding);
+ break;
+ }
+ case ELEMSET: {
+ ElementSet *es = (ElementSet *) This;
+ deleteElementEncoding(&es->encoding);
+ break;
+ }
+ case ELEMCONST: {
+ ElementConst *ec = (ElementConst *) This;
+ deleteSet(ec->set);//Client did not create, so we free it
+ deleteElementEncoding(&ec->encoding);
+ break;
+ }
+ default:
+ ASSERT(0);
+ }
+ deleteVectorArrayASTNode(GETELEMENTPARENTS(This));
+ ourfree(This);
+}
+++ /dev/null
-#include "function.h"
-#include "table.h"
-#include "set.h"
-
-
-Function *allocFunctionOperator(ArithOp op, Set **domain, uint numDomain, Set *range, OverFlowBehavior overflowbehavior) {
- FunctionOperator *This = (FunctionOperator *) ourmalloc(sizeof(FunctionOperator));
- GETFUNCTIONTYPE(This) = OPERATORFUNC;
- initArrayInitSet(&This->domains, domain, numDomain);
- This->op = op;
- This->overflowbehavior = overflowbehavior;
- This->range = range;
- return &This->base;
-}
-
-Function *allocFunctionTable (Table *table, UndefinedBehavior undefBehavior) {
- FunctionTable *This = (FunctionTable *) ourmalloc(sizeof(FunctionTable));
- GETFUNCTIONTYPE(This) = TABLEFUNC;
- This->table = table;
- This->undefBehavior = undefBehavior;
- return &This->base;
-}
-
-uint64_t applyFunctionOperator(FunctionOperator *This, uint numVals, uint64_t *values) {
- ASSERT(numVals == 2);
- switch (This->op) {
- case ADD:
- return values[0] + values[1];
- break;
- case SUB:
- return values[0] - values[1];
- break;
- default:
- ASSERT(0);
- }
-}
-
-bool isInRangeFunction(FunctionOperator *This, uint64_t val) {
- return existsInSet(This->range, val);
-}
-
-void deleteFunction(Function *This) {
- switch (GETFUNCTIONTYPE(This)) {
- case TABLEFUNC:
- break;
- case OPERATORFUNC:
- deleteInlineArraySet(&((FunctionOperator *) This)->domains);
- break;
- default:
- ASSERT(0);
- }
- ourfree(This);
-}
--- /dev/null
+#include "function.h"
+#include "table.h"
+#include "set.h"
+
+
+Function *allocFunctionOperator(ArithOp op, Set **domain, uint numDomain, Set *range, OverFlowBehavior overflowbehavior) {
+ FunctionOperator *This = (FunctionOperator *) ourmalloc(sizeof(FunctionOperator));
+ GETFUNCTIONTYPE(This) = OPERATORFUNC;
+ initArrayInitSet(&This->domains, domain, numDomain);
+ This->op = op;
+ This->overflowbehavior = overflowbehavior;
+ This->range = range;
+ return &This->base;
+}
+
+Function *allocFunctionTable (Table *table, UndefinedBehavior undefBehavior) {
+ FunctionTable *This = (FunctionTable *) ourmalloc(sizeof(FunctionTable));
+ GETFUNCTIONTYPE(This) = TABLEFUNC;
+ This->table = table;
+ This->undefBehavior = undefBehavior;
+ return &This->base;
+}
+
+uint64_t applyFunctionOperator(FunctionOperator *This, uint numVals, uint64_t *values) {
+ ASSERT(numVals == 2);
+ switch (This->op) {
+ case ADD:
+ return values[0] + values[1];
+ break;
+ case SUB:
+ return values[0] - values[1];
+ break;
+ default:
+ ASSERT(0);
+ }
+}
+
+bool isInRangeFunction(FunctionOperator *This, uint64_t val) {
+ return existsInSet(This->range, val);
+}
+
+void deleteFunction(Function *This) {
+ switch (GETFUNCTIONTYPE(This)) {
+ case TABLEFUNC:
+ break;
+ case OPERATORFUNC:
+ deleteInlineArraySet(&((FunctionOperator *) This)->domains);
+ break;
+ default:
+ ASSERT(0);
+ }
+ ourfree(This);
+}
+++ /dev/null
-#include "mutableset.h"
-
-MutableSet *allocMutableSet(VarType t) {
- MutableSet *This = (MutableSet *)ourmalloc(sizeof(MutableSet));
- This->type = t;
- This->isRange = false;
- This->low = 0;
- This->high = 0;
- This->members = allocDefVectorInt();
- return This;
-}
-
-void addElementMSet(MutableSet *set, uint64_t element) {
- pushVectorInt(set->members, element);
-}
--- /dev/null
+#include "mutableset.h"
+
+MutableSet *allocMutableSet(VarType t) {
+ MutableSet *This = (MutableSet *)ourmalloc(sizeof(MutableSet));
+ This->type = t;
+ This->isRange = false;
+ This->low = 0;
+ This->high = 0;
+ This->members = allocDefVectorInt();
+ return This;
+}
+
+void addElementMSet(MutableSet *set, uint64_t element) {
+ pushVectorInt(set->members, element);
+}
+++ /dev/null
-#include "order.h"
-#include "structs.h"
-#include "set.h"
-#include "boolean.h"
-#include "ordergraph.h"
-
-Order *allocOrder(OrderType type, Set *set) {
- Order *This = (Order *)ourmalloc(sizeof(Order));
- This->set = set;
- initDefVectorBooleanOrder(&This->constraints);
- This->type = type;
- initOrderEncoding(&This->order, This);
- This->orderPairTable = NULL;
- This->elementTable = NULL;
- This->graph = NULL;
- return This;
-}
-
-void initializeOrderHashTable(Order *This) {
- This->orderPairTable = allocHashTableOrderPair(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
-}
-
-void initializeOrderElementsHashTable(Order *This){
- This->elementTable = allocHashSetOrderElement(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
-}
-
-void addOrderConstraint(Order *This, BooleanOrder *constraint) {
- pushVectorBooleanOrder( &This->constraints, constraint);
-}
-
-void setOrderEncodingType(Order *This, OrderEncodingType type) {
- This->order.type = type;
-}
-
-void deleteOrder(Order *This) {
- deleteVectorArrayBooleanOrder(&This->constraints);
- deleteOrderEncoding(&This->order);
- if (This->orderPairTable != NULL) {
- resetAndDeleteHashTableOrderPair(This->orderPairTable);
- deleteHashTableOrderPair(This->orderPairTable);
- }
- if(This->elementTable != NULL){
- deleteHashSetOrderElement(This->elementTable);
- }
- if (This->graph != NULL) {
- deleteOrderGraph(This->graph);
- }
- ourfree(This);
-}
--- /dev/null
+#include "order.h"
+#include "structs.h"
+#include "set.h"
+#include "boolean.h"
+#include "ordergraph.h"
+
+Order *allocOrder(OrderType type, Set *set) {
+ Order *This = (Order *)ourmalloc(sizeof(Order));
+ This->set = set;
+ initDefVectorBooleanOrder(&This->constraints);
+ This->type = type;
+ initOrderEncoding(&This->order, This);
+ This->orderPairTable = NULL;
+ This->elementTable = NULL;
+ This->graph = NULL;
+ return This;
+}
+
+void initializeOrderHashTable(Order *This) {
+ This->orderPairTable = allocHashTableOrderPair(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
+}
+
+void initializeOrderElementsHashTable(Order *This){
+ This->elementTable = allocHashSetOrderElement(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
+}
+
+void addOrderConstraint(Order *This, BooleanOrder *constraint) {
+ pushVectorBooleanOrder( &This->constraints, constraint);
+}
+
+void setOrderEncodingType(Order *This, OrderEncodingType type) {
+ This->order.type = type;
+}
+
+void deleteOrder(Order *This) {
+ deleteVectorArrayBooleanOrder(&This->constraints);
+ deleteOrderEncoding(&This->order);
+ if (This->orderPairTable != NULL) {
+ resetAndDeleteHashTableOrderPair(This->orderPairTable);
+ deleteHashTableOrderPair(This->orderPairTable);
+ }
+ if(This->elementTable != NULL){
+ deleteHashSetOrderElement(This->elementTable);
+ }
+ if (This->graph != NULL) {
+ deleteOrderGraph(This->graph);
+ }
+ ourfree(This);
+}
+++ /dev/null
-#include "predicate.h"
-#include "boolean.h"
-#include "set.h"
-#include "table.h"
-
-Predicate *allocPredicateOperator(CompOp op, Set **domain, uint numDomain) {
- PredicateOperator *This = ourmalloc(sizeof(PredicateOperator));
- GETPREDICATETYPE(This) = OPERATORPRED;
- initArrayInitSet(&This->domains, domain, numDomain);
- This->op = op;
- return &This->base;
-}
-
-Predicate *allocPredicateTable(Table *table, UndefinedBehavior undefBehavior) {
- ASSERT(table->range == NULL);
- PredicateTable *This = ourmalloc(sizeof(PredicateTable));
- GETPREDICATETYPE(This) = TABLEPRED;
- This->table = table;
- This->undefinedbehavior = undefBehavior;
- return &This->base;
-}
-
-void deletePredicate(Predicate *This) {
- switch (GETPREDICATETYPE(This)) {
- case OPERATORPRED: {
- PredicateOperator *operpred = (PredicateOperator *) This;
- deleteInlineArraySet(&operpred->domains);
- break;
- }
- case TABLEPRED: {
- break;
- }
- }
- //need to handle freeing array...
- ourfree(This);
-}
-
-bool evalPredicateOperator(PredicateOperator *This, uint64_t *inputs) {
- switch (This->op) {
- case EQUALS:
- return inputs[0] == inputs[1];
- case LT:
- return inputs[0] < inputs[1];
- case GT:
- return inputs[0] > inputs[1];
- case LTE:
- return inputs[0] <= inputs[1];
- case GTE:
- return inputs[0] >= inputs[1];
- }
- ASSERT(0);
- return false;
-}
--- /dev/null
+#include "predicate.h"
+#include "boolean.h"
+#include "set.h"
+#include "table.h"
+
+Predicate *allocPredicateOperator(CompOp op, Set **domain, uint numDomain) {
+ PredicateOperator *This = (PredicateOperator *)ourmalloc(sizeof(PredicateOperator));
+ GETPREDICATETYPE(This) = OPERATORPRED;
+ initArrayInitSet(&This->domains, domain, numDomain);
+ This->op = op;
+ return &This->base;
+}
+
+Predicate *allocPredicateTable(Table *table, UndefinedBehavior undefBehavior) {
+ ASSERT(table->range == NULL);
+ PredicateTable *This = (PredicateTable *) ourmalloc(sizeof(PredicateTable));
+ GETPREDICATETYPE(This) = TABLEPRED;
+ This->table = table;
+ This->undefinedbehavior = undefBehavior;
+ return &This->base;
+}
+
+void deletePredicate(Predicate *This) {
+ switch (GETPREDICATETYPE(This)) {
+ case OPERATORPRED: {
+ PredicateOperator *operpred = (PredicateOperator *) This;
+ deleteInlineArraySet(&operpred->domains);
+ break;
+ }
+ case TABLEPRED: {
+ break;
+ }
+ }
+ //need to handle freeing array...
+ ourfree(This);
+}
+
+bool evalPredicateOperator(PredicateOperator *This, uint64_t *inputs) {
+ switch (This->op) {
+ case EQUALS:
+ return inputs[0] == inputs[1];
+ case LT:
+ return inputs[0] < inputs[1];
+ case GT:
+ return inputs[0] > inputs[1];
+ case LTE:
+ return inputs[0] <= inputs[1];
+ case GTE:
+ return inputs[0] >= inputs[1];
+ }
+ ASSERT(0);
+ return false;
+}
+++ /dev/null
-#include "rewriter.h"
-#include "boolean.h"
-#include "csolver.h"
-
-void replaceBooleanWithTrue(CSolver * This, Boolean *bexpr) {
- if (containsHashSetBoolean(This->constraints, bexpr)) {
- removeHashSetBoolean(This->constraints, bexpr);
- }
-
- uint size = getSizeVectorBoolean(&bexpr->parents);
- for (uint i = 0; i < size; i++) {
- Boolean *parent = getVectorBoolean(&bexpr->parents, i);
- BooleanLogic *logicop = (BooleanLogic *) parent;
- switch (logicop->op) {
- case L_AND:
- handleANDTrue(This, logicop, bexpr);
- break;
- case L_OR:
- replaceBooleanWithTrue(This, parent);
- break;
- case L_NOT:
- replaceBooleanWithFalse(This, parent);
- break;
- case L_XOR:
- handleXORTrue(logicop, bexpr);
- break;
- case L_IMPLIES:
- handleIMPLIESTrue(This, logicop, bexpr);
- break;
- }
- }
-}
-
-void replaceBooleanWithBoolean(CSolver * This, Boolean *oldb, Boolean *newb) {
- if (containsHashSetBoolean(This->constraints, oldb)) {
- removeHashSetBoolean(This->constraints, oldb);
- addHashSetBoolean(This->constraints, newb);
- }
-
- uint size = getSizeVectorBoolean(&oldb->parents);
- for (uint i = 0; i < size; i++) {
- Boolean *parent = getVectorBoolean(&oldb->parents, i);
- BooleanLogic *logicop = (BooleanLogic *) parent;
-
- uint parentsize = getSizeArrayBoolean(&logicop->inputs);
-
- for (uint j = 0; j < parentsize; j++) {
- Boolean *b = getArrayBoolean(&logicop->inputs, i);
- if (b == oldb) {
- setArrayBoolean(&logicop->inputs, i, newb);
- pushVectorBoolean(&newb->parents, parent);
- }
- }
- }
-}
-
-void handleXORTrue(BooleanLogic *bexpr, Boolean *child) {
- uint size = getSizeArrayBoolean(&bexpr->inputs);
- Boolean *b = getArrayBoolean(&bexpr->inputs, 0);
- uint childindex = (b == child) ? 0 : 1;
- removeElementArrayBoolean(&bexpr->inputs, childindex);
- bexpr->op = L_NOT;
-}
-
-void handleXORFalse(CSolver * This, BooleanLogic *bexpr, Boolean *child) {
- uint size = getSizeArrayBoolean(&bexpr->inputs);
- Boolean *b = getArrayBoolean(&bexpr->inputs, 0);
- uint otherindex = (b == child) ? 1 : 0;
- replaceBooleanWithBoolean(This, (Boolean *)bexpr, getArrayBoolean(&bexpr->inputs, otherindex));
-}
-
-void handleIMPLIESTrue(CSolver * This, BooleanLogic *bexpr, Boolean *child) {
- uint size = getSizeArrayBoolean(&bexpr->inputs);
- Boolean *b = getArrayBoolean(&bexpr->inputs, 0);
- if (b == child) {
- //Replace with other term
- replaceBooleanWithBoolean(This, (Boolean *)bexpr, getArrayBoolean(&bexpr->inputs, 1));
- } else {
- //Statement is true...
- replaceBooleanWithTrue(This, (Boolean *)bexpr);
- }
-}
-
-void handleIMPLIESFalse(CSolver * This, BooleanLogic *bexpr, Boolean *child) {
- uint size = getSizeArrayBoolean(&bexpr->inputs);
- Boolean *b = getArrayBoolean(&bexpr->inputs, 0);
- if (b == child) {
- //Statement is true...
- replaceBooleanWithTrue(This, (Boolean *)bexpr);
- } else {
- //Make into negation of first term
- removeElementArrayBoolean(&bexpr->inputs, 1);
- bexpr->op = L_NOT;
- }
-}
-
-void handleANDTrue(CSolver * This, BooleanLogic *bexpr, Boolean *child) {
- uint size = getSizeArrayBoolean(&bexpr->inputs);
-
- if (size == 1) {
- replaceBooleanWithTrue(This, (Boolean *)bexpr);
- return;
- }
-
- for (uint i = 0; i < size; i++) {
- Boolean *b = getArrayBoolean(&bexpr->inputs, i);
- if (b == child) {
- removeElementArrayBoolean(&bexpr->inputs, i);
- }
- }
-
- if (size == 2) {
- replaceBooleanWithBoolean(This, (Boolean *)bexpr, getArrayBoolean(&bexpr->inputs, 0));
- }
-}
-
-void handleORFalse(CSolver * This, BooleanLogic *bexpr, Boolean *child) {
- uint size = getSizeArrayBoolean(&bexpr->inputs);
-
- if (size == 1) {
- replaceBooleanWithFalse(This, (Boolean *) bexpr);
- }
-
- for (uint i = 0; i < size; i++) {
- Boolean *b = getArrayBoolean(&bexpr->inputs, i);
- if (b == child) {
- removeElementArrayBoolean(&bexpr->inputs, i);
- }
- }
-
- if (size == 2) {
- replaceBooleanWithBoolean(This, (Boolean *)bexpr, getArrayBoolean(&bexpr->inputs, 0));
- }
-}
-
-void replaceBooleanWithFalse(CSolver * This, Boolean *bexpr) {
- if (containsHashSetBoolean(This->constraints, bexpr)) {
- This->unsat=true;
- removeHashSetBoolean(This->constraints, bexpr);
- }
-
- uint size = getSizeVectorBoolean(&bexpr->parents);
- for (uint i = 0; i < size; i++) {
- Boolean *parent = getVectorBoolean(&bexpr->parents, i);
- BooleanLogic *logicop = (BooleanLogic *) parent;
- switch (logicop->op) {
- case L_AND:
- replaceBooleanWithFalse(This, parent);
- break;
- case L_OR:
- handleORFalse(This, logicop, bexpr);
- break;
- case L_NOT:
- replaceBooleanWithTrue(This, parent);
- break;
- case L_XOR:
- handleXORFalse(This, logicop, bexpr);
- break;
- case L_IMPLIES:
- handleIMPLIESFalse(This, logicop, bexpr);
- break;
- }
- }
-}
--- /dev/null
+#include "rewriter.h"
+#include "boolean.h"
+#include "csolver.h"
+
+void replaceBooleanWithTrue(CSolver * This, Boolean *bexpr) {
+ if (containsHashSetBoolean(This->constraints, bexpr)) {
+ removeHashSetBoolean(This->constraints, bexpr);
+ }
+
+ uint size = getSizeVectorBoolean(&bexpr->parents);
+ for (uint i = 0; i < size; i++) {
+ Boolean *parent = getVectorBoolean(&bexpr->parents, i);
+ BooleanLogic *logicop = (BooleanLogic *) parent;
+ switch (logicop->op) {
+ case L_AND:
+ handleANDTrue(This, logicop, bexpr);
+ break;
+ case L_OR:
+ replaceBooleanWithTrue(This, parent);
+ break;
+ case L_NOT:
+ replaceBooleanWithFalse(This, parent);
+ break;
+ case L_XOR:
+ handleXORTrue(logicop, bexpr);
+ break;
+ case L_IMPLIES:
+ handleIMPLIESTrue(This, logicop, bexpr);
+ break;
+ }
+ }
+}
+
+void replaceBooleanWithBoolean(CSolver * This, Boolean *oldb, Boolean *newb) {
+ if (containsHashSetBoolean(This->constraints, oldb)) {
+ removeHashSetBoolean(This->constraints, oldb);
+ addHashSetBoolean(This->constraints, newb);
+ }
+
+ uint size = getSizeVectorBoolean(&oldb->parents);
+ for (uint i = 0; i < size; i++) {
+ Boolean *parent = getVectorBoolean(&oldb->parents, i);
+ BooleanLogic *logicop = (BooleanLogic *) parent;
+
+ uint parentsize = getSizeArrayBoolean(&logicop->inputs);
+
+ for (uint j = 0; j < parentsize; j++) {
+ Boolean *b = getArrayBoolean(&logicop->inputs, i);
+ if (b == oldb) {
+ setArrayBoolean(&logicop->inputs, i, newb);
+ pushVectorBoolean(&newb->parents, parent);
+ }
+ }
+ }
+}
+
+void handleXORTrue(BooleanLogic *bexpr, Boolean *child) {
+ uint size = getSizeArrayBoolean(&bexpr->inputs);
+ Boolean *b = getArrayBoolean(&bexpr->inputs, 0);
+ uint childindex = (b == child) ? 0 : 1;
+ removeElementArrayBoolean(&bexpr->inputs, childindex);
+ bexpr->op = L_NOT;
+}
+
+void handleXORFalse(CSolver * This, BooleanLogic *bexpr, Boolean *child) {
+ uint size = getSizeArrayBoolean(&bexpr->inputs);
+ Boolean *b = getArrayBoolean(&bexpr->inputs, 0);
+ uint otherindex = (b == child) ? 1 : 0;
+ replaceBooleanWithBoolean(This, (Boolean *)bexpr, getArrayBoolean(&bexpr->inputs, otherindex));
+}
+
+void handleIMPLIESTrue(CSolver * This, BooleanLogic *bexpr, Boolean *child) {
+ uint size = getSizeArrayBoolean(&bexpr->inputs);
+ Boolean *b = getArrayBoolean(&bexpr->inputs, 0);
+ if (b == child) {
+ //Replace with other term
+ replaceBooleanWithBoolean(This, (Boolean *)bexpr, getArrayBoolean(&bexpr->inputs, 1));
+ } else {
+ //Statement is true...
+ replaceBooleanWithTrue(This, (Boolean *)bexpr);
+ }
+}
+
+void handleIMPLIESFalse(CSolver * This, BooleanLogic *bexpr, Boolean *child) {
+ uint size = getSizeArrayBoolean(&bexpr->inputs);
+ Boolean *b = getArrayBoolean(&bexpr->inputs, 0);
+ if (b == child) {
+ //Statement is true...
+ replaceBooleanWithTrue(This, (Boolean *)bexpr);
+ } else {
+ //Make into negation of first term
+ removeElementArrayBoolean(&bexpr->inputs, 1);
+ bexpr->op = L_NOT;
+ }
+}
+
+void handleANDTrue(CSolver * This, BooleanLogic *bexpr, Boolean *child) {
+ uint size = getSizeArrayBoolean(&bexpr->inputs);
+
+ if (size == 1) {
+ replaceBooleanWithTrue(This, (Boolean *)bexpr);
+ return;
+ }
+
+ for (uint i = 0; i < size; i++) {
+ Boolean *b = getArrayBoolean(&bexpr->inputs, i);
+ if (b == child) {
+ removeElementArrayBoolean(&bexpr->inputs, i);
+ }
+ }
+
+ if (size == 2) {
+ replaceBooleanWithBoolean(This, (Boolean *)bexpr, getArrayBoolean(&bexpr->inputs, 0));
+ }
+}
+
+void handleORFalse(CSolver * This, BooleanLogic *bexpr, Boolean *child) {
+ uint size = getSizeArrayBoolean(&bexpr->inputs);
+
+ if (size == 1) {
+ replaceBooleanWithFalse(This, (Boolean *) bexpr);
+ }
+
+ for (uint i = 0; i < size; i++) {
+ Boolean *b = getArrayBoolean(&bexpr->inputs, i);
+ if (b == child) {
+ removeElementArrayBoolean(&bexpr->inputs, i);
+ }
+ }
+
+ if (size == 2) {
+ replaceBooleanWithBoolean(This, (Boolean *)bexpr, getArrayBoolean(&bexpr->inputs, 0));
+ }
+}
+
+void replaceBooleanWithFalse(CSolver * This, Boolean *bexpr) {
+ if (containsHashSetBoolean(This->constraints, bexpr)) {
+ This->unsat=true;
+ removeHashSetBoolean(This->constraints, bexpr);
+ }
+
+ uint size = getSizeVectorBoolean(&bexpr->parents);
+ for (uint i = 0; i < size; i++) {
+ Boolean *parent = getVectorBoolean(&bexpr->parents, i);
+ BooleanLogic *logicop = (BooleanLogic *) parent;
+ switch (logicop->op) {
+ case L_AND:
+ replaceBooleanWithFalse(This, parent);
+ break;
+ case L_OR:
+ handleORFalse(This, logicop, bexpr);
+ break;
+ case L_NOT:
+ replaceBooleanWithTrue(This, parent);
+ break;
+ case L_XOR:
+ handleXORFalse(This, logicop, bexpr);
+ break;
+ case L_IMPLIES:
+ handleIMPLIESFalse(This, logicop, bexpr);
+ break;
+ }
+ }
+}
+++ /dev/null
-#include "set.h"
-#include <stddef.h>
-
-Set *allocSet(VarType t, uint64_t *elements, uint num) {
- Set *This = (Set *)ourmalloc(sizeof(Set));
- This->type = t;
- This->isRange = false;
- This->low = 0;
- This->high = 0;
- This->members = allocVectorArrayInt(num, elements);
- return This;
-}
-
-Set *allocSetRange(VarType t, uint64_t lowrange, uint64_t highrange) {
- Set *This = (Set *)ourmalloc(sizeof(Set));
- This->type = t;
- This->isRange = true;
- This->low = lowrange;
- This->high = highrange;
- This->members = NULL;
- return This;
-}
-
-bool existsInSet(Set *This, uint64_t element) {
- if (This->isRange) {
- return element >= This->low && element <= This->high;
- } else {
- uint size = getSizeVectorInt(This->members);
- for (uint i = 0; i < size; i++) {
- if (element == getVectorInt(This->members, i))
- return true;
- }
- return false;
- }
-}
-
-uint64_t getSetElement(Set *This, uint index) {
- if (This->isRange)
- return This->low + index;
- else
- return getVectorInt(This->members, index);
-}
-
-uint getSetSize(Set *This) {
- if (This->isRange) {
- return This->high - This->low + 1;
- } else {
- return getSizeVectorInt(This->members);
- }
-}
-
-void deleteSet(Set *This) {
- if (!This->isRange)
- deleteVectorInt(This->members);
- ourfree(This);
-}
--- /dev/null
+#include "set.h"
+#include <stddef.h>
+
+Set *allocSet(VarType t, uint64_t *elements, uint num) {
+ Set *This = (Set *)ourmalloc(sizeof(Set));
+ This->type = t;
+ This->isRange = false;
+ This->low = 0;
+ This->high = 0;
+ This->members = allocVectorArrayInt(num, elements);
+ return This;
+}
+
+Set *allocSetRange(VarType t, uint64_t lowrange, uint64_t highrange) {
+ Set *This = (Set *)ourmalloc(sizeof(Set));
+ This->type = t;
+ This->isRange = true;
+ This->low = lowrange;
+ This->high = highrange;
+ This->members = NULL;
+ return This;
+}
+
+bool existsInSet(Set *This, uint64_t element) {
+ if (This->isRange) {
+ return element >= This->low && element <= This->high;
+ } else {
+ uint size = getSizeVectorInt(This->members);
+ for (uint i = 0; i < size; i++) {
+ if (element == getVectorInt(This->members, i))
+ return true;
+ }
+ return false;
+ }
+}
+
+uint64_t getSetElement(Set *This, uint index) {
+ if (This->isRange)
+ return This->low + index;
+ else
+ return getVectorInt(This->members, index);
+}
+
+uint getSetSize(Set *This) {
+ if (This->isRange) {
+ return This->high - This->low + 1;
+ } else {
+ return getSizeVectorInt(This->members);
+ }
+}
+
+void deleteSet(Set *This) {
+ if (!This->isRange)
+ deleteVectorInt(This->members);
+ ourfree(This);
+}
+++ /dev/null
-#include "table.h"
-#include "common.h"
-#include "structs.h"
-#include "tableentry.h"
-#include "set.h"
-#include "mutableset.h"
-
-Table *allocTable(Set **domains, uint numDomain, Set *range) {
- Table *This = (Table *) ourmalloc(sizeof(Table));
- initArrayInitSet(&This->domains, domains, numDomain);
- This->entries = allocHashSetTableEntry(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
- This->range = range;
- return This;
-}
-
-void addNewTableEntry(Table *This, uint64_t *inputs, uint inputSize, uint64_t result) {
- ASSERT(getSizeArraySet( &This->domains) == inputSize);
-#ifdef CONFIG_ASSERT
- if (This->range == NULL)
- ASSERT(result == true || result == false);
-#endif
- TableEntry *tb = allocTableEntry(inputs, inputSize, result);
- ASSERT(!containsHashSetTableEntry(This->entries, tb));
- bool status = addHashSetTableEntry(This->entries, tb);
- ASSERT(status);
-}
-
-TableEntry *getTableEntryFromTable(Table *table, uint64_t *inputs, uint inputSize) {
- TableEntry *temp = allocTableEntry(inputs, inputSize, -1);
- TableEntry *result = getHashSetTableEntry(table->entries, temp);
- deleteTableEntry(temp);
- return result;
-}
-
-void deleteTable(Table *This) {
- deleteInlineArraySet(&This->domains);
- HSIteratorTableEntry *iterator = iteratorTableEntry(This->entries);
- while (hasNextTableEntry(iterator)) {
- deleteTableEntry( nextTableEntry(iterator) );
- }
- deleteIterTableEntry(iterator);
- deleteHashSetTableEntry(This->entries);
- ourfree(This);
-}
-
--- /dev/null
+#include "table.h"
+#include "common.h"
+#include "structs.h"
+#include "tableentry.h"
+#include "set.h"
+#include "mutableset.h"
+
+Table *allocTable(Set **domains, uint numDomain, Set *range) {
+ Table *This = (Table *) ourmalloc(sizeof(Table));
+ initArrayInitSet(&This->domains, domains, numDomain);
+ This->entries = allocHashSetTableEntry(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
+ This->range = range;
+ return This;
+}
+
+void addNewTableEntry(Table *This, uint64_t *inputs, uint inputSize, uint64_t result) {
+ ASSERT(getSizeArraySet( &This->domains) == inputSize);
+#ifdef CONFIG_ASSERT
+ if (This->range == NULL)
+ ASSERT(result == true || result == false);
+#endif
+ TableEntry *tb = allocTableEntry(inputs, inputSize, result);
+ ASSERT(!containsHashSetTableEntry(This->entries, tb));
+ bool status = addHashSetTableEntry(This->entries, tb);
+ ASSERT(status);
+}
+
+TableEntry *getTableEntryFromTable(Table *table, uint64_t *inputs, uint inputSize) {
+ TableEntry *temp = allocTableEntry(inputs, inputSize, -1);
+ TableEntry *result = getHashSetTableEntry(table->entries, temp);
+ deleteTableEntry(temp);
+ return result;
+}
+
+void deleteTable(Table *This) {
+ deleteInlineArraySet(&This->domains);
+ HSIteratorTableEntry *iterator = iteratorTableEntry(This->entries);
+ while (hasNextTableEntry(iterator)) {
+ deleteTableEntry( nextTableEntry(iterator) );
+ }
+ deleteIterTableEntry(iterator);
+ deleteHashSetTableEntry(This->entries);
+ ourfree(This);
+}
+
+++ /dev/null
-#include "tableentry.h"
-#include <string.h>
-
-TableEntry *allocTableEntry(uint64_t *inputs, uint inputSize, uint64_t result) {
- TableEntry *te = (TableEntry *) ourmalloc(sizeof(TableEntry) + inputSize * sizeof(uint64_t));
- te->output = result;
- te->inputSize = inputSize;
- memcpy(te->inputs, inputs, inputSize * sizeof(uint64_t));
- return te;
-}
-
-void deleteTableEntry(TableEntry *tableEntry) {
- ourfree(tableEntry);
-}
--- /dev/null
+#include "tableentry.h"
+#include <string.h>
+
+TableEntry *allocTableEntry(uint64_t *inputs, uint inputSize, uint64_t result) {
+ TableEntry *te = (TableEntry *) ourmalloc(sizeof(TableEntry) + inputSize * sizeof(uint64_t));
+ te->output = result;
+ te->inputSize = inputSize;
+ memcpy(te->inputs, inputs, inputSize * sizeof(uint64_t));
+ return te;
+}
+
+void deleteTableEntry(TableEntry *tableEntry) {
+ ourfree(tableEntry);
+}
+++ /dev/null
-#include "cnfexpr.h"
-#include <stdio.h>
-/*
- V2 Copyright (c) 2014 Ben Chambers, Eugene Goldberg, Pete Manolios,
- Vasilis Papavasileiou, Sudarshan Srinivasan, and Daron Vroon.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software. If
- you download or use the software, send email to Pete Manolios
- (pete@ccs.neu.edu) with your name, contact information, and a short
- note describing what you want to use BAT for. For any reuse or
- distribution, you must make clear to others the license terms of this
- work.
-
- Contact Pete Manolios if you want any of these conditions waived.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- C port of CNF SAT Conversion Copyright Brian Demsky 2017.
- */
-
-#define LITCAPACITY 4
-#define MERGESIZE 5
-
-VectorImpl(LitVector, LitVector *, 4)
-
-static inline uint boundedSize(uint x) { return (x > MERGESIZE) ? MERGESIZE : x; }
-
-LitVector *allocLitVector() {
- LitVector *This = ourmalloc(sizeof(LitVector));
- initLitVector(This);
- return This;
-}
-
-void initLitVector(LitVector *This) {
- This->size = 0;
- This->capacity = LITCAPACITY;
- This->literals = ourmalloc(This->capacity * sizeof(Literal));
-}
-
-LitVector *cloneLitVector(LitVector *orig) {
- LitVector *This = ourmalloc(sizeof(LitVector));
- This->size = orig->size;
- This->capacity = orig->capacity;
- This->literals = ourmalloc(This->capacity * sizeof(Literal));
- memcpy(This->literals, orig->literals, sizeof(Literal) * This->size);
- return This;
-}
-
-void clearLitVector(LitVector *This) {
- This->size = 0;
-}
-
-void freeLitVector(LitVector *This) {
- ourfree(This->literals);
-}
-
-void deleteLitVector(LitVector *This) {
- freeLitVector(This);
- ourfree(This);
-}
-
-Literal getLiteralLitVector(LitVector *This, uint index) {
- return This->literals[index];
-}
-
-void setLiteralLitVector(LitVector *This, uint index, Literal l) {
- This->literals[index] = l;
-}
-
-void addLiteralLitVector(LitVector *This, Literal l) {
- Literal labs = abs(l);
- uint vec_size = This->size;
- uint searchsize = boundedSize(vec_size);
- uint i = 0;
- for (; i < searchsize; i++) {
- Literal curr = This->literals[i];
- Literal currabs = abs(curr);
- if (currabs > labs)
- break;
- if (currabs == labs) {
- if (curr == -l)
- This->size = 0; //either true or false now depending on whether this is a conj or disj
- return;
- }
- }
- if ((++This->size) >= This->capacity) {
- This->capacity <<= 1;
- This->literals = ourrealloc(This->literals, This->capacity * sizeof(Literal));
- }
-
- if (vec_size < MERGESIZE) {
- memmove(&This->literals[i + 1], &This->literals[i], (vec_size - i) * sizeof(Literal));
- This->literals[i] = l;
- } else {
- This->literals[vec_size] = l;
- }
-}
-
-CNFExpr *allocCNFExprBool(bool isTrue) {
- CNFExpr *This = ourmalloc(sizeof(CNFExpr));
- This->litSize = 0;
- This->isTrue = isTrue;
- initVectorLitVector(&This->clauses, 2);
- initLitVector(&This->singletons);
- return This;
-}
-
-CNFExpr *allocCNFExprLiteral(Literal l) {
- CNFExpr *This = ourmalloc(sizeof(CNFExpr));
- This->litSize = 1;
- This->isTrue = false;
- initVectorLitVector(&This->clauses, 2);
- initLitVector(&This->singletons);
- addLiteralLitVector(&This->singletons, l);
- return This;
-}
-
-void clearCNFExpr(CNFExpr *This, bool isTrue) {
- for (uint i = 0; i < getSizeVectorLitVector(&This->clauses); i++) {
- deleteLitVector(getVectorLitVector(&This->clauses, i));
- }
- clearVectorLitVector(&This->clauses);
- clearLitVector(&This->singletons);
- This->litSize = 0;
- This->isTrue = isTrue;
-}
-
-void deleteCNFExpr(CNFExpr *This) {
- for (uint i = 0; i < getSizeVectorLitVector(&This->clauses); i++) {
- deleteLitVector(getVectorLitVector(&This->clauses, i));
- }
- deleteVectorArrayLitVector(&This->clauses);
- freeLitVector(&This->singletons);
- ourfree(This);
-}
-
-void conjoinCNFLit(CNFExpr *This, Literal l) {
- if (This->litSize == 0 && !This->isTrue)//Handle False
- return;
-
- This->litSize -= getSizeLitVector(&This->singletons);
- addLiteralLitVector(&This->singletons, l);
- uint newsize = getSizeLitVector(&This->singletons);
- if (newsize == 0)
- clearCNFExpr(This, false);//We found a conflict
- else
- This->litSize += getSizeLitVector(&This->singletons);
-}
-
-void copyCNF(CNFExpr *This, CNFExpr *expr, bool destroy) {
- if (destroy) {
- ourfree(This->singletons.literals);
- ourfree(This->clauses.array);
- This->litSize = expr->litSize;
- This->singletons.literals = expr->singletons.literals;
- This->singletons.capacity = expr->singletons.capacity;
- This->clauses.size = expr->clauses.size;
- This->clauses.array = expr->clauses.array;
- This->clauses.capacity = expr->clauses.capacity;
- ourfree(expr);
- } else {
- for (uint i = 0; i < getSizeLitVector(&expr->singletons); i++) {
- Literal l = getLiteralLitVector(&expr->singletons,i);
- addLiteralLitVector(&This->singletons, l);
- }
- for (uint i = 0; i < getSizeVectorLitVector(&expr->clauses); i++) {
- LitVector *lv = getVectorLitVector(&expr->clauses,i);
- pushVectorLitVector(&This->clauses, cloneLitVector(lv));
- }
- This->litSize = expr->litSize;
- }
-}
-
-void conjoinCNFExpr(CNFExpr *This, CNFExpr *expr, bool destroy) {
- if (expr->litSize == 0) {
- if (!This->isTrue) {
- clearCNFExpr(This, false);
- }
- if (destroy) {
- deleteCNFExpr(expr);
- }
- return;
- }
- if (This->litSize == 0) {
- if (This->isTrue) {
- copyCNF(This, expr, destroy);
- } else if (destroy) {
- deleteCNFExpr(expr);
- }
- return;
- }
- uint litSize = This->litSize;
- litSize -= getSizeLitVector(&expr->singletons);
- for (uint i = 0; i < getSizeLitVector(&expr->singletons); i++) {
- Literal l = getLiteralLitVector(&expr->singletons,i);
- addLiteralLitVector(&This->singletons, l);
- if (getSizeLitVector(&This->singletons) == 0) {
- //Found conflict...
- clearCNFExpr(This, false);
- if (destroy) {
- deleteCNFExpr(expr);
- }
- return;
- }
- }
- litSize += getSizeLitVector(&expr->singletons);
- if (destroy) {
- for (uint i = 0; i < getSizeVectorLitVector(&expr->clauses); i++) {
- LitVector *lv = getVectorLitVector(&expr->clauses,i);
- litSize += getSizeLitVector(lv);
- pushVectorLitVector(&This->clauses, lv);
- }
- clearVectorLitVector(&expr->clauses);
- deleteCNFExpr(expr);
- } else {
- for (uint i = 0; i < getSizeVectorLitVector(&expr->clauses); i++) {
- LitVector *lv = getVectorLitVector(&expr->clauses,i);
- litSize += getSizeLitVector(lv);
- pushVectorLitVector(&This->clauses, cloneLitVector(lv));
- }
- }
- This->litSize = litSize;
-}
-
-void disjoinCNFLit(CNFExpr *This, Literal l) {
- if (This->litSize == 0) {
- if (!This->isTrue) {
- This->litSize++;
- addLiteralLitVector(&This->singletons, l);
- }
- return;
- }
-
- uint litSize = 0;
- uint newindex = 0;
- for (uint i = 0; i < getSizeVectorLitVector(&This->clauses); i++) {
- LitVector *lv = getVectorLitVector(&This->clauses, i);
- addLiteralLitVector(lv, l);
- uint newSize = getSizeLitVector(lv);
- if (newSize != 0) {
- setVectorLitVector(&This->clauses, newindex++, lv);
- } else {
- deleteLitVector(lv);
- }
- litSize += newSize;
- }
- setSizeVectorLitVector(&This->clauses, newindex);
-
- bool hasSameSingleton = false;
- for (uint i = 0; i < getSizeLitVector(&This->singletons); i++) {
- Literal lsing = getLiteralLitVector(&This->singletons, i);
- if (lsing == l) {
- hasSameSingleton = true;
- } else if (lsing != -l) {
- //Create new LitVector with both l and lsing
- LitVector *newlitvec = allocLitVector();
- addLiteralLitVector(newlitvec, l);
- addLiteralLitVector(newlitvec, lsing);
- litSize += 2;
- pushVectorLitVector(&This->clauses, newlitvec);
- }
- }
- clearLitVector(&This->singletons);
- if (hasSameSingleton) {
- addLiteralLitVector(&This->singletons, l);
- litSize++;
- } else if (litSize == 0) {
- This->isTrue = true;//we are true
- }
- This->litSize = litSize;
-}
-
-#define MERGETHRESHOLD 2
-LitVector *mergeLitVectors(LitVector *This, LitVector *expr) {
- uint maxsize = This->size + expr->size + MERGETHRESHOLD;
- LitVector *merged = ourmalloc(sizeof(LitVector));
- merged->literals = ourmalloc(sizeof(Literal) * maxsize);
- merged->capacity = maxsize;
- uint thisSize = boundedSize(This->size);
- uint exprSize = boundedSize(expr->size);
- uint iThis = 0, iExpr = 0, iMerge = 0;
- Literal lThis = This->literals[iThis];
- Literal lExpr = expr->literals[iExpr];
- Literal thisAbs = abs(lThis);
- Literal exprAbs = abs(lExpr);
-
- while (iThis < thisSize && iExpr < exprSize) {
- if (thisAbs < exprAbs) {
- merged->literals[iMerge++] = lThis;
- lThis = This->literals[++iThis];
- thisAbs = abs(lThis);
- } else if (thisAbs > exprAbs) {
- merged->literals[iMerge++] = lExpr;
- lExpr = expr->literals[++iExpr];
- exprAbs = abs(lExpr);
- } else if (lThis == lExpr) {
- merged->literals[iMerge++] = lExpr;
- lExpr = expr->literals[++iExpr];
- exprAbs = abs(lExpr);
- lThis = This->literals[++iThis];
- thisAbs = abs(lThis);
- } else if (lThis == -lExpr) {
- merged->size = 0;
- return merged;
- }
- }
- if (iThis < thisSize) {
- memcpy(&merged->literals[iMerge], &This->literals[iThis], (thisSize - iThis) * sizeof(Literal));
- iMerge += (thisSize - iThis);
- }
- if (iExpr < exprSize) {
- memcpy(&merged->literals[iMerge], &expr->literals[iExpr], (exprSize - iExpr) * sizeof(Literal));
- iMerge += (exprSize - iExpr);
- }
- merged->size = iMerge;
- return merged;
-}
-
-LitVector *mergeLitVectorLiteral(LitVector *This, Literal l) {
- LitVector *copy = cloneLitVector(This);
- addLiteralLitVector(copy, l);
- return copy;
-}
-
-void disjoinCNFExpr(CNFExpr *This, CNFExpr *expr, bool destroy) {
- /** Handle the special cases */
- if (expr->litSize == 0) {
- if (expr->isTrue) {
- clearCNFExpr(This, true);
- }
- if (destroy) {
- deleteCNFExpr(expr);
- }
- return;
- } else if (This->litSize == 0) {
- if (!This->isTrue) {
- copyCNF(This, expr, destroy);
- } else if (destroy) {
- deleteCNFExpr(expr);
- }
- return;
- } else if (expr->litSize == 1) {
- disjoinCNFLit(This, getLiteralLitVector(&expr->singletons,0));
- if (destroy) {
- deleteCNFExpr(expr);
- }
- return;
- } else if (destroy && This->litSize == 1) {
- Literal l = getLiteralLitVector(&This->singletons,0);
- copyCNF(This, expr, true);
- disjoinCNFLit(This, l);
- return;
- }
-
- /** Handle the full cross product */
- uint mergeIndex = 0;
- uint newCapacity = getClauseSizeCNF(This) * getClauseSizeCNF(expr);
- LitVector **mergeArray = ourmalloc(newCapacity * sizeof(LitVector *));
- uint singleIndex = 0;
- /** First do the singleton, clause pairs */
- for (uint i = 0; i < getSizeLitVector(&This->singletons); i++) {
- Literal lThis = getLiteralLitVector(&This->singletons, i);
- for (uint j = 0; j < getSizeVectorLitVector(&expr->clauses); j++) {
- LitVector *lExpr = getVectorLitVector(&expr->clauses, j);
- LitVector *copy = cloneLitVector(lExpr);
- addLiteralLitVector(copy, lThis);
- if (getSizeLitVector(copy) == 0) {
- deleteLitVector(copy);
- } else {
- mergeArray[mergeIndex++] = copy;
- }
- }
- }
-
- /** Next do the clause, singleton pairs */
- for (uint i = 0; i < getSizeLitVector(&expr->singletons); i++) {
- Literal lExpr = getLiteralLitVector(&expr->singletons, i);
- for (uint j = 0; j < getSizeVectorLitVector(&This->clauses); j++) {
- LitVector *lThis = getVectorLitVector(&This->clauses, j);
- LitVector *copy = cloneLitVector(lThis);
- addLiteralLitVector(copy, lExpr);
- if (getSizeLitVector(copy) == 0) {
- deleteLitVector(copy);
- } else {
- mergeArray[mergeIndex++] = copy;
- }
- }
- }
-
- /** Next do the clause, clause pairs */
- for (uint i = 0; i < getSizeVectorLitVector(&This->clauses); i++) {
- LitVector *lThis = getVectorLitVector(&This->clauses, i);
- for (uint j = 0; j < getSizeVectorLitVector(&expr->clauses); j++) {
- LitVector *lExpr = getVectorLitVector(&expr->clauses, j);
- LitVector *merge = mergeLitVectors(lThis, lExpr);
- if (getSizeLitVector(merge) == 0) {
- deleteLitVector(merge);
- } else {
- mergeArray[mergeIndex++] = merge;
- }
- }
- deleteLitVector(lThis);//Done with this litVector
- }
-
- /** Finally do the singleton, singleton pairs */
- for (uint i = 0; i < getSizeLitVector(&This->singletons); i++) {
- Literal lThis = getLiteralLitVector(&This->singletons, i);
- for (uint j = 0; j < getSizeLitVector(&expr->singletons); j++) {
- Literal lExpr = getLiteralLitVector(&expr->singletons, j);
- if (lThis == lExpr) {
- //We have a singleton still in the final result
- setLiteralLitVector(&This->singletons, singleIndex++, lThis);
- } else if (lThis != -lExpr) {
- LitVector *mergeLV = allocLitVector();
- addLiteralLitVector(mergeLV, lThis);
- addLiteralLitVector(mergeLV, lExpr);
- mergeArray[mergeIndex++] = mergeLV;
- }
- }
- }
-
- ourfree(This->clauses.array);
- setSizeLitVector(&This->singletons, singleIndex);
- This->clauses.capacity = newCapacity;
- This->clauses.array = mergeArray;
- This->clauses.size = mergeIndex;
- if (destroy)
- deleteCNFExpr(expr);
-}
-
-void printCNFExpr(CNFExpr *This) {
- for (uint i = 0; i < getSizeLitVector(&This->singletons); i++) {
- if (i != 0)
- printf(" ^ ");
- Literal l = getLiteralLitVector(&This->singletons,i);
- printf ("%d",l);
- }
- for (uint i = 0; i < getSizeVectorLitVector(&This->clauses); i++) {
- LitVector *lv = getVectorLitVector(&This->clauses,i);
- printf(" ^ (");
- for (uint j = 0; j < getSizeLitVector(lv); j++) {
- if (j != 0)
- printf(" v ");
- printf("%d", getLiteralLitVector(lv, j));
- }
- printf(")");
- }
-}
--- /dev/null
+#include "cnfexpr.h"
+#include <stdio.h>
+/*
+ V2 Copyright (c) 2014 Ben Chambers, Eugene Goldberg, Pete Manolios,
+ Vasilis Papavasileiou, Sudarshan Srinivasan, and Daron Vroon.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software. If
+ you download or use the software, send email to Pete Manolios
+ (pete@ccs.neu.edu) with your name, contact information, and a short
+ note describing what you want to use BAT for. For any reuse or
+ distribution, you must make clear to others the license terms of this
+ work.
+
+ Contact Pete Manolios if you want any of these conditions waived.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ C port of CNF SAT Conversion Copyright Brian Demsky 2017.
+ */
+
+#define LITCAPACITY 4
+#define MERGESIZE 5
+
+VectorImpl(LitVector, LitVector *, 4)
+
+static inline uint boundedSize(uint x) { return (x > MERGESIZE) ? MERGESIZE : x; }
+
+LitVector *allocLitVector() {
+ LitVector *This = (LitVector *)ourmalloc(sizeof(LitVector));
+ initLitVector(This);
+ return This;
+}
+
+void initLitVector(LitVector *This) {
+ This->size = 0;
+ This->capacity = LITCAPACITY;
+ This->literals = (Literal *)ourmalloc(This->capacity * sizeof(Literal));
+}
+
+LitVector *cloneLitVector(LitVector *orig) {
+ LitVector *This = (LitVector *)ourmalloc(sizeof(LitVector));
+ This->size = orig->size;
+ This->capacity = orig->capacity;
+ This->literals = (Literal *)ourmalloc(This->capacity * sizeof(Literal));
+ memcpy(This->literals, orig->literals, sizeof(Literal) * This->size);
+ return This;
+}
+
+void clearLitVector(LitVector *This) {
+ This->size = 0;
+}
+
+void freeLitVector(LitVector *This) {
+ ourfree(This->literals);
+}
+
+void deleteLitVector(LitVector *This) {
+ freeLitVector(This);
+ ourfree(This);
+}
+
+Literal getLiteralLitVector(LitVector *This, uint index) {
+ return This->literals[index];
+}
+
+void setLiteralLitVector(LitVector *This, uint index, Literal l) {
+ This->literals[index] = l;
+}
+
+void addLiteralLitVector(LitVector *This, Literal l) {
+ Literal labs = abs(l);
+ uint vec_size = This->size;
+ uint searchsize = boundedSize(vec_size);
+ uint i = 0;
+ for (; i < searchsize; i++) {
+ Literal curr = This->literals[i];
+ Literal currabs = abs(curr);
+ if (currabs > labs)
+ break;
+ if (currabs == labs) {
+ if (curr == -l)
+ This->size = 0; //either true or false now depending on whether this is a conj or disj
+ return;
+ }
+ }
+ if ((++This->size) >= This->capacity) {
+ This->capacity <<= 1;
+ This->literals = (Literal *) ourrealloc(This->literals, This->capacity * sizeof(Literal));
+ }
+
+ if (vec_size < MERGESIZE) {
+ memmove(&This->literals[i + 1], &This->literals[i], (vec_size - i) * sizeof(Literal));
+ This->literals[i] = l;
+ } else {
+ This->literals[vec_size] = l;
+ }
+}
+
+CNFExpr *allocCNFExprBool(bool isTrue) {
+ CNFExpr *This = (CNFExpr *)ourmalloc(sizeof(CNFExpr));
+ This->litSize = 0;
+ This->isTrue = isTrue;
+ initVectorLitVector(&This->clauses, 2);
+ initLitVector(&This->singletons);
+ return This;
+}
+
+CNFExpr *allocCNFExprLiteral(Literal l) {
+ CNFExpr *This = (CNFExpr *)ourmalloc(sizeof(CNFExpr));
+ This->litSize = 1;
+ This->isTrue = false;
+ initVectorLitVector(&This->clauses, 2);
+ initLitVector(&This->singletons);
+ addLiteralLitVector(&This->singletons, l);
+ return This;
+}
+
+void clearCNFExpr(CNFExpr *This, bool isTrue) {
+ for (uint i = 0; i < getSizeVectorLitVector(&This->clauses); i++) {
+ deleteLitVector(getVectorLitVector(&This->clauses, i));
+ }
+ clearVectorLitVector(&This->clauses);
+ clearLitVector(&This->singletons);
+ This->litSize = 0;
+ This->isTrue = isTrue;
+}
+
+void deleteCNFExpr(CNFExpr *This) {
+ for (uint i = 0; i < getSizeVectorLitVector(&This->clauses); i++) {
+ deleteLitVector(getVectorLitVector(&This->clauses, i));
+ }
+ deleteVectorArrayLitVector(&This->clauses);
+ freeLitVector(&This->singletons);
+ ourfree(This);
+}
+
+void conjoinCNFLit(CNFExpr *This, Literal l) {
+ if (This->litSize == 0 && !This->isTrue)//Handle False
+ return;
+
+ This->litSize -= getSizeLitVector(&This->singletons);
+ addLiteralLitVector(&This->singletons, l);
+ uint newsize = getSizeLitVector(&This->singletons);
+ if (newsize == 0)
+ clearCNFExpr(This, false);//We found a conflict
+ else
+ This->litSize += getSizeLitVector(&This->singletons);
+}
+
+void copyCNF(CNFExpr *This, CNFExpr *expr, bool destroy) {
+ if (destroy) {
+ ourfree(This->singletons.literals);
+ ourfree(This->clauses.array);
+ This->litSize = expr->litSize;
+ This->singletons.literals = expr->singletons.literals;
+ This->singletons.capacity = expr->singletons.capacity;
+ This->clauses.size = expr->clauses.size;
+ This->clauses.array = expr->clauses.array;
+ This->clauses.capacity = expr->clauses.capacity;
+ ourfree(expr);
+ } else {
+ for (uint i = 0; i < getSizeLitVector(&expr->singletons); i++) {
+ Literal l = getLiteralLitVector(&expr->singletons,i);
+ addLiteralLitVector(&This->singletons, l);
+ }
+ for (uint i = 0; i < getSizeVectorLitVector(&expr->clauses); i++) {
+ LitVector *lv = getVectorLitVector(&expr->clauses,i);
+ pushVectorLitVector(&This->clauses, cloneLitVector(lv));
+ }
+ This->litSize = expr->litSize;
+ }
+}
+
+void conjoinCNFExpr(CNFExpr *This, CNFExpr *expr, bool destroy) {
+ if (expr->litSize == 0) {
+ if (!This->isTrue) {
+ clearCNFExpr(This, false);
+ }
+ if (destroy) {
+ deleteCNFExpr(expr);
+ }
+ return;
+ }
+ if (This->litSize == 0) {
+ if (This->isTrue) {
+ copyCNF(This, expr, destroy);
+ } else if (destroy) {
+ deleteCNFExpr(expr);
+ }
+ return;
+ }
+ uint litSize = This->litSize;
+ litSize -= getSizeLitVector(&expr->singletons);
+ for (uint i = 0; i < getSizeLitVector(&expr->singletons); i++) {
+ Literal l = getLiteralLitVector(&expr->singletons,i);
+ addLiteralLitVector(&This->singletons, l);
+ if (getSizeLitVector(&This->singletons) == 0) {
+ //Found conflict...
+ clearCNFExpr(This, false);
+ if (destroy) {
+ deleteCNFExpr(expr);
+ }
+ return;
+ }
+ }
+ litSize += getSizeLitVector(&expr->singletons);
+ if (destroy) {
+ for (uint i = 0; i < getSizeVectorLitVector(&expr->clauses); i++) {
+ LitVector *lv = getVectorLitVector(&expr->clauses,i);
+ litSize += getSizeLitVector(lv);
+ pushVectorLitVector(&This->clauses, lv);
+ }
+ clearVectorLitVector(&expr->clauses);
+ deleteCNFExpr(expr);
+ } else {
+ for (uint i = 0; i < getSizeVectorLitVector(&expr->clauses); i++) {
+ LitVector *lv = getVectorLitVector(&expr->clauses,i);
+ litSize += getSizeLitVector(lv);
+ pushVectorLitVector(&This->clauses, cloneLitVector(lv));
+ }
+ }
+ This->litSize = litSize;
+}
+
+void disjoinCNFLit(CNFExpr *This, Literal l) {
+ if (This->litSize == 0) {
+ if (!This->isTrue) {
+ This->litSize++;
+ addLiteralLitVector(&This->singletons, l);
+ }
+ return;
+ }
+
+ uint litSize = 0;
+ uint newindex = 0;
+ for (uint i = 0; i < getSizeVectorLitVector(&This->clauses); i++) {
+ LitVector *lv = getVectorLitVector(&This->clauses, i);
+ addLiteralLitVector(lv, l);
+ uint newSize = getSizeLitVector(lv);
+ if (newSize != 0) {
+ setVectorLitVector(&This->clauses, newindex++, lv);
+ } else {
+ deleteLitVector(lv);
+ }
+ litSize += newSize;
+ }
+ setSizeVectorLitVector(&This->clauses, newindex);
+
+ bool hasSameSingleton = false;
+ for (uint i = 0; i < getSizeLitVector(&This->singletons); i++) {
+ Literal lsing = getLiteralLitVector(&This->singletons, i);
+ if (lsing == l) {
+ hasSameSingleton = true;
+ } else if (lsing != -l) {
+ //Create new LitVector with both l and lsing
+ LitVector *newlitvec = allocLitVector();
+ addLiteralLitVector(newlitvec, l);
+ addLiteralLitVector(newlitvec, lsing);
+ litSize += 2;
+ pushVectorLitVector(&This->clauses, newlitvec);
+ }
+ }
+ clearLitVector(&This->singletons);
+ if (hasSameSingleton) {
+ addLiteralLitVector(&This->singletons, l);
+ litSize++;
+ } else if (litSize == 0) {
+ This->isTrue = true;//we are true
+ }
+ This->litSize = litSize;
+}
+
+#define MERGETHRESHOLD 2
+LitVector *mergeLitVectors(LitVector *This, LitVector *expr) {
+ uint maxsize = This->size + expr->size + MERGETHRESHOLD;
+ LitVector *merged = (LitVector *)ourmalloc(sizeof(LitVector));
+ merged->literals = (Literal *)ourmalloc(sizeof(Literal) * maxsize);
+ merged->capacity = maxsize;
+ uint thisSize = boundedSize(This->size);
+ uint exprSize = boundedSize(expr->size);
+ uint iThis = 0, iExpr = 0, iMerge = 0;
+ Literal lThis = This->literals[iThis];
+ Literal lExpr = expr->literals[iExpr];
+ Literal thisAbs = abs(lThis);
+ Literal exprAbs = abs(lExpr);
+
+ while (iThis < thisSize && iExpr < exprSize) {
+ if (thisAbs < exprAbs) {
+ merged->literals[iMerge++] = lThis;
+ lThis = This->literals[++iThis];
+ thisAbs = abs(lThis);
+ } else if (thisAbs > exprAbs) {
+ merged->literals[iMerge++] = lExpr;
+ lExpr = expr->literals[++iExpr];
+ exprAbs = abs(lExpr);
+ } else if (lThis == lExpr) {
+ merged->literals[iMerge++] = lExpr;
+ lExpr = expr->literals[++iExpr];
+ exprAbs = abs(lExpr);
+ lThis = This->literals[++iThis];
+ thisAbs = abs(lThis);
+ } else if (lThis == -lExpr) {
+ merged->size = 0;
+ return merged;
+ }
+ }
+ if (iThis < thisSize) {
+ memcpy(&merged->literals[iMerge], &This->literals[iThis], (thisSize - iThis) * sizeof(Literal));
+ iMerge += (thisSize - iThis);
+ }
+ if (iExpr < exprSize) {
+ memcpy(&merged->literals[iMerge], &expr->literals[iExpr], (exprSize - iExpr) * sizeof(Literal));
+ iMerge += (exprSize - iExpr);
+ }
+ merged->size = iMerge;
+ return merged;
+}
+
+LitVector *mergeLitVectorLiteral(LitVector *This, Literal l) {
+ LitVector *copy = cloneLitVector(This);
+ addLiteralLitVector(copy, l);
+ return copy;
+}
+
+void disjoinCNFExpr(CNFExpr *This, CNFExpr *expr, bool destroy) {
+ /** Handle the special cases */
+ if (expr->litSize == 0) {
+ if (expr->isTrue) {
+ clearCNFExpr(This, true);
+ }
+ if (destroy) {
+ deleteCNFExpr(expr);
+ }
+ return;
+ } else if (This->litSize == 0) {
+ if (!This->isTrue) {
+ copyCNF(This, expr, destroy);
+ } else if (destroy) {
+ deleteCNFExpr(expr);
+ }
+ return;
+ } else if (expr->litSize == 1) {
+ disjoinCNFLit(This, getLiteralLitVector(&expr->singletons,0));
+ if (destroy) {
+ deleteCNFExpr(expr);
+ }
+ return;
+ } else if (destroy && This->litSize == 1) {
+ Literal l = getLiteralLitVector(&This->singletons,0);
+ copyCNF(This, expr, true);
+ disjoinCNFLit(This, l);
+ return;
+ }
+
+ /** Handle the full cross product */
+ uint mergeIndex = 0;
+ uint newCapacity = getClauseSizeCNF(This) * getClauseSizeCNF(expr);
+ LitVector **mergeArray = (LitVector **)ourmalloc(newCapacity * sizeof(LitVector *));
+ uint singleIndex = 0;
+ /** First do the singleton, clause pairs */
+ for (uint i = 0; i < getSizeLitVector(&This->singletons); i++) {
+ Literal lThis = getLiteralLitVector(&This->singletons, i);
+ for (uint j = 0; j < getSizeVectorLitVector(&expr->clauses); j++) {
+ LitVector *lExpr = getVectorLitVector(&expr->clauses, j);
+ LitVector *copy = cloneLitVector(lExpr);
+ addLiteralLitVector(copy, lThis);
+ if (getSizeLitVector(copy) == 0) {
+ deleteLitVector(copy);
+ } else {
+ mergeArray[mergeIndex++] = copy;
+ }
+ }
+ }
+
+ /** Next do the clause, singleton pairs */
+ for (uint i = 0; i < getSizeLitVector(&expr->singletons); i++) {
+ Literal lExpr = getLiteralLitVector(&expr->singletons, i);
+ for (uint j = 0; j < getSizeVectorLitVector(&This->clauses); j++) {
+ LitVector *lThis = getVectorLitVector(&This->clauses, j);
+ LitVector *copy = cloneLitVector(lThis);
+ addLiteralLitVector(copy, lExpr);
+ if (getSizeLitVector(copy) == 0) {
+ deleteLitVector(copy);
+ } else {
+ mergeArray[mergeIndex++] = copy;
+ }
+ }
+ }
+
+ /** Next do the clause, clause pairs */
+ for (uint i = 0; i < getSizeVectorLitVector(&This->clauses); i++) {
+ LitVector *lThis = getVectorLitVector(&This->clauses, i);
+ for (uint j = 0; j < getSizeVectorLitVector(&expr->clauses); j++) {
+ LitVector *lExpr = getVectorLitVector(&expr->clauses, j);
+ LitVector *merge = mergeLitVectors(lThis, lExpr);
+ if (getSizeLitVector(merge) == 0) {
+ deleteLitVector(merge);
+ } else {
+ mergeArray[mergeIndex++] = merge;
+ }
+ }
+ deleteLitVector(lThis);//Done with this litVector
+ }
+
+ /** Finally do the singleton, singleton pairs */
+ for (uint i = 0; i < getSizeLitVector(&This->singletons); i++) {
+ Literal lThis = getLiteralLitVector(&This->singletons, i);
+ for (uint j = 0; j < getSizeLitVector(&expr->singletons); j++) {
+ Literal lExpr = getLiteralLitVector(&expr->singletons, j);
+ if (lThis == lExpr) {
+ //We have a singleton still in the final result
+ setLiteralLitVector(&This->singletons, singleIndex++, lThis);
+ } else if (lThis != -lExpr) {
+ LitVector *mergeLV = allocLitVector();
+ addLiteralLitVector(mergeLV, lThis);
+ addLiteralLitVector(mergeLV, lExpr);
+ mergeArray[mergeIndex++] = mergeLV;
+ }
+ }
+ }
+
+ ourfree(This->clauses.array);
+ setSizeLitVector(&This->singletons, singleIndex);
+ This->clauses.capacity = newCapacity;
+ This->clauses.array = mergeArray;
+ This->clauses.size = mergeIndex;
+ if (destroy)
+ deleteCNFExpr(expr);
+}
+
+void printCNFExpr(CNFExpr *This) {
+ for (uint i = 0; i < getSizeLitVector(&This->singletons); i++) {
+ if (i != 0)
+ printf(" ^ ");
+ Literal l = getLiteralLitVector(&This->singletons,i);
+ printf ("%d",l);
+ }
+ for (uint i = 0; i < getSizeVectorLitVector(&This->clauses); i++) {
+ LitVector *lv = getVectorLitVector(&This->clauses,i);
+ printf(" ^ (");
+ for (uint j = 0; j < getSizeLitVector(lv); j++) {
+ if (j != 0)
+ printf(" v ");
+ printf("%d", getLiteralLitVector(lv, j));
+ }
+ printf(")");
+ }
+}
+++ /dev/null
-#include "constraint.h"
-#include <string.h>
-#include <stdlib.h>
-#include "inc_solver.h"
-#include "cnfexpr.h"
-#include "common.h"
-/*
- V2 Copyright (c) 2014 Ben Chambers, Eugene Goldberg, Pete Manolios,
- Vasilis Papavasileiou, Sudarshan Srinivasan, and Daron Vroon.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software. If
- you download or use the software, send email to Pete Manolios
- (pete@ccs.neu.edu) with your name, contact information, and a short
- note describing what you want to use BAT for. For any reuse or
- distribution, you must make clear to others the license terms of this
- work.
-
- Contact Pete Manolios if you want any of these conditions waived.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- C port of CNF SAT Conversion Copyright Brian Demsky 2017.
- */
-
-
-VectorImpl(Edge, Edge, 16)
-Edge E_True = {(Node *)(uintptr_t) EDGE_IS_VAR_CONSTANT};
-Edge E_False = {(Node *)(uintptr_t) (EDGE_IS_VAR_CONSTANT | NEGATE_EDGE)};
-Edge E_BOGUS = {(Node *)0x12345673};
-Edge E_NULL = {(Node *)NULL};
-
-
-CNF *createCNF() {
- CNF *cnf = ourmalloc(sizeof(CNF));
- cnf->varcount = 1;
- cnf->capacity = DEFAULT_CNF_ARRAY_SIZE;
- cnf->mask = cnf->capacity - 1;
- cnf->node_array = ourcalloc(1, sizeof(Node *) * cnf->capacity);
- cnf->size = 0;
- cnf->maxsize = (uint)(((double)cnf->capacity) * LOAD_FACTOR);
- cnf->enableMatching = true;
- initDefVectorEdge(&cnf->constraints);
- initDefVectorEdge(&cnf->args);
- cnf->solver = allocIncrementalSolver();
- return cnf;
-}
-
-void deleteCNF(CNF *cnf) {
- for (uint i = 0; i < cnf->capacity; i++) {
- Node *n = cnf->node_array[i];
- if (n != NULL)
- ourfree(n);
- }
- deleteVectorArrayEdge(&cnf->constraints);
- deleteVectorArrayEdge(&cnf->args);
- deleteIncrementalSolver(cnf->solver);
- ourfree(cnf->node_array);
- ourfree(cnf);
-}
-
-void resizeCNF(CNF *cnf, uint newCapacity) {
- Node **old_array = cnf->node_array;
- Node **new_array = ourcalloc(1, sizeof(Node *) * newCapacity);
- uint oldCapacity = cnf->capacity;
- uint newMask = newCapacity - 1;
- for (uint i = 0; i < oldCapacity; i++) {
- Node *n = old_array[i];
- uint hashCode = n->hashCode;
- uint newindex = hashCode & newMask;
- for (;; newindex = (newindex + 1) & newMask) {
- if (new_array[newindex] == NULL) {
- new_array[newindex] = n;
- break;
- }
- }
- }
- ourfree(old_array);
- cnf->node_array = new_array;
- cnf->capacity = newCapacity;
- cnf->maxsize = (uint)(((double)cnf->capacity) * LOAD_FACTOR);
- cnf->mask = newMask;
-}
-
-Node *allocNode(NodeType type, uint numEdges, Edge *edges, uint hashcode) {
- Node *n = (Node *)ourmalloc(sizeof(Node) + sizeof(Edge) * numEdges);
- memcpy(n->edges, edges, sizeof(Edge) * numEdges);
- n->flags.type = type;
- n->flags.wasExpanded = 0;
- n->flags.cnfVisitedDown = 0;
- n->flags.cnfVisitedUp = 0;
- n->flags.varForced = 0;
- n->numEdges = numEdges;
- n->hashCode = hashcode;
- n->intAnnot[0] = 0;n->intAnnot[1] = 0;
- n->ptrAnnot[0] = NULL;n->ptrAnnot[1] = NULL;
- return n;
-}
-
-Edge createNode(CNF *cnf, NodeType type, uint numEdges, Edge *edges) {
- if (cnf->size > cnf->maxsize) {
- resizeCNF(cnf, cnf->capacity << 1);
- }
- uint hashvalue = hashNode(type, numEdges, edges);
- uint mask = cnf->mask;
- uint index = hashvalue & mask;
- Node **n_ptr;
- for (;; index = (index + 1) & mask) {
- n_ptr = &cnf->node_array[index];
- if (*n_ptr != NULL) {
- if ((*n_ptr)->hashCode == hashvalue) {
- if (compareNodes(*n_ptr, type, numEdges, edges)) {
- Edge e = {*n_ptr};
- return e;
- }
- }
- } else {
- break;
- }
- }
- *n_ptr = allocNode(type, numEdges, edges, hashvalue);
- Edge e = {*n_ptr};
- return e;
-}
-
-uint hashNode(NodeType type, uint numEdges, Edge *edges) {
- uint hashvalue = type ^ numEdges;
- for (uint i = 0; i < numEdges; i++) {
- hashvalue ^= (uint) ((uintptr_t) edges[i].node_ptr);
- hashvalue = (hashvalue << 3) | (hashvalue >> 29); //rotate left by 3 bits
- }
- return (uint) hashvalue;
-}
-
-bool compareNodes(Node *node, NodeType type, uint numEdges, Edge *edges) {
- if (node->flags.type != type || node->numEdges != numEdges)
- return false;
- Edge *nodeedges = node->edges;
- for (uint i = 0; i < numEdges; i++) {
- if (!equalsEdge(nodeedges[i], edges[i]))
- return false;
- }
- return true;
-}
-
-Edge constraintOR(CNF *cnf, uint numEdges, Edge *edges) {
- Edge edgearray[numEdges];
-
- for (uint i = 0; i < numEdges; i++) {
- edgearray[i] = constraintNegate(edges[i]);
- }
- Edge eand = constraintAND(cnf, numEdges, edgearray);
- return constraintNegate(eand);
-}
-
-Edge constraintOR2(CNF *cnf, Edge left, Edge right) {
- Edge lneg = constraintNegate(left);
- Edge rneg = constraintNegate(right);
- Edge eand = constraintAND2(cnf, lneg, rneg);
- return constraintNegate(eand);
-}
-
-int comparefunction(const Edge *e1, const Edge *e2) {
- return ((uintptr_t)e1->node_ptr) - ((uintptr_t)e2->node_ptr);
-}
-
-Edge constraintAND(CNF *cnf, uint numEdges, Edge *edges) {
- ASSERT(numEdges != 0);
- qsort(edges, numEdges, sizeof(Edge), (int (*)(const void *, const void *))comparefunction);
- int initindex = 0;
- while (initindex < numEdges && equalsEdge(edges[initindex], E_True))
- initindex++;
-
- uint remainSize = numEdges - initindex;
-
- if (remainSize == 0)
- return E_True;
- else if (remainSize == 1)
- return edges[initindex];
- else if (equalsEdge(edges[initindex], E_False))
- return E_False;
-
- /** De-duplicate array */
- uint lowindex = 0;
- edges[lowindex] = edges[initindex++];
-
- for (; initindex < numEdges; initindex++) {
- Edge e1 = edges[lowindex];
- Edge e2 = edges[initindex];
- if (sameNodeVarEdge(e1, e2)) {
- if (!sameSignEdge(e1, e2)) {
- return E_False;
- }
- } else
- edges[++lowindex] = edges[initindex];
- }
- lowindex++; //Make lowindex look like size
-
- if (lowindex == 1)
- return edges[0];
-
- if (cnf->enableMatching && lowindex == 2 &&
- isNegNodeEdge(edges[0]) && isNegNodeEdge(edges[1]) &&
- getNodeType(edges[0]) == NodeType_AND &&
- getNodeType(edges[1]) == NodeType_AND &&
- getNodeSize(edges[0]) == 2 &&
- getNodeSize(edges[1]) == 2) {
- Edge *e0edges = getEdgeArray(edges[0]);
- Edge *e1edges = getEdgeArray(edges[1]);
- if (sameNodeOppSign(e0edges[0], e1edges[0])) {
- return constraintNegate(constraintITE(cnf, e0edges[0], e0edges[1], e1edges[1]));
- } else if (sameNodeOppSign(e0edges[0], e1edges[1])) {
- return constraintNegate(constraintITE(cnf, e0edges[0], e0edges[1], e1edges[0]));
- } else if (sameNodeOppSign(e0edges[1], e1edges[0])) {
- return constraintNegate(constraintITE(cnf, e0edges[1], e0edges[0], e1edges[1]));
- } else if (sameNodeOppSign(e0edges[1], e1edges[1])) {
- return constraintNegate(constraintITE(cnf, e0edges[1], e0edges[0], e1edges[0]));
- }
- }
-
- return createNode(cnf, NodeType_AND, lowindex, edges);
-}
-
-Edge constraintAND2(CNF *cnf, Edge left, Edge right) {
- Edge edges[2] = {left, right};
- return constraintAND(cnf, 2, edges);
-}
-
-Edge constraintIMPLIES(CNF *cnf, Edge left, Edge right) {
- Edge array[2];
- array[0] = left;
- array[1] = constraintNegate(right);
- Edge eand = constraintAND(cnf, 2, array);
- return constraintNegate(eand);
-}
-
-Edge constraintIFF(CNF *cnf, Edge left, Edge right) {
- bool negate = !sameSignEdge(left, right);
- Edge lpos = getNonNeg(left);
- Edge rpos = getNonNeg(right);
-
- Edge e;
- if (equalsEdge(lpos, rpos)) {
- e = E_True;
- } else if (ltEdge(lpos, rpos)) {
- Edge edges[] = {lpos, rpos};
- e = (edgeIsConst(lpos)) ? rpos : createNode(cnf, NodeType_IFF, 2, edges);
- } else {
- Edge edges[] = {rpos, lpos};
- e = (edgeIsConst(rpos)) ? lpos : createNode(cnf, NodeType_IFF, 2, edges);
- }
- if (negate)
- e = constraintNegate(e);
- return e;
-}
-
-Edge constraintITE(CNF *cnf, Edge cond, Edge thenedge, Edge elseedge) {
- if (isNegEdge(cond)) {
- cond = constraintNegate(cond);
- Edge tmp = thenedge;
- thenedge = elseedge;
- elseedge = tmp;
- }
-
- bool negate = isNegEdge(thenedge);
- if (negate) {
- thenedge = constraintNegate(thenedge);
- elseedge = constraintNegate(elseedge);
- }
-
- Edge result;
- if (equalsEdge(cond, E_True)) {
- result = thenedge;
- } else if (equalsEdge(thenedge, E_True) || equalsEdge(cond, thenedge)) {
- result = constraintOR(cnf, 2, (Edge[]) {cond, elseedge});
- } else if (equalsEdge(elseedge, E_True) || sameNodeOppSign(cond, elseedge)) {
- result = constraintIMPLIES(cnf, cond, thenedge);
- } else if (equalsEdge(thenedge, E_False) || equalsEdge(cond, elseedge)) {
- result = constraintAND(cnf, 2, (Edge[]) {cond, thenedge});
- } else if (equalsEdge(thenedge, elseedge)) {
- result = thenedge;
- } else if (sameNodeOppSign(thenedge, elseedge)) {
- if (ltEdge(cond, thenedge)) {
- result = createNode(cnf, NodeType_IFF, 2, (Edge[]) {cond, thenedge});
- } else {
- result = createNode(cnf, NodeType_IFF, 2, (Edge[]) {thenedge, cond});
- }
- } else {
- Edge edges[] = {cond, thenedge, elseedge};
- result = createNode(cnf, NodeType_ITE, 3, edges);
- }
- if (negate)
- result = constraintNegate(result);
- return result;
-}
-
-void addConstraintCNF(CNF *cnf, Edge constraint) {
- pushVectorEdge(&cnf->constraints, constraint);
- model_print("****ADDING NEW Constraint*****\n");
- printCNF(constraint);
- model_print("\n******************************\n");
-}
-
-Edge constraintNewVar(CNF *cnf) {
- uint varnum = cnf->varcount++;
- Edge e = {(Node *) ((((uintptr_t)varnum) << VAR_SHIFT) | EDGE_IS_VAR_CONSTANT) };
- return e;
-}
-
-int solveCNF(CNF *cnf) {
- countPass(cnf);
- convertPass(cnf, false);
- finishedClauses(cnf->solver);
- return solve(cnf->solver);
-}
-
-bool getValueCNF(CNF *cnf, Edge var) {
- Literal l = getEdgeVar(var);
- bool isneg = (l < 0);
- l = abs(l);
- return isneg ^ getValueSolver(cnf->solver, l);
-}
-
-void countPass(CNF *cnf) {
- uint numConstraints = getSizeVectorEdge(&cnf->constraints);
- VectorEdge *ve = allocDefVectorEdge();
- for (uint i = 0; i < numConstraints; i++) {
- countConstraint(cnf, ve, getVectorEdge(&cnf->constraints, i));
- }
- deleteVectorEdge(ve);
-}
-
-void countConstraint(CNF *cnf, VectorEdge *stack, Edge eroot) {
- //Skip constants and variables...
- if (edgeIsVarConst(eroot))
- return;
-
- clearVectorEdge(stack);pushVectorEdge(stack, eroot);
-
- bool isMatching = cnf->enableMatching;
-
- while (getSizeVectorEdge(stack) != 0) {
- Edge e = lastVectorEdge(stack); popVectorEdge(stack);
- bool polarity = isNegEdge(e);
- Node *n = getNodePtrFromEdge(e);
- if (getExpanded(n, polarity)) {
- if (n->flags.type == NodeType_IFF ||
- n->flags.type == NodeType_ITE) {
- Edge pExp = {n->ptrAnnot[polarity]};
- getNodePtrFromEdge(pExp)->intAnnot[0]++;
- } else {
- n->intAnnot[polarity]++;
- }
- } else {
- setExpanded(n, polarity);
-
- if (n->flags.type == NodeType_ITE ||
- n->flags.type == NodeType_IFF) {
- n->intAnnot[polarity] = 0;
- Edge cond = n->edges[0];
- Edge thenedge = n->edges[1];
- Edge elseedge = n->flags.type == NodeType_IFF ? constraintNegate(thenedge) : n->edges[2];
- thenedge = constraintNegateIf(thenedge, !polarity);
- elseedge = constraintNegateIf(elseedge, !polarity);
- thenedge = constraintAND2(cnf, cond, thenedge);
- cond = constraintNegate(cond);
- elseedge = constraintAND2(cnf, cond, elseedge);
- thenedge = constraintNegate(thenedge);
- elseedge = constraintNegate(elseedge);
- cnf->enableMatching = false;
- Edge succ1 = constraintAND2(cnf, thenedge, elseedge);
- n->ptrAnnot[polarity] = succ1.node_ptr;
- cnf->enableMatching = isMatching;
- pushVectorEdge(stack, succ1);
- if (getExpanded(n, !polarity)) {
- Edge succ2 = {(Node *)n->ptrAnnot[!polarity]};
- Node *n1 = getNodePtrFromEdge(succ1);
- Node *n2 = getNodePtrFromEdge(succ2);
- n1->ptrAnnot[0] = succ2.node_ptr;
- n2->ptrAnnot[0] = succ1.node_ptr;
- n1->ptrAnnot[1] = succ2.node_ptr;
- n2->ptrAnnot[1] = succ1.node_ptr;
- }
- } else {
- n->intAnnot[polarity] = 1;
- for (uint i = 0; i < n->numEdges; i++) {
- Edge succ = n->edges[i];
- if (!edgeIsVarConst(succ)) {
- succ = constraintNegateIf(succ, polarity);
- pushVectorEdge(stack, succ);
- }
- }
- }
- }
- }
-}
-
-void convertPass(CNF *cnf, bool backtrackLit) {
- uint numConstraints = getSizeVectorEdge(&cnf->constraints);
- VectorEdge *ve = allocDefVectorEdge();
- for (uint i = 0; i < numConstraints; i++) {
- convertConstraint(cnf, ve, getVectorEdge(&cnf->constraints, i), backtrackLit);
- }
- deleteVectorEdge(ve);
-}
-
-void convertConstraint(CNF *cnf, VectorEdge *stack, Edge root, bool backtrackLit) {
- Node *nroot = getNodePtrFromEdge(root);
-
- if (isNodeEdge(root) && (nroot->flags.type == NodeType_ITE || nroot->flags.type == NodeType_IFF)) {
- nroot = (Node *) nroot->ptrAnnot[isNegEdge(root)];
- root = (Edge) { nroot };
- }
- if (edgeIsConst(root)) {
- if (isNegEdge(root)) {
- //trivally unsat
- Edge newvar = constraintNewVar(cnf);
- Literal var = getEdgeVar(newvar);
- Literal clause[] = {var};
- addArrayClauseLiteral(cnf->solver, 1, clause);
- clause[0] = -var;
- addArrayClauseLiteral(cnf->solver, 1, clause);
- return;
- } else {
- //trivially true
- return;
- }
- } else if (edgeIsVarConst(root)) {
- Literal clause[] = { getEdgeVar(root)};
- addArrayClauseLiteral(cnf->solver, 1, clause);
- return;
- }
-
- clearVectorEdge(stack);pushVectorEdge(stack, root);
- while (getSizeVectorEdge(stack) != 0) {
- Edge e = lastVectorEdge(stack);
- Node *n = getNodePtrFromEdge(e);
-
- if (edgeIsVarConst(e)) {
- popVectorEdge(stack);
- continue;
- } else if (n->flags.type == NodeType_ITE ||
- n->flags.type == NodeType_IFF) {
- popVectorEdge(stack);
- if (n->ptrAnnot[0] != NULL)
- pushVectorEdge(stack, (Edge) {(Node *)n->ptrAnnot[0]});
- if (n->ptrAnnot[1] != NULL)
- pushVectorEdge(stack, (Edge) {(Node *)n->ptrAnnot[1]});
- continue;
- }
-
- bool needPos = (n->intAnnot[0] > 0);
- bool needNeg = (n->intAnnot[1] > 0);
- if ((!needPos || n->flags.cnfVisitedUp & 1) &&
- (!needNeg || n->flags.cnfVisitedUp & 2)) {
- popVectorEdge(stack);
- } else if ((needPos && !(n->flags.cnfVisitedDown & 1)) ||
- (needNeg && !(n->flags.cnfVisitedDown & 2))) {
- if (needPos)
- n->flags.cnfVisitedDown |= 1;
- if (needNeg)
- n->flags.cnfVisitedDown |= 2;
- for (uint i = 0; i < n->numEdges; i++) {
- Edge arg = n->edges[i];
- arg = constraintNegateIf(arg, isNegEdge(e));
- pushVectorEdge(stack, arg); //WARNING, THIS LOOKS LIKE A BUG IN THE ORIGINAL CODE
- }
- } else {
- popVectorEdge(stack);
- produceCNF(cnf, e);
- }
- }
- CNFExpr *cnfExp = (CNFExpr *) nroot->ptrAnnot[isNegEdge(root)];
- ASSERT(cnfExp != NULL);
- if (isProxy(cnfExp)) {
- Literal l = getProxy(cnfExp);
- Literal clause[] = {l};
- addArrayClauseLiteral(cnf->solver, 1, clause);
- } else if (backtrackLit) {
- Literal l = introProxy(cnf, root, cnfExp, isNegEdge(root));
- Literal clause[] = {l};
- addArrayClauseLiteral(cnf->solver, 1, clause);
- } else {
- outputCNF(cnf, cnfExp);
- }
-
- if (!((intptr_t) cnfExp & 1)) {
- deleteCNFExpr(cnfExp);
- nroot->ptrAnnot[isNegEdge(root)] = NULL;
- }
-}
-
-
-Literal introProxy(CNF *cnf, Edge e, CNFExpr *exp, bool isNeg) {
- Literal l = 0;
- Node *n = getNodePtrFromEdge(e);
-
- if (n->flags.cnfVisitedUp & (1 << !isNeg)) {
- CNFExpr *otherExp = (CNFExpr *) n->ptrAnnot[!isNeg];
- if (isProxy(otherExp))
- l = -getProxy(otherExp);
- } else {
- Edge semNeg = {(Node *) n->ptrAnnot[isNeg]};
- Node *nsemNeg = getNodePtrFromEdge(semNeg);
- if (nsemNeg != NULL) {
- if (nsemNeg->flags.cnfVisitedUp & (1 << isNeg)) {
- CNFExpr *otherExp = (CNFExpr *) nsemNeg->ptrAnnot[isNeg];
- if (isProxy(otherExp))
- l = -getProxy(otherExp);
- } else if (nsemNeg->flags.cnfVisitedUp & (1 << !isNeg)) {
- CNFExpr *otherExp = (CNFExpr *) nsemNeg->ptrAnnot[!isNeg];
- if (isProxy(otherExp))
- l = getProxy(otherExp);
- }
- }
- }
-
- if (l == 0) {
- Edge newvar = constraintNewVar(cnf);
- l = getEdgeVar(newvar);
- }
- // Output the constraints on the auxiliary variable
- constrainCNF(cnf, l, exp);
- deleteCNFExpr(exp);
-
- n->ptrAnnot[isNeg] = (void *) ((intptr_t) (l << 1) | 1);
-
- return l;
-}
-
-void produceCNF(CNF *cnf, Edge e) {
- CNFExpr *expPos = NULL;
- CNFExpr *expNeg = NULL;
- Node *n = getNodePtrFromEdge(e);
-
- if (n->intAnnot[0] > 0) {
- expPos = produceConjunction(cnf, e);
- }
-
- if (n->intAnnot[1] > 0) {
- expNeg = produceDisjunction(cnf, e);
- }
-
- /// @todo Propagate constants across semantic negations (this can
- /// be done similarly to the calls to propagate shown below). The
- /// trick here is that we need to figure out how to get the
- /// semantic negation pointers, and ensure that they can have CNF
- /// produced for them at the right point
- ///
- /// propagate(solver, expPos, snPos, false) || propagate(solver, expNeg, snNeg, false)
-
- // propagate from positive to negative, negative to positive
- if (!propagate(cnf, &expPos, expNeg, true))
- propagate(cnf, &expNeg, expPos, true);
-
- // The polarity heuristic entails visiting the discovery polarity first
- if (isPosEdge(e)) {
- saveCNF(cnf, expPos, e, false);
- saveCNF(cnf, expNeg, e, true);
- } else {
- saveCNF(cnf, expNeg, e, true);
- saveCNF(cnf, expPos, e, false);
- }
-}
-
-bool propagate(CNF *cnf, CNFExpr **dest, CNFExpr *src, bool negate) {
- if (src != NULL && !isProxy(src) && getLitSizeCNF(src) == 0) {
- if (*dest == NULL) {
- *dest = allocCNFExprBool(negate ? alwaysFalseCNF(src) : alwaysTrueCNF(src));
- } else if (isProxy(*dest)) {
- bool alwaysTrue = (negate ? alwaysFalseCNF(src) : alwaysTrueCNF(src));
- if (alwaysTrue) {
- Literal clause[] = {getProxy(*dest)};
- addArrayClauseLiteral(cnf->solver, 1, clause);
- } else {
- Literal clause[] = {-getProxy(*dest)};
- addArrayClauseLiteral(cnf->solver, 1, clause);
- }
-
- *dest = allocCNFExprBool(negate ? alwaysFalseCNF(src) : alwaysTrueCNF(src));
- } else {
- clearCNFExpr(*dest, negate ? alwaysFalseCNF(src) : alwaysTrueCNF(src));
- }
- return true;
- }
- return false;
-}
-
-void saveCNF(CNF *cnf, CNFExpr *exp, Edge e, bool sign) {
- Node *n = getNodePtrFromEdge(e);
- n->flags.cnfVisitedUp |= (1 << sign);
- if (exp == NULL || isProxy(exp)) return;
-
- if (exp->litSize == 1) {
- Literal l = getLiteralLitVector(&exp->singletons, 0);
- deleteCNFExpr(exp);
- n->ptrAnnot[sign] = (void *) ((((intptr_t) l) << 1) | 1);
- } else if (exp->litSize != 0 && (n->intAnnot[sign] > 1 || n->flags.varForced)) {
- introProxy(cnf, e, exp, sign);
- } else {
- n->ptrAnnot[sign] = exp;
- }
-}
-
-void constrainCNF(CNF *cnf, Literal lcond, CNFExpr *expr) {
- if (alwaysTrueCNF(expr)) {
- return;
- } else if (alwaysFalseCNF(expr)) {
- Literal clause[] = {-lcond};
- addArrayClauseLiteral(cnf->solver, 1, clause);
- return;
- }
-
- for (uint i = 0; i < getSizeLitVector(&expr->singletons); i++) {
- Literal l = getLiteralLitVector(&expr->singletons,i);
- Literal clause[] = {-lcond, l};
- addArrayClauseLiteral(cnf->solver, 2, clause);
- }
- for (uint i = 0; i < getSizeVectorLitVector(&expr->clauses); i++) {
- LitVector *lv = getVectorLitVector(&expr->clauses,i);
- addClauseLiteral(cnf->solver, -lcond);//Add first literal
- addArrayClauseLiteral(cnf->solver, getSizeLitVector(lv), lv->literals); //Add rest
- }
-}
-
-void outputCNF(CNF *cnf, CNFExpr *expr) {
- for (uint i = 0; i < getSizeLitVector(&expr->singletons); i++) {
- Literal l = getLiteralLitVector(&expr->singletons,i);
- Literal clause[] = {l};
- addArrayClauseLiteral(cnf->solver, 1, clause);
- }
- for (uint i = 0; i < getSizeVectorLitVector(&expr->clauses); i++) {
- LitVector *lv = getVectorLitVector(&expr->clauses,i);
- addArrayClauseLiteral(cnf->solver, getSizeLitVector(lv), lv->literals);
- }
-}
-
-CNFExpr *fillArgs(CNF *cnf, Edge e, bool isNeg, Edge *largestEdge) {
- clearVectorEdge(&cnf->args);
-
- *largestEdge = (Edge) {(Node *) NULL};
- CNFExpr *largest = NULL;
- Node *n = getNodePtrFromEdge(e);
- int i = n->numEdges;
- while (i != 0) {
- Edge arg = n->edges[--i];
- arg = constraintNegateIf(arg, isNeg);
- Node *narg = getNodePtrFromEdge(arg);
-
- if (edgeIsVarConst(arg)) {
- pushVectorEdge(&cnf->args, arg);
- continue;
- }
-
- if (narg->flags.type == NodeType_ITE || narg->flags.type == NodeType_IFF) {
- arg = (Edge) {(Node *) narg->ptrAnnot[isNegEdge(arg)]};
- }
-
- if (narg->intAnnot[isNegEdge(arg)] == 1) {
- CNFExpr *argExp = (CNFExpr *) narg->ptrAnnot[isNegEdge(arg)];
- if (!isProxy(argExp)) {
- if (largest == NULL) {
- largest = argExp;
- *largestEdge = arg;
- continue;
- } else if (argExp->litSize > largest->litSize) {
- pushVectorEdge(&cnf->args, *largestEdge);
- largest = argExp;
- *largestEdge = arg;
- continue;
- }
- }
- }
- pushVectorEdge(&cnf->args, arg);
- }
-
- if (largest != NULL) {
- Node *nlargestEdge = getNodePtrFromEdge(*largestEdge);
- nlargestEdge->ptrAnnot[isNegEdge(*largestEdge)] = NULL;
- }
-
- return largest;
-}
-
-void printCNF(Edge e) {
- if (edgeIsVarConst(e)) {
- Literal l = getEdgeVar(e);
- model_print ("%d", l);
- return;
- }
- bool isNeg = isNegEdge(e);
- if (edgeIsConst(e)) {
- if (isNeg)
- model_print("T");
- else
- model_print("F");
- return;
- }
- Node *n = getNodePtrFromEdge(e);
- if (isNeg) {
- //Pretty print things that are equivalent to OR's
- if (getNodeType(e) == NodeType_AND) {
- model_print("or(");
- for (uint i = 0; i < n->numEdges; i++) {
- Edge e = n->edges[i];
- if (i != 0)
- model_print(" ");
- printCNF(constraintNegate(e));
- }
- model_print(")");
- return;
- }
-
- model_print("!");
- }
- switch (getNodeType(e)) {
- case NodeType_AND:
- model_print("and");
- break;
- case NodeType_ITE:
- model_print("ite");
- break;
- case NodeType_IFF:
- model_print("iff");
- break;
- }
- model_print("(");
- for (uint i = 0; i < n->numEdges; i++) {
- Edge e = n->edges[i];
- if (i != 0)
- model_print(" ");
- printCNF(e);
- }
- model_print(")");
-}
-
-CNFExpr *produceConjunction(CNF *cnf, Edge e) {
- Edge largestEdge;
-
- CNFExpr *accum = fillArgs(cnf, e, false, &largestEdge);
- if (accum == NULL)
- accum = allocCNFExprBool(true);
-
- int i = getSizeVectorEdge(&cnf->args);
- while (i != 0) {
- Edge arg = getVectorEdge(&cnf->args, --i);
- if (edgeIsVarConst(arg)) {
- conjoinCNFLit(accum, getEdgeVar(arg));
- } else {
- Node *narg = getNodePtrFromEdge(arg);
- CNFExpr *argExp = (CNFExpr *) narg->ptrAnnot[isNegEdge(arg)];
-
- bool destroy = (--narg->intAnnot[isNegEdge(arg)] == 0);
- if (isProxy(argExp)) {// variable has been introduced
- conjoinCNFLit(accum, getProxy(argExp));
- } else {
- conjoinCNFExpr(accum, argExp, destroy);
- if (destroy)
- narg->ptrAnnot[isNegEdge(arg)] = NULL;
- }
- }
- }
-
- return accum;
-}
-
-#define CLAUSE_MAX 3
-
-CNFExpr *produceDisjunction(CNF *cnf, Edge e) {
- Edge largestEdge;
- CNFExpr *accum = fillArgs(cnf, e, true, &largestEdge);
- if (accum == NULL)
- accum = allocCNFExprBool(false);
-
- // This is necessary to check to make sure that we don't start out
- // with an accumulator that is "too large".
-
- /// @todo Strictly speaking, introProxy doesn't *need* to free
- /// memory, then this wouldn't have to reallocate CNFExpr
-
- /// @todo When this call to introProxy is made, the semantic
- /// negation pointer will have been destroyed. Thus, it will not
- /// be possible to use the correct proxy. That should be fixed.
-
- // at this point, we will either have NULL, or a destructible expression
- if (getClauseSizeCNF(accum) > CLAUSE_MAX)
- accum = allocCNFExprLiteral(introProxy(cnf, largestEdge, accum, isNegEdge(largestEdge)));
-
- int i = getSizeVectorEdge(&cnf->args);
- while (i != 0) {
- Edge arg = getVectorEdge(&cnf->args, --i);
- Node *narg = getNodePtrFromEdge(arg);
- if (edgeIsVarConst(arg)) {
- disjoinCNFLit(accum, getEdgeVar(arg));
- } else {
- CNFExpr *argExp = (CNFExpr *) narg->ptrAnnot[isNegEdge(arg)];
-
- bool destroy = (--narg->intAnnot[isNegEdge(arg)] == 0);
- if (isProxy(argExp)) {// variable has been introduced
- disjoinCNFLit(accum, getProxy(argExp));
- } else if (argExp->litSize == 0) {
- disjoinCNFExpr(accum, argExp, destroy);
- } else {
- // check to see if we should introduce a proxy
- int aL = accum->litSize; // lits in accum
- int eL = argExp->litSize; // lits in argument
- int aC = getClauseSizeCNF(accum); // clauses in accum
- int eC = getClauseSizeCNF(argExp); // clauses in argument
-
- if (eC > CLAUSE_MAX || (eL * aC + aL * eC > eL + aC + aL + aC)) {
- disjoinCNFLit(accum, introProxy(cnf, arg, argExp, isNegEdge(arg)));
- } else {
- disjoinCNFExpr(accum, argExp, destroy);
- if (destroy) narg->ptrAnnot[isNegEdge(arg)] = NULL;
- }
- }
- }
- }
-
- return accum;
-}
-
-Edge generateBinaryConstraint(CNF *cnf, uint numvars, Edge *vars, uint value) {
- Edge carray[numvars];
- for (uint j = 0; j < numvars; j++) {
- carray[j] = ((value & 1) == 1) ? vars[j] : constraintNegate(vars[j]);
- value = value >> 1;
- }
-
- return constraintAND(cnf, numvars, carray);
-}
-
-/** Generates a constraint to ensure that all encodings are less than value */
-Edge generateLTValueConstraint(CNF *cnf, uint numvars, Edge *vars, uint value) {
- Edge orarray[numvars];
- Edge andarray[numvars];
- uint andi = 0;
-
- while (true) {
- uint val = value;
- uint ori = 0;
- for (uint j = 0; j < numvars; j++) {
- if ((val & 1) == 1)
- orarray[ori++] = constraintNegate(vars[j]);
- val = val >> 1;
- }
- //no ones to flip, so bail now...
- if (ori == 0) {
- return constraintAND(cnf, andi, andarray);
- }
- andarray[andi++] = constraintOR(cnf, ori, orarray);
-
- value = value + (1 << (__builtin_ctz(value)));
- //flip the last one
- }
-}
-
-Edge generateEquivNVConstraint(CNF *cnf, uint numvars, Edge *var1, Edge *var2) {
- if (numvars == 0)
- return E_True;
- Edge array[numvars];
- for (uint i = 0; i < numvars; i++) {
- array[i] = constraintIFF(cnf, var1[i], var2[i]);
- }
- return constraintAND(cnf, numvars, array);
-}
-
-Edge generateLTConstraint(CNF *cnf, uint numvars, Edge *var1, Edge *var2){
- if(numvars == 0 )
- return E_False;
- Edge result =constraintAND2(cnf, constraintNegate( var1[0]), var2[0]);
- for (uint i = 1; i < numvars; i++) {
- Edge lt = constraintAND2(cnf, constraintNegate( var1[i]), var2[i]);
- Edge eq = constraintAND2(cnf, constraintIFF(cnf, var1[i], var2[i]), result);
- result = constraintOR2(cnf, lt, eq);
- }
- return result;
-}
-
-Edge generateLTEConstraint(CNF *cnf, uint numvars, Edge *var1, Edge *var2){
- if(numvars == 0 )
- return E_True;
- Edge result =constraintIMPLIES(cnf, var1[0], var2[0]);
- for (uint i = 1; i < numvars; i++) {
- Edge lt = constraintAND2(cnf, constraintNegate( var1[i]), var2[i]);
- Edge eq = constraintAND2(cnf, constraintIFF(cnf, var1[i], var2[i]), result);
- result = constraintOR2(cnf, lt, eq);
- }
- return result;
-}
--- /dev/null
+#include "constraint.h"
+#include <string.h>
+#include <stdlib.h>
+#include "inc_solver.h"
+#include "cnfexpr.h"
+#include "common.h"
+/*
+ V2 Copyright (c) 2014 Ben Chambers, Eugene Goldberg, Pete Manolios,
+ Vasilis Papavasileiou, Sudarshan Srinivasan, and Daron Vroon.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software. If
+ you download or use the software, send email to Pete Manolios
+ (pete@ccs.neu.edu) with your name, contact information, and a short
+ note describing what you want to use BAT for. For any reuse or
+ distribution, you must make clear to others the license terms of this
+ work.
+
+ Contact Pete Manolios if you want any of these conditions waived.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ C port of CNF SAT Conversion Copyright Brian Demsky 2017.
+ */
+
+
+VectorImpl(Edge, Edge, 16)
+Edge E_True = {(Node *)(uintptr_t) EDGE_IS_VAR_CONSTANT};
+Edge E_False = {(Node *)(uintptr_t) (EDGE_IS_VAR_CONSTANT | NEGATE_EDGE)};
+Edge E_BOGUS = {(Node *)0x12345673};
+Edge E_NULL = {(Node *)NULL};
+
+
+CNF *createCNF() {
+ CNF *cnf = (CNF *) ourmalloc(sizeof(CNF));
+ cnf->varcount = 1;
+ cnf->capacity = DEFAULT_CNF_ARRAY_SIZE;
+ cnf->mask = cnf->capacity - 1;
+ cnf->node_array = (Node **) ourcalloc(1, sizeof(Node *) * cnf->capacity);
+ cnf->size = 0;
+ cnf->maxsize = (uint)(((double)cnf->capacity) * LOAD_FACTOR);
+ cnf->enableMatching = true;
+ initDefVectorEdge(&cnf->constraints);
+ initDefVectorEdge(&cnf->args);
+ cnf->solver = allocIncrementalSolver();
+ return cnf;
+}
+
+void deleteCNF(CNF *cnf) {
+ for (uint i = 0; i < cnf->capacity; i++) {
+ Node *n = cnf->node_array[i];
+ if (n != NULL)
+ ourfree(n);
+ }
+ deleteVectorArrayEdge(&cnf->constraints);
+ deleteVectorArrayEdge(&cnf->args);
+ deleteIncrementalSolver(cnf->solver);
+ ourfree(cnf->node_array);
+ ourfree(cnf);
+}
+
+void resizeCNF(CNF *cnf, uint newCapacity) {
+ Node **old_array = cnf->node_array;
+ Node **new_array = (Node **) ourcalloc(1, sizeof(Node *) * newCapacity);
+ uint oldCapacity = cnf->capacity;
+ uint newMask = newCapacity - 1;
+ for (uint i = 0; i < oldCapacity; i++) {
+ Node *n = old_array[i];
+ uint hashCode = n->hashCode;
+ uint newindex = hashCode & newMask;
+ for (;; newindex = (newindex + 1) & newMask) {
+ if (new_array[newindex] == NULL) {
+ new_array[newindex] = n;
+ break;
+ }
+ }
+ }
+ ourfree(old_array);
+ cnf->node_array = new_array;
+ cnf->capacity = newCapacity;
+ cnf->maxsize = (uint)(((double)cnf->capacity) * LOAD_FACTOR);
+ cnf->mask = newMask;
+}
+
+Node *allocNode(NodeType type, uint numEdges, Edge *edges, uint hashcode) {
+ Node *n = (Node *)ourmalloc(sizeof(Node) + sizeof(Edge) * numEdges);
+ memcpy(n->edges, edges, sizeof(Edge) * numEdges);
+ n->flags.type = type;
+ n->flags.wasExpanded = 0;
+ n->flags.cnfVisitedDown = 0;
+ n->flags.cnfVisitedUp = 0;
+ n->flags.varForced = 0;
+ n->numEdges = numEdges;
+ n->hashCode = hashcode;
+ n->intAnnot[0] = 0;n->intAnnot[1] = 0;
+ n->ptrAnnot[0] = NULL;n->ptrAnnot[1] = NULL;
+ return n;
+}
+
+Edge createNode(CNF *cnf, NodeType type, uint numEdges, Edge *edges) {
+ if (cnf->size > cnf->maxsize) {
+ resizeCNF(cnf, cnf->capacity << 1);
+ }
+ uint hashvalue = hashNode(type, numEdges, edges);
+ uint mask = cnf->mask;
+ uint index = hashvalue & mask;
+ Node **n_ptr;
+ for (;; index = (index + 1) & mask) {
+ n_ptr = &cnf->node_array[index];
+ if (*n_ptr != NULL) {
+ if ((*n_ptr)->hashCode == hashvalue) {
+ if (compareNodes(*n_ptr, type, numEdges, edges)) {
+ Edge e = {*n_ptr};
+ return e;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ *n_ptr = allocNode(type, numEdges, edges, hashvalue);
+ Edge e = {*n_ptr};
+ return e;
+}
+
+uint hashNode(NodeType type, uint numEdges, Edge *edges) {
+ uint hashvalue = type ^ numEdges;
+ for (uint i = 0; i < numEdges; i++) {
+ hashvalue ^= (uint) ((uintptr_t) edges[i].node_ptr);
+ hashvalue = (hashvalue << 3) | (hashvalue >> 29); //rotate left by 3 bits
+ }
+ return (uint) hashvalue;
+}
+
+bool compareNodes(Node *node, NodeType type, uint numEdges, Edge *edges) {
+ if (node->flags.type != type || node->numEdges != numEdges)
+ return false;
+ Edge *nodeedges = node->edges;
+ for (uint i = 0; i < numEdges; i++) {
+ if (!equalsEdge(nodeedges[i], edges[i]))
+ return false;
+ }
+ return true;
+}
+
+Edge constraintOR(CNF *cnf, uint numEdges, Edge *edges) {
+ Edge edgearray[numEdges];
+
+ for (uint i = 0; i < numEdges; i++) {
+ edgearray[i] = constraintNegate(edges[i]);
+ }
+ Edge eand = constraintAND(cnf, numEdges, edgearray);
+ return constraintNegate(eand);
+}
+
+Edge constraintOR2(CNF *cnf, Edge left, Edge right) {
+ Edge lneg = constraintNegate(left);
+ Edge rneg = constraintNegate(right);
+ Edge eand = constraintAND2(cnf, lneg, rneg);
+ return constraintNegate(eand);
+}
+
+int comparefunction(const Edge *e1, const Edge *e2) {
+ return ((uintptr_t)e1->node_ptr) - ((uintptr_t)e2->node_ptr);
+}
+
+Edge constraintAND(CNF *cnf, uint numEdges, Edge *edges) {
+ ASSERT(numEdges != 0);
+ qsort(edges, numEdges, sizeof(Edge), (int (*)(const void *, const void *))comparefunction);
+ int initindex = 0;
+ while (initindex < numEdges && equalsEdge(edges[initindex], E_True))
+ initindex++;
+
+ uint remainSize = numEdges - initindex;
+
+ if (remainSize == 0)
+ return E_True;
+ else if (remainSize == 1)
+ return edges[initindex];
+ else if (equalsEdge(edges[initindex], E_False))
+ return E_False;
+
+ /** De-duplicate array */
+ uint lowindex = 0;
+ edges[lowindex] = edges[initindex++];
+
+ for (; initindex < numEdges; initindex++) {
+ Edge e1 = edges[lowindex];
+ Edge e2 = edges[initindex];
+ if (sameNodeVarEdge(e1, e2)) {
+ if (!sameSignEdge(e1, e2)) {
+ return E_False;
+ }
+ } else
+ edges[++lowindex] = edges[initindex];
+ }
+ lowindex++; //Make lowindex look like size
+
+ if (lowindex == 1)
+ return edges[0];
+
+ if (cnf->enableMatching && lowindex == 2 &&
+ isNegNodeEdge(edges[0]) && isNegNodeEdge(edges[1]) &&
+ getNodeType(edges[0]) == NodeType_AND &&
+ getNodeType(edges[1]) == NodeType_AND &&
+ getNodeSize(edges[0]) == 2 &&
+ getNodeSize(edges[1]) == 2) {
+ Edge *e0edges = getEdgeArray(edges[0]);
+ Edge *e1edges = getEdgeArray(edges[1]);
+ if (sameNodeOppSign(e0edges[0], e1edges[0])) {
+ return constraintNegate(constraintITE(cnf, e0edges[0], e0edges[1], e1edges[1]));
+ } else if (sameNodeOppSign(e0edges[0], e1edges[1])) {
+ return constraintNegate(constraintITE(cnf, e0edges[0], e0edges[1], e1edges[0]));
+ } else if (sameNodeOppSign(e0edges[1], e1edges[0])) {
+ return constraintNegate(constraintITE(cnf, e0edges[1], e0edges[0], e1edges[1]));
+ } else if (sameNodeOppSign(e0edges[1], e1edges[1])) {
+ return constraintNegate(constraintITE(cnf, e0edges[1], e0edges[0], e1edges[0]));
+ }
+ }
+
+ return createNode(cnf, NodeType_AND, lowindex, edges);
+}
+
+Edge constraintAND2(CNF *cnf, Edge left, Edge right) {
+ Edge edges[2] = {left, right};
+ return constraintAND(cnf, 2, edges);
+}
+
+Edge constraintIMPLIES(CNF *cnf, Edge left, Edge right) {
+ Edge array[2];
+ array[0] = left;
+ array[1] = constraintNegate(right);
+ Edge eand = constraintAND(cnf, 2, array);
+ return constraintNegate(eand);
+}
+
+Edge constraintIFF(CNF *cnf, Edge left, Edge right) {
+ bool negate = !sameSignEdge(left, right);
+ Edge lpos = getNonNeg(left);
+ Edge rpos = getNonNeg(right);
+
+ Edge e;
+ if (equalsEdge(lpos, rpos)) {
+ e = E_True;
+ } else if (ltEdge(lpos, rpos)) {
+ Edge edges[] = {lpos, rpos};
+ e = (edgeIsConst(lpos)) ? rpos : createNode(cnf, NodeType_IFF, 2, edges);
+ } else {
+ Edge edges[] = {rpos, lpos};
+ e = (edgeIsConst(rpos)) ? lpos : createNode(cnf, NodeType_IFF, 2, edges);
+ }
+ if (negate)
+ e = constraintNegate(e);
+ return e;
+}
+
+Edge constraintITE(CNF *cnf, Edge cond, Edge thenedge, Edge elseedge) {
+ if (isNegEdge(cond)) {
+ cond = constraintNegate(cond);
+ Edge tmp = thenedge;
+ thenedge = elseedge;
+ elseedge = tmp;
+ }
+
+ bool negate = isNegEdge(thenedge);
+ if (negate) {
+ thenedge = constraintNegate(thenedge);
+ elseedge = constraintNegate(elseedge);
+ }
+
+ Edge result;
+ if (equalsEdge(cond, E_True)) {
+ result = thenedge;
+ } else if (equalsEdge(thenedge, E_True) || equalsEdge(cond, thenedge)) {
+ result = constraintOR(cnf, 2, (Edge[]) {cond, elseedge});
+ } else if (equalsEdge(elseedge, E_True) || sameNodeOppSign(cond, elseedge)) {
+ result = constraintIMPLIES(cnf, cond, thenedge);
+ } else if (equalsEdge(thenedge, E_False) || equalsEdge(cond, elseedge)) {
+ result = constraintAND(cnf, 2, (Edge[]) {cond, thenedge});
+ } else if (equalsEdge(thenedge, elseedge)) {
+ result = thenedge;
+ } else if (sameNodeOppSign(thenedge, elseedge)) {
+ if (ltEdge(cond, thenedge)) {
+ result = createNode(cnf, NodeType_IFF, 2, (Edge[]) {cond, thenedge});
+ } else {
+ result = createNode(cnf, NodeType_IFF, 2, (Edge[]) {thenedge, cond});
+ }
+ } else {
+ Edge edges[] = {cond, thenedge, elseedge};
+ result = createNode(cnf, NodeType_ITE, 3, edges);
+ }
+ if (negate)
+ result = constraintNegate(result);
+ return result;
+}
+
+void addConstraintCNF(CNF *cnf, Edge constraint) {
+ pushVectorEdge(&cnf->constraints, constraint);
+ model_print("****ADDING NEW Constraint*****\n");
+ printCNF(constraint);
+ model_print("\n******************************\n");
+}
+
+Edge constraintNewVar(CNF *cnf) {
+ uint varnum = cnf->varcount++;
+ Edge e = {(Node *) ((((uintptr_t)varnum) << VAR_SHIFT) | EDGE_IS_VAR_CONSTANT) };
+ return e;
+}
+
+int solveCNF(CNF *cnf) {
+ countPass(cnf);
+ convertPass(cnf, false);
+ finishedClauses(cnf->solver);
+ return solve(cnf->solver);
+}
+
+bool getValueCNF(CNF *cnf, Edge var) {
+ Literal l = getEdgeVar(var);
+ bool isneg = (l < 0);
+ l = abs(l);
+ return isneg ^ getValueSolver(cnf->solver, l);
+}
+
+void countPass(CNF *cnf) {
+ uint numConstraints = getSizeVectorEdge(&cnf->constraints);
+ VectorEdge *ve = allocDefVectorEdge();
+ for (uint i = 0; i < numConstraints; i++) {
+ countConstraint(cnf, ve, getVectorEdge(&cnf->constraints, i));
+ }
+ deleteVectorEdge(ve);
+}
+
+void countConstraint(CNF *cnf, VectorEdge *stack, Edge eroot) {
+ //Skip constants and variables...
+ if (edgeIsVarConst(eroot))
+ return;
+
+ clearVectorEdge(stack);pushVectorEdge(stack, eroot);
+
+ bool isMatching = cnf->enableMatching;
+
+ while (getSizeVectorEdge(stack) != 0) {
+ Edge e = lastVectorEdge(stack); popVectorEdge(stack);
+ bool polarity = isNegEdge(e);
+ Node *n = getNodePtrFromEdge(e);
+ if (getExpanded(n, polarity)) {
+ if (n->flags.type == NodeType_IFF ||
+ n->flags.type == NodeType_ITE) {
+ Edge pExp = {(Node *)n->ptrAnnot[polarity]};
+ getNodePtrFromEdge(pExp)->intAnnot[0]++;
+ } else {
+ n->intAnnot[polarity]++;
+ }
+ } else {
+ setExpanded(n, polarity);
+
+ if (n->flags.type == NodeType_ITE ||
+ n->flags.type == NodeType_IFF) {
+ n->intAnnot[polarity] = 0;
+ Edge cond = n->edges[0];
+ Edge thenedge = n->edges[1];
+ Edge elseedge = n->flags.type == NodeType_IFF ? constraintNegate(thenedge) : n->edges[2];
+ thenedge = constraintNegateIf(thenedge, !polarity);
+ elseedge = constraintNegateIf(elseedge, !polarity);
+ thenedge = constraintAND2(cnf, cond, thenedge);
+ cond = constraintNegate(cond);
+ elseedge = constraintAND2(cnf, cond, elseedge);
+ thenedge = constraintNegate(thenedge);
+ elseedge = constraintNegate(elseedge);
+ cnf->enableMatching = false;
+ Edge succ1 = constraintAND2(cnf, thenedge, elseedge);
+ n->ptrAnnot[polarity] = succ1.node_ptr;
+ cnf->enableMatching = isMatching;
+ pushVectorEdge(stack, succ1);
+ if (getExpanded(n, !polarity)) {
+ Edge succ2 = {(Node *)n->ptrAnnot[!polarity]};
+ Node *n1 = getNodePtrFromEdge(succ1);
+ Node *n2 = getNodePtrFromEdge(succ2);
+ n1->ptrAnnot[0] = succ2.node_ptr;
+ n2->ptrAnnot[0] = succ1.node_ptr;
+ n1->ptrAnnot[1] = succ2.node_ptr;
+ n2->ptrAnnot[1] = succ1.node_ptr;
+ }
+ } else {
+ n->intAnnot[polarity] = 1;
+ for (uint i = 0; i < n->numEdges; i++) {
+ Edge succ = n->edges[i];
+ if (!edgeIsVarConst(succ)) {
+ succ = constraintNegateIf(succ, polarity);
+ pushVectorEdge(stack, succ);
+ }
+ }
+ }
+ }
+ }
+}
+
+void convertPass(CNF *cnf, bool backtrackLit) {
+ uint numConstraints = getSizeVectorEdge(&cnf->constraints);
+ VectorEdge *ve = allocDefVectorEdge();
+ for (uint i = 0; i < numConstraints; i++) {
+ convertConstraint(cnf, ve, getVectorEdge(&cnf->constraints, i), backtrackLit);
+ }
+ deleteVectorEdge(ve);
+}
+
+void convertConstraint(CNF *cnf, VectorEdge *stack, Edge root, bool backtrackLit) {
+ Node *nroot = getNodePtrFromEdge(root);
+
+ if (isNodeEdge(root) && (nroot->flags.type == NodeType_ITE || nroot->flags.type == NodeType_IFF)) {
+ nroot = (Node *) nroot->ptrAnnot[isNegEdge(root)];
+ root = (Edge) { nroot };
+ }
+ if (edgeIsConst(root)) {
+ if (isNegEdge(root)) {
+ //trivally unsat
+ Edge newvar = constraintNewVar(cnf);
+ Literal var = getEdgeVar(newvar);
+ Literal clause[] = {var};
+ addArrayClauseLiteral(cnf->solver, 1, clause);
+ clause[0] = -var;
+ addArrayClauseLiteral(cnf->solver, 1, clause);
+ return;
+ } else {
+ //trivially true
+ return;
+ }
+ } else if (edgeIsVarConst(root)) {
+ Literal clause[] = { getEdgeVar(root)};
+ addArrayClauseLiteral(cnf->solver, 1, clause);
+ return;
+ }
+
+ clearVectorEdge(stack);pushVectorEdge(stack, root);
+ while (getSizeVectorEdge(stack) != 0) {
+ Edge e = lastVectorEdge(stack);
+ Node *n = getNodePtrFromEdge(e);
+
+ if (edgeIsVarConst(e)) {
+ popVectorEdge(stack);
+ continue;
+ } else if (n->flags.type == NodeType_ITE ||
+ n->flags.type == NodeType_IFF) {
+ popVectorEdge(stack);
+ if (n->ptrAnnot[0] != NULL)
+ pushVectorEdge(stack, (Edge) {(Node *)n->ptrAnnot[0]});
+ if (n->ptrAnnot[1] != NULL)
+ pushVectorEdge(stack, (Edge) {(Node *)n->ptrAnnot[1]});
+ continue;
+ }
+
+ bool needPos = (n->intAnnot[0] > 0);
+ bool needNeg = (n->intAnnot[1] > 0);
+ if ((!needPos || n->flags.cnfVisitedUp & 1) &&
+ (!needNeg || n->flags.cnfVisitedUp & 2)) {
+ popVectorEdge(stack);
+ } else if ((needPos && !(n->flags.cnfVisitedDown & 1)) ||
+ (needNeg && !(n->flags.cnfVisitedDown & 2))) {
+ if (needPos)
+ n->flags.cnfVisitedDown |= 1;
+ if (needNeg)
+ n->flags.cnfVisitedDown |= 2;
+ for (uint i = 0; i < n->numEdges; i++) {
+ Edge arg = n->edges[i];
+ arg = constraintNegateIf(arg, isNegEdge(e));
+ pushVectorEdge(stack, arg); //WARNING, THIS LOOKS LIKE A BUG IN THE ORIGINAL CODE
+ }
+ } else {
+ popVectorEdge(stack);
+ produceCNF(cnf, e);
+ }
+ }
+ CNFExpr *cnfExp = (CNFExpr *) nroot->ptrAnnot[isNegEdge(root)];
+ ASSERT(cnfExp != NULL);
+ if (isProxy(cnfExp)) {
+ Literal l = getProxy(cnfExp);
+ Literal clause[] = {l};
+ addArrayClauseLiteral(cnf->solver, 1, clause);
+ } else if (backtrackLit) {
+ Literal l = introProxy(cnf, root, cnfExp, isNegEdge(root));
+ Literal clause[] = {l};
+ addArrayClauseLiteral(cnf->solver, 1, clause);
+ } else {
+ outputCNF(cnf, cnfExp);
+ }
+
+ if (!((intptr_t) cnfExp & 1)) {
+ deleteCNFExpr(cnfExp);
+ nroot->ptrAnnot[isNegEdge(root)] = NULL;
+ }
+}
+
+
+Literal introProxy(CNF *cnf, Edge e, CNFExpr *exp, bool isNeg) {
+ Literal l = 0;
+ Node *n = getNodePtrFromEdge(e);
+
+ if (n->flags.cnfVisitedUp & (1 << !isNeg)) {
+ CNFExpr *otherExp = (CNFExpr *) n->ptrAnnot[!isNeg];
+ if (isProxy(otherExp))
+ l = -getProxy(otherExp);
+ } else {
+ Edge semNeg = {(Node *) n->ptrAnnot[isNeg]};
+ Node *nsemNeg = getNodePtrFromEdge(semNeg);
+ if (nsemNeg != NULL) {
+ if (nsemNeg->flags.cnfVisitedUp & (1 << isNeg)) {
+ CNFExpr *otherExp = (CNFExpr *) nsemNeg->ptrAnnot[isNeg];
+ if (isProxy(otherExp))
+ l = -getProxy(otherExp);
+ } else if (nsemNeg->flags.cnfVisitedUp & (1 << !isNeg)) {
+ CNFExpr *otherExp = (CNFExpr *) nsemNeg->ptrAnnot[!isNeg];
+ if (isProxy(otherExp))
+ l = getProxy(otherExp);
+ }
+ }
+ }
+
+ if (l == 0) {
+ Edge newvar = constraintNewVar(cnf);
+ l = getEdgeVar(newvar);
+ }
+ // Output the constraints on the auxiliary variable
+ constrainCNF(cnf, l, exp);
+ deleteCNFExpr(exp);
+
+ n->ptrAnnot[isNeg] = (void *) ((intptr_t) (l << 1) | 1);
+
+ return l;
+}
+
+void produceCNF(CNF *cnf, Edge e) {
+ CNFExpr *expPos = NULL;
+ CNFExpr *expNeg = NULL;
+ Node *n = getNodePtrFromEdge(e);
+
+ if (n->intAnnot[0] > 0) {
+ expPos = produceConjunction(cnf, e);
+ }
+
+ if (n->intAnnot[1] > 0) {
+ expNeg = produceDisjunction(cnf, e);
+ }
+
+ /// @todo Propagate constants across semantic negations (this can
+ /// be done similarly to the calls to propagate shown below). The
+ /// trick here is that we need to figure out how to get the
+ /// semantic negation pointers, and ensure that they can have CNF
+ /// produced for them at the right point
+ ///
+ /// propagate(solver, expPos, snPos, false) || propagate(solver, expNeg, snNeg, false)
+
+ // propagate from positive to negative, negative to positive
+ if (!propagate(cnf, &expPos, expNeg, true))
+ propagate(cnf, &expNeg, expPos, true);
+
+ // The polarity heuristic entails visiting the discovery polarity first
+ if (isPosEdge(e)) {
+ saveCNF(cnf, expPos, e, false);
+ saveCNF(cnf, expNeg, e, true);
+ } else {
+ saveCNF(cnf, expNeg, e, true);
+ saveCNF(cnf, expPos, e, false);
+ }
+}
+
+bool propagate(CNF *cnf, CNFExpr **dest, CNFExpr *src, bool negate) {
+ if (src != NULL && !isProxy(src) && getLitSizeCNF(src) == 0) {
+ if (*dest == NULL) {
+ *dest = allocCNFExprBool(negate ? alwaysFalseCNF(src) : alwaysTrueCNF(src));
+ } else if (isProxy(*dest)) {
+ bool alwaysTrue = (negate ? alwaysFalseCNF(src) : alwaysTrueCNF(src));
+ if (alwaysTrue) {
+ Literal clause[] = {getProxy(*dest)};
+ addArrayClauseLiteral(cnf->solver, 1, clause);
+ } else {
+ Literal clause[] = {-getProxy(*dest)};
+ addArrayClauseLiteral(cnf->solver, 1, clause);
+ }
+
+ *dest = allocCNFExprBool(negate ? alwaysFalseCNF(src) : alwaysTrueCNF(src));
+ } else {
+ clearCNFExpr(*dest, negate ? alwaysFalseCNF(src) : alwaysTrueCNF(src));
+ }
+ return true;
+ }
+ return false;
+}
+
+void saveCNF(CNF *cnf, CNFExpr *exp, Edge e, bool sign) {
+ Node *n = getNodePtrFromEdge(e);
+ n->flags.cnfVisitedUp |= (1 << sign);
+ if (exp == NULL || isProxy(exp)) return;
+
+ if (exp->litSize == 1) {
+ Literal l = getLiteralLitVector(&exp->singletons, 0);
+ deleteCNFExpr(exp);
+ n->ptrAnnot[sign] = (void *) ((((intptr_t) l) << 1) | 1);
+ } else if (exp->litSize != 0 && (n->intAnnot[sign] > 1 || n->flags.varForced)) {
+ introProxy(cnf, e, exp, sign);
+ } else {
+ n->ptrAnnot[sign] = exp;
+ }
+}
+
+void constrainCNF(CNF *cnf, Literal lcond, CNFExpr *expr) {
+ if (alwaysTrueCNF(expr)) {
+ return;
+ } else if (alwaysFalseCNF(expr)) {
+ Literal clause[] = {-lcond};
+ addArrayClauseLiteral(cnf->solver, 1, clause);
+ return;
+ }
+
+ for (uint i = 0; i < getSizeLitVector(&expr->singletons); i++) {
+ Literal l = getLiteralLitVector(&expr->singletons,i);
+ Literal clause[] = {-lcond, l};
+ addArrayClauseLiteral(cnf->solver, 2, clause);
+ }
+ for (uint i = 0; i < getSizeVectorLitVector(&expr->clauses); i++) {
+ LitVector *lv = getVectorLitVector(&expr->clauses,i);
+ addClauseLiteral(cnf->solver, -lcond);//Add first literal
+ addArrayClauseLiteral(cnf->solver, getSizeLitVector(lv), lv->literals); //Add rest
+ }
+}
+
+void outputCNF(CNF *cnf, CNFExpr *expr) {
+ for (uint i = 0; i < getSizeLitVector(&expr->singletons); i++) {
+ Literal l = getLiteralLitVector(&expr->singletons,i);
+ Literal clause[] = {l};
+ addArrayClauseLiteral(cnf->solver, 1, clause);
+ }
+ for (uint i = 0; i < getSizeVectorLitVector(&expr->clauses); i++) {
+ LitVector *lv = getVectorLitVector(&expr->clauses,i);
+ addArrayClauseLiteral(cnf->solver, getSizeLitVector(lv), lv->literals);
+ }
+}
+
+CNFExpr *fillArgs(CNF *cnf, Edge e, bool isNeg, Edge *largestEdge) {
+ clearVectorEdge(&cnf->args);
+
+ *largestEdge = (Edge) {(Node *) NULL};
+ CNFExpr *largest = NULL;
+ Node *n = getNodePtrFromEdge(e);
+ int i = n->numEdges;
+ while (i != 0) {
+ Edge arg = n->edges[--i];
+ arg = constraintNegateIf(arg, isNeg);
+ Node *narg = getNodePtrFromEdge(arg);
+
+ if (edgeIsVarConst(arg)) {
+ pushVectorEdge(&cnf->args, arg);
+ continue;
+ }
+
+ if (narg->flags.type == NodeType_ITE || narg->flags.type == NodeType_IFF) {
+ arg = (Edge) {(Node *) narg->ptrAnnot[isNegEdge(arg)]};
+ }
+
+ if (narg->intAnnot[isNegEdge(arg)] == 1) {
+ CNFExpr *argExp = (CNFExpr *) narg->ptrAnnot[isNegEdge(arg)];
+ if (!isProxy(argExp)) {
+ if (largest == NULL) {
+ largest = argExp;
+ *largestEdge = arg;
+ continue;
+ } else if (argExp->litSize > largest->litSize) {
+ pushVectorEdge(&cnf->args, *largestEdge);
+ largest = argExp;
+ *largestEdge = arg;
+ continue;
+ }
+ }
+ }
+ pushVectorEdge(&cnf->args, arg);
+ }
+
+ if (largest != NULL) {
+ Node *nlargestEdge = getNodePtrFromEdge(*largestEdge);
+ nlargestEdge->ptrAnnot[isNegEdge(*largestEdge)] = NULL;
+ }
+
+ return largest;
+}
+
+void printCNF(Edge e) {
+ if (edgeIsVarConst(e)) {
+ Literal l = getEdgeVar(e);
+ model_print ("%d", l);
+ return;
+ }
+ bool isNeg = isNegEdge(e);
+ if (edgeIsConst(e)) {
+ if (isNeg)
+ model_print("T");
+ else
+ model_print("F");
+ return;
+ }
+ Node *n = getNodePtrFromEdge(e);
+ if (isNeg) {
+ //Pretty print things that are equivalent to OR's
+ if (getNodeType(e) == NodeType_AND) {
+ model_print("or(");
+ for (uint i = 0; i < n->numEdges; i++) {
+ Edge e = n->edges[i];
+ if (i != 0)
+ model_print(" ");
+ printCNF(constraintNegate(e));
+ }
+ model_print(")");
+ return;
+ }
+
+ model_print("!");
+ }
+ switch (getNodeType(e)) {
+ case NodeType_AND:
+ model_print("and");
+ break;
+ case NodeType_ITE:
+ model_print("ite");
+ break;
+ case NodeType_IFF:
+ model_print("iff");
+ break;
+ }
+ model_print("(");
+ for (uint i = 0; i < n->numEdges; i++) {
+ Edge e = n->edges[i];
+ if (i != 0)
+ model_print(" ");
+ printCNF(e);
+ }
+ model_print(")");
+}
+
+CNFExpr *produceConjunction(CNF *cnf, Edge e) {
+ Edge largestEdge;
+
+ CNFExpr *accum = fillArgs(cnf, e, false, &largestEdge);
+ if (accum == NULL)
+ accum = allocCNFExprBool(true);
+
+ int i = getSizeVectorEdge(&cnf->args);
+ while (i != 0) {
+ Edge arg = getVectorEdge(&cnf->args, --i);
+ if (edgeIsVarConst(arg)) {
+ conjoinCNFLit(accum, getEdgeVar(arg));
+ } else {
+ Node *narg = getNodePtrFromEdge(arg);
+ CNFExpr *argExp = (CNFExpr *) narg->ptrAnnot[isNegEdge(arg)];
+
+ bool destroy = (--narg->intAnnot[isNegEdge(arg)] == 0);
+ if (isProxy(argExp)) {// variable has been introduced
+ conjoinCNFLit(accum, getProxy(argExp));
+ } else {
+ conjoinCNFExpr(accum, argExp, destroy);
+ if (destroy)
+ narg->ptrAnnot[isNegEdge(arg)] = NULL;
+ }
+ }
+ }
+
+ return accum;
+}
+
+#define CLAUSE_MAX 3
+
+CNFExpr *produceDisjunction(CNF *cnf, Edge e) {
+ Edge largestEdge;
+ CNFExpr *accum = fillArgs(cnf, e, true, &largestEdge);
+ if (accum == NULL)
+ accum = allocCNFExprBool(false);
+
+ // This is necessary to check to make sure that we don't start out
+ // with an accumulator that is "too large".
+
+ /// @todo Strictly speaking, introProxy doesn't *need* to free
+ /// memory, then this wouldn't have to reallocate CNFExpr
+
+ /// @todo When this call to introProxy is made, the semantic
+ /// negation pointer will have been destroyed. Thus, it will not
+ /// be possible to use the correct proxy. That should be fixed.
+
+ // at this point, we will either have NULL, or a destructible expression
+ if (getClauseSizeCNF(accum) > CLAUSE_MAX)
+ accum = allocCNFExprLiteral(introProxy(cnf, largestEdge, accum, isNegEdge(largestEdge)));
+
+ int i = getSizeVectorEdge(&cnf->args);
+ while (i != 0) {
+ Edge arg = getVectorEdge(&cnf->args, --i);
+ Node *narg = getNodePtrFromEdge(arg);
+ if (edgeIsVarConst(arg)) {
+ disjoinCNFLit(accum, getEdgeVar(arg));
+ } else {
+ CNFExpr *argExp = (CNFExpr *) narg->ptrAnnot[isNegEdge(arg)];
+
+ bool destroy = (--narg->intAnnot[isNegEdge(arg)] == 0);
+ if (isProxy(argExp)) {// variable has been introduced
+ disjoinCNFLit(accum, getProxy(argExp));
+ } else if (argExp->litSize == 0) {
+ disjoinCNFExpr(accum, argExp, destroy);
+ } else {
+ // check to see if we should introduce a proxy
+ int aL = accum->litSize; // lits in accum
+ int eL = argExp->litSize; // lits in argument
+ int aC = getClauseSizeCNF(accum); // clauses in accum
+ int eC = getClauseSizeCNF(argExp); // clauses in argument
+
+ if (eC > CLAUSE_MAX || (eL * aC + aL * eC > eL + aC + aL + aC)) {
+ disjoinCNFLit(accum, introProxy(cnf, arg, argExp, isNegEdge(arg)));
+ } else {
+ disjoinCNFExpr(accum, argExp, destroy);
+ if (destroy) narg->ptrAnnot[isNegEdge(arg)] = NULL;
+ }
+ }
+ }
+ }
+
+ return accum;
+}
+
+Edge generateBinaryConstraint(CNF *cnf, uint numvars, Edge *vars, uint value) {
+ Edge carray[numvars];
+ for (uint j = 0; j < numvars; j++) {
+ carray[j] = ((value & 1) == 1) ? vars[j] : constraintNegate(vars[j]);
+ value = value >> 1;
+ }
+
+ return constraintAND(cnf, numvars, carray);
+}
+
+/** Generates a constraint to ensure that all encodings are less than value */
+Edge generateLTValueConstraint(CNF *cnf, uint numvars, Edge *vars, uint value) {
+ Edge orarray[numvars];
+ Edge andarray[numvars];
+ uint andi = 0;
+
+ while (true) {
+ uint val = value;
+ uint ori = 0;
+ for (uint j = 0; j < numvars; j++) {
+ if ((val & 1) == 1)
+ orarray[ori++] = constraintNegate(vars[j]);
+ val = val >> 1;
+ }
+ //no ones to flip, so bail now...
+ if (ori == 0) {
+ return constraintAND(cnf, andi, andarray);
+ }
+ andarray[andi++] = constraintOR(cnf, ori, orarray);
+
+ value = value + (1 << (__builtin_ctz(value)));
+ //flip the last one
+ }
+}
+
+Edge generateEquivNVConstraint(CNF *cnf, uint numvars, Edge *var1, Edge *var2) {
+ if (numvars == 0)
+ return E_True;
+ Edge array[numvars];
+ for (uint i = 0; i < numvars; i++) {
+ array[i] = constraintIFF(cnf, var1[i], var2[i]);
+ }
+ return constraintAND(cnf, numvars, array);
+}
+
+Edge generateLTConstraint(CNF *cnf, uint numvars, Edge *var1, Edge *var2){
+ if(numvars == 0 )
+ return E_False;
+ Edge result =constraintAND2(cnf, constraintNegate( var1[0]), var2[0]);
+ for (uint i = 1; i < numvars; i++) {
+ Edge lt = constraintAND2(cnf, constraintNegate( var1[i]), var2[i]);
+ Edge eq = constraintAND2(cnf, constraintIFF(cnf, var1[i], var2[i]), result);
+ result = constraintOR2(cnf, lt, eq);
+ }
+ return result;
+}
+
+Edge generateLTEConstraint(CNF *cnf, uint numvars, Edge *var1, Edge *var2){
+ if(numvars == 0 )
+ return E_True;
+ Edge result =constraintIMPLIES(cnf, var1[0], var2[0]);
+ for (uint i = 1; i < numvars; i++) {
+ Edge lt = constraintAND2(cnf, constraintNegate( var1[i]), var2[i]);
+ Edge eq = constraintAND2(cnf, constraintIFF(cnf, var1[i], var2[i]), result);
+ result = constraintOR2(cnf, lt, eq);
+ }
+ return result;
+}
+++ /dev/null
-/* Copyright (c) 2015 Regents of the University of California
- *
- * Author: Brian Demsky <bdemsky@uci.edu>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- */
-
-#include "inc_solver.h"
-#define SATSOLVER "sat_solver"
-#include <fcntl.h>
-#include "common.h"
-#include <string.h>
-
-IncrementalSolver *allocIncrementalSolver() {
- IncrementalSolver *This = (IncrementalSolver *)ourmalloc(sizeof(IncrementalSolver));
- This->buffer = ((int *)ourmalloc(sizeof(int) * IS_BUFFERSIZE));
- This->solution = NULL;
- This->solutionsize = 0;
- This->offset = 0;
- createSolver(This);
- return This;
-}
-
-void deleteIncrementalSolver(IncrementalSolver *This) {
- killSolver(This);
- ourfree(This->buffer);
- if (This->solution != NULL)
- ourfree(This->solution);
- ourfree(This);
-}
-
-void resetSolver(IncrementalSolver *This) {
- killSolver(This);
- This->offset = 0;
- createSolver(This);
-}
-
-void addClauseLiteral(IncrementalSolver *This, int literal) {
- This->buffer[This->offset++] = literal;
- if (This->offset == IS_BUFFERSIZE) {
- flushBufferSolver(This);
- }
-}
-
-void addArrayClauseLiteral(IncrementalSolver *This, uint numliterals, int *literals) {
- uint index = 0;
- while (true) {
- uint bufferspace = IS_BUFFERSIZE - This->offset;
- uint numtowrite = numliterals - index;
- if (bufferspace > numtowrite) {
- memcpy(&This->buffer[This->offset], &literals[index], numtowrite * sizeof(int));
- This->offset += numtowrite;
- This->buffer[This->offset++] = 0; //have one extra spot always
- if (This->offset == IS_BUFFERSIZE) {//Check if full
- flushBufferSolver(This);
- }
- return;
- } else {
- memcpy(&This->buffer[This->offset], &literals[index], bufferspace * sizeof(int));
- This->offset += bufferspace;
- index += bufferspace;
- flushBufferSolver(This);
- }
- }
-}
-
-void finishedClauses(IncrementalSolver *This) {
- addClauseLiteral(This, 0);
-}
-
-void freeze(IncrementalSolver *This, int variable) {
- addClauseLiteral(This, IS_FREEZE);
- addClauseLiteral(This, variable);
-}
-
-int solve(IncrementalSolver *This) {
- //add an empty clause
- startSolve(This);
- return getSolution(This);
-}
-
-void startSolve(IncrementalSolver *This) {
- addClauseLiteral(This, IS_RUNSOLVER);
- flushBufferSolver(This);
-}
-
-int getSolution(IncrementalSolver *This) {
- int result = readIntSolver(This);
- if (result == IS_SAT) {
- int numVars = readIntSolver(This);
- if (numVars > This->solutionsize) {
- if (This->solution != NULL)
- ourfree(This->solution);
- This->solution = (int *) ourmalloc((numVars + 1) * sizeof(int));
- This->solution[0] = 0;
- }
- readSolver(This, &This->solution[1], numVars * sizeof(int));
- This->solutionsize = numVars;
- }
- return result;
-}
-
-int readIntSolver(IncrementalSolver *This) {
- int value;
- readSolver(This, &value, 4);
- return value;
-}
-
-void readSolver(IncrementalSolver *This, void *tmp, ssize_t size) {
- char *result = (char *) tmp;
- ssize_t bytestoread = size;
- ssize_t bytesread = 0;
- do {
- ssize_t n = read(This->from_solver_fd, &((char *)result)[bytesread], bytestoread);
- if (n == -1) {
- model_print("Read failure\n");
- exit(-1);
- }
- bytestoread -= n;
- bytesread += n;
- } while (bytestoread != 0);
-}
-
-bool getValueSolver(IncrementalSolver *This, int variable) {
- return This->solution[variable];
-}
-
-void createSolver(IncrementalSolver *This) {
- int to_pipe[2];
- int from_pipe[2];
- if (pipe(to_pipe) || pipe(from_pipe)) {
- model_print("Error creating pipe.\n");
- exit(-1);
- }
- if ((This->solver_pid = fork()) == -1) {
- model_print("Error forking.\n");
- exit(-1);
- }
- if (This->solver_pid == 0) {
- //Solver process
- close(to_pipe[1]);
- close(from_pipe[0]);
- int fd = open("log_file", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
-
- if ((dup2(to_pipe[0], 0) == -1) ||
- (dup2(from_pipe[1], IS_OUT_FD) == -1) ||
- (dup2(fd, 1) == -1)) {
- model_print("Error duplicating pipes\n");
- }
- // setsid();
- execlp(SATSOLVER, SATSOLVER, NULL);
- model_print("execlp Failed\n");
- close(fd);
- } else {
- //Our process
- This->to_solver_fd = to_pipe[1];
- This->from_solver_fd = from_pipe[0];
- close(to_pipe[0]);
- close(from_pipe[1]);
- }
-}
-
-void killSolver(IncrementalSolver *This) {
- close(This->to_solver_fd);
- close(This->from_solver_fd);
- //Stop the solver
- if (This->solver_pid > 0) {
- int status;
- kill(This->solver_pid, SIGKILL);
- waitpid(This->solver_pid, &status, 0);
- }
-}
-
-//DEBUGGING CODE STARTS
-bool first = true;
-//DEBUGGING CODE ENDS
-
-void flushBufferSolver(IncrementalSolver *This) {
- ssize_t bytestowrite = sizeof(int) * This->offset;
- ssize_t byteswritten = 0;
- //DEBUGGING CODE STARTS
- for (uint i = 0; i < This->offset; i++) {
- if (first)
- printf("(");
- if (This->buffer[i] == 0) {
- printf(")\n");
- first = true;
- } else {
- if (!first)
- printf(" + ");
- first = false;
- printf("%d", This->buffer[i]);
- }
- }
- //DEBUGGING CODE ENDS
- do {
- ssize_t n = write(This->to_solver_fd, &((char *)This->buffer)[byteswritten], bytestowrite);
- if (n == -1) {
- perror("Write failure\n");
- model_print("to_solver_fd=%d\n",This->to_solver_fd);
- exit(-1);
- }
- bytestowrite -= n;
- byteswritten += n;
- } while (bytestowrite != 0);
- This->offset = 0;
-}
--- /dev/null
+/* Copyright (c) 2015 Regents of the University of California
+ *
+ * Author: Brian Demsky <bdemsky@uci.edu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#include "inc_solver.h"
+#define SATSOLVER "sat_solver"
+#include <fcntl.h>
+#include "common.h"
+#include <string.h>
+
+IncrementalSolver *allocIncrementalSolver() {
+ IncrementalSolver *This = (IncrementalSolver *)ourmalloc(sizeof(IncrementalSolver));
+ This->buffer = ((int *)ourmalloc(sizeof(int) * IS_BUFFERSIZE));
+ This->solution = NULL;
+ This->solutionsize = 0;
+ This->offset = 0;
+ createSolver(This);
+ return This;
+}
+
+void deleteIncrementalSolver(IncrementalSolver *This) {
+ killSolver(This);
+ ourfree(This->buffer);
+ if (This->solution != NULL)
+ ourfree(This->solution);
+ ourfree(This);
+}
+
+void resetSolver(IncrementalSolver *This) {
+ killSolver(This);
+ This->offset = 0;
+ createSolver(This);
+}
+
+void addClauseLiteral(IncrementalSolver *This, int literal) {
+ This->buffer[This->offset++] = literal;
+ if (This->offset == IS_BUFFERSIZE) {
+ flushBufferSolver(This);
+ }
+}
+
+void addArrayClauseLiteral(IncrementalSolver *This, uint numliterals, int *literals) {
+ uint index = 0;
+ while (true) {
+ uint bufferspace = IS_BUFFERSIZE - This->offset;
+ uint numtowrite = numliterals - index;
+ if (bufferspace > numtowrite) {
+ memcpy(&This->buffer[This->offset], &literals[index], numtowrite * sizeof(int));
+ This->offset += numtowrite;
+ This->buffer[This->offset++] = 0; //have one extra spot always
+ if (This->offset == IS_BUFFERSIZE) {//Check if full
+ flushBufferSolver(This);
+ }
+ return;
+ } else {
+ memcpy(&This->buffer[This->offset], &literals[index], bufferspace * sizeof(int));
+ This->offset += bufferspace;
+ index += bufferspace;
+ flushBufferSolver(This);
+ }
+ }
+}
+
+void finishedClauses(IncrementalSolver *This) {
+ addClauseLiteral(This, 0);
+}
+
+void freeze(IncrementalSolver *This, int variable) {
+ addClauseLiteral(This, IS_FREEZE);
+ addClauseLiteral(This, variable);
+}
+
+int solve(IncrementalSolver *This) {
+ //add an empty clause
+ startSolve(This);
+ return getSolution(This);
+}
+
+void startSolve(IncrementalSolver *This) {
+ addClauseLiteral(This, IS_RUNSOLVER);
+ flushBufferSolver(This);
+}
+
+int getSolution(IncrementalSolver *This) {
+ int result = readIntSolver(This);
+ if (result == IS_SAT) {
+ int numVars = readIntSolver(This);
+ if (numVars > This->solutionsize) {
+ if (This->solution != NULL)
+ ourfree(This->solution);
+ This->solution = (int *) ourmalloc((numVars + 1) * sizeof(int));
+ This->solution[0] = 0;
+ }
+ readSolver(This, &This->solution[1], numVars * sizeof(int));
+ This->solutionsize = numVars;
+ }
+ return result;
+}
+
+int readIntSolver(IncrementalSolver *This) {
+ int value;
+ readSolver(This, &value, 4);
+ return value;
+}
+
+void readSolver(IncrementalSolver *This, void *tmp, ssize_t size) {
+ char *result = (char *) tmp;
+ ssize_t bytestoread = size;
+ ssize_t bytesread = 0;
+ do {
+ ssize_t n = read(This->from_solver_fd, &((char *)result)[bytesread], bytestoread);
+ if (n == -1) {
+ model_print("Read failure\n");
+ exit(-1);
+ }
+ bytestoread -= n;
+ bytesread += n;
+ } while (bytestoread != 0);
+}
+
+bool getValueSolver(IncrementalSolver *This, int variable) {
+ return This->solution[variable];
+}
+
+void createSolver(IncrementalSolver *This) {
+ int to_pipe[2];
+ int from_pipe[2];
+ if (pipe(to_pipe) || pipe(from_pipe)) {
+ model_print("Error creating pipe.\n");
+ exit(-1);
+ }
+ if ((This->solver_pid = fork()) == -1) {
+ model_print("Error forking.\n");
+ exit(-1);
+ }
+ if (This->solver_pid == 0) {
+ //Solver process
+ close(to_pipe[1]);
+ close(from_pipe[0]);
+ int fd = open("log_file", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
+
+ if ((dup2(to_pipe[0], 0) == -1) ||
+ (dup2(from_pipe[1], IS_OUT_FD) == -1) ||
+ (dup2(fd, 1) == -1)) {
+ model_print("Error duplicating pipes\n");
+ }
+ // setsid();
+ execlp(SATSOLVER, SATSOLVER, NULL);
+ model_print("execlp Failed\n");
+ close(fd);
+ } else {
+ //Our process
+ This->to_solver_fd = to_pipe[1];
+ This->from_solver_fd = from_pipe[0];
+ close(to_pipe[0]);
+ close(from_pipe[1]);
+ }
+}
+
+void killSolver(IncrementalSolver *This) {
+ close(This->to_solver_fd);
+ close(This->from_solver_fd);
+ //Stop the solver
+ if (This->solver_pid > 0) {
+ int status;
+ kill(This->solver_pid, SIGKILL);
+ waitpid(This->solver_pid, &status, 0);
+ }
+}
+
+//DEBUGGING CODE STARTS
+bool first = true;
+//DEBUGGING CODE ENDS
+
+void flushBufferSolver(IncrementalSolver *This) {
+ ssize_t bytestowrite = sizeof(int) * This->offset;
+ ssize_t byteswritten = 0;
+ //DEBUGGING CODE STARTS
+ for (uint i = 0; i < This->offset; i++) {
+ if (first)
+ printf("(");
+ if (This->buffer[i] == 0) {
+ printf(")\n");
+ first = true;
+ } else {
+ if (!first)
+ printf(" + ");
+ first = false;
+ printf("%d", This->buffer[i]);
+ }
+ }
+ //DEBUGGING CODE ENDS
+ do {
+ ssize_t n = write(This->to_solver_fd, &((char *)This->buffer)[byteswritten], bytestowrite);
+ if (n == -1) {
+ perror("Write failure\n");
+ model_print("to_solver_fd=%d\n",This->to_solver_fd);
+ exit(-1);
+ }
+ bytestowrite -= n;
+ byteswritten += n;
+ } while (bytestowrite != 0);
+ This->offset = 0;
+}
+++ /dev/null
-#include "orderelement.h"
-
-
-OrderElement *allocOrderElement(uint64_t item, Element* elem) {
- OrderElement *This = (OrderElement *) ourmalloc(sizeof(OrderElement));
- This->elem = elem;
- This->item = item;
- return This;
-}
-
-void deleteOrderElement(OrderElement *pair) {
- ourfree(pair);
-}
--- /dev/null
+#include "orderelement.h"
+
+
+OrderElement *allocOrderElement(uint64_t item, Element* elem) {
+ OrderElement *This = (OrderElement *) ourmalloc(sizeof(OrderElement));
+ This->elem = elem;
+ This->item = item;
+ return This;
+}
+
+void deleteOrderElement(OrderElement *pair) {
+ ourfree(pair);
+}
+++ /dev/null
-#include "orderpair.h"
-
-
-OrderPair *allocOrderPair(uint64_t first, uint64_t second, Edge constraint) {
- OrderPair *pair = (OrderPair *) ourmalloc(sizeof(OrderPair));
- pair->first = first;
- pair->second = second;
- pair->constraint = constraint;
- return pair;
-}
-
-void deleteOrderPair(OrderPair *pair) {
- ourfree(pair);
-}
--- /dev/null
+#include "orderpair.h"
+
+
+OrderPair *allocOrderPair(uint64_t first, uint64_t second, Edge constraint) {
+ OrderPair *pair = (OrderPair *) ourmalloc(sizeof(OrderPair));
+ pair->first = first;
+ pair->second = second;
+ pair->constraint = constraint;
+ return pair;
+}
+
+void deleteOrderPair(OrderPair *pair) {
+ ourfree(pair);
+}
+++ /dev/null
-#include "satencoder.h"
-#include "structs.h"
-#include "common.h"
-#include "ops.h"
-#include "element.h"
-#include "set.h"
-
-Edge getElementValueConstraint(SATEncoder *This, Element *elem, uint64_t value) {
- switch (getElementEncoding(elem)->type) {
- case ONEHOT:
- return getElementValueOneHotConstraint(This, elem, value);
- case UNARY:
- return getElementValueUnaryConstraint(This, elem, value);
- case BINARYINDEX:
- return getElementValueBinaryIndexConstraint(This, elem, value);
- case ONEHOTBINARY:
- ASSERT(0);
- break;
- case BINARYVAL:
- return getElementValueBinaryValueConstraint(This, elem, value);
- break;
- default:
- ASSERT(0);
- break;
- }
- return E_BOGUS;
-}
-
-Edge getElementValueBinaryIndexConstraint(SATEncoder *This, Element *elem, uint64_t value) {
- ASTNodeType type = GETELEMENTTYPE(elem);
- ASSERT(type == ELEMSET || type == ELEMFUNCRETURN || type == ELEMCONST);
- ElementEncoding *elemEnc = getElementEncoding(elem);
- for (uint i = 0; i < elemEnc->encArraySize; i++) {
- if (isinUseElement(elemEnc, i) && elemEnc->encodingArray[i] == value) {
- return (elemEnc->numVars == 0) ? E_True : generateBinaryConstraint(This->cnf, elemEnc->numVars, elemEnc->variables, i);
- }
- }
- return E_False;
-}
-
-Edge getElementValueOneHotConstraint(SATEncoder *This, Element *elem, uint64_t value) {
- ASTNodeType type = GETELEMENTTYPE(elem);
- ASSERT(type == ELEMSET || type == ELEMFUNCRETURN || type == ELEMCONST);
- ElementEncoding *elemEnc = getElementEncoding(elem);
- for (uint i = 0; i < elemEnc->encArraySize; i++) {
- if (isinUseElement(elemEnc, i) && elemEnc->encodingArray[i] == value) {
- return (elemEnc->numVars == 0) ? E_True : elemEnc->variables[i];
- }
- }
- return E_False;
-}
-
-Edge getElementValueUnaryConstraint(SATEncoder *This, Element *elem, uint64_t value) {
- ASTNodeType type = GETELEMENTTYPE(elem);
- ASSERT(type == ELEMSET || type == ELEMFUNCRETURN || type == ELEMCONST);
- ElementEncoding *elemEnc = getElementEncoding(elem);
- for (uint i = 0; i < elemEnc->encArraySize; i++) {
- if (isinUseElement(elemEnc, i) && elemEnc->encodingArray[i] == value) {
- if (elemEnc->numVars == 0)
- return E_True;
- if (i == 0)
- return constraintNegate(elemEnc->variables[0]);
- else if ((i + 1) == elemEnc->encArraySize)
- return elemEnc->variables[i - 1];
- else
- return constraintAND2(This->cnf, elemEnc->variables[i - 1], constraintNegate(elemEnc->variables[i]));
- }
- }
- return E_False;
-}
-
-Edge getElementValueBinaryValueConstraint(SATEncoder *This, Element *element, uint64_t value) {
- ASTNodeType type = GETELEMENTTYPE(element);
- ASSERT(type == ELEMSET || type == ELEMFUNCRETURN);
- ElementEncoding *elemEnc = getElementEncoding(element);
- if (elemEnc->low <= elemEnc->high) {
- if (value < elemEnc->low || value > elemEnc->high)
- return E_False;
- } else {
- //Range wraps around 0
- if (value < elemEnc->low && value > elemEnc->high)
- return E_False;
- }
-
- uint64_t valueminusoffset = value - elemEnc->offset;
- return generateBinaryConstraint(This->cnf, elemEnc->numVars, elemEnc->variables, valueminusoffset);
-}
-
-void allocElementConstraintVariables(ElementEncoding *This, uint numVars) {
- This->numVars = numVars;
- This->variables = ourmalloc(sizeof(Edge) * numVars);
-}
-
-void generateBinaryValueEncodingVars(SATEncoder *This, ElementEncoding *encoding) {
- ASSERT(encoding->type == BINARYVAL);
- allocElementConstraintVariables(encoding, encoding->numBits);
- getArrayNewVarsSATEncoder(This, encoding->numVars, encoding->variables);
-}
-
-void generateBinaryIndexEncodingVars(SATEncoder *This, ElementEncoding *encoding) {
- ASSERT(encoding->type == BINARYINDEX);
- allocElementConstraintVariables(encoding, NUMBITS(encoding->encArraySize - 1));
- getArrayNewVarsSATEncoder(This, encoding->numVars, encoding->variables);
-}
-
-void generateOneHotEncodingVars(SATEncoder *This, ElementEncoding *encoding) {
- allocElementConstraintVariables(encoding, encoding->encArraySize);
- getArrayNewVarsSATEncoder(This, encoding->numVars, encoding->variables);
- for (uint i = 0; i < encoding->numVars; i++) {
- for (uint j = i + 1; j < encoding->numVars; j++) {
- addConstraintCNF(This->cnf, constraintNegate(constraintAND2(This->cnf, encoding->variables[i], encoding->variables[j])));
- }
- }
- addConstraintCNF(This->cnf, constraintOR(This->cnf, encoding->numVars, encoding->variables));
-}
-
-void generateUnaryEncodingVars(SATEncoder *This, ElementEncoding *encoding) {
- allocElementConstraintVariables(encoding, encoding->encArraySize - 1);
- getArrayNewVarsSATEncoder(This, encoding->numVars, encoding->variables);
- //Add unary constraint
- for (uint i = 1; i < encoding->numVars; i++) {
- addConstraintCNF(This->cnf, constraintOR2(This->cnf, encoding->variables[i - 1], constraintNegate(encoding->variables[i])));
- }
-}
-
-void generateElementEncoding(SATEncoder *This, Element *element) {
- ElementEncoding *encoding = getElementEncoding(element);
- ASSERT(encoding->type != ELEM_UNASSIGNED);
- if (encoding->variables != NULL)
- return;
- switch (encoding->type) {
- case ONEHOT:
- generateOneHotEncodingVars(This, encoding);
- return;
- case BINARYINDEX:
- generateBinaryIndexEncodingVars(This, encoding);
- return;
- case UNARY:
- generateUnaryEncodingVars(This, encoding);
- return;
- case ONEHOTBINARY:
- return;
- case BINARYVAL:
- generateBinaryValueEncodingVars(This, encoding);
- return;
- default:
- ASSERT(0);
- }
-}
-
--- /dev/null
+#include "satencoder.h"
+#include "structs.h"
+#include "common.h"
+#include "ops.h"
+#include "element.h"
+#include "set.h"
+
+Edge getElementValueConstraint(SATEncoder *This, Element *elem, uint64_t value) {
+ switch (getElementEncoding(elem)->type) {
+ case ONEHOT:
+ return getElementValueOneHotConstraint(This, elem, value);
+ case UNARY:
+ return getElementValueUnaryConstraint(This, elem, value);
+ case BINARYINDEX:
+ return getElementValueBinaryIndexConstraint(This, elem, value);
+ case ONEHOTBINARY:
+ ASSERT(0);
+ break;
+ case BINARYVAL:
+ return getElementValueBinaryValueConstraint(This, elem, value);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ return E_BOGUS;
+}
+
+Edge getElementValueBinaryIndexConstraint(SATEncoder *This, Element *elem, uint64_t value) {
+ ASTNodeType type = GETELEMENTTYPE(elem);
+ ASSERT(type == ELEMSET || type == ELEMFUNCRETURN || type == ELEMCONST);
+ ElementEncoding *elemEnc = getElementEncoding(elem);
+ for (uint i = 0; i < elemEnc->encArraySize; i++) {
+ if (isinUseElement(elemEnc, i) && elemEnc->encodingArray[i] == value) {
+ return (elemEnc->numVars == 0) ? E_True : generateBinaryConstraint(This->cnf, elemEnc->numVars, elemEnc->variables, i);
+ }
+ }
+ return E_False;
+}
+
+Edge getElementValueOneHotConstraint(SATEncoder *This, Element *elem, uint64_t value) {
+ ASTNodeType type = GETELEMENTTYPE(elem);
+ ASSERT(type == ELEMSET || type == ELEMFUNCRETURN || type == ELEMCONST);
+ ElementEncoding *elemEnc = getElementEncoding(elem);
+ for (uint i = 0; i < elemEnc->encArraySize; i++) {
+ if (isinUseElement(elemEnc, i) && elemEnc->encodingArray[i] == value) {
+ return (elemEnc->numVars == 0) ? E_True : elemEnc->variables[i];
+ }
+ }
+ return E_False;
+}
+
+Edge getElementValueUnaryConstraint(SATEncoder *This, Element *elem, uint64_t value) {
+ ASTNodeType type = GETELEMENTTYPE(elem);
+ ASSERT(type == ELEMSET || type == ELEMFUNCRETURN || type == ELEMCONST);
+ ElementEncoding *elemEnc = getElementEncoding(elem);
+ for (uint i = 0; i < elemEnc->encArraySize; i++) {
+ if (isinUseElement(elemEnc, i) && elemEnc->encodingArray[i] == value) {
+ if (elemEnc->numVars == 0)
+ return E_True;
+ if (i == 0)
+ return constraintNegate(elemEnc->variables[0]);
+ else if ((i + 1) == elemEnc->encArraySize)
+ return elemEnc->variables[i - 1];
+ else
+ return constraintAND2(This->cnf, elemEnc->variables[i - 1], constraintNegate(elemEnc->variables[i]));
+ }
+ }
+ return E_False;
+}
+
+Edge getElementValueBinaryValueConstraint(SATEncoder *This, Element *element, uint64_t value) {
+ ASTNodeType type = GETELEMENTTYPE(element);
+ ASSERT(type == ELEMSET || type == ELEMFUNCRETURN);
+ ElementEncoding *elemEnc = getElementEncoding(element);
+ if (elemEnc->low <= elemEnc->high) {
+ if (value < elemEnc->low || value > elemEnc->high)
+ return E_False;
+ } else {
+ //Range wraps around 0
+ if (value < elemEnc->low && value > elemEnc->high)
+ return E_False;
+ }
+
+ uint64_t valueminusoffset = value - elemEnc->offset;
+ return generateBinaryConstraint(This->cnf, elemEnc->numVars, elemEnc->variables, valueminusoffset);
+}
+
+void allocElementConstraintVariables(ElementEncoding *This, uint numVars) {
+ This->numVars = numVars;
+ This->variables = (Edge *)ourmalloc(sizeof(Edge) * numVars);
+}
+
+void generateBinaryValueEncodingVars(SATEncoder *This, ElementEncoding *encoding) {
+ ASSERT(encoding->type == BINARYVAL);
+ allocElementConstraintVariables(encoding, encoding->numBits);
+ getArrayNewVarsSATEncoder(This, encoding->numVars, encoding->variables);
+}
+
+void generateBinaryIndexEncodingVars(SATEncoder *This, ElementEncoding *encoding) {
+ ASSERT(encoding->type == BINARYINDEX);
+ allocElementConstraintVariables(encoding, NUMBITS(encoding->encArraySize - 1));
+ getArrayNewVarsSATEncoder(This, encoding->numVars, encoding->variables);
+}
+
+void generateOneHotEncodingVars(SATEncoder *This, ElementEncoding *encoding) {
+ allocElementConstraintVariables(encoding, encoding->encArraySize);
+ getArrayNewVarsSATEncoder(This, encoding->numVars, encoding->variables);
+ for (uint i = 0; i < encoding->numVars; i++) {
+ for (uint j = i + 1; j < encoding->numVars; j++) {
+ addConstraintCNF(This->cnf, constraintNegate(constraintAND2(This->cnf, encoding->variables[i], encoding->variables[j])));
+ }
+ }
+ addConstraintCNF(This->cnf, constraintOR(This->cnf, encoding->numVars, encoding->variables));
+}
+
+void generateUnaryEncodingVars(SATEncoder *This, ElementEncoding *encoding) {
+ allocElementConstraintVariables(encoding, encoding->encArraySize - 1);
+ getArrayNewVarsSATEncoder(This, encoding->numVars, encoding->variables);
+ //Add unary constraint
+ for (uint i = 1; i < encoding->numVars; i++) {
+ addConstraintCNF(This->cnf, constraintOR2(This->cnf, encoding->variables[i - 1], constraintNegate(encoding->variables[i])));
+ }
+}
+
+void generateElementEncoding(SATEncoder *This, Element *element) {
+ ElementEncoding *encoding = getElementEncoding(element);
+ ASSERT(encoding->type != ELEM_UNASSIGNED);
+ if (encoding->variables != NULL)
+ return;
+ switch (encoding->type) {
+ case ONEHOT:
+ generateOneHotEncodingVars(This, encoding);
+ return;
+ case BINARYINDEX:
+ generateBinaryIndexEncodingVars(This, encoding);
+ return;
+ case UNARY:
+ generateUnaryEncodingVars(This, encoding);
+ return;
+ case ONEHOTBINARY:
+ return;
+ case BINARYVAL:
+ generateBinaryValueEncodingVars(This, encoding);
+ return;
+ default:
+ ASSERT(0);
+ }
+}
+
+++ /dev/null
-#include "satencoder.h"
-#include "structs.h"
-#include "csolver.h"
-#include "boolean.h"
-#include "constraint.h"
-#include "common.h"
-#include "element.h"
-#include "function.h"
-#include "tableentry.h"
-#include "table.h"
-#include "order.h"
-#include "predicate.h"
-#include "set.h"
-#include "satfuncopencoder.h"
-
-//TODO: Should handle sharing of AST Nodes without recoding them a second time
-
-SATEncoder *allocSATEncoder(CSolver *solver) {
- SATEncoder *This = ourmalloc(sizeof (SATEncoder));
- This->solver = solver;
- This->varcount = 1;
- This->cnf = createCNF();
- return This;
-}
-
-void deleteSATEncoder(SATEncoder *This) {
- deleteCNF(This->cnf);
- ourfree(This);
-}
-
-void encodeAllSATEncoder(CSolver *csolver, SATEncoder *This) {
- HSIteratorBoolean *iterator=iteratorBoolean(csolver->constraints);
- while(hasNextBoolean(iterator)) {
- Boolean *constraint = nextBoolean(iterator);
- model_print("Encoding All ...\n\n");
- Edge c = encodeConstraintSATEncoder(This, constraint);
- model_print("Returned Constraint in EncodingAll:\n");
- addConstraintCNF(This->cnf, c);
- }
- deleteIterBoolean(iterator);
-}
-
-Edge encodeConstraintSATEncoder(SATEncoder *This, Boolean *constraint) {
- switch (GETBOOLEANTYPE(constraint)) {
- case ORDERCONST:
- return encodeOrderSATEncoder(This, (BooleanOrder *) constraint);
- case BOOLEANVAR:
- return encodeVarSATEncoder(This, (BooleanVar *) constraint);
- case LOGICOP:
- return encodeLogicSATEncoder(This, (BooleanLogic *) constraint);
- case PREDICATEOP:
- return encodePredicateSATEncoder(This, (BooleanPredicate *) constraint);
- default:
- model_print("Unhandled case in encodeConstraintSATEncoder %u", GETBOOLEANTYPE(constraint));
- exit(-1);
- }
-}
-
-void getArrayNewVarsSATEncoder(SATEncoder *encoder, uint num, Edge *carray) {
- for (uint i = 0; i < num; i++)
- carray[i] = getNewVarSATEncoder(encoder);
-}
-
-Edge getNewVarSATEncoder(SATEncoder *This) {
- return constraintNewVar(This->cnf);
-}
-
-Edge encodeVarSATEncoder(SATEncoder *This, BooleanVar *constraint) {
- if (edgeIsNull(constraint->var)) {
- constraint->var = getNewVarSATEncoder(This);
- }
- return constraint->var;
-}
-
-Edge encodeLogicSATEncoder(SATEncoder *This, BooleanLogic *constraint) {
- Edge array[getSizeArrayBoolean(&constraint->inputs)];
- for (uint i = 0; i < getSizeArrayBoolean(&constraint->inputs); i++)
- array[i] = encodeConstraintSATEncoder(This, getArrayBoolean(&constraint->inputs, i));
-
- switch (constraint->op) {
- case L_AND:
- return constraintAND(This->cnf, getSizeArrayBoolean(&constraint->inputs), array);
- case L_OR:
- return constraintOR(This->cnf, getSizeArrayBoolean(&constraint->inputs), array);
- case L_NOT:
- ASSERT( getSizeArrayBoolean(&constraint->inputs) == 1);
- return constraintNegate(array[0]);
- case L_XOR:
- ASSERT( getSizeArrayBoolean(&constraint->inputs) == 2);
- return constraintXOR(This->cnf, array[0], array[1]);
- case L_IMPLIES:
- ASSERT( getSizeArrayBoolean( &constraint->inputs) == 2);
- return constraintIMPLIES(This->cnf, array[0], array[1]);
- default:
- model_print("Unhandled case in encodeLogicSATEncoder %u", constraint->op);
- exit(-1);
- }
-}
-
-Edge encodePredicateSATEncoder(SATEncoder *This, BooleanPredicate *constraint) {
- switch (GETPREDICATETYPE(constraint->predicate) ) {
- case TABLEPRED:
- return encodeTablePredicateSATEncoder(This, constraint);
- case OPERATORPRED:
- return encodeOperatorPredicateSATEncoder(This, constraint);
- default:
- ASSERT(0);
- }
- return E_BOGUS;
-}
-
-Edge encodeTablePredicateSATEncoder(SATEncoder *This, BooleanPredicate *constraint) {
- switch (constraint->encoding.type) {
- case ENUMERATEIMPLICATIONS:
- case ENUMERATEIMPLICATIONSNEGATE:
- return encodeEnumTablePredicateSATEncoder(This, constraint);
- case CIRCUIT:
- ASSERT(0);
- break;
- default:
- ASSERT(0);
- }
- return E_BOGUS;
-}
-
-void encodeElementSATEncoder(SATEncoder *encoder, Element *This) {
- switch ( GETELEMENTTYPE(This) ) {
- case ELEMFUNCRETURN:
- generateElementEncoding(encoder, This);
- encodeElementFunctionSATEncoder(encoder, (ElementFunction *) This);
- break;
- case ELEMSET:
- generateElementEncoding(encoder, This);
- return;
- case ELEMCONST:
- return;
- default:
- ASSERT(0);
- }
-}
-
-void encodeElementFunctionSATEncoder(SATEncoder *encoder, ElementFunction *This) {
- switch (GETFUNCTIONTYPE(This->function)) {
- case TABLEFUNC:
- encodeTableElementFunctionSATEncoder(encoder, This);
- break;
- case OPERATORFUNC:
- encodeOperatorElementFunctionSATEncoder(encoder, This);
- break;
- default:
- ASSERT(0);
- }
-}
-
-void encodeTableElementFunctionSATEncoder(SATEncoder *encoder, ElementFunction *This) {
- switch (getElementFunctionEncoding(This)->type) {
- case ENUMERATEIMPLICATIONS:
- encodeEnumTableElemFunctionSATEncoder(encoder, This);
- break;
- case CIRCUIT:
- ASSERT(0);
- break;
- default:
- ASSERT(0);
- }
-}
--- /dev/null
+#include "satencoder.h"
+#include "structs.h"
+#include "csolver.h"
+#include "boolean.h"
+#include "constraint.h"
+#include "common.h"
+#include "element.h"
+#include "function.h"
+#include "tableentry.h"
+#include "table.h"
+#include "order.h"
+#include "predicate.h"
+#include "set.h"
+#include "satfuncopencoder.h"
+
+//TODO: Should handle sharing of AST Nodes without recoding them a second time
+
+SATEncoder *allocSATEncoder(CSolver *solver) {
+ SATEncoder *This = (SATEncoder *)ourmalloc(sizeof (SATEncoder));
+ This->solver = solver;
+ This->varcount = 1;
+ This->cnf = createCNF();
+ return This;
+}
+
+void deleteSATEncoder(SATEncoder *This) {
+ deleteCNF(This->cnf);
+ ourfree(This);
+}
+
+void encodeAllSATEncoder(CSolver *csolver, SATEncoder *This) {
+ HSIteratorBoolean *iterator=iteratorBoolean(csolver->constraints);
+ while(hasNextBoolean(iterator)) {
+ Boolean *constraint = nextBoolean(iterator);
+ model_print("Encoding All ...\n\n");
+ Edge c = encodeConstraintSATEncoder(This, constraint);
+ model_print("Returned Constraint in EncodingAll:\n");
+ addConstraintCNF(This->cnf, c);
+ }
+ deleteIterBoolean(iterator);
+}
+
+Edge encodeConstraintSATEncoder(SATEncoder *This, Boolean *constraint) {
+ switch (GETBOOLEANTYPE(constraint)) {
+ case ORDERCONST:
+ return encodeOrderSATEncoder(This, (BooleanOrder *) constraint);
+ case BOOLEANVAR:
+ return encodeVarSATEncoder(This, (BooleanVar *) constraint);
+ case LOGICOP:
+ return encodeLogicSATEncoder(This, (BooleanLogic *) constraint);
+ case PREDICATEOP:
+ return encodePredicateSATEncoder(This, (BooleanPredicate *) constraint);
+ default:
+ model_print("Unhandled case in encodeConstraintSATEncoder %u", GETBOOLEANTYPE(constraint));
+ exit(-1);
+ }
+}
+
+void getArrayNewVarsSATEncoder(SATEncoder *encoder, uint num, Edge *carray) {
+ for (uint i = 0; i < num; i++)
+ carray[i] = getNewVarSATEncoder(encoder);
+}
+
+Edge getNewVarSATEncoder(SATEncoder *This) {
+ return constraintNewVar(This->cnf);
+}
+
+Edge encodeVarSATEncoder(SATEncoder *This, BooleanVar *constraint) {
+ if (edgeIsNull(constraint->var)) {
+ constraint->var = getNewVarSATEncoder(This);
+ }
+ return constraint->var;
+}
+
+Edge encodeLogicSATEncoder(SATEncoder *This, BooleanLogic *constraint) {
+ Edge array[getSizeArrayBoolean(&constraint->inputs)];
+ for (uint i = 0; i < getSizeArrayBoolean(&constraint->inputs); i++)
+ array[i] = encodeConstraintSATEncoder(This, getArrayBoolean(&constraint->inputs, i));
+
+ switch (constraint->op) {
+ case L_AND:
+ return constraintAND(This->cnf, getSizeArrayBoolean(&constraint->inputs), array);
+ case L_OR:
+ return constraintOR(This->cnf, getSizeArrayBoolean(&constraint->inputs), array);
+ case L_NOT:
+ ASSERT( getSizeArrayBoolean(&constraint->inputs) == 1);
+ return constraintNegate(array[0]);
+ case L_XOR:
+ ASSERT( getSizeArrayBoolean(&constraint->inputs) == 2);
+ return constraintXOR(This->cnf, array[0], array[1]);
+ case L_IMPLIES:
+ ASSERT( getSizeArrayBoolean( &constraint->inputs) == 2);
+ return constraintIMPLIES(This->cnf, array[0], array[1]);
+ default:
+ model_print("Unhandled case in encodeLogicSATEncoder %u", constraint->op);
+ exit(-1);
+ }
+}
+
+Edge encodePredicateSATEncoder(SATEncoder *This, BooleanPredicate *constraint) {
+ switch (GETPREDICATETYPE(constraint->predicate) ) {
+ case TABLEPRED:
+ return encodeTablePredicateSATEncoder(This, constraint);
+ case OPERATORPRED:
+ return encodeOperatorPredicateSATEncoder(This, constraint);
+ default:
+ ASSERT(0);
+ }
+ return E_BOGUS;
+}
+
+Edge encodeTablePredicateSATEncoder(SATEncoder *This, BooleanPredicate *constraint) {
+ switch (constraint->encoding.type) {
+ case ENUMERATEIMPLICATIONS:
+ case ENUMERATEIMPLICATIONSNEGATE:
+ return encodeEnumTablePredicateSATEncoder(This, constraint);
+ case CIRCUIT:
+ ASSERT(0);
+ break;
+ default:
+ ASSERT(0);
+ }
+ return E_BOGUS;
+}
+
+void encodeElementSATEncoder(SATEncoder *encoder, Element *This) {
+ switch ( GETELEMENTTYPE(This) ) {
+ case ELEMFUNCRETURN:
+ generateElementEncoding(encoder, This);
+ encodeElementFunctionSATEncoder(encoder, (ElementFunction *) This);
+ break;
+ case ELEMSET:
+ generateElementEncoding(encoder, This);
+ return;
+ case ELEMCONST:
+ return;
+ default:
+ ASSERT(0);
+ }
+}
+
+void encodeElementFunctionSATEncoder(SATEncoder *encoder, ElementFunction *This) {
+ switch (GETFUNCTIONTYPE(This->function)) {
+ case TABLEFUNC:
+ encodeTableElementFunctionSATEncoder(encoder, This);
+ break;
+ case OPERATORFUNC:
+ encodeOperatorElementFunctionSATEncoder(encoder, This);
+ break;
+ default:
+ ASSERT(0);
+ }
+}
+
+void encodeTableElementFunctionSATEncoder(SATEncoder *encoder, ElementFunction *This) {
+ switch (getElementFunctionEncoding(This)->type) {
+ case ENUMERATEIMPLICATIONS:
+ encodeEnumTableElemFunctionSATEncoder(encoder, This);
+ break;
+ case CIRCUIT:
+ ASSERT(0);
+ break;
+ default:
+ ASSERT(0);
+ }
+}
+++ /dev/null
-#include "satencoder.h"
-#include "common.h"
-#include "function.h"
-#include "ops.h"
-#include "predicate.h"
-#include "boolean.h"
-#include "table.h"
-#include "tableentry.h"
-#include "set.h"
-#include "element.h"
-#include "common.h"
-#include "satfuncopencoder.h"
-
-Edge encodeOperatorPredicateSATEncoder(SATEncoder *This, BooleanPredicate *constraint) {
- switch (constraint->encoding.type) {
- case ENUMERATEIMPLICATIONS:
- return encodeEnumOperatorPredicateSATEncoder(This, constraint);
- case CIRCUIT:
- return encodeCircuitOperatorPredicateEncoder(This, constraint);
- default:
- ASSERT(0);
- }
- exit(-1);
-}
-
-Edge encodeEnumOperatorPredicateSATEncoder(SATEncoder *This, BooleanPredicate *constraint) {
- PredicateOperator *predicate = (PredicateOperator *)constraint->predicate;
- uint numDomains = getSizeArraySet(&predicate->domains);
-
- FunctionEncodingType encType = constraint->encoding.type;
- bool generateNegation = encType == ENUMERATEIMPLICATIONSNEGATE;
-
- /* Call base encoders for children */
- for (uint i = 0; i < numDomains; i++) {
- Element *elem = getArrayElement( &constraint->inputs, i);
- encodeElementSATEncoder(This, elem);
- }
- VectorEdge *clauses = allocDefVectorEdge(); // Setup array of clauses
-
- uint indices[numDomains]; //setup indices
- bzero(indices, sizeof(uint) * numDomains);
-
- uint64_t vals[numDomains];//setup value array
- for (uint i = 0; i < numDomains; i++) {
- Set *set = getArraySet(&predicate->domains, i);
- vals[i] = getSetElement(set, indices[i]);
- }
-
- bool notfinished = true;
- while (notfinished) {
- Edge carray[numDomains];
-
- if (evalPredicateOperator(predicate, vals) ^ generateNegation) {
- //Include this in the set of terms
- for (uint i = 0; i < numDomains; i++) {
- Element *elem = getArrayElement(&constraint->inputs, i);
- carray[i] = getElementValueConstraint(This, elem, vals[i]);
- }
- Edge term = constraintAND(This->cnf, numDomains, carray);
- pushVectorEdge(clauses, term);
- }
-
- notfinished = false;
- for (uint i = 0; i < numDomains; i++) {
- uint index = ++indices[i];
- Set *set = getArraySet(&predicate->domains, i);
-
- if (index < getSetSize(set)) {
- vals[i] = getSetElement(set, index);
- notfinished = true;
- break;
- } else {
- indices[i] = 0;
- vals[i] = getSetElement(set, 0);
- }
- }
- }
- if (getSizeVectorEdge(clauses) == 0) {
- deleteVectorEdge(clauses);
- return E_False;
- }
- Edge cor = constraintOR(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
- deleteVectorEdge(clauses);
- return generateNegation ? constraintNegate(cor) : cor;
-}
-
-
-void encodeOperatorElementFunctionSATEncoder(SATEncoder *This, ElementFunction *func) {
-#ifdef TRACE_DEBUG
- model_print("Operator Function ...\n");
-#endif
- FunctionOperator *function = (FunctionOperator *) func->function;
- uint numDomains = getSizeArrayElement(&func->inputs);
-
- /* Call base encoders for children */
- for (uint i = 0; i < numDomains; i++) {
- Element *elem = getArrayElement( &func->inputs, i);
- encodeElementSATEncoder(This, elem);
- }
-
- VectorEdge *clauses = allocDefVectorEdge(); // Setup array of clauses
-
- uint indices[numDomains]; //setup indices
- bzero(indices, sizeof(uint) * numDomains);
-
- uint64_t vals[numDomains];//setup value array
- for (uint i = 0; i < numDomains; i++) {
- Set *set = getElementSet(getArrayElement(&func->inputs, i));
- vals[i] = getSetElement(set, indices[i]);
- }
-
- Edge overFlowConstraint = ((BooleanVar *) func->overflowstatus)->var;
-
- bool notfinished = true;
- while (notfinished) {
- Edge carray[numDomains + 1];
-
- uint64_t result = applyFunctionOperator(function, numDomains, vals);
- bool isInRange = isInRangeFunction((FunctionOperator *)func->function, result);
- bool needClause = isInRange;
- if (function->overflowbehavior == OVERFLOWSETSFLAG || function->overflowbehavior == FLAGIFFOVERFLOW) {
- needClause = true;
- }
-
- if (needClause) {
- //Include this in the set of terms
- for (uint i = 0; i < numDomains; i++) {
- Element *elem = getArrayElement(&func->inputs, i);
- carray[i] = getElementValueConstraint(This, elem, vals[i]);
- }
- if (isInRange) {
- carray[numDomains] = getElementValueConstraint(This, &func->base, result);
- }
-
- Edge clause;
- switch (function->overflowbehavior) {
- case IGNORE:
- case NOOVERFLOW:
- case WRAPAROUND: {
- clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
- break;
- }
- case FLAGFORCESOVERFLOW: {
- clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintAND2(This->cnf, carray[numDomains], constraintNegate(overFlowConstraint)));
- break;
- }
- case OVERFLOWSETSFLAG: {
- if (isInRange) {
- clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
- } else {
- clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), overFlowConstraint);
- }
- break;
- }
- case FLAGIFFOVERFLOW: {
- if (isInRange) {
- clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintAND2(This->cnf, carray[numDomains], constraintNegate(overFlowConstraint)));
- } else {
- clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), overFlowConstraint);
- }
- break;
- }
- default:
- ASSERT(0);
- }
-#ifdef TRACE_DEBUG
- model_print("added clause in operator function\n");
- printCNF(clause);
- model_print("\n");
-#endif
- pushVectorEdge(clauses, clause);
- }
-
- notfinished = false;
- for (uint i = 0; i < numDomains; i++) {
- uint index = ++indices[i];
- Set *set = getElementSet(getArrayElement(&func->inputs, i));
-
- if (index < getSetSize(set)) {
- vals[i] = getSetElement(set, index);
- notfinished = true;
- break;
- } else {
- indices[i] = 0;
- vals[i] = getSetElement(set, 0);
- }
- }
- }
- if (getSizeVectorEdge(clauses) == 0) {
- deleteVectorEdge(clauses);
- return;
- }
- Edge cor = constraintAND(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
- addConstraintCNF(This->cnf, cor);
- deleteVectorEdge(clauses);
-}
-
-Edge encodeCircuitOperatorPredicateEncoder(SATEncoder *This, BooleanPredicate *constraint) {
- PredicateOperator *predicate = (PredicateOperator *) constraint->predicate;
- ASSERT(getSizeArraySet(&predicate->domains) == 2);
- Element *elem0 = getArrayElement( &constraint->inputs, 0);
- encodeElementSATEncoder(This, elem0);
- Element *elem1 = getArrayElement( &constraint->inputs, 1);
- encodeElementSATEncoder(This, elem1);
- ElementEncoding *ee0 = getElementEncoding(elem0);
- ElementEncoding *ee1 = getElementEncoding(elem1);
- ASSERT(ee0->numVars == ee1->numVars);
- uint numVars = ee0->numVars;
- switch (predicate->op) {
- case EQUALS:
- return generateEquivNVConstraint(This->cnf, numVars, ee0->variables, ee1->variables);
- case LT:
- return generateLTConstraint(This->cnf, numVars, ee0->variables, ee1->variables);
- case GT:
- return generateLTConstraint(This->cnf, numVars, ee1->variables, ee0->variables);
- default:
- ASSERT(0);
- }
- exit(-1);
-}
-
--- /dev/null
+#include "satencoder.h"
+#include "common.h"
+#include "function.h"
+#include "ops.h"
+#include "predicate.h"
+#include "boolean.h"
+#include "table.h"
+#include "tableentry.h"
+#include "set.h"
+#include "element.h"
+#include "common.h"
+#include "satfuncopencoder.h"
+
+Edge encodeOperatorPredicateSATEncoder(SATEncoder *This, BooleanPredicate *constraint) {
+ switch (constraint->encoding.type) {
+ case ENUMERATEIMPLICATIONS:
+ return encodeEnumOperatorPredicateSATEncoder(This, constraint);
+ case CIRCUIT:
+ return encodeCircuitOperatorPredicateEncoder(This, constraint);
+ default:
+ ASSERT(0);
+ }
+ exit(-1);
+}
+
+Edge encodeEnumOperatorPredicateSATEncoder(SATEncoder *This, BooleanPredicate *constraint) {
+ PredicateOperator *predicate = (PredicateOperator *)constraint->predicate;
+ uint numDomains = getSizeArraySet(&predicate->domains);
+
+ FunctionEncodingType encType = constraint->encoding.type;
+ bool generateNegation = encType == ENUMERATEIMPLICATIONSNEGATE;
+
+ /* Call base encoders for children */
+ for (uint i = 0; i < numDomains; i++) {
+ Element *elem = getArrayElement( &constraint->inputs, i);
+ encodeElementSATEncoder(This, elem);
+ }
+ VectorEdge *clauses = allocDefVectorEdge(); // Setup array of clauses
+
+ uint indices[numDomains]; //setup indices
+ bzero(indices, sizeof(uint) * numDomains);
+
+ uint64_t vals[numDomains];//setup value array
+ for (uint i = 0; i < numDomains; i++) {
+ Set *set = getArraySet(&predicate->domains, i);
+ vals[i] = getSetElement(set, indices[i]);
+ }
+
+ bool notfinished = true;
+ while (notfinished) {
+ Edge carray[numDomains];
+
+ if (evalPredicateOperator(predicate, vals) ^ generateNegation) {
+ //Include this in the set of terms
+ for (uint i = 0; i < numDomains; i++) {
+ Element *elem = getArrayElement(&constraint->inputs, i);
+ carray[i] = getElementValueConstraint(This, elem, vals[i]);
+ }
+ Edge term = constraintAND(This->cnf, numDomains, carray);
+ pushVectorEdge(clauses, term);
+ }
+
+ notfinished = false;
+ for (uint i = 0; i < numDomains; i++) {
+ uint index = ++indices[i];
+ Set *set = getArraySet(&predicate->domains, i);
+
+ if (index < getSetSize(set)) {
+ vals[i] = getSetElement(set, index);
+ notfinished = true;
+ break;
+ } else {
+ indices[i] = 0;
+ vals[i] = getSetElement(set, 0);
+ }
+ }
+ }
+ if (getSizeVectorEdge(clauses) == 0) {
+ deleteVectorEdge(clauses);
+ return E_False;
+ }
+ Edge cor = constraintOR(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
+ deleteVectorEdge(clauses);
+ return generateNegation ? constraintNegate(cor) : cor;
+}
+
+
+void encodeOperatorElementFunctionSATEncoder(SATEncoder *This, ElementFunction *func) {
+#ifdef TRACE_DEBUG
+ model_print("Operator Function ...\n");
+#endif
+ FunctionOperator *function = (FunctionOperator *) func->function;
+ uint numDomains = getSizeArrayElement(&func->inputs);
+
+ /* Call base encoders for children */
+ for (uint i = 0; i < numDomains; i++) {
+ Element *elem = getArrayElement( &func->inputs, i);
+ encodeElementSATEncoder(This, elem);
+ }
+
+ VectorEdge *clauses = allocDefVectorEdge(); // Setup array of clauses
+
+ uint indices[numDomains]; //setup indices
+ bzero(indices, sizeof(uint) * numDomains);
+
+ uint64_t vals[numDomains];//setup value array
+ for (uint i = 0; i < numDomains; i++) {
+ Set *set = getElementSet(getArrayElement(&func->inputs, i));
+ vals[i] = getSetElement(set, indices[i]);
+ }
+
+ Edge overFlowConstraint = ((BooleanVar *) func->overflowstatus)->var;
+
+ bool notfinished = true;
+ while (notfinished) {
+ Edge carray[numDomains + 1];
+
+ uint64_t result = applyFunctionOperator(function, numDomains, vals);
+ bool isInRange = isInRangeFunction((FunctionOperator *)func->function, result);
+ bool needClause = isInRange;
+ if (function->overflowbehavior == OVERFLOWSETSFLAG || function->overflowbehavior == FLAGIFFOVERFLOW) {
+ needClause = true;
+ }
+
+ if (needClause) {
+ //Include this in the set of terms
+ for (uint i = 0; i < numDomains; i++) {
+ Element *elem = getArrayElement(&func->inputs, i);
+ carray[i] = getElementValueConstraint(This, elem, vals[i]);
+ }
+ if (isInRange) {
+ carray[numDomains] = getElementValueConstraint(This, &func->base, result);
+ }
+
+ Edge clause;
+ switch (function->overflowbehavior) {
+ case IGNORE:
+ case NOOVERFLOW:
+ case WRAPAROUND: {
+ clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
+ break;
+ }
+ case FLAGFORCESOVERFLOW: {
+ clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintAND2(This->cnf, carray[numDomains], constraintNegate(overFlowConstraint)));
+ break;
+ }
+ case OVERFLOWSETSFLAG: {
+ if (isInRange) {
+ clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
+ } else {
+ clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), overFlowConstraint);
+ }
+ break;
+ }
+ case FLAGIFFOVERFLOW: {
+ if (isInRange) {
+ clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintAND2(This->cnf, carray[numDomains], constraintNegate(overFlowConstraint)));
+ } else {
+ clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), overFlowConstraint);
+ }
+ break;
+ }
+ default:
+ ASSERT(0);
+ }
+#ifdef TRACE_DEBUG
+ model_print("added clause in operator function\n");
+ printCNF(clause);
+ model_print("\n");
+#endif
+ pushVectorEdge(clauses, clause);
+ }
+
+ notfinished = false;
+ for (uint i = 0; i < numDomains; i++) {
+ uint index = ++indices[i];
+ Set *set = getElementSet(getArrayElement(&func->inputs, i));
+
+ if (index < getSetSize(set)) {
+ vals[i] = getSetElement(set, index);
+ notfinished = true;
+ break;
+ } else {
+ indices[i] = 0;
+ vals[i] = getSetElement(set, 0);
+ }
+ }
+ }
+ if (getSizeVectorEdge(clauses) == 0) {
+ deleteVectorEdge(clauses);
+ return;
+ }
+ Edge cor = constraintAND(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
+ addConstraintCNF(This->cnf, cor);
+ deleteVectorEdge(clauses);
+}
+
+Edge encodeCircuitOperatorPredicateEncoder(SATEncoder *This, BooleanPredicate *constraint) {
+ PredicateOperator *predicate = (PredicateOperator *) constraint->predicate;
+ ASSERT(getSizeArraySet(&predicate->domains) == 2);
+ Element *elem0 = getArrayElement( &constraint->inputs, 0);
+ encodeElementSATEncoder(This, elem0);
+ Element *elem1 = getArrayElement( &constraint->inputs, 1);
+ encodeElementSATEncoder(This, elem1);
+ ElementEncoding *ee0 = getElementEncoding(elem0);
+ ElementEncoding *ee1 = getElementEncoding(elem1);
+ ASSERT(ee0->numVars == ee1->numVars);
+ uint numVars = ee0->numVars;
+ switch (predicate->op) {
+ case EQUALS:
+ return generateEquivNVConstraint(This->cnf, numVars, ee0->variables, ee1->variables);
+ case LT:
+ return generateLTConstraint(This->cnf, numVars, ee0->variables, ee1->variables);
+ case GT:
+ return generateLTConstraint(This->cnf, numVars, ee1->variables, ee0->variables);
+ default:
+ ASSERT(0);
+ }
+ exit(-1);
+}
+
+++ /dev/null
-#include "satencoder.h"
-#include "common.h"
-#include "function.h"
-#include "ops.h"
-#include "predicate.h"
-#include "boolean.h"
-#include "table.h"
-#include "tableentry.h"
-#include "set.h"
-#include "element.h"
-#include "common.h"
-
-Edge encodeEnumEntriesTablePredicateSATEncoder(SATEncoder *This, BooleanPredicate *constraint) {
- ASSERT(GETPREDICATETYPE(constraint->predicate) == TABLEPRED);
- UndefinedBehavior undefStatus = ((PredicateTable *)constraint->predicate)->undefinedbehavior;
- ASSERT(undefStatus == IGNOREBEHAVIOR || undefStatus == FLAGFORCEUNDEFINED);
- Table *table = ((PredicateTable *)constraint->predicate)->table;
- FunctionEncodingType encType = constraint->encoding.type;
- ArrayElement *inputs = &constraint->inputs;
- uint inputNum = getSizeArrayElement(inputs);
- uint size = getSizeHashSetTableEntry(table->entries);
- bool generateNegation = encType == ENUMERATEIMPLICATIONSNEGATE;
- Edge constraints[size];
- Edge undefConst = encodeConstraintSATEncoder(This, constraint->undefStatus);
- printCNF(undefConst);
- model_print("**\n");
- HSIteratorTableEntry *iterator = iteratorTableEntry(table->entries);
- uint i = 0;
- while (hasNextTableEntry(iterator)) {
- TableEntry *entry = nextTableEntry(iterator);
- if (generateNegation == entry->output && undefStatus == IGNOREBEHAVIOR) {
- //Skip the irrelevant entries
- continue;
- }
- Edge carray[inputNum];
- for (uint j = 0; j < inputNum; j++) {
- Element *el = getArrayElement(inputs, j);
- carray[j] = getElementValueConstraint(This, el, entry->inputs[j]);
- printCNF(carray[j]);
- model_print("\n");
- }
- Edge row;
- switch (undefStatus) {
- case IGNOREBEHAVIOR:
- row = constraintAND(This->cnf, inputNum, carray);
- break;
- case FLAGFORCEUNDEFINED: {
- addConstraintCNF(This->cnf, constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), constraintNegate(undefConst)));
- if (generateNegation == entry->output) {
- continue;
- }
- row = constraintAND(This->cnf, inputNum, carray);
- break;
- }
- default:
- ASSERT(0);
- }
- constraints[i++] = row;
- printCNF(row);
-
- model_print("\n\n");
- }
- deleteIterTableEntry(iterator);
- ASSERT(i != 0);
- Edge result = generateNegation ? constraintNegate(constraintOR(This->cnf, i, constraints))
- : constraintOR(This->cnf, i, constraints);
- printCNF(result);
- return result;
-}
-Edge encodeEnumTablePredicateSATEncoder(SATEncoder *This, BooleanPredicate *constraint) {
-#ifdef TRACE_DEBUG
- model_print("Enumeration Table Predicate ...\n");
-#endif
- ASSERT(GETPREDICATETYPE(constraint->predicate) == TABLEPRED);
- //First encode children
- ArrayElement *inputs = &constraint->inputs;
- uint inputNum = getSizeArrayElement(inputs);
- //Encode all the inputs first ...
- for (uint i = 0; i < inputNum; i++) {
- encodeElementSATEncoder(This, getArrayElement(inputs, i));
- }
- PredicateTable *predicate = (PredicateTable *)constraint->predicate;
- switch (predicate->undefinedbehavior) {
- case IGNOREBEHAVIOR:
- case FLAGFORCEUNDEFINED:
- return encodeEnumEntriesTablePredicateSATEncoder(This, constraint);
- default:
- break;
- }
- bool generateNegation = constraint->encoding.type == ENUMERATEIMPLICATIONSNEGATE;
- uint numDomains = getSizeArraySet(&predicate->table->domains);
-
- VectorEdge *clauses = allocDefVectorEdge();
-
- uint indices[numDomains]; //setup indices
- bzero(indices, sizeof(uint) * numDomains);
-
- uint64_t vals[numDomains];//setup value array
- for (uint i = 0; i < numDomains; i++) {
- Set *set = getArraySet(&predicate->table->domains, i);
- vals[i] = getSetElement(set, indices[i]);
- }
- bool hasOverflow = false;
- Edge undefConstraint = encodeConstraintSATEncoder (This, constraint->undefStatus);
- printCNF(undefConstraint);
- bool notfinished = true;
- while (notfinished) {
- Edge carray[numDomains];
- TableEntry *tableEntry = getTableEntryFromTable(predicate->table, vals, numDomains);
- bool isInRange = tableEntry != NULL;
- if (!isInRange && !hasOverflow) {
- hasOverflow = true;
- }
- Edge clause;
- for (uint i = 0; i < numDomains; i++) {
- Element *elem = getArrayElement(&constraint->inputs, i);
- carray[i] = getElementValueConstraint(This, elem, vals[i]);
- }
-
- switch (predicate->undefinedbehavior) {
- case UNDEFINEDSETSFLAG:
- if (isInRange) {
- clause = constraintAND(This->cnf, numDomains, carray);
- } else {
- addConstraintCNF(This->cnf, constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint) );
- }
- break;
- case FLAGIFFUNDEFINED:
- if (isInRange) {
- clause = constraintAND(This->cnf, numDomains, carray);
- addConstraintCNF(This->cnf, constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintNegate(undefConstraint)));
- } else {
- addConstraintCNF(This->cnf, constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint) );
- }
- break;
-
- default:
- ASSERT(0);
- }
-
- if (isInRange) {
-#ifdef TRACE_DEBUG
- model_print("added clause in predicate table enumeration ...\n");
- printCNF(clause);
- model_print("\n");
-#endif
- pushVectorEdge(clauses, clause);
- }
-
- notfinished = false;
- for (uint i = 0; i < numDomains; i++) {
- uint index = ++indices[i];
- Set *set = getArraySet(&predicate->table->domains, i);
-
- if (index < getSetSize(set)) {
- vals[i] = getSetElement(set, index);
- notfinished = true;
- break;
- } else {
- indices[i] = 0;
- vals[i] = getSetElement(set, 0);
- }
- }
- }
- Edge result = E_NULL;
- ASSERT(getSizeVectorEdge(clauses) != 0);
- result = constraintOR(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
- if (hasOverflow) {
- result = constraintOR2(This->cnf, result, undefConstraint);
- }
- if (generateNegation) {
- ASSERT(!hasOverflow);
- result = constraintNegate(result);
- }
- deleteVectorEdge(clauses);
- return result;
-}
-
-void encodeEnumEntriesTableElemFuncSATEncoder(SATEncoder *This, ElementFunction *func) {
- UndefinedBehavior undefStatus = ((FunctionTable *) func->function)->undefBehavior;
- ASSERT(undefStatus == IGNOREBEHAVIOR || undefStatus == FLAGFORCEUNDEFINED);
- ArrayElement *elements = &func->inputs;
- Table *table = ((FunctionTable *) (func->function))->table;
- uint size = getSizeHashSetTableEntry(table->entries);
- Edge constraints[size];
- HSIteratorTableEntry *iterator = iteratorTableEntry(table->entries);
- uint i = 0;
- while (hasNextTableEntry(iterator)) {
- TableEntry *entry = nextTableEntry(iterator);
- ASSERT(entry != NULL);
- uint inputNum = getSizeArrayElement(elements);
- Edge carray[inputNum];
- for (uint j = 0; j < inputNum; j++) {
- Element *el = getArrayElement(elements, j);
- carray[j] = getElementValueConstraint(This, el, entry->inputs[j]);
- }
- Edge output = getElementValueConstraint(This, (Element *)func, entry->output);
- Edge row;
- switch (undefStatus ) {
- case IGNOREBEHAVIOR: {
- row = constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), output);
- break;
- }
- case FLAGFORCEUNDEFINED: {
- Edge undefConst = encodeConstraintSATEncoder(This, func->overflowstatus);
- row = constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), constraintAND2(This->cnf, output, constraintNegate(undefConst)));
- break;
- }
- default:
- ASSERT(0);
-
- }
- constraints[i++] = row;
- }
- deleteIterTableEntry(iterator);
- addConstraintCNF(This->cnf, constraintAND(This->cnf, size, constraints));
-}
-
-void encodeEnumTableElemFunctionSATEncoder(SATEncoder *This, ElementFunction *elemFunc) {
-#ifdef TRACE_DEBUG
- model_print("Enumeration Table functions ...\n");
-#endif
- ASSERT(GETFUNCTIONTYPE(elemFunc->function) == TABLEFUNC);
- //First encode children
- ArrayElement *elements = &elemFunc->inputs;
- for (uint i = 0; i < getSizeArrayElement(elements); i++) {
- Element *elem = getArrayElement( elements, i);
- encodeElementSATEncoder(This, elem);
- }
-
- FunctionTable *function = (FunctionTable *)elemFunc->function;
- switch (function->undefBehavior) {
- case IGNOREBEHAVIOR:
- case FLAGFORCEUNDEFINED:
- return encodeEnumEntriesTableElemFuncSATEncoder(This, elemFunc);
- default:
- break;
- }
-
- uint numDomains = getSizeArraySet(&function->table->domains);
-
- VectorEdge *clauses = allocDefVectorEdge(); // Setup array of clauses
-
- uint indices[numDomains]; //setup indices
- bzero(indices, sizeof(uint) * numDomains);
-
- uint64_t vals[numDomains];//setup value array
- for (uint i = 0; i < numDomains; i++) {
- Set *set = getArraySet(&function->table->domains, i);
- vals[i] = getSetElement(set, indices[i]);
- }
-
- Edge undefConstraint = encodeConstraintSATEncoder(This, elemFunc->overflowstatus);
- bool notfinished = true;
- while (notfinished) {
- Edge carray[numDomains + 1];
- TableEntry *tableEntry = getTableEntryFromTable(function->table, vals, numDomains);
- bool isInRange = tableEntry != NULL;
- ASSERT(function->undefBehavior == UNDEFINEDSETSFLAG || function->undefBehavior == FLAGIFFUNDEFINED);
- for (uint i = 0; i < numDomains; i++) {
- Element *elem = getArrayElement(&elemFunc->inputs, i);
- carray[i] = getElementValueConstraint(This, elem, vals[i]);
- }
- if (isInRange) {
- carray[numDomains] = getElementValueConstraint(This, (Element *)elemFunc, tableEntry->output);
- }
-
- Edge clause;
- switch (function->undefBehavior) {
- case UNDEFINEDSETSFLAG: {
- if (isInRange) {
- //FIXME: Talk to Brian, It should be IFF not only IMPLY. --HG
- clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
- } else {
- addConstraintCNF(This->cnf, constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint));
- }
- break;
- }
- case FLAGIFFUNDEFINED: {
- if (isInRange) {
- clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
- addConstraintCNF(This->cnf, constraintIMPLIES(This->cnf, constraintAND(This->cnf, numDomains, carray), constraintNegate(undefConstraint) ));
- } else {
- addConstraintCNF(This->cnf,constraintIMPLIES(This->cnf, constraintAND(This->cnf, numDomains, carray), undefConstraint));
- }
- break;
- }
- default:
- ASSERT(0);
- }
- if (isInRange) {
-#ifdef TRACE_DEBUG
- model_print("added clause in function table enumeration ...\n");
- printCNF(clause);
- model_print("\n");
-#endif
- pushVectorEdge(clauses, clause);
- }
-
- notfinished = false;
- for (uint i = 0; i < numDomains; i++) {
- uint index = ++indices[i];
- Set *set = getArraySet(&function->table->domains, i);
-
- if (index < getSetSize(set)) {
- vals[i] = getSetElement(set, index);
- notfinished = true;
- break;
- } else {
- indices[i] = 0;
- vals[i] = getSetElement(set, 0);
- }
- }
- }
- if (getSizeVectorEdge(clauses) == 0) {
- deleteVectorEdge(clauses);
- return;
- }
- Edge cor = constraintAND(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
- addConstraintCNF(This->cnf, cor);
- deleteVectorEdge(clauses);
-
-}
--- /dev/null
+#include "satencoder.h"
+#include "common.h"
+#include "function.h"
+#include "ops.h"
+#include "predicate.h"
+#include "boolean.h"
+#include "table.h"
+#include "tableentry.h"
+#include "set.h"
+#include "element.h"
+#include "common.h"
+
+Edge encodeEnumEntriesTablePredicateSATEncoder(SATEncoder *This, BooleanPredicate *constraint) {
+ ASSERT(GETPREDICATETYPE(constraint->predicate) == TABLEPRED);
+ UndefinedBehavior undefStatus = ((PredicateTable *)constraint->predicate)->undefinedbehavior;
+ ASSERT(undefStatus == IGNOREBEHAVIOR || undefStatus == FLAGFORCEUNDEFINED);
+ Table *table = ((PredicateTable *)constraint->predicate)->table;
+ FunctionEncodingType encType = constraint->encoding.type;
+ ArrayElement *inputs = &constraint->inputs;
+ uint inputNum = getSizeArrayElement(inputs);
+ uint size = getSizeHashSetTableEntry(table->entries);
+ bool generateNegation = encType == ENUMERATEIMPLICATIONSNEGATE;
+ Edge constraints[size];
+ Edge undefConst = encodeConstraintSATEncoder(This, constraint->undefStatus);
+ printCNF(undefConst);
+ model_print("**\n");
+ HSIteratorTableEntry *iterator = iteratorTableEntry(table->entries);
+ uint i = 0;
+ while (hasNextTableEntry(iterator)) {
+ TableEntry *entry = nextTableEntry(iterator);
+ if (generateNegation == entry->output && undefStatus == IGNOREBEHAVIOR) {
+ //Skip the irrelevant entries
+ continue;
+ }
+ Edge carray[inputNum];
+ for (uint j = 0; j < inputNum; j++) {
+ Element *el = getArrayElement(inputs, j);
+ carray[j] = getElementValueConstraint(This, el, entry->inputs[j]);
+ printCNF(carray[j]);
+ model_print("\n");
+ }
+ Edge row;
+ switch (undefStatus) {
+ case IGNOREBEHAVIOR:
+ row = constraintAND(This->cnf, inputNum, carray);
+ break;
+ case FLAGFORCEUNDEFINED: {
+ addConstraintCNF(This->cnf, constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), constraintNegate(undefConst)));
+ if (generateNegation == entry->output) {
+ continue;
+ }
+ row = constraintAND(This->cnf, inputNum, carray);
+ break;
+ }
+ default:
+ ASSERT(0);
+ }
+ constraints[i++] = row;
+ printCNF(row);
+
+ model_print("\n\n");
+ }
+ deleteIterTableEntry(iterator);
+ ASSERT(i != 0);
+ Edge result = generateNegation ? constraintNegate(constraintOR(This->cnf, i, constraints))
+ : constraintOR(This->cnf, i, constraints);
+ printCNF(result);
+ return result;
+}
+Edge encodeEnumTablePredicateSATEncoder(SATEncoder *This, BooleanPredicate *constraint) {
+#ifdef TRACE_DEBUG
+ model_print("Enumeration Table Predicate ...\n");
+#endif
+ ASSERT(GETPREDICATETYPE(constraint->predicate) == TABLEPRED);
+ //First encode children
+ ArrayElement *inputs = &constraint->inputs;
+ uint inputNum = getSizeArrayElement(inputs);
+ //Encode all the inputs first ...
+ for (uint i = 0; i < inputNum; i++) {
+ encodeElementSATEncoder(This, getArrayElement(inputs, i));
+ }
+ PredicateTable *predicate = (PredicateTable *)constraint->predicate;
+ switch (predicate->undefinedbehavior) {
+ case IGNOREBEHAVIOR:
+ case FLAGFORCEUNDEFINED:
+ return encodeEnumEntriesTablePredicateSATEncoder(This, constraint);
+ default:
+ break;
+ }
+ bool generateNegation = constraint->encoding.type == ENUMERATEIMPLICATIONSNEGATE;
+ uint numDomains = getSizeArraySet(&predicate->table->domains);
+
+ VectorEdge *clauses = allocDefVectorEdge();
+
+ uint indices[numDomains]; //setup indices
+ bzero(indices, sizeof(uint) * numDomains);
+
+ uint64_t vals[numDomains];//setup value array
+ for (uint i = 0; i < numDomains; i++) {
+ Set *set = getArraySet(&predicate->table->domains, i);
+ vals[i] = getSetElement(set, indices[i]);
+ }
+ bool hasOverflow = false;
+ Edge undefConstraint = encodeConstraintSATEncoder (This, constraint->undefStatus);
+ printCNF(undefConstraint);
+ bool notfinished = true;
+ while (notfinished) {
+ Edge carray[numDomains];
+ TableEntry *tableEntry = getTableEntryFromTable(predicate->table, vals, numDomains);
+ bool isInRange = tableEntry != NULL;
+ if (!isInRange && !hasOverflow) {
+ hasOverflow = true;
+ }
+ Edge clause;
+ for (uint i = 0; i < numDomains; i++) {
+ Element *elem = getArrayElement(&constraint->inputs, i);
+ carray[i] = getElementValueConstraint(This, elem, vals[i]);
+ }
+
+ switch (predicate->undefinedbehavior) {
+ case UNDEFINEDSETSFLAG:
+ if (isInRange) {
+ clause = constraintAND(This->cnf, numDomains, carray);
+ } else {
+ addConstraintCNF(This->cnf, constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint) );
+ }
+ break;
+ case FLAGIFFUNDEFINED:
+ if (isInRange) {
+ clause = constraintAND(This->cnf, numDomains, carray);
+ addConstraintCNF(This->cnf, constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintNegate(undefConstraint)));
+ } else {
+ addConstraintCNF(This->cnf, constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint) );
+ }
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ if (isInRange) {
+#ifdef TRACE_DEBUG
+ model_print("added clause in predicate table enumeration ...\n");
+ printCNF(clause);
+ model_print("\n");
+#endif
+ pushVectorEdge(clauses, clause);
+ }
+
+ notfinished = false;
+ for (uint i = 0; i < numDomains; i++) {
+ uint index = ++indices[i];
+ Set *set = getArraySet(&predicate->table->domains, i);
+
+ if (index < getSetSize(set)) {
+ vals[i] = getSetElement(set, index);
+ notfinished = true;
+ break;
+ } else {
+ indices[i] = 0;
+ vals[i] = getSetElement(set, 0);
+ }
+ }
+ }
+ Edge result = E_NULL;
+ ASSERT(getSizeVectorEdge(clauses) != 0);
+ result = constraintOR(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
+ if (hasOverflow) {
+ result = constraintOR2(This->cnf, result, undefConstraint);
+ }
+ if (generateNegation) {
+ ASSERT(!hasOverflow);
+ result = constraintNegate(result);
+ }
+ deleteVectorEdge(clauses);
+ return result;
+}
+
+void encodeEnumEntriesTableElemFuncSATEncoder(SATEncoder *This, ElementFunction *func) {
+ UndefinedBehavior undefStatus = ((FunctionTable *) func->function)->undefBehavior;
+ ASSERT(undefStatus == IGNOREBEHAVIOR || undefStatus == FLAGFORCEUNDEFINED);
+ ArrayElement *elements = &func->inputs;
+ Table *table = ((FunctionTable *) (func->function))->table;
+ uint size = getSizeHashSetTableEntry(table->entries);
+ Edge constraints[size];
+ HSIteratorTableEntry *iterator = iteratorTableEntry(table->entries);
+ uint i = 0;
+ while (hasNextTableEntry(iterator)) {
+ TableEntry *entry = nextTableEntry(iterator);
+ ASSERT(entry != NULL);
+ uint inputNum = getSizeArrayElement(elements);
+ Edge carray[inputNum];
+ for (uint j = 0; j < inputNum; j++) {
+ Element *el = getArrayElement(elements, j);
+ carray[j] = getElementValueConstraint(This, el, entry->inputs[j]);
+ }
+ Edge output = getElementValueConstraint(This, (Element *)func, entry->output);
+ Edge row;
+ switch (undefStatus ) {
+ case IGNOREBEHAVIOR: {
+ row = constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), output);
+ break;
+ }
+ case FLAGFORCEUNDEFINED: {
+ Edge undefConst = encodeConstraintSATEncoder(This, func->overflowstatus);
+ row = constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), constraintAND2(This->cnf, output, constraintNegate(undefConst)));
+ break;
+ }
+ default:
+ ASSERT(0);
+
+ }
+ constraints[i++] = row;
+ }
+ deleteIterTableEntry(iterator);
+ addConstraintCNF(This->cnf, constraintAND(This->cnf, size, constraints));
+}
+
+void encodeEnumTableElemFunctionSATEncoder(SATEncoder *This, ElementFunction *elemFunc) {
+#ifdef TRACE_DEBUG
+ model_print("Enumeration Table functions ...\n");
+#endif
+ ASSERT(GETFUNCTIONTYPE(elemFunc->function) == TABLEFUNC);
+ //First encode children
+ ArrayElement *elements = &elemFunc->inputs;
+ for (uint i = 0; i < getSizeArrayElement(elements); i++) {
+ Element *elem = getArrayElement( elements, i);
+ encodeElementSATEncoder(This, elem);
+ }
+
+ FunctionTable *function = (FunctionTable *)elemFunc->function;
+ switch (function->undefBehavior) {
+ case IGNOREBEHAVIOR:
+ case FLAGFORCEUNDEFINED:
+ return encodeEnumEntriesTableElemFuncSATEncoder(This, elemFunc);
+ default:
+ break;
+ }
+
+ uint numDomains = getSizeArraySet(&function->table->domains);
+
+ VectorEdge *clauses = allocDefVectorEdge(); // Setup array of clauses
+
+ uint indices[numDomains]; //setup indices
+ bzero(indices, sizeof(uint) * numDomains);
+
+ uint64_t vals[numDomains];//setup value array
+ for (uint i = 0; i < numDomains; i++) {
+ Set *set = getArraySet(&function->table->domains, i);
+ vals[i] = getSetElement(set, indices[i]);
+ }
+
+ Edge undefConstraint = encodeConstraintSATEncoder(This, elemFunc->overflowstatus);
+ bool notfinished = true;
+ while (notfinished) {
+ Edge carray[numDomains + 1];
+ TableEntry *tableEntry = getTableEntryFromTable(function->table, vals, numDomains);
+ bool isInRange = tableEntry != NULL;
+ ASSERT(function->undefBehavior == UNDEFINEDSETSFLAG || function->undefBehavior == FLAGIFFUNDEFINED);
+ for (uint i = 0; i < numDomains; i++) {
+ Element *elem = getArrayElement(&elemFunc->inputs, i);
+ carray[i] = getElementValueConstraint(This, elem, vals[i]);
+ }
+ if (isInRange) {
+ carray[numDomains] = getElementValueConstraint(This, (Element *)elemFunc, tableEntry->output);
+ }
+
+ Edge clause;
+ switch (function->undefBehavior) {
+ case UNDEFINEDSETSFLAG: {
+ if (isInRange) {
+ //FIXME: Talk to Brian, It should be IFF not only IMPLY. --HG
+ clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
+ } else {
+ addConstraintCNF(This->cnf, constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint));
+ }
+ break;
+ }
+ case FLAGIFFUNDEFINED: {
+ if (isInRange) {
+ clause = constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
+ addConstraintCNF(This->cnf, constraintIMPLIES(This->cnf, constraintAND(This->cnf, numDomains, carray), constraintNegate(undefConstraint) ));
+ } else {
+ addConstraintCNF(This->cnf,constraintIMPLIES(This->cnf, constraintAND(This->cnf, numDomains, carray), undefConstraint));
+ }
+ break;
+ }
+ default:
+ ASSERT(0);
+ }
+ if (isInRange) {
+#ifdef TRACE_DEBUG
+ model_print("added clause in function table enumeration ...\n");
+ printCNF(clause);
+ model_print("\n");
+#endif
+ pushVectorEdge(clauses, clause);
+ }
+
+ notfinished = false;
+ for (uint i = 0; i < numDomains; i++) {
+ uint index = ++indices[i];
+ Set *set = getArraySet(&function->table->domains, i);
+
+ if (index < getSetSize(set)) {
+ vals[i] = getSetElement(set, index);
+ notfinished = true;
+ break;
+ } else {
+ indices[i] = 0;
+ vals[i] = getSetElement(set, 0);
+ }
+ }
+ }
+ if (getSizeVectorEdge(clauses) == 0) {
+ deleteVectorEdge(clauses);
+ return;
+ }
+ Edge cor = constraintAND(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
+ addConstraintCNF(This->cnf, cor);
+ deleteVectorEdge(clauses);
+
+}
+++ /dev/null
-#include "satencoder.h"
-#include "structs.h"
-#include "common.h"
-#include "order.h"
-#include "csolver.h"
-#include "orderpair.h"
-#include "set.h"
-#include "tunable.h"
-#include "orderencoder.h"
-#include "ordergraph.h"
-#include "orderedge.h"
-#include "element.h"
-#include "predicate.h"
-#include "orderelement.h"
-
-Edge encodeOrderSATEncoder(SATEncoder *This, BooleanOrder *constraint) {
- if(constraint->order->order.type == INTEGERENCODING){
- return orderIntegerEncodingSATEncoder(This, constraint);
- }
- switch ( constraint->order->type) {
- case PARTIAL:
- return encodePartialOrderSATEncoder(This, constraint);
- case TOTAL:
- return encodeTotalOrderSATEncoder(This, constraint);
- default:
- ASSERT(0);
- }
- return E_BOGUS;
-}
-
-Edge orderIntegerEncodingSATEncoder(SATEncoder *This, BooleanOrder *boolOrder){
- if(boolOrder->order->graph == NULL){
- bool doOptOrderStructure=GETVARTUNABLE(This->solver->tuner, boolOrder->order->type,
- OPTIMIZEORDERSTRUCTURE, &onoff);
- if (doOptOrderStructure ) {
- boolOrder->order->graph = buildMustOrderGraph(boolOrder->order);
- reachMustAnalysis(This->solver, boolOrder->order->graph, true);
- }
- }
- Order* order = boolOrder->order;
- Edge gvalue = inferOrderConstraintFromGraph(order, boolOrder->first, boolOrder->second);
- if(!edgeIsNull(gvalue))
- return gvalue;
-
- if (boolOrder->order->elementTable == NULL) {
- initializeOrderElementsHashTable(boolOrder->order);
- }
- //getting two elements and using LT predicate ...
- Element* elem1 = getOrderIntegerElement(This, order, boolOrder->first);
- ElementEncoding *encoding = getElementEncoding(elem1);
- if (getElementEncodingType(encoding) == ELEM_UNASSIGNED) {
- setElementEncodingType(encoding, BINARYINDEX);
- encodingArrayInitialization(encoding);
- }
- Element* elem2 = getOrderIntegerElement(This, order, boolOrder->second);
- encoding = getElementEncoding(elem2);
- if (getElementEncodingType(encoding) == ELEM_UNASSIGNED) {
- setElementEncodingType(encoding, BINARYINDEX);
- encodingArrayInitialization(encoding);
- }
- Predicate *predicate =allocPredicateOperator(LT, (Set*[]){order->set, order->set}, 2);
- Boolean * boolean=allocBooleanPredicate(predicate, (Element *[]){elem1,elem2}, 2, NULL);
- setFunctionEncodingType(getPredicateFunctionEncoding((BooleanPredicate*)boolean), CIRCUIT);
- {//Adding new elements and boolean/predicate to solver regarding memory management
- pushVectorBoolean(This->solver->allBooleans, boolean);
- pushVectorPredicate(This->solver->allPredicates, predicate);
- pushVectorElement(This->solver->allElements, elem1);
- pushVectorElement(This->solver->allElements, elem2);
- }
- return encodeConstraintSATEncoder(This, boolean);
-}
-
-Edge inferOrderConstraintFromGraph(Order* order, uint64_t _first, uint64_t _second){
- if (order->graph != NULL) {
- OrderGraph *graph=order->graph;
- OrderNode *first=lookupOrderNodeFromOrderGraph(graph, _first);
- OrderNode *second=lookupOrderNodeFromOrderGraph(graph, _second);
- if ((first != NULL) && (second != NULL)) {
- OrderEdge *edge=lookupOrderEdgeFromOrderGraph(graph, first, second);
- if (edge != NULL) {
- if (edge->mustPos)
- return E_True;
- else if (edge->mustNeg)
- return E_False;
- }
- OrderEdge *invedge=getOrderEdgeFromOrderGraph(graph, second, first);
- if (invedge != NULL) {
- if (invedge->mustPos)
- return E_False;
- else if (invedge->mustNeg)
- return E_True;
- }
- }
- }
- return E_NULL;
-}
-
-Element* getOrderIntegerElement(SATEncoder* This,Order *order, uint64_t item) {
- HashSetOrderElement* eset = order->elementTable;
- OrderElement oelement ={item, NULL};
- if( !containsHashSetOrderElement(eset, &oelement)){
- Element* elem = allocElementSet(order->set);
- ElementEncoding* encoding = getElementEncoding(elem);
- setElementEncodingType(encoding, BINARYINDEX);
- encodingArrayInitialization(encoding);
- encodeElementSATEncoder(This, elem);
- addHashSetOrderElement(eset, allocOrderElement(item, elem));
- return elem;
- }else
- return getHashSetOrderElement(eset, &oelement)->elem;
-}
-Edge getPairConstraint(SATEncoder *This, Order *order, OrderPair *pair) {
- Edge gvalue = inferOrderConstraintFromGraph(order, pair->first, pair->second);
- if(!edgeIsNull(gvalue))
- return gvalue;
-
- HashTableOrderPair *table = order->orderPairTable;
- bool negate = false;
- OrderPair flipped;
- if (pair->first < pair->second) {
- negate = true;
- flipped.first = pair->second;
- flipped.second = pair->first;
- pair = &flipped;
- }
- Edge constraint;
- if (!containsOrderPair(table, pair)) {
- constraint = getNewVarSATEncoder(This);
- OrderPair *paircopy = allocOrderPair(pair->first, pair->second, constraint);
- putOrderPair(table, paircopy, paircopy);
- } else
- constraint = getOrderPair(table, pair)->constraint;
-
- return negate ? constraintNegate(constraint) : constraint;
-}
-
-Edge encodeTotalOrderSATEncoder(SATEncoder *This, BooleanOrder *boolOrder) {
- ASSERT(boolOrder->order->type == TOTAL);
- if (boolOrder->order->orderPairTable == NULL) {
- initializeOrderHashTable(boolOrder->order);
- bool doOptOrderStructure=GETVARTUNABLE(This->solver->tuner, boolOrder->order->type, OPTIMIZEORDERSTRUCTURE, &onoff);
- if (doOptOrderStructure) {
- boolOrder->order->graph = buildMustOrderGraph(boolOrder->order);
- reachMustAnalysis(This->solver, boolOrder->order->graph, true);
- }
- createAllTotalOrderConstraintsSATEncoder(This, boolOrder->order);
- }
- OrderPair pair = {boolOrder->first, boolOrder->second, E_NULL};
- Edge constraint = getPairConstraint(This, boolOrder->order, &pair);
- return constraint;
-}
-
-
-void createAllTotalOrderConstraintsSATEncoder(SATEncoder *This, Order *order) {
-#ifdef TRACE_DEBUG
- model_print("in total order ...\n");
-#endif
- ASSERT(order->type == TOTAL);
- VectorInt *mems = order->set->members;
- uint size = getSizeVectorInt(mems);
- for (uint i = 0; i < size; i++) {
- uint64_t valueI = getVectorInt(mems, i);
- for (uint j = i + 1; j < size; j++) {
- uint64_t valueJ = getVectorInt(mems, j);
- OrderPair pairIJ = {valueI, valueJ};
- Edge constIJ = getPairConstraint(This, order, &pairIJ);
- for (uint k = j + 1; k < size; k++) {
- uint64_t valueK = getVectorInt(mems, k);
- OrderPair pairJK = {valueJ, valueK};
- OrderPair pairIK = {valueI, valueK};
- Edge constIK = getPairConstraint(This, order, &pairIK);
- Edge constJK = getPairConstraint(This, order, &pairJK);
- addConstraintCNF(This->cnf, generateTransOrderConstraintSATEncoder(This, constIJ, constJK, constIK));
- }
- }
- }
-}
-
-Edge getOrderConstraint(HashTableOrderPair *table, OrderPair *pair) {
- ASSERT(pair->first != pair->second);
- bool negate = false;
- OrderPair flipped;
- if (pair->first < pair->second) {
- negate = true;
- flipped.first = pair->second;
- flipped.second = pair->first;
- pair = &flipped;
- }
- if (!containsOrderPair(table, pair)) {
- return E_NULL;
- }
- Edge constraint = getOrderPair(table, pair)->constraint;
- ASSERT(!edgeIsNull(constraint));
- return negate ? constraintNegate(constraint) : constraint;
-}
-
-Edge generateTransOrderConstraintSATEncoder(SATEncoder *This, Edge constIJ,Edge constJK,Edge constIK) {
- Edge carray[] = {constIJ, constJK, constraintNegate(constIK)};
- Edge loop1 = constraintOR(This->cnf, 3, carray);
- Edge carray2[] = {constraintNegate(constIJ), constraintNegate(constJK), constIK};
- Edge loop2 = constraintOR(This->cnf, 3, carray2 );
- return constraintAND2(This->cnf, loop1, loop2);
-}
-
-Edge encodePartialOrderSATEncoder(SATEncoder *This, BooleanOrder *constraint) {
- ASSERT(constraint->order->type == PARTIAL);
- return E_BOGUS;
-}
--- /dev/null
+#include "satencoder.h"
+#include "structs.h"
+#include "common.h"
+#include "order.h"
+#include "csolver.h"
+#include "orderpair.h"
+#include "set.h"
+#include "tunable.h"
+#include "orderencoder.h"
+#include "ordergraph.h"
+#include "orderedge.h"
+#include "element.h"
+#include "predicate.h"
+#include "orderelement.h"
+
+Edge encodeOrderSATEncoder(SATEncoder *This, BooleanOrder *constraint) {
+ if(constraint->order->order.type == INTEGERENCODING){
+ return orderIntegerEncodingSATEncoder(This, constraint);
+ }
+ switch ( constraint->order->type) {
+ case PARTIAL:
+ return encodePartialOrderSATEncoder(This, constraint);
+ case TOTAL:
+ return encodeTotalOrderSATEncoder(This, constraint);
+ default:
+ ASSERT(0);
+ }
+ return E_BOGUS;
+}
+
+Edge orderIntegerEncodingSATEncoder(SATEncoder *This, BooleanOrder *boolOrder){
+ if(boolOrder->order->graph == NULL){
+ bool doOptOrderStructure=GETVARTUNABLE(This->solver->tuner, boolOrder->order->type,
+ OPTIMIZEORDERSTRUCTURE, &onoff);
+ if (doOptOrderStructure ) {
+ boolOrder->order->graph = buildMustOrderGraph(boolOrder->order);
+ reachMustAnalysis(This->solver, boolOrder->order->graph, true);
+ }
+ }
+ Order* order = boolOrder->order;
+ Edge gvalue = inferOrderConstraintFromGraph(order, boolOrder->first, boolOrder->second);
+ if(!edgeIsNull(gvalue))
+ return gvalue;
+
+ if (boolOrder->order->elementTable == NULL) {
+ initializeOrderElementsHashTable(boolOrder->order);
+ }
+ //getting two elements and using LT predicate ...
+ Element* elem1 = getOrderIntegerElement(This, order, boolOrder->first);
+ ElementEncoding *encoding = getElementEncoding(elem1);
+ if (getElementEncodingType(encoding) == ELEM_UNASSIGNED) {
+ setElementEncodingType(encoding, BINARYINDEX);
+ encodingArrayInitialization(encoding);
+ }
+ Element* elem2 = getOrderIntegerElement(This, order, boolOrder->second);
+ encoding = getElementEncoding(elem2);
+ if (getElementEncodingType(encoding) == ELEM_UNASSIGNED) {
+ setElementEncodingType(encoding, BINARYINDEX);
+ encodingArrayInitialization(encoding);
+ }
+ Predicate *predicate =allocPredicateOperator(LT, (Set*[]){order->set, order->set}, 2);
+ Boolean * boolean=allocBooleanPredicate(predicate, (Element *[]){elem1,elem2}, 2, NULL);
+ setFunctionEncodingType(getPredicateFunctionEncoding((BooleanPredicate*)boolean), CIRCUIT);
+ {//Adding new elements and boolean/predicate to solver regarding memory management
+ pushVectorBoolean(This->solver->allBooleans, boolean);
+ pushVectorPredicate(This->solver->allPredicates, predicate);
+ pushVectorElement(This->solver->allElements, elem1);
+ pushVectorElement(This->solver->allElements, elem2);
+ }
+ return encodeConstraintSATEncoder(This, boolean);
+}
+
+Edge inferOrderConstraintFromGraph(Order* order, uint64_t _first, uint64_t _second){
+ if (order->graph != NULL) {
+ OrderGraph *graph=order->graph;
+ OrderNode *first=lookupOrderNodeFromOrderGraph(graph, _first);
+ OrderNode *second=lookupOrderNodeFromOrderGraph(graph, _second);
+ if ((first != NULL) && (second != NULL)) {
+ OrderEdge *edge=lookupOrderEdgeFromOrderGraph(graph, first, second);
+ if (edge != NULL) {
+ if (edge->mustPos)
+ return E_True;
+ else if (edge->mustNeg)
+ return E_False;
+ }
+ OrderEdge *invedge=getOrderEdgeFromOrderGraph(graph, second, first);
+ if (invedge != NULL) {
+ if (invedge->mustPos)
+ return E_False;
+ else if (invedge->mustNeg)
+ return E_True;
+ }
+ }
+ }
+ return E_NULL;
+}
+
+Element* getOrderIntegerElement(SATEncoder* This,Order *order, uint64_t item) {
+ HashSetOrderElement* eset = order->elementTable;
+ OrderElement oelement ={item, NULL};
+ if( !containsHashSetOrderElement(eset, &oelement)){
+ Element* elem = allocElementSet(order->set);
+ ElementEncoding* encoding = getElementEncoding(elem);
+ setElementEncodingType(encoding, BINARYINDEX);
+ encodingArrayInitialization(encoding);
+ encodeElementSATEncoder(This, elem);
+ addHashSetOrderElement(eset, allocOrderElement(item, elem));
+ return elem;
+ }else
+ return getHashSetOrderElement(eset, &oelement)->elem;
+}
+Edge getPairConstraint(SATEncoder *This, Order *order, OrderPair *pair) {
+ Edge gvalue = inferOrderConstraintFromGraph(order, pair->first, pair->second);
+ if(!edgeIsNull(gvalue))
+ return gvalue;
+
+ HashTableOrderPair *table = order->orderPairTable;
+ bool negate = false;
+ OrderPair flipped;
+ if (pair->first < pair->second) {
+ negate = true;
+ flipped.first = pair->second;
+ flipped.second = pair->first;
+ pair = &flipped;
+ }
+ Edge constraint;
+ if (!containsOrderPair(table, pair)) {
+ constraint = getNewVarSATEncoder(This);
+ OrderPair *paircopy = allocOrderPair(pair->first, pair->second, constraint);
+ putOrderPair(table, paircopy, paircopy);
+ } else
+ constraint = getOrderPair(table, pair)->constraint;
+
+ return negate ? constraintNegate(constraint) : constraint;
+}
+
+Edge encodeTotalOrderSATEncoder(SATEncoder *This, BooleanOrder *boolOrder) {
+ ASSERT(boolOrder->order->type == TOTAL);
+ if (boolOrder->order->orderPairTable == NULL) {
+ initializeOrderHashTable(boolOrder->order);
+ bool doOptOrderStructure=GETVARTUNABLE(This->solver->tuner, boolOrder->order->type, OPTIMIZEORDERSTRUCTURE, &onoff);
+ if (doOptOrderStructure) {
+ boolOrder->order->graph = buildMustOrderGraph(boolOrder->order);
+ reachMustAnalysis(This->solver, boolOrder->order->graph, true);
+ }
+ createAllTotalOrderConstraintsSATEncoder(This, boolOrder->order);
+ }
+ OrderPair pair = {boolOrder->first, boolOrder->second, E_NULL};
+ Edge constraint = getPairConstraint(This, boolOrder->order, &pair);
+ return constraint;
+}
+
+
+void createAllTotalOrderConstraintsSATEncoder(SATEncoder *This, Order *order) {
+#ifdef TRACE_DEBUG
+ model_print("in total order ...\n");
+#endif
+ ASSERT(order->type == TOTAL);
+ VectorInt *mems = order->set->members;
+ uint size = getSizeVectorInt(mems);
+ for (uint i = 0; i < size; i++) {
+ uint64_t valueI = getVectorInt(mems, i);
+ for (uint j = i + 1; j < size; j++) {
+ uint64_t valueJ = getVectorInt(mems, j);
+ OrderPair pairIJ = {valueI, valueJ};
+ Edge constIJ = getPairConstraint(This, order, &pairIJ);
+ for (uint k = j + 1; k < size; k++) {
+ uint64_t valueK = getVectorInt(mems, k);
+ OrderPair pairJK = {valueJ, valueK};
+ OrderPair pairIK = {valueI, valueK};
+ Edge constIK = getPairConstraint(This, order, &pairIK);
+ Edge constJK = getPairConstraint(This, order, &pairJK);
+ addConstraintCNF(This->cnf, generateTransOrderConstraintSATEncoder(This, constIJ, constJK, constIK));
+ }
+ }
+ }
+}
+
+Edge getOrderConstraint(HashTableOrderPair *table, OrderPair *pair) {
+ ASSERT(pair->first != pair->second);
+ bool negate = false;
+ OrderPair flipped;
+ if (pair->first < pair->second) {
+ negate = true;
+ flipped.first = pair->second;
+ flipped.second = pair->first;
+ pair = &flipped;
+ }
+ if (!containsOrderPair(table, pair)) {
+ return E_NULL;
+ }
+ Edge constraint = getOrderPair(table, pair)->constraint;
+ ASSERT(!edgeIsNull(constraint));
+ return negate ? constraintNegate(constraint) : constraint;
+}
+
+Edge generateTransOrderConstraintSATEncoder(SATEncoder *This, Edge constIJ,Edge constJK,Edge constIK) {
+ Edge carray[] = {constIJ, constJK, constraintNegate(constIK)};
+ Edge loop1 = constraintOR(This->cnf, 3, carray);
+ Edge carray2[] = {constraintNegate(constIJ), constraintNegate(constJK), constIK};
+ Edge loop2 = constraintOR(This->cnf, 3, carray2 );
+ return constraintAND2(This->cnf, loop1, loop2);
+}
+
+Edge encodePartialOrderSATEncoder(SATEncoder *This, BooleanOrder *constraint) {
+ ASSERT(constraint->order->type == PARTIAL);
+ return E_BOGUS;
+}
+++ /dev/null
-#include "sattranslator.h"
-#include "element.h"
-#include "csolver.h"
-#include "satencoder.h"
-#include "set.h"
-#include "order.h"
-#include "orderpair.h"
-
-uint64_t getElementValueBinaryIndexSATTranslator(CSolver *This, ElementEncoding *elemEnc) {
- uint index = 0;
- for (int i = elemEnc->numVars - 1; i >= 0; i--) {
- index = index << 1;
- if (getValueSolver(This->satEncoder->cnf->solver, getEdgeVar( elemEnc->variables[i] )))
- index |= 1;
- }
- model_print("index:%u\tencArraySize:%u\tisInUseElement:%u\n", index, elemEnc->encArraySize, isinUseElement(elemEnc, index));
- ASSERT(elemEnc->encArraySize > index && isinUseElement(elemEnc, index));
- return elemEnc->encodingArray[index];
-}
-
-uint64_t getElementValueBinaryValueSATTranslator(CSolver *This, ElementEncoding *elemEnc) {
- uint64_t value = 0;
- for (int i = elemEnc->numVars - 1; i >= 0; i--) {
- value = value << 1;
- if (getValueSolver(This->satEncoder->cnf->solver, getEdgeVar( elemEnc->variables[i] )) )
- value |= 1;
- }
- if (elemEnc->isBinaryValSigned &&
- This->satEncoder->cnf->solver->solution[ getEdgeVar( elemEnc->variables[elemEnc->numVars - 1])]) {
- //Do sign extension of negative number
- uint64_t highbits = 0xffffffffffffffff - ((1 << (elemEnc->numVars)) - 1);
- value += highbits;
- }
- value += elemEnc->offset;
- return value;
-}
-
-uint64_t getElementValueOneHotSATTranslator(CSolver *This, ElementEncoding *elemEnc) {
- uint index = 0;
- for (uint i = 0; i < elemEnc->numVars; i++) {
- if (getValueSolver(This->satEncoder->cnf->solver, getEdgeVar( elemEnc->variables[i] )))
- index = i;
- }
- ASSERT(elemEnc->encArraySize > index && isinUseElement(elemEnc, index));
- return elemEnc->encodingArray[index];
-}
-
-uint64_t getElementValueUnarySATTranslator(CSolver *This, ElementEncoding *elemEnc) {
- uint i;
- for (i = 0; i < elemEnc->numVars; i++) {
- if (!getValueSolver(This->satEncoder->cnf->solver, getEdgeVar( elemEnc->variables[i] )) ) {
- break;
- }
- }
-
- return elemEnc->encodingArray[i];
-}
-
-uint64_t getElementValueSATTranslator(CSolver *This, Element *element) {
- ElementEncoding *elemEnc = getElementEncoding(element);
- if (elemEnc->numVars == 0)//case when the set has only one item
- return getSetElement(getElementSet(element), 0);
- switch (elemEnc->type) {
- case ONEHOT:
- return getElementValueOneHotSATTranslator(This, elemEnc);
- case UNARY:
- return getElementValueUnarySATTranslator(This, elemEnc);
- case BINARYINDEX:
- return getElementValueBinaryIndexSATTranslator(This, elemEnc);
- case ONEHOTBINARY:
- ASSERT(0);
- break;
- case BINARYVAL:
- ASSERT(0);
- break;
- default:
- ASSERT(0);
- break;
- }
- return -1;
-}
-
-bool getBooleanVariableValueSATTranslator( CSolver *This, Boolean *boolean) {
- int index = getEdgeVar( ((BooleanVar *) boolean)->var );
- return getValueSolver(This->satEncoder->cnf->solver, index);
-}
-
-HappenedBefore getOrderConstraintValueSATTranslator(CSolver *This, Order *order, uint64_t first, uint64_t second) {
- ASSERT(order->orderPairTable != NULL);
- OrderPair pair = {first, second, E_NULL};
- Edge var = getOrderConstraint(order->orderPairTable, &pair);
- if (edgeIsNull(var))
- return UNORDERED;
- return getValueCNF(This->satEncoder->cnf, var) ? FIRST : SECOND;
-}
-
--- /dev/null
+#include "sattranslator.h"
+#include "element.h"
+#include "csolver.h"
+#include "satencoder.h"
+#include "set.h"
+#include "order.h"
+#include "orderpair.h"
+
+uint64_t getElementValueBinaryIndexSATTranslator(CSolver *This, ElementEncoding *elemEnc) {
+ uint index = 0;
+ for (int i = elemEnc->numVars - 1; i >= 0; i--) {
+ index = index << 1;
+ if (getValueSolver(This->satEncoder->cnf->solver, getEdgeVar( elemEnc->variables[i] )))
+ index |= 1;
+ }
+ model_print("index:%u\tencArraySize:%u\tisInUseElement:%u\n", index, elemEnc->encArraySize, isinUseElement(elemEnc, index));
+ ASSERT(elemEnc->encArraySize > index && isinUseElement(elemEnc, index));
+ return elemEnc->encodingArray[index];
+}
+
+uint64_t getElementValueBinaryValueSATTranslator(CSolver *This, ElementEncoding *elemEnc) {
+ uint64_t value = 0;
+ for (int i = elemEnc->numVars - 1; i >= 0; i--) {
+ value = value << 1;
+ if (getValueSolver(This->satEncoder->cnf->solver, getEdgeVar( elemEnc->variables[i] )) )
+ value |= 1;
+ }
+ if (elemEnc->isBinaryValSigned &&
+ This->satEncoder->cnf->solver->solution[ getEdgeVar( elemEnc->variables[elemEnc->numVars - 1])]) {
+ //Do sign extension of negative number
+ uint64_t highbits = 0xffffffffffffffff - ((1 << (elemEnc->numVars)) - 1);
+ value += highbits;
+ }
+ value += elemEnc->offset;
+ return value;
+}
+
+uint64_t getElementValueOneHotSATTranslator(CSolver *This, ElementEncoding *elemEnc) {
+ uint index = 0;
+ for (uint i = 0; i < elemEnc->numVars; i++) {
+ if (getValueSolver(This->satEncoder->cnf->solver, getEdgeVar( elemEnc->variables[i] )))
+ index = i;
+ }
+ ASSERT(elemEnc->encArraySize > index && isinUseElement(elemEnc, index));
+ return elemEnc->encodingArray[index];
+}
+
+uint64_t getElementValueUnarySATTranslator(CSolver *This, ElementEncoding *elemEnc) {
+ uint i;
+ for (i = 0; i < elemEnc->numVars; i++) {
+ if (!getValueSolver(This->satEncoder->cnf->solver, getEdgeVar( elemEnc->variables[i] )) ) {
+ break;
+ }
+ }
+
+ return elemEnc->encodingArray[i];
+}
+
+uint64_t getElementValueSATTranslator(CSolver *This, Element *element) {
+ ElementEncoding *elemEnc = getElementEncoding(element);
+ if (elemEnc->numVars == 0)//case when the set has only one item
+ return getSetElement(getElementSet(element), 0);
+ switch (elemEnc->type) {
+ case ONEHOT:
+ return getElementValueOneHotSATTranslator(This, elemEnc);
+ case UNARY:
+ return getElementValueUnarySATTranslator(This, elemEnc);
+ case BINARYINDEX:
+ return getElementValueBinaryIndexSATTranslator(This, elemEnc);
+ case ONEHOTBINARY:
+ ASSERT(0);
+ break;
+ case BINARYVAL:
+ ASSERT(0);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ return -1;
+}
+
+bool getBooleanVariableValueSATTranslator( CSolver *This, Boolean *boolean) {
+ int index = getEdgeVar( ((BooleanVar *) boolean)->var );
+ return getValueSolver(This->satEncoder->cnf->solver, index);
+}
+
+HappenedBefore getOrderConstraintValueSATTranslator(CSolver *This, Order *order, uint64_t first, uint64_t second) {
+ ASSERT(order->orderPairTable != NULL);
+ OrderPair pair = {first, second, E_NULL};
+ Edge var = getOrderConstraint(order->orderPairTable, &pair);
+ if (edgeIsNull(var))
+ return UNORDERED;
+ return getValueCNF(This->satEncoder->cnf, var) ? FIRST : SECOND;
+}
+
+++ /dev/null
-#include "structs.h"
-#include "mymemory.h"
-#include "orderpair.h"
-#include "tableentry.h"
-#include "ordernode.h"
-#include "orderedge.h"
-#include "ordergraph.h"
-#include "orderelement.h"
-
-VectorImpl(Table, Table *, 4);
-VectorImpl(Set, Set *, 4);
-VectorImpl(Boolean, Boolean *, 4);
-VectorImpl(BooleanOrder, BooleanOrder *, 4);
-VectorImpl(Function, Function *, 4);
-VectorImpl(Predicate, Predicate *, 4);
-VectorImpl(Element, Element *, 4);
-VectorImpl(Order, Order *, 4);
-VectorImpl(TableEntry, TableEntry *, 4);
-VectorImpl(ASTNode, ASTNode *, 4);
-VectorImpl(Int, uint64_t, 4);
-VectorImpl(OrderNode, OrderNode *, 4);
-VectorImpl(OrderGraph, OrderGraph *, 4);
-
-static inline unsigned int Ptr_hash_function(void *hash) {
- return (unsigned int)((int64)hash >> 4);
-}
-
-static inline bool Ptr_equals(void *key1, void *key2) {
- return key1 == key2;
-}
-
-static inline unsigned int order_pair_hash_function(OrderPair *This) {
- return (uint) (This->first << 2) ^ This->second;
-}
-
-static inline unsigned int order_pair_equals(OrderPair *key1, OrderPair *key2) {
- return key1->first == key2->first && key1->second == key2->second;
-}
-
-static inline unsigned int table_entry_hash_function(TableEntry *This) {
- unsigned int h = 0;
- for (uint i = 0; i < This->inputSize; i++) {
- h += This->inputs[i];
- h *= 31;
- }
- return h;
-}
-
-static inline bool table_entry_equals(TableEntry *key1, TableEntry *key2) {
- if (key1->inputSize != key2->inputSize)
- return false;
- for (uint i = 0; i < key1->inputSize; i++)
- if (key1->inputs[i] != key2->inputs[i])
- return false;
- return true;
-}
-
-static inline unsigned int order_node_hash_function(OrderNode *This) {
- return (uint) This->id;
-
-}
-
-static inline bool order_node_equals(OrderNode *key1, OrderNode *key2) {
- return key1->id == key2->id;
-}
-
-static inline unsigned int order_edge_hash_function(OrderEdge *This) {
- return (uint) (((uintptr_t)This->sink) ^ ((uintptr_t)This->source << 4));
-}
-
-static inline bool order_edge_equals(OrderEdge *key1, OrderEdge *key2) {
- return key1->sink == key2->sink && key1->source == key2->source;
-}
-
-static inline unsigned int order_element_hash_function(OrderElement* This) {
- return (uint)This->item;
-}
-
-static inline bool order_element_equals(OrderElement* key1, OrderElement* key2) {
- return key1->item == key2->item;
-}
-
-
-HashSetImpl(Boolean, Boolean *, Ptr_hash_function, Ptr_equals);
-HashSetImpl(TableEntry, TableEntry *, table_entry_hash_function, table_entry_equals);
-HashSetImpl(OrderNode, OrderNode *, order_node_hash_function, order_node_equals);
-HashSetImpl(OrderEdge, OrderEdge *, order_edge_hash_function, order_edge_equals);
-HashSetImpl(OrderElement, OrderElement *, order_element_hash_function, order_element_equals);
-
-HashTableImpl(NodeToNodeSet, OrderNode *, HashSetOrderNode *, Ptr_hash_function, Ptr_equals, deleteHashSetOrderNode);
-HashTableImpl(OrderPair, OrderPair *, OrderPair *, order_pair_hash_function, order_pair_equals, ourfree);
--- /dev/null
+#include "structs.h"
+#include "mymemory.h"
+#include "orderpair.h"
+#include "tableentry.h"
+#include "ordernode.h"
+#include "orderedge.h"
+#include "ordergraph.h"
+#include "orderelement.h"
+
+VectorImpl(Table, Table *, 4);
+VectorImpl(Set, Set *, 4);
+VectorImpl(Boolean, Boolean *, 4);
+VectorImpl(BooleanOrder, BooleanOrder *, 4);
+VectorImpl(Function, Function *, 4);
+VectorImpl(Predicate, Predicate *, 4);
+VectorImpl(Element, Element *, 4);
+VectorImpl(Order, Order *, 4);
+VectorImpl(TableEntry, TableEntry *, 4);
+VectorImpl(ASTNode, ASTNode *, 4);
+VectorImpl(Int, uint64_t, 4);
+VectorImpl(OrderNode, OrderNode *, 4);
+VectorImpl(OrderGraph, OrderGraph *, 4);
+
+static inline unsigned int Ptr_hash_function(void *hash) {
+ return (unsigned int)((int64)hash >> 4);
+}
+
+static inline bool Ptr_equals(void *key1, void *key2) {
+ return key1 == key2;
+}
+
+static inline unsigned int order_pair_hash_function(OrderPair *This) {
+ return (uint) (This->first << 2) ^ This->second;
+}
+
+static inline unsigned int order_pair_equals(OrderPair *key1, OrderPair *key2) {
+ return key1->first == key2->first && key1->second == key2->second;
+}
+
+static inline unsigned int table_entry_hash_function(TableEntry *This) {
+ unsigned int h = 0;
+ for (uint i = 0; i < This->inputSize; i++) {
+ h += This->inputs[i];
+ h *= 31;
+ }
+ return h;
+}
+
+static inline bool table_entry_equals(TableEntry *key1, TableEntry *key2) {
+ if (key1->inputSize != key2->inputSize)
+ return false;
+ for (uint i = 0; i < key1->inputSize; i++)
+ if (key1->inputs[i] != key2->inputs[i])
+ return false;
+ return true;
+}
+
+static inline unsigned int order_node_hash_function(OrderNode *This) {
+ return (uint) This->id;
+
+}
+
+static inline bool order_node_equals(OrderNode *key1, OrderNode *key2) {
+ return key1->id == key2->id;
+}
+
+static inline unsigned int order_edge_hash_function(OrderEdge *This) {
+ return (uint) (((uintptr_t)This->sink) ^ ((uintptr_t)This->source << 4));
+}
+
+static inline bool order_edge_equals(OrderEdge *key1, OrderEdge *key2) {
+ return key1->sink == key2->sink && key1->source == key2->source;
+}
+
+static inline unsigned int order_element_hash_function(OrderElement* This) {
+ return (uint)This->item;
+}
+
+static inline bool order_element_equals(OrderElement* key1, OrderElement* key2) {
+ return key1->item == key2->item;
+}
+
+
+HashSetImpl(Boolean, Boolean *, Ptr_hash_function, Ptr_equals);
+HashSetImpl(TableEntry, TableEntry *, table_entry_hash_function, table_entry_equals);
+HashSetImpl(OrderNode, OrderNode *, order_node_hash_function, order_node_equals);
+HashSetImpl(OrderEdge, OrderEdge *, order_edge_hash_function, order_edge_equals);
+HashSetImpl(OrderElement, OrderElement *, order_element_hash_function, order_element_equals);
+
+HashTableImpl(NodeToNodeSet, OrderNode *, HashSetOrderNode *, Ptr_hash_function, Ptr_equals, deleteHashSetOrderNode);
+HashTableImpl(OrderPair, OrderPair *, OrderPair *, order_pair_hash_function, order_pair_equals, ourfree);
+++ /dev/null
-#include "elementencoding.h"
-#include "common.h"
-#include "naiveencoder.h"
-#include "element.h"
-#include "satencoder.h"
-
-void initElementEncoding(ElementEncoding *This, Element *element) {
- This->element = element;
- This->type = ELEM_UNASSIGNED;
- This->variables = NULL;
- This->encodingArray = NULL;
- This->inUseArray = NULL;
- This->numVars = 0;
- This->encArraySize = 0;
-}
-
-void deleteElementEncoding(ElementEncoding *This) {
- if (This->variables != NULL)
- ourfree(This->variables);
- if (This->encodingArray != NULL)
- ourfree(This->encodingArray);
- if (This->inUseArray != NULL)
- ourfree(This->inUseArray);
-}
-
-void allocEncodingArrayElement(ElementEncoding *This, uint size) {
- This->encodingArray = ourcalloc(1, sizeof(uint64_t) * size);
- This->encArraySize = size;
-}
-
-void allocInUseArrayElement(ElementEncoding *This, uint size) {
- uint bytes = ((size + ((1 << 9) - 1)) >> 6) & ~7;//Depends on size of inUseArray
- This->inUseArray = ourcalloc(1, bytes);
-}
-
-void setElementEncodingType(ElementEncoding *This, ElementEncodingType type) {
- This->type = type;
-}
-
-
--- /dev/null
+#include "elementencoding.h"
+#include "common.h"
+#include "naiveencoder.h"
+#include "element.h"
+#include "satencoder.h"
+
+void initElementEncoding(ElementEncoding *This, Element *element) {
+ This->element = element;
+ This->type = ELEM_UNASSIGNED;
+ This->variables = NULL;
+ This->encodingArray = NULL;
+ This->inUseArray = NULL;
+ This->numVars = 0;
+ This->encArraySize = 0;
+}
+
+void deleteElementEncoding(ElementEncoding *This) {
+ if (This->variables != NULL)
+ ourfree(This->variables);
+ if (This->encodingArray != NULL)
+ ourfree(This->encodingArray);
+ if (This->inUseArray != NULL)
+ ourfree(This->inUseArray);
+}
+
+void allocEncodingArrayElement(ElementEncoding *This, uint size) {
+ This->encodingArray = (uint64_t *) ourcalloc(1, sizeof(uint64_t) * size);
+ This->encArraySize = size;
+}
+
+void allocInUseArrayElement(ElementEncoding *This, uint size) {
+ uint bytes = ((size + ((1 << 9) - 1)) >> 6) & ~7;//Depends on size of inUseArray
+ This->inUseArray = (uint64_t *) ourcalloc(1, bytes);
+}
+
+void setElementEncodingType(ElementEncoding *This, ElementEncodingType type) {
+ This->type = type;
+}
+
+
+++ /dev/null
-#include "functionencoding.h"
-
-void initFunctionEncoding(FunctionEncoding *This, Element *function) {
- This->op.function = function;
- This->type = FUNC_UNASSIGNED;
-}
-
-void initPredicateEncoding(FunctionEncoding *This, Boolean *predicate) {
- This->op.predicate = predicate;
- This->type = FUNC_UNASSIGNED;
-}
-
-void deleteFunctionEncoding(FunctionEncoding *This) {
-}
-
-void setFunctionEncodingType(FunctionEncoding *encoding, FunctionEncodingType type) {
- encoding->type = type;
-}
--- /dev/null
+#include "functionencoding.h"
+
+void initFunctionEncoding(FunctionEncoding *This, Element *function) {
+ This->op.function = function;
+ This->type = FUNC_UNASSIGNED;
+}
+
+void initPredicateEncoding(FunctionEncoding *This, Boolean *predicate) {
+ This->op.predicate = predicate;
+ This->type = FUNC_UNASSIGNED;
+}
+
+void deleteFunctionEncoding(FunctionEncoding *This) {
+}
+
+void setFunctionEncodingType(FunctionEncoding *encoding, FunctionEncodingType type) {
+ encoding->type = type;
+}
+++ /dev/null
-#include "naiveencoder.h"
-#include "elementencoding.h"
-#include "element.h"
-#include "functionencoding.h"
-#include "function.h"
-#include "set.h"
-#include "common.h"
-#include "structs.h"
-#include "csolver.h"
-#include "boolean.h"
-#include "table.h"
-#include "tableentry.h"
-#include "order.h"
-#include <strings.h>
-
-void naiveEncodingDecision(CSolver *This) {
- HSIteratorBoolean *iterator=iteratorBoolean(This->constraints);
- while(hasNextBoolean(iterator)) {
- Boolean *boolean = nextBoolean(iterator);
- naiveEncodingConstraint(boolean);
- }
- deleteIterBoolean(iterator);
-}
-
-void naiveEncodingConstraint(Boolean *This) {
- switch (GETBOOLEANTYPE(This)) {
- case BOOLEANVAR: {
- return;
- }
- case ORDERCONST: {
- setOrderEncodingType( ((BooleanOrder *)This)->order, PAIRWISE );
- return;
- }
- case LOGICOP: {
- naiveEncodingLogicOp((BooleanLogic *) This);
- return;
- }
- case PREDICATEOP: {
- naiveEncodingPredicate((BooleanPredicate *) This);
- return;
- }
- default:
- ASSERT(0);
- }
-}
-
-void naiveEncodingLogicOp(BooleanLogic *This) {
- for (uint i = 0; i < getSizeArrayBoolean(&This->inputs); i++) {
- naiveEncodingConstraint(getArrayBoolean(&This->inputs, i));
- }
-}
-
-void naiveEncodingPredicate(BooleanPredicate *This) {
- FunctionEncoding *encoding = getPredicateFunctionEncoding(This);
- if (getFunctionEncodingType(encoding) == FUNC_UNASSIGNED)
- setFunctionEncodingType(getPredicateFunctionEncoding(This), ENUMERATEIMPLICATIONS);
-
- for (uint i = 0; i < getSizeArrayElement(&This->inputs); i++) {
- Element *element = getArrayElement(&This->inputs, i);
- naiveEncodingElement(element);
- }
-}
-
-void naiveEncodingElement(Element *This) {
- ElementEncoding *encoding = getElementEncoding(This);
- if (getElementEncodingType(encoding) == ELEM_UNASSIGNED) {
- setElementEncodingType(encoding, BINARYINDEX);
- encodingArrayInitialization(encoding);
- }
-
- if (GETELEMENTTYPE(This) == ELEMFUNCRETURN) {
- ElementFunction *function = (ElementFunction *) This;
- for (uint i = 0; i < getSizeArrayElement(&function->inputs); i++) {
- Element *element = getArrayElement(&function->inputs, i);
- naiveEncodingElement(element);
- }
- FunctionEncoding *encoding = getElementFunctionEncoding(function);
- if (getFunctionEncodingType(encoding) == FUNC_UNASSIGNED)
- setFunctionEncodingType(getElementFunctionEncoding(function), ENUMERATEIMPLICATIONS);
- }
-}
-
-uint getSizeEncodingArray(ElementEncoding *This, uint setSize) {
- switch (This->type) {
- case BINARYINDEX:
- return NEXTPOW2(setSize);
- case ONEHOT:
- case UNARY:
- return setSize;
- default:
- ASSERT(0);
- }
- return -1;
-}
-
-void encodingArrayInitialization(ElementEncoding *This) {
- Element *element = This->element;
- Set *set = getElementSet(element);
- ASSERT(set->isRange == false);
- uint size = getSizeVectorInt(set->members);
- uint encSize = getSizeEncodingArray(This, size);
- allocEncodingArrayElement(This, encSize);
- allocInUseArrayElement(This, encSize);
- for (uint i = 0; i < size; i++) {
- This->encodingArray[i] = getVectorInt(set->members, i);
- setInUseElement(This, i);
- }
-}
--- /dev/null
+#include "naiveencoder.h"
+#include "elementencoding.h"
+#include "element.h"
+#include "functionencoding.h"
+#include "function.h"
+#include "set.h"
+#include "common.h"
+#include "structs.h"
+#include "csolver.h"
+#include "boolean.h"
+#include "table.h"
+#include "tableentry.h"
+#include "order.h"
+#include <strings.h>
+
+void naiveEncodingDecision(CSolver *This) {
+ HSIteratorBoolean *iterator=iteratorBoolean(This->constraints);
+ while(hasNextBoolean(iterator)) {
+ Boolean *boolean = nextBoolean(iterator);
+ naiveEncodingConstraint(boolean);
+ }
+ deleteIterBoolean(iterator);
+}
+
+void naiveEncodingConstraint(Boolean *This) {
+ switch (GETBOOLEANTYPE(This)) {
+ case BOOLEANVAR: {
+ return;
+ }
+ case ORDERCONST: {
+ setOrderEncodingType( ((BooleanOrder *)This)->order, PAIRWISE );
+ return;
+ }
+ case LOGICOP: {
+ naiveEncodingLogicOp((BooleanLogic *) This);
+ return;
+ }
+ case PREDICATEOP: {
+ naiveEncodingPredicate((BooleanPredicate *) This);
+ return;
+ }
+ default:
+ ASSERT(0);
+ }
+}
+
+void naiveEncodingLogicOp(BooleanLogic *This) {
+ for (uint i = 0; i < getSizeArrayBoolean(&This->inputs); i++) {
+ naiveEncodingConstraint(getArrayBoolean(&This->inputs, i));
+ }
+}
+
+void naiveEncodingPredicate(BooleanPredicate *This) {
+ FunctionEncoding *encoding = getPredicateFunctionEncoding(This);
+ if (getFunctionEncodingType(encoding) == FUNC_UNASSIGNED)
+ setFunctionEncodingType(getPredicateFunctionEncoding(This), ENUMERATEIMPLICATIONS);
+
+ for (uint i = 0; i < getSizeArrayElement(&This->inputs); i++) {
+ Element *element = getArrayElement(&This->inputs, i);
+ naiveEncodingElement(element);
+ }
+}
+
+void naiveEncodingElement(Element *This) {
+ ElementEncoding *encoding = getElementEncoding(This);
+ if (getElementEncodingType(encoding) == ELEM_UNASSIGNED) {
+ setElementEncodingType(encoding, BINARYINDEX);
+ encodingArrayInitialization(encoding);
+ }
+
+ if (GETELEMENTTYPE(This) == ELEMFUNCRETURN) {
+ ElementFunction *function = (ElementFunction *) This;
+ for (uint i = 0; i < getSizeArrayElement(&function->inputs); i++) {
+ Element *element = getArrayElement(&function->inputs, i);
+ naiveEncodingElement(element);
+ }
+ FunctionEncoding *encoding = getElementFunctionEncoding(function);
+ if (getFunctionEncodingType(encoding) == FUNC_UNASSIGNED)
+ setFunctionEncodingType(getElementFunctionEncoding(function), ENUMERATEIMPLICATIONS);
+ }
+}
+
+uint getSizeEncodingArray(ElementEncoding *This, uint setSize) {
+ switch (This->type) {
+ case BINARYINDEX:
+ return NEXTPOW2(setSize);
+ case ONEHOT:
+ case UNARY:
+ return setSize;
+ default:
+ ASSERT(0);
+ }
+ return -1;
+}
+
+void encodingArrayInitialization(ElementEncoding *This) {
+ Element *element = This->element;
+ Set *set = getElementSet(element);
+ ASSERT(set->isRange == false);
+ uint size = getSizeVectorInt(set->members);
+ uint encSize = getSizeEncodingArray(This, size);
+ allocEncodingArrayElement(This, encSize);
+ allocInUseArrayElement(This, encSize);
+ for (uint i = 0; i < size; i++) {
+ This->encodingArray[i] = getVectorInt(set->members, i);
+ setInUseElement(This, i);
+ }
+}
+++ /dev/null
-#include "orderedge.h"
-#include "ordergraph.h"
-
-OrderEdge *allocOrderEdge(OrderNode *source, OrderNode *sink) {
- OrderEdge *This = (OrderEdge *) ourmalloc(sizeof(OrderEdge));
- This->source = source;
- This->sink = sink;
- This->polPos = false;
- This->polNeg = false;
- This->mustPos = false;
- This->mustNeg = false;
- This->pseudoPos = false;
- return This;
-}
-
-void deleteOrderEdge(OrderEdge *This) {
- ourfree(This);
-}
-
--- /dev/null
+#include "orderedge.h"
+#include "ordergraph.h"
+
+OrderEdge *allocOrderEdge(OrderNode *source, OrderNode *sink) {
+ OrderEdge *This = (OrderEdge *) ourmalloc(sizeof(OrderEdge));
+ This->source = source;
+ This->sink = sink;
+ This->polPos = false;
+ This->polNeg = false;
+ This->mustPos = false;
+ This->mustNeg = false;
+ This->pseudoPos = false;
+ return This;
+}
+
+void deleteOrderEdge(OrderEdge *This) {
+ ourfree(This);
+}
+
+++ /dev/null
-#include "orderencoder.h"
-#include "structs.h"
-#include "csolver.h"
-#include "boolean.h"
-#include "ordergraph.h"
-#include "order.h"
-#include "ordernode.h"
-#include "rewriter.h"
-#include "mutableset.h"
-#include "tunable.h"
-
-void DFS(OrderGraph *graph, VectorOrderNode *finishNodes) {
- HSIteratorOrderNode *iterator = iteratorOrderNode(graph->nodes);
- while (hasNextOrderNode(iterator)) {
- OrderNode *node = nextOrderNode(iterator);
- if (node->status == NOTVISITED) {
- node->status = VISITED;
- DFSNodeVisit(node, finishNodes, false, false, 0);
- node->status = FINISHED;
- pushVectorOrderNode(finishNodes, node);
- }
- }
- deleteIterOrderNode(iterator);
-}
-
-void DFSReverse(OrderGraph *graph, VectorOrderNode *finishNodes) {
- uint size = getSizeVectorOrderNode(finishNodes);
- uint sccNum = 1;
- for (int i = size - 1; i >= 0; i--) {
- OrderNode *node = getVectorOrderNode(finishNodes, i);
- if (node->status == NOTVISITED) {
- node->status = VISITED;
- DFSNodeVisit(node, NULL, true, false, sccNum);
- node->sccNum = sccNum;
- node->status = FINISHED;
- sccNum++;
- }
- }
-}
-
-void DFSNodeVisit(OrderNode *node, VectorOrderNode *finishNodes, bool isReverse, bool mustvisit, uint sccNum) {
- HSIteratorOrderEdge *iterator = isReverse ? iteratorOrderEdge(node->inEdges) : iteratorOrderEdge(node->outEdges);
- while (hasNextOrderEdge(iterator)) {
- OrderEdge *edge = nextOrderEdge(iterator);
- if (mustvisit) {
- if (!edge->mustPos)
- continue;
- } else
- if (!edge->polPos && !edge->pseudoPos)//Ignore edges that do not have positive polarity
- continue;
-
- OrderNode *child = isReverse ? edge->source : edge->sink;
-
- if (child->status == NOTVISITED) {
- child->status = VISITED;
- DFSNodeVisit(child, finishNodes, isReverse, mustvisit, sccNum);
- child->status = FINISHED;
- if (finishNodes != NULL)
- pushVectorOrderNode(finishNodes, child);
- if (isReverse)
- child->sccNum = sccNum;
- }
- }
- deleteIterOrderEdge(iterator);
-}
-
-void resetNodeInfoStatusSCC(OrderGraph *graph) {
- HSIteratorOrderNode *iterator = iteratorOrderNode(graph->nodes);
- while (hasNextOrderNode(iterator)) {
- nextOrderNode(iterator)->status = NOTVISITED;
- }
- deleteIterOrderNode(iterator);
-}
-
-void computeStronglyConnectedComponentGraph(OrderGraph *graph) {
- VectorOrderNode finishNodes;
- initDefVectorOrderNode(&finishNodes);
- DFS(graph, &finishNodes);
- resetNodeInfoStatusSCC(graph);
- DFSReverse(graph, &finishNodes);
- resetNodeInfoStatusSCC(graph);
- deleteVectorArrayOrderNode(&finishNodes);
-}
-
-void removeMustBeTrueNodes(OrderGraph *graph) {
- //TODO: Nodes that all the incoming/outgoing edges are MUST_BE_TRUE
-}
-
-/** This function computes a source set for every nodes, the set of
- nodes that can reach that node via pospolarity edges. It then
- looks for negative polarity edges from nodes in the the source set
- to determine whether we need to generate pseudoPos edges. */
-
-void completePartialOrderGraph(OrderGraph *graph) {
- VectorOrderNode finishNodes;
- initDefVectorOrderNode(&finishNodes);
- DFS(graph, &finishNodes);
- resetNodeInfoStatusSCC(graph);
- HashTableNodeToNodeSet *table = allocHashTableNodeToNodeSet(128, 0.25);
-
- VectorOrderNode sccNodes;
- initDefVectorOrderNode(&sccNodes);
-
- uint size = getSizeVectorOrderNode(&finishNodes);
- uint sccNum = 1;
- for (int i = size - 1; i >= 0; i--) {
- OrderNode *node = getVectorOrderNode(&finishNodes, i);
- HashSetOrderNode *sources = allocHashSetOrderNode(4, 0.25);
- putNodeToNodeSet(table, node, sources);
-
- if (node->status == NOTVISITED) {
- //Need to do reverse traversal here...
- node->status = VISITED;
- DFSNodeVisit(node, &sccNodes, true, false, sccNum);
- node->status = FINISHED;
- node->sccNum = sccNum;
- sccNum++;
- pushVectorOrderNode(&sccNodes, node);
-
- //Compute in set for entire SCC
- uint rSize = getSizeVectorOrderNode(&sccNodes);
- for (int j = 0; j < rSize; j++) {
- OrderNode *rnode = getVectorOrderNode(&sccNodes, j);
- //Compute source sets
- HSIteratorOrderEdge *iterator = iteratorOrderEdge(rnode->inEdges);
- while (hasNextOrderEdge(iterator)) {
- OrderEdge *edge = nextOrderEdge(iterator);
- OrderNode *parent = edge->source;
- if (edge->polPos) {
- addHashSetOrderNode(sources, parent);
- HashSetOrderNode *parent_srcs = (HashSetOrderNode *)getNodeToNodeSet(table, parent);
- addAllHashSetOrderNode(sources, parent_srcs);
- }
- }
- deleteIterOrderEdge(iterator);
- }
- for (int j=0; j < rSize; j++) {
- //Copy in set of entire SCC
- OrderNode *rnode = getVectorOrderNode(&sccNodes, j);
- HashSetOrderNode * set = (j==0) ? sources : copyHashSetOrderNode(sources);
- putNodeToNodeSet(table, rnode, set);
-
- //Use source sets to compute pseudoPos edges
- HSIteratorOrderEdge *iterator = iteratorOrderEdge(rnode->inEdges);
- while (hasNextOrderEdge(iterator)) {
- OrderEdge *edge = nextOrderEdge(iterator);
- OrderNode *parent = edge->source;
- ASSERT(parent != rnode);
- if (edge->polNeg && parent->sccNum != rnode->sccNum &&
- containsHashSetOrderNode(sources, parent)) {
- OrderEdge *newedge = getOrderEdgeFromOrderGraph(graph, rnode, parent);
- newedge->pseudoPos = true;
- }
- }
- deleteIterOrderEdge(iterator);
- }
-
- clearVectorOrderNode(&sccNodes);
- }
- }
-
- resetAndDeleteHashTableNodeToNodeSet(table);
- deleteHashTableNodeToNodeSet(table);
- resetNodeInfoStatusSCC(graph);
- deleteVectorArrayOrderNode(&sccNodes);
- deleteVectorArrayOrderNode(&finishNodes);
-}
-
-void DFSMust(OrderGraph *graph, VectorOrderNode *finishNodes) {
- HSIteratorOrderNode *iterator = iteratorOrderNode(graph->nodes);
- while (hasNextOrderNode(iterator)) {
- OrderNode *node = nextOrderNode(iterator);
- if (node->status == NOTVISITED) {
- node->status = VISITED;
- DFSNodeVisit(node, finishNodes, false, true, 0);
- node->status = FINISHED;
- pushVectorOrderNode(finishNodes, node);
- }
- }
- deleteIterOrderNode(iterator);
-}
-
-void DFSClearContradictions(CSolver *solver, OrderGraph *graph, VectorOrderNode *finishNodes, bool computeTransitiveClosure) {
- uint size = getSizeVectorOrderNode(finishNodes);
- HashTableNodeToNodeSet *table = allocHashTableNodeToNodeSet(128, 0.25);
-
- for (int i = size - 1; i >= 0; i--) {
- OrderNode *node = getVectorOrderNode(finishNodes, i);
- HashSetOrderNode *sources = allocHashSetOrderNode(4, 0.25);
- putNodeToNodeSet(table, node, sources);
-
- {
- //Compute source sets
- HSIteratorOrderEdge *iterator = iteratorOrderEdge(node->inEdges);
- while (hasNextOrderEdge(iterator)) {
- OrderEdge *edge = nextOrderEdge(iterator);
- OrderNode *parent = edge->source;
- if (edge->mustPos) {
- addHashSetOrderNode(sources, parent);
- HashSetOrderNode *parent_srcs = (HashSetOrderNode *)getNodeToNodeSet(table, parent);
- addAllHashSetOrderNode(sources, parent_srcs);
- }
- }
- deleteIterOrderEdge(iterator);
- }
- if (computeTransitiveClosure) {
- //Compute full transitive closure for nodes
- HSIteratorOrderNode *srciterator = iteratorOrderNode(sources);
- while (hasNextOrderNode(srciterator)) {
- OrderNode *srcnode = nextOrderNode(srciterator);
- OrderEdge *newedge = getOrderEdgeFromOrderGraph(graph, srcnode, node);
- newedge->mustPos = true;
- newedge->polPos = true;
- if (newedge->mustNeg)
- solver->unsat = true;
- addHashSetOrderEdge(srcnode->outEdges,newedge);
- addHashSetOrderEdge(node->inEdges,newedge);
- }
- deleteIterOrderNode(srciterator);
- }
- {
- //Use source sets to compute mustPos edges
- HSIteratorOrderEdge *iterator = iteratorOrderEdge(node->inEdges);
- while (hasNextOrderEdge(iterator)) {
- OrderEdge *edge = nextOrderEdge(iterator);
- OrderNode *parent = edge->source;
- if (!edge->mustPos && containsHashSetOrderNode(sources, parent)) {
- edge->mustPos = true;
- edge->polPos = true;
- if (edge->mustNeg)
- solver->unsat = true;
- }
- }
- deleteIterOrderEdge(iterator);
- }
- {
- //Use source sets to compute mustNeg for edges that would introduce cycle if true
- HSIteratorOrderEdge *iterator = iteratorOrderEdge(node->outEdges);
- while (hasNextOrderEdge(iterator)) {
- OrderEdge *edge = nextOrderEdge(iterator);
- OrderNode *child = edge->sink;
- if (!edge->mustNeg && containsHashSetOrderNode(sources, child)) {
- edge->mustNeg = true;
- edge->polNeg = true;
- if (edge->mustPos)
- solver->unsat = true;
- }
- }
- deleteIterOrderEdge(iterator);
- }
- }
-
- resetAndDeleteHashTableNodeToNodeSet(table);
- deleteHashTableNodeToNodeSet(table);
-}
-
-/* This function finds edges that would form a cycle with must edges
- and forces them to be mustNeg. It also decides whether an edge
- must be true because of transitivity from other must be true
- edges. */
-
-void reachMustAnalysis(CSolver * solver, OrderGraph *graph, bool computeTransitiveClosure) {
- VectorOrderNode finishNodes;
- initDefVectorOrderNode(&finishNodes);
- //Topologically sort the mustPos edge graph
- DFSMust(graph, &finishNodes);
- resetNodeInfoStatusSCC(graph);
-
- //Find any backwards edges that complete cycles and force them to be mustNeg
- DFSClearContradictions(solver, graph, &finishNodes, computeTransitiveClosure);
- deleteVectorArrayOrderNode(&finishNodes);
-}
-
-/* This function finds edges that must be positive and forces the
- inverse edge to be negative (and clears its positive polarity if it
- had one). */
-
-void localMustAnalysisTotal(CSolver *solver, OrderGraph *graph) {
- HSIteratorOrderEdge *iterator = iteratorOrderEdge(graph->edges);
- while (hasNextOrderEdge(iterator)) {
- OrderEdge *edge = nextOrderEdge(iterator);
- if (edge->mustPos) {
- OrderEdge *invEdge = getInverseOrderEdge(graph, edge);
- if (invEdge != NULL) {
- if (!invEdge->mustPos) {
- invEdge->polPos = false;
- } else {
- solver->unsat = true;
- }
- invEdge->mustNeg = true;
- invEdge->polNeg = true;
- }
- }
- }
- deleteIterOrderEdge(iterator);
-}
-
-/** This finds edges that must be positive and forces the inverse edge
- to be negative. It also clears the negative flag of this edge.
- It also finds edges that must be negative and clears the positive
- polarity. */
-
-void localMustAnalysisPartial(CSolver *solver, OrderGraph *graph) {
- HSIteratorOrderEdge *iterator = iteratorOrderEdge(graph->edges);
- while (hasNextOrderEdge(iterator)) {
- OrderEdge *edge = nextOrderEdge(iterator);
- if (edge->mustPos) {
- if (!edge->mustNeg) {
- edge->polNeg = false;
- } else
- solver->unsat = true;
-
- OrderEdge *invEdge = getInverseOrderEdge(graph, edge);
- if (invEdge != NULL) {
- if (!invEdge->mustPos)
- invEdge->polPos = false;
- else
- solver->unsat = true;
- invEdge->mustNeg = true;
- invEdge->polNeg = true;
- }
- }
- if (edge->mustNeg && !edge->mustPos) {
- edge->polPos = false;
- }
- }
- deleteIterOrderEdge(iterator);
-}
-
-void decomposeOrder(CSolver *This, Order *order, OrderGraph *graph) {
- VectorOrder ordervec;
- VectorOrder partialcandidatevec;
- initDefVectorOrder(&ordervec);
- initDefVectorOrder(&partialcandidatevec);
- uint size = getSizeVectorBooleanOrder(&order->constraints);
- for (uint i = 0; i < size; i++) {
- BooleanOrder *orderconstraint = getVectorBooleanOrder(&order->constraints, i);
- OrderNode *from = getOrderNodeFromOrderGraph(graph, orderconstraint->first);
- OrderNode *to = getOrderNodeFromOrderGraph(graph, orderconstraint->second);
- model_print("from->sccNum:%u\tto->sccNum:%u\n", from->sccNum, to->sccNum);
- if (from->sccNum != to->sccNum) {
- OrderEdge *edge = getOrderEdgeFromOrderGraph(graph, from, to);
- if (edge->polPos) {
- replaceBooleanWithTrue(This, (Boolean *)orderconstraint);
- } else if (edge->polNeg) {
- replaceBooleanWithFalse(This, (Boolean *)orderconstraint);
- } else {
- //This case should only be possible if constraint isn't in AST
- ASSERT(0);
- }
- } else {
- //Build new order and change constraint's order
- Order *neworder = NULL;
- if (getSizeVectorOrder(&ordervec) > from->sccNum)
- neworder = getVectorOrder(&ordervec, from->sccNum);
- if (neworder == NULL) {
- Set *set = (Set *) allocMutableSet(order->set->type);
- neworder = allocOrder(order->type, set);
- pushVectorOrder(This->allOrders, neworder);
- setExpandVectorOrder(&ordervec, from->sccNum, neworder);
- if (order->type == PARTIAL)
- setExpandVectorOrder(&partialcandidatevec, from->sccNum, neworder);
- else
- setExpandVectorOrder(&partialcandidatevec, from->sccNum, NULL);
- }
- if (from->status != ADDEDTOSET) {
- from->status = ADDEDTOSET;
- addElementMSet((MutableSet *)neworder->set, from->id);
- }
- if (to->status != ADDEDTOSET) {
- to->status = ADDEDTOSET;
- addElementMSet((MutableSet *)neworder->set, to->id);
- }
- if (order->type == PARTIAL) {
- OrderEdge *edge = getOrderEdgeFromOrderGraph(graph, from, to);
- if (edge->polNeg)
- setExpandVectorOrder(&partialcandidatevec, from->sccNum, NULL);
- }
- orderconstraint->order = neworder;
- addOrderConstraint(neworder, orderconstraint);
- }
- }
-
- uint pcvsize=getSizeVectorOrder(&partialcandidatevec);
- for(uint i=0;i<pcvsize;i++) {
- Order * neworder=getVectorOrder(&partialcandidatevec, i);
- if (neworder != NULL){
- neworder->type = TOTAL;
- model_print("i=%u\t", i);
- }
- }
-
- deleteVectorArrayOrder(&ordervec);
- deleteVectorArrayOrder(&partialcandidatevec);
-}
-
-void orderAnalysis(CSolver *This) {
- uint size = getSizeVectorOrder(This->allOrders);
- for (uint i = 0; i < size; i++) {
- Order *order = getVectorOrder(This->allOrders, i);
- bool doDecompose=GETVARTUNABLE(This->tuner, order->type, DECOMPOSEORDER, &onoff);
- if (!doDecompose)
- continue;
-
- OrderGraph *graph = buildOrderGraph(order);
- if (order->type == PARTIAL) {
- //Required to do SCC analysis for partial order graphs. It
- //makes sure we don't incorrectly optimize graphs with negative
- //polarity edges
- completePartialOrderGraph(graph);
- }
-
-
- bool mustReachGlobal=GETVARTUNABLE(This->tuner, order->type, MUSTREACHGLOBAL, &onoff);
-
- if (mustReachGlobal)
- reachMustAnalysis(This, graph, false);
-
- bool mustReachLocal=GETVARTUNABLE(This->tuner, order->type, MUSTREACHLOCAL, &onoff);
-
- if (mustReachLocal) {
- //This pair of analysis is also optional
- if (order->type == PARTIAL) {
- localMustAnalysisPartial(This, graph);
- } else {
- localMustAnalysisTotal(This, graph);
- }
- }
-
- bool mustReachPrune=GETVARTUNABLE(This->tuner, order->type, MUSTREACHPRUNE, &onoff);
-
- if (mustReachPrune)
- removeMustBeTrueNodes(graph);
-
- //This is needed for splitorder
- computeStronglyConnectedComponentGraph(graph);
-
- decomposeOrder(This, order, graph);
-
- deleteOrderGraph(graph);
- }
-}
--- /dev/null
+#include "orderencoder.h"
+#include "structs.h"
+#include "csolver.h"
+#include "boolean.h"
+#include "ordergraph.h"
+#include "order.h"
+#include "ordernode.h"
+#include "rewriter.h"
+#include "mutableset.h"
+#include "tunable.h"
+
+void DFS(OrderGraph *graph, VectorOrderNode *finishNodes) {
+ HSIteratorOrderNode *iterator = iteratorOrderNode(graph->nodes);
+ while (hasNextOrderNode(iterator)) {
+ OrderNode *node = nextOrderNode(iterator);
+ if (node->status == NOTVISITED) {
+ node->status = VISITED;
+ DFSNodeVisit(node, finishNodes, false, false, 0);
+ node->status = FINISHED;
+ pushVectorOrderNode(finishNodes, node);
+ }
+ }
+ deleteIterOrderNode(iterator);
+}
+
+void DFSReverse(OrderGraph *graph, VectorOrderNode *finishNodes) {
+ uint size = getSizeVectorOrderNode(finishNodes);
+ uint sccNum = 1;
+ for (int i = size - 1; i >= 0; i--) {
+ OrderNode *node = getVectorOrderNode(finishNodes, i);
+ if (node->status == NOTVISITED) {
+ node->status = VISITED;
+ DFSNodeVisit(node, NULL, true, false, sccNum);
+ node->sccNum = sccNum;
+ node->status = FINISHED;
+ sccNum++;
+ }
+ }
+}
+
+void DFSNodeVisit(OrderNode *node, VectorOrderNode *finishNodes, bool isReverse, bool mustvisit, uint sccNum) {
+ HSIteratorOrderEdge *iterator = isReverse ? iteratorOrderEdge(node->inEdges) : iteratorOrderEdge(node->outEdges);
+ while (hasNextOrderEdge(iterator)) {
+ OrderEdge *edge = nextOrderEdge(iterator);
+ if (mustvisit) {
+ if (!edge->mustPos)
+ continue;
+ } else
+ if (!edge->polPos && !edge->pseudoPos)//Ignore edges that do not have positive polarity
+ continue;
+
+ OrderNode *child = isReverse ? edge->source : edge->sink;
+
+ if (child->status == NOTVISITED) {
+ child->status = VISITED;
+ DFSNodeVisit(child, finishNodes, isReverse, mustvisit, sccNum);
+ child->status = FINISHED;
+ if (finishNodes != NULL)
+ pushVectorOrderNode(finishNodes, child);
+ if (isReverse)
+ child->sccNum = sccNum;
+ }
+ }
+ deleteIterOrderEdge(iterator);
+}
+
+void resetNodeInfoStatusSCC(OrderGraph *graph) {
+ HSIteratorOrderNode *iterator = iteratorOrderNode(graph->nodes);
+ while (hasNextOrderNode(iterator)) {
+ nextOrderNode(iterator)->status = NOTVISITED;
+ }
+ deleteIterOrderNode(iterator);
+}
+
+void computeStronglyConnectedComponentGraph(OrderGraph *graph) {
+ VectorOrderNode finishNodes;
+ initDefVectorOrderNode(&finishNodes);
+ DFS(graph, &finishNodes);
+ resetNodeInfoStatusSCC(graph);
+ DFSReverse(graph, &finishNodes);
+ resetNodeInfoStatusSCC(graph);
+ deleteVectorArrayOrderNode(&finishNodes);
+}
+
+void removeMustBeTrueNodes(OrderGraph *graph) {
+ //TODO: Nodes that all the incoming/outgoing edges are MUST_BE_TRUE
+}
+
+/** This function computes a source set for every nodes, the set of
+ nodes that can reach that node via pospolarity edges. It then
+ looks for negative polarity edges from nodes in the the source set
+ to determine whether we need to generate pseudoPos edges. */
+
+void completePartialOrderGraph(OrderGraph *graph) {
+ VectorOrderNode finishNodes;
+ initDefVectorOrderNode(&finishNodes);
+ DFS(graph, &finishNodes);
+ resetNodeInfoStatusSCC(graph);
+ HashTableNodeToNodeSet *table = allocHashTableNodeToNodeSet(128, 0.25);
+
+ VectorOrderNode sccNodes;
+ initDefVectorOrderNode(&sccNodes);
+
+ uint size = getSizeVectorOrderNode(&finishNodes);
+ uint sccNum = 1;
+ for (int i = size - 1; i >= 0; i--) {
+ OrderNode *node = getVectorOrderNode(&finishNodes, i);
+ HashSetOrderNode *sources = allocHashSetOrderNode(4, 0.25);
+ putNodeToNodeSet(table, node, sources);
+
+ if (node->status == NOTVISITED) {
+ //Need to do reverse traversal here...
+ node->status = VISITED;
+ DFSNodeVisit(node, &sccNodes, true, false, sccNum);
+ node->status = FINISHED;
+ node->sccNum = sccNum;
+ sccNum++;
+ pushVectorOrderNode(&sccNodes, node);
+
+ //Compute in set for entire SCC
+ uint rSize = getSizeVectorOrderNode(&sccNodes);
+ for (int j = 0; j < rSize; j++) {
+ OrderNode *rnode = getVectorOrderNode(&sccNodes, j);
+ //Compute source sets
+ HSIteratorOrderEdge *iterator = iteratorOrderEdge(rnode->inEdges);
+ while (hasNextOrderEdge(iterator)) {
+ OrderEdge *edge = nextOrderEdge(iterator);
+ OrderNode *parent = edge->source;
+ if (edge->polPos) {
+ addHashSetOrderNode(sources, parent);
+ HashSetOrderNode *parent_srcs = (HashSetOrderNode *)getNodeToNodeSet(table, parent);
+ addAllHashSetOrderNode(sources, parent_srcs);
+ }
+ }
+ deleteIterOrderEdge(iterator);
+ }
+ for (int j=0; j < rSize; j++) {
+ //Copy in set of entire SCC
+ OrderNode *rnode = getVectorOrderNode(&sccNodes, j);
+ HashSetOrderNode * set = (j==0) ? sources : copyHashSetOrderNode(sources);
+ putNodeToNodeSet(table, rnode, set);
+
+ //Use source sets to compute pseudoPos edges
+ HSIteratorOrderEdge *iterator = iteratorOrderEdge(rnode->inEdges);
+ while (hasNextOrderEdge(iterator)) {
+ OrderEdge *edge = nextOrderEdge(iterator);
+ OrderNode *parent = edge->source;
+ ASSERT(parent != rnode);
+ if (edge->polNeg && parent->sccNum != rnode->sccNum &&
+ containsHashSetOrderNode(sources, parent)) {
+ OrderEdge *newedge = getOrderEdgeFromOrderGraph(graph, rnode, parent);
+ newedge->pseudoPos = true;
+ }
+ }
+ deleteIterOrderEdge(iterator);
+ }
+
+ clearVectorOrderNode(&sccNodes);
+ }
+ }
+
+ resetAndDeleteHashTableNodeToNodeSet(table);
+ deleteHashTableNodeToNodeSet(table);
+ resetNodeInfoStatusSCC(graph);
+ deleteVectorArrayOrderNode(&sccNodes);
+ deleteVectorArrayOrderNode(&finishNodes);
+}
+
+void DFSMust(OrderGraph *graph, VectorOrderNode *finishNodes) {
+ HSIteratorOrderNode *iterator = iteratorOrderNode(graph->nodes);
+ while (hasNextOrderNode(iterator)) {
+ OrderNode *node = nextOrderNode(iterator);
+ if (node->status == NOTVISITED) {
+ node->status = VISITED;
+ DFSNodeVisit(node, finishNodes, false, true, 0);
+ node->status = FINISHED;
+ pushVectorOrderNode(finishNodes, node);
+ }
+ }
+ deleteIterOrderNode(iterator);
+}
+
+void DFSClearContradictions(CSolver *solver, OrderGraph *graph, VectorOrderNode *finishNodes, bool computeTransitiveClosure) {
+ uint size = getSizeVectorOrderNode(finishNodes);
+ HashTableNodeToNodeSet *table = allocHashTableNodeToNodeSet(128, 0.25);
+
+ for (int i = size - 1; i >= 0; i--) {
+ OrderNode *node = getVectorOrderNode(finishNodes, i);
+ HashSetOrderNode *sources = allocHashSetOrderNode(4, 0.25);
+ putNodeToNodeSet(table, node, sources);
+
+ {
+ //Compute source sets
+ HSIteratorOrderEdge *iterator = iteratorOrderEdge(node->inEdges);
+ while (hasNextOrderEdge(iterator)) {
+ OrderEdge *edge = nextOrderEdge(iterator);
+ OrderNode *parent = edge->source;
+ if (edge->mustPos) {
+ addHashSetOrderNode(sources, parent);
+ HashSetOrderNode *parent_srcs = (HashSetOrderNode *)getNodeToNodeSet(table, parent);
+ addAllHashSetOrderNode(sources, parent_srcs);
+ }
+ }
+ deleteIterOrderEdge(iterator);
+ }
+ if (computeTransitiveClosure) {
+ //Compute full transitive closure for nodes
+ HSIteratorOrderNode *srciterator = iteratorOrderNode(sources);
+ while (hasNextOrderNode(srciterator)) {
+ OrderNode *srcnode = nextOrderNode(srciterator);
+ OrderEdge *newedge = getOrderEdgeFromOrderGraph(graph, srcnode, node);
+ newedge->mustPos = true;
+ newedge->polPos = true;
+ if (newedge->mustNeg)
+ solver->unsat = true;
+ addHashSetOrderEdge(srcnode->outEdges,newedge);
+ addHashSetOrderEdge(node->inEdges,newedge);
+ }
+ deleteIterOrderNode(srciterator);
+ }
+ {
+ //Use source sets to compute mustPos edges
+ HSIteratorOrderEdge *iterator = iteratorOrderEdge(node->inEdges);
+ while (hasNextOrderEdge(iterator)) {
+ OrderEdge *edge = nextOrderEdge(iterator);
+ OrderNode *parent = edge->source;
+ if (!edge->mustPos && containsHashSetOrderNode(sources, parent)) {
+ edge->mustPos = true;
+ edge->polPos = true;
+ if (edge->mustNeg)
+ solver->unsat = true;
+ }
+ }
+ deleteIterOrderEdge(iterator);
+ }
+ {
+ //Use source sets to compute mustNeg for edges that would introduce cycle if true
+ HSIteratorOrderEdge *iterator = iteratorOrderEdge(node->outEdges);
+ while (hasNextOrderEdge(iterator)) {
+ OrderEdge *edge = nextOrderEdge(iterator);
+ OrderNode *child = edge->sink;
+ if (!edge->mustNeg && containsHashSetOrderNode(sources, child)) {
+ edge->mustNeg = true;
+ edge->polNeg = true;
+ if (edge->mustPos)
+ solver->unsat = true;
+ }
+ }
+ deleteIterOrderEdge(iterator);
+ }
+ }
+
+ resetAndDeleteHashTableNodeToNodeSet(table);
+ deleteHashTableNodeToNodeSet(table);
+}
+
+/* This function finds edges that would form a cycle with must edges
+ and forces them to be mustNeg. It also decides whether an edge
+ must be true because of transitivity from other must be true
+ edges. */
+
+void reachMustAnalysis(CSolver * solver, OrderGraph *graph, bool computeTransitiveClosure) {
+ VectorOrderNode finishNodes;
+ initDefVectorOrderNode(&finishNodes);
+ //Topologically sort the mustPos edge graph
+ DFSMust(graph, &finishNodes);
+ resetNodeInfoStatusSCC(graph);
+
+ //Find any backwards edges that complete cycles and force them to be mustNeg
+ DFSClearContradictions(solver, graph, &finishNodes, computeTransitiveClosure);
+ deleteVectorArrayOrderNode(&finishNodes);
+}
+
+/* This function finds edges that must be positive and forces the
+ inverse edge to be negative (and clears its positive polarity if it
+ had one). */
+
+void localMustAnalysisTotal(CSolver *solver, OrderGraph *graph) {
+ HSIteratorOrderEdge *iterator = iteratorOrderEdge(graph->edges);
+ while (hasNextOrderEdge(iterator)) {
+ OrderEdge *edge = nextOrderEdge(iterator);
+ if (edge->mustPos) {
+ OrderEdge *invEdge = getInverseOrderEdge(graph, edge);
+ if (invEdge != NULL) {
+ if (!invEdge->mustPos) {
+ invEdge->polPos = false;
+ } else {
+ solver->unsat = true;
+ }
+ invEdge->mustNeg = true;
+ invEdge->polNeg = true;
+ }
+ }
+ }
+ deleteIterOrderEdge(iterator);
+}
+
+/** This finds edges that must be positive and forces the inverse edge
+ to be negative. It also clears the negative flag of this edge.
+ It also finds edges that must be negative and clears the positive
+ polarity. */
+
+void localMustAnalysisPartial(CSolver *solver, OrderGraph *graph) {
+ HSIteratorOrderEdge *iterator = iteratorOrderEdge(graph->edges);
+ while (hasNextOrderEdge(iterator)) {
+ OrderEdge *edge = nextOrderEdge(iterator);
+ if (edge->mustPos) {
+ if (!edge->mustNeg) {
+ edge->polNeg = false;
+ } else
+ solver->unsat = true;
+
+ OrderEdge *invEdge = getInverseOrderEdge(graph, edge);
+ if (invEdge != NULL) {
+ if (!invEdge->mustPos)
+ invEdge->polPos = false;
+ else
+ solver->unsat = true;
+ invEdge->mustNeg = true;
+ invEdge->polNeg = true;
+ }
+ }
+ if (edge->mustNeg && !edge->mustPos) {
+ edge->polPos = false;
+ }
+ }
+ deleteIterOrderEdge(iterator);
+}
+
+void decomposeOrder(CSolver *This, Order *order, OrderGraph *graph) {
+ VectorOrder ordervec;
+ VectorOrder partialcandidatevec;
+ initDefVectorOrder(&ordervec);
+ initDefVectorOrder(&partialcandidatevec);
+ uint size = getSizeVectorBooleanOrder(&order->constraints);
+ for (uint i = 0; i < size; i++) {
+ BooleanOrder *orderconstraint = getVectorBooleanOrder(&order->constraints, i);
+ OrderNode *from = getOrderNodeFromOrderGraph(graph, orderconstraint->first);
+ OrderNode *to = getOrderNodeFromOrderGraph(graph, orderconstraint->second);
+ model_print("from->sccNum:%u\tto->sccNum:%u\n", from->sccNum, to->sccNum);
+ if (from->sccNum != to->sccNum) {
+ OrderEdge *edge = getOrderEdgeFromOrderGraph(graph, from, to);
+ if (edge->polPos) {
+ replaceBooleanWithTrue(This, (Boolean *)orderconstraint);
+ } else if (edge->polNeg) {
+ replaceBooleanWithFalse(This, (Boolean *)orderconstraint);
+ } else {
+ //This case should only be possible if constraint isn't in AST
+ ASSERT(0);
+ }
+ } else {
+ //Build new order and change constraint's order
+ Order *neworder = NULL;
+ if (getSizeVectorOrder(&ordervec) > from->sccNum)
+ neworder = getVectorOrder(&ordervec, from->sccNum);
+ if (neworder == NULL) {
+ Set *set = (Set *) allocMutableSet(order->set->type);
+ neworder = allocOrder(order->type, set);
+ pushVectorOrder(This->allOrders, neworder);
+ setExpandVectorOrder(&ordervec, from->sccNum, neworder);
+ if (order->type == PARTIAL)
+ setExpandVectorOrder(&partialcandidatevec, from->sccNum, neworder);
+ else
+ setExpandVectorOrder(&partialcandidatevec, from->sccNum, NULL);
+ }
+ if (from->status != ADDEDTOSET) {
+ from->status = ADDEDTOSET;
+ addElementMSet((MutableSet *)neworder->set, from->id);
+ }
+ if (to->status != ADDEDTOSET) {
+ to->status = ADDEDTOSET;
+ addElementMSet((MutableSet *)neworder->set, to->id);
+ }
+ if (order->type == PARTIAL) {
+ OrderEdge *edge = getOrderEdgeFromOrderGraph(graph, from, to);
+ if (edge->polNeg)
+ setExpandVectorOrder(&partialcandidatevec, from->sccNum, NULL);
+ }
+ orderconstraint->order = neworder;
+ addOrderConstraint(neworder, orderconstraint);
+ }
+ }
+
+ uint pcvsize=getSizeVectorOrder(&partialcandidatevec);
+ for(uint i=0;i<pcvsize;i++) {
+ Order * neworder=getVectorOrder(&partialcandidatevec, i);
+ if (neworder != NULL){
+ neworder->type = TOTAL;
+ model_print("i=%u\t", i);
+ }
+ }
+
+ deleteVectorArrayOrder(&ordervec);
+ deleteVectorArrayOrder(&partialcandidatevec);
+}
+
+void orderAnalysis(CSolver *This) {
+ uint size = getSizeVectorOrder(This->allOrders);
+ for (uint i = 0; i < size; i++) {
+ Order *order = getVectorOrder(This->allOrders, i);
+ bool doDecompose=GETVARTUNABLE(This->tuner, order->type, DECOMPOSEORDER, &onoff);
+ if (!doDecompose)
+ continue;
+
+ OrderGraph *graph = buildOrderGraph(order);
+ if (order->type == PARTIAL) {
+ //Required to do SCC analysis for partial order graphs. It
+ //makes sure we don't incorrectly optimize graphs with negative
+ //polarity edges
+ completePartialOrderGraph(graph);
+ }
+
+
+ bool mustReachGlobal=GETVARTUNABLE(This->tuner, order->type, MUSTREACHGLOBAL, &onoff);
+
+ if (mustReachGlobal)
+ reachMustAnalysis(This, graph, false);
+
+ bool mustReachLocal=GETVARTUNABLE(This->tuner, order->type, MUSTREACHLOCAL, &onoff);
+
+ if (mustReachLocal) {
+ //This pair of analysis is also optional
+ if (order->type == PARTIAL) {
+ localMustAnalysisPartial(This, graph);
+ } else {
+ localMustAnalysisTotal(This, graph);
+ }
+ }
+
+ bool mustReachPrune=GETVARTUNABLE(This->tuner, order->type, MUSTREACHPRUNE, &onoff);
+
+ if (mustReachPrune)
+ removeMustBeTrueNodes(graph);
+
+ //This is needed for splitorder
+ computeStronglyConnectedComponentGraph(graph);
+
+ decomposeOrder(This, order, graph);
+
+ deleteOrderGraph(graph);
+ }
+}
+++ /dev/null
-#include "orderencoding.h"
-
-void initOrderEncoding(OrderEncoding *This, Order *order) {
- This->type = ORDER_UNASSIGNED;
- This->order = order;
-}
-
-void deleteOrderEncoding(OrderEncoding *This) {
-}
--- /dev/null
+#include "orderencoding.h"
+
+void initOrderEncoding(OrderEncoding *This, Order *order) {
+ This->type = ORDER_UNASSIGNED;
+ This->order = order;
+}
+
+void deleteOrderEncoding(OrderEncoding *This) {
+}
+++ /dev/null
-#include "ordergraph.h"
-#include "ordernode.h"
-#include "boolean.h"
-#include "orderedge.h"
-#include "ordergraph.h"
-#include "order.h"
-
-OrderGraph *allocOrderGraph(Order *order) {
- OrderGraph *This = (OrderGraph *) ourmalloc(sizeof(OrderGraph));
- This->nodes = allocHashSetOrderNode(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
- This->edges = allocHashSetOrderEdge(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
- This->order = order;
- return This;
-}
-
-OrderGraph *buildOrderGraph(Order *order) {
- OrderGraph *orderGraph = allocOrderGraph(order);
- uint constrSize = getSizeVectorBooleanOrder(&order->constraints);
- for (uint j = 0; j < constrSize; j++) {
- addOrderConstraintToOrderGraph(orderGraph, getVectorBooleanOrder(&order->constraints, j));
- }
- return orderGraph;
-}
-
-//Builds only the subgraph for the must order graph.
-OrderGraph *buildMustOrderGraph(Order *order) {
- OrderGraph *orderGraph = allocOrderGraph(order);
- uint constrSize = getSizeVectorBooleanOrder(&order->constraints);
- for (uint j = 0; j < constrSize; j++) {
- addMustOrderConstraintToOrderGraph(orderGraph, getVectorBooleanOrder(&order->constraints, j));
- }
- return orderGraph;
-}
-
-void addOrderEdge(OrderGraph *graph, OrderNode *node1, OrderNode *node2, BooleanOrder *constr) {
- Polarity polarity = constr->base.polarity;
- BooleanValue mustval = constr->base.boolVal;
- Order *order = graph->order;
- switch (polarity) {
- case P_BOTHTRUEFALSE:
- case P_TRUE: {
- OrderEdge *_1to2 = getOrderEdgeFromOrderGraph(graph, node1, node2);
- if (mustval == BV_MUSTBETRUE || mustval == BV_UNSAT)
- _1to2->mustPos = true;
- _1to2->polPos = true;
- addNewOutgoingEdge(node1, _1to2);
- addNewIncomingEdge(node2, _1to2);
- if (constr->base.polarity == P_TRUE)
- break;
- }
- case P_FALSE: {
- if (order->type == TOTAL) {
- OrderEdge *_2to1 = getOrderEdgeFromOrderGraph(graph, node2, node1);
- if (mustval == BV_MUSTBEFALSE || mustval == BV_UNSAT)
- _2to1->mustPos = true;
- _2to1->polPos = true;
- addNewOutgoingEdge(node2, _2to1);
- addNewIncomingEdge(node1, _2to1);
- } else {
- OrderEdge *_1to2 = getOrderEdgeFromOrderGraph(graph, node1, node2);
- if (mustval == BV_MUSTBEFALSE || mustval == BV_UNSAT)
- _1to2->mustNeg = true;
- _1to2->polNeg = true;
- addNewOutgoingEdge(node1, _1to2);
- addNewIncomingEdge(node2, _1to2);
- }
- break;
- }
- case P_UNDEFINED:
- //There is an unreachable order constraint if this assert fires
- ASSERT(0);
- }
-}
-
-void addMustOrderEdge(OrderGraph *graph, OrderNode *node1, OrderNode *node2, BooleanOrder *constr) {
- BooleanValue mustval = constr->base.boolVal;
- Order *order = graph->order;
- switch (mustval) {
- case BV_UNSAT:
- case BV_MUSTBETRUE: {
- OrderEdge *_1to2 = getOrderEdgeFromOrderGraph(graph, node1, node2);
- _1to2->mustPos = true;
- _1to2->polPos = true;
- addNewOutgoingEdge(node1, _1to2);
- addNewIncomingEdge(node2, _1to2);
- if (constr->base.boolVal == BV_MUSTBETRUE)
- break;
- }
- case BV_MUSTBEFALSE: {
- if (order->type == TOTAL) {
- OrderEdge *_2to1 = getOrderEdgeFromOrderGraph(graph, node2, node1);
- _2to1->mustPos = true;
- _2to1->polPos = true;
- addNewOutgoingEdge(node2, _2to1);
- addNewIncomingEdge(node1, _2to1);
- } else {
- OrderEdge *_1to2 = getOrderEdgeFromOrderGraph(graph, node1, node2);
- _1to2->mustNeg = true;
- _1to2->polNeg = true;
- addNewOutgoingEdge(node1, _1to2);
- addNewIncomingEdge(node2, _1to2);
- }
- break;
- }
- case BV_UNDEFINED:
- //Do Nothing
- break;
- }
-}
-
-OrderNode *getOrderNodeFromOrderGraph(OrderGraph *graph, uint64_t id) {
- OrderNode *node = allocOrderNode(id);
- OrderNode *tmp = getHashSetOrderNode(graph->nodes, node);
- if ( tmp != NULL) {
- deleteOrderNode(node);
- node = tmp;
- } else {
- addHashSetOrderNode(graph->nodes, node);
- }
- return node;
-}
-
-OrderNode *lookupOrderNodeFromOrderGraph(OrderGraph *graph, uint64_t id) {
- OrderNode node = {id, NULL, NULL, 0, 0};
- OrderNode *tmp = getHashSetOrderNode(graph->nodes, &node);
- return tmp;
-}
-
-OrderEdge *getOrderEdgeFromOrderGraph(OrderGraph *graph, OrderNode *begin, OrderNode *end) {
- OrderEdge *edge = allocOrderEdge(begin, end);
- OrderEdge *tmp = getHashSetOrderEdge(graph->edges, edge);
- if ( tmp != NULL ) {
- deleteOrderEdge(edge);
- edge = tmp;
- } else {
- addHashSetOrderEdge(graph->edges, edge);
- }
- return edge;
-}
-
-OrderEdge *lookupOrderEdgeFromOrderGraph(OrderGraph *graph, OrderNode *begin, OrderNode *end) {
- OrderEdge edge = {begin, end, 0, 0, 0, 0, 0};
- OrderEdge *tmp = getHashSetOrderEdge(graph->edges, &edge);
- return tmp;
-}
-
-OrderEdge *getInverseOrderEdge(OrderGraph *graph, OrderEdge *edge) {
- OrderEdge inverseedge = {edge->sink, edge->source, false, false, false, false, false};
- OrderEdge *tmp = getHashSetOrderEdge(graph->edges, &inverseedge);
- return tmp;
-}
-
-void addOrderConstraintToOrderGraph(OrderGraph *graph, BooleanOrder *bOrder) {
- OrderNode *from = getOrderNodeFromOrderGraph(graph, bOrder->first);
- OrderNode *to = getOrderNodeFromOrderGraph(graph, bOrder->second);
- addOrderEdge(graph, from, to, bOrder);
-}
-
-void addMustOrderConstraintToOrderGraph(OrderGraph *graph, BooleanOrder *bOrder) {
- OrderNode *from = getOrderNodeFromOrderGraph(graph, bOrder->first);
- OrderNode *to = getOrderNodeFromOrderGraph(graph, bOrder->second);
- addMustOrderEdge(graph, from, to, bOrder);
-}
-
-void deleteOrderGraph(OrderGraph *graph) {
- HSIteratorOrderNode *iterator = iteratorOrderNode(graph->nodes);
- while (hasNextOrderNode(iterator)) {
- OrderNode *node = nextOrderNode(iterator);
- deleteOrderNode(node);
- }
- deleteIterOrderNode(iterator);
-
- HSIteratorOrderEdge *eiterator = iteratorOrderEdge(graph->edges);
- while (hasNextOrderEdge(eiterator)) {
- OrderEdge *edge = nextOrderEdge(eiterator);
- deleteOrderEdge(edge);
- }
- deleteIterOrderEdge(eiterator);
- deleteHashSetOrderNode(graph->nodes);
- deleteHashSetOrderEdge(graph->edges);
- ourfree(graph);
-}
--- /dev/null
+#include "ordergraph.h"
+#include "ordernode.h"
+#include "boolean.h"
+#include "orderedge.h"
+#include "ordergraph.h"
+#include "order.h"
+
+OrderGraph *allocOrderGraph(Order *order) {
+ OrderGraph *This = (OrderGraph *) ourmalloc(sizeof(OrderGraph));
+ This->nodes = allocHashSetOrderNode(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
+ This->edges = allocHashSetOrderEdge(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
+ This->order = order;
+ return This;
+}
+
+OrderGraph *buildOrderGraph(Order *order) {
+ OrderGraph *orderGraph = allocOrderGraph(order);
+ uint constrSize = getSizeVectorBooleanOrder(&order->constraints);
+ for (uint j = 0; j < constrSize; j++) {
+ addOrderConstraintToOrderGraph(orderGraph, getVectorBooleanOrder(&order->constraints, j));
+ }
+ return orderGraph;
+}
+
+//Builds only the subgraph for the must order graph.
+OrderGraph *buildMustOrderGraph(Order *order) {
+ OrderGraph *orderGraph = allocOrderGraph(order);
+ uint constrSize = getSizeVectorBooleanOrder(&order->constraints);
+ for (uint j = 0; j < constrSize; j++) {
+ addMustOrderConstraintToOrderGraph(orderGraph, getVectorBooleanOrder(&order->constraints, j));
+ }
+ return orderGraph;
+}
+
+void addOrderEdge(OrderGraph *graph, OrderNode *node1, OrderNode *node2, BooleanOrder *constr) {
+ Polarity polarity = constr->base.polarity;
+ BooleanValue mustval = constr->base.boolVal;
+ Order *order = graph->order;
+ switch (polarity) {
+ case P_BOTHTRUEFALSE:
+ case P_TRUE: {
+ OrderEdge *_1to2 = getOrderEdgeFromOrderGraph(graph, node1, node2);
+ if (mustval == BV_MUSTBETRUE || mustval == BV_UNSAT)
+ _1to2->mustPos = true;
+ _1to2->polPos = true;
+ addNewOutgoingEdge(node1, _1to2);
+ addNewIncomingEdge(node2, _1to2);
+ if (constr->base.polarity == P_TRUE)
+ break;
+ }
+ case P_FALSE: {
+ if (order->type == TOTAL) {
+ OrderEdge *_2to1 = getOrderEdgeFromOrderGraph(graph, node2, node1);
+ if (mustval == BV_MUSTBEFALSE || mustval == BV_UNSAT)
+ _2to1->mustPos = true;
+ _2to1->polPos = true;
+ addNewOutgoingEdge(node2, _2to1);
+ addNewIncomingEdge(node1, _2to1);
+ } else {
+ OrderEdge *_1to2 = getOrderEdgeFromOrderGraph(graph, node1, node2);
+ if (mustval == BV_MUSTBEFALSE || mustval == BV_UNSAT)
+ _1to2->mustNeg = true;
+ _1to2->polNeg = true;
+ addNewOutgoingEdge(node1, _1to2);
+ addNewIncomingEdge(node2, _1to2);
+ }
+ break;
+ }
+ case P_UNDEFINED:
+ //There is an unreachable order constraint if this assert fires
+ ASSERT(0);
+ }
+}
+
+void addMustOrderEdge(OrderGraph *graph, OrderNode *node1, OrderNode *node2, BooleanOrder *constr) {
+ BooleanValue mustval = constr->base.boolVal;
+ Order *order = graph->order;
+ switch (mustval) {
+ case BV_UNSAT:
+ case BV_MUSTBETRUE: {
+ OrderEdge *_1to2 = getOrderEdgeFromOrderGraph(graph, node1, node2);
+ _1to2->mustPos = true;
+ _1to2->polPos = true;
+ addNewOutgoingEdge(node1, _1to2);
+ addNewIncomingEdge(node2, _1to2);
+ if (constr->base.boolVal == BV_MUSTBETRUE)
+ break;
+ }
+ case BV_MUSTBEFALSE: {
+ if (order->type == TOTAL) {
+ OrderEdge *_2to1 = getOrderEdgeFromOrderGraph(graph, node2, node1);
+ _2to1->mustPos = true;
+ _2to1->polPos = true;
+ addNewOutgoingEdge(node2, _2to1);
+ addNewIncomingEdge(node1, _2to1);
+ } else {
+ OrderEdge *_1to2 = getOrderEdgeFromOrderGraph(graph, node1, node2);
+ _1to2->mustNeg = true;
+ _1to2->polNeg = true;
+ addNewOutgoingEdge(node1, _1to2);
+ addNewIncomingEdge(node2, _1to2);
+ }
+ break;
+ }
+ case BV_UNDEFINED:
+ //Do Nothing
+ break;
+ }
+}
+
+OrderNode *getOrderNodeFromOrderGraph(OrderGraph *graph, uint64_t id) {
+ OrderNode *node = allocOrderNode(id);
+ OrderNode *tmp = getHashSetOrderNode(graph->nodes, node);
+ if ( tmp != NULL) {
+ deleteOrderNode(node);
+ node = tmp;
+ } else {
+ addHashSetOrderNode(graph->nodes, node);
+ }
+ return node;
+}
+
+OrderNode *lookupOrderNodeFromOrderGraph(OrderGraph *graph, uint64_t id) {
+ OrderNode node = {id, NULL, NULL, NOTVISITED, 0};
+ OrderNode *tmp = getHashSetOrderNode(graph->nodes, &node);
+ return tmp;
+}
+
+OrderEdge *getOrderEdgeFromOrderGraph(OrderGraph *graph, OrderNode *begin, OrderNode *end) {
+ OrderEdge *edge = allocOrderEdge(begin, end);
+ OrderEdge *tmp = getHashSetOrderEdge(graph->edges, edge);
+ if ( tmp != NULL ) {
+ deleteOrderEdge(edge);
+ edge = tmp;
+ } else {
+ addHashSetOrderEdge(graph->edges, edge);
+ }
+ return edge;
+}
+
+OrderEdge *lookupOrderEdgeFromOrderGraph(OrderGraph *graph, OrderNode *begin, OrderNode *end) {
+ OrderEdge edge = {begin, end, 0, 0, 0, 0, 0};
+ OrderEdge *tmp = getHashSetOrderEdge(graph->edges, &edge);
+ return tmp;
+}
+
+OrderEdge *getInverseOrderEdge(OrderGraph *graph, OrderEdge *edge) {
+ OrderEdge inverseedge = {edge->sink, edge->source, false, false, false, false, false};
+ OrderEdge *tmp = getHashSetOrderEdge(graph->edges, &inverseedge);
+ return tmp;
+}
+
+void addOrderConstraintToOrderGraph(OrderGraph *graph, BooleanOrder *bOrder) {
+ OrderNode *from = getOrderNodeFromOrderGraph(graph, bOrder->first);
+ OrderNode *to = getOrderNodeFromOrderGraph(graph, bOrder->second);
+ addOrderEdge(graph, from, to, bOrder);
+}
+
+void addMustOrderConstraintToOrderGraph(OrderGraph *graph, BooleanOrder *bOrder) {
+ OrderNode *from = getOrderNodeFromOrderGraph(graph, bOrder->first);
+ OrderNode *to = getOrderNodeFromOrderGraph(graph, bOrder->second);
+ addMustOrderEdge(graph, from, to, bOrder);
+}
+
+void deleteOrderGraph(OrderGraph *graph) {
+ HSIteratorOrderNode *iterator = iteratorOrderNode(graph->nodes);
+ while (hasNextOrderNode(iterator)) {
+ OrderNode *node = nextOrderNode(iterator);
+ deleteOrderNode(node);
+ }
+ deleteIterOrderNode(iterator);
+
+ HSIteratorOrderEdge *eiterator = iteratorOrderEdge(graph->edges);
+ while (hasNextOrderEdge(eiterator)) {
+ OrderEdge *edge = nextOrderEdge(eiterator);
+ deleteOrderEdge(edge);
+ }
+ deleteIterOrderEdge(eiterator);
+ deleteHashSetOrderNode(graph->nodes);
+ deleteHashSetOrderEdge(graph->edges);
+ ourfree(graph);
+}
+++ /dev/null
-#include "ordernode.h"
-#include "orderedge.h"
-
-OrderNode *allocOrderNode(uint64_t id) {
- OrderNode *This = (OrderNode *) ourmalloc(sizeof(OrderNode));
- This->id = id;
- This->inEdges = allocHashSetOrderEdge(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
- This->outEdges = allocHashSetOrderEdge(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
- This->status = NOTVISITED;
- This->sccNum = 0;
- return This;
-}
-
-void addNewIncomingEdge(OrderNode *node, OrderEdge *edge) {
- ASSERT(!containsHashSetOrderEdge(node->inEdges, edge)); // Only for testing ... Should be removed after testing
- addHashSetOrderEdge(node->inEdges, edge);
-}
-
-void addNewOutgoingEdge(OrderNode *node, OrderEdge *edge) {
- ASSERT(!containsHashSetOrderEdge(node->outEdges, edge));
- addHashSetOrderEdge(node->outEdges, edge);
-}
-
-void deleteOrderNode(OrderNode *node) {
- deleteHashSetOrderEdge(node->inEdges);
- deleteHashSetOrderEdge(node->outEdges);
- ourfree(node);
-}
--- /dev/null
+#include "ordernode.h"
+#include "orderedge.h"
+
+OrderNode *allocOrderNode(uint64_t id) {
+ OrderNode *This = (OrderNode *) ourmalloc(sizeof(OrderNode));
+ This->id = id;
+ This->inEdges = allocHashSetOrderEdge(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
+ This->outEdges = allocHashSetOrderEdge(HT_INITIAL_CAPACITY, HT_DEFAULT_FACTOR);
+ This->status = NOTVISITED;
+ This->sccNum = 0;
+ return This;
+}
+
+void addNewIncomingEdge(OrderNode *node, OrderEdge *edge) {
+ ASSERT(!containsHashSetOrderEdge(node->inEdges, edge)); // Only for testing ... Should be removed after testing
+ addHashSetOrderEdge(node->inEdges, edge);
+}
+
+void addNewOutgoingEdge(OrderNode *node, OrderEdge *edge) {
+ ASSERT(!containsHashSetOrderEdge(node->outEdges, edge));
+ addHashSetOrderEdge(node->outEdges, edge);
+}
+
+void deleteOrderNode(OrderNode *node) {
+ deleteHashSetOrderEdge(node->inEdges);
+ deleteHashSetOrderEdge(node->outEdges);
+ ourfree(node);
+}
+++ /dev/null
-#include "polarityassignment.h"
-#include "csolver.h"
-
-void computePolarities(CSolver *This) {
- HSIteratorBoolean *iterator=iteratorBoolean(This->constraints);
- while(hasNextBoolean(iterator)) {
- Boolean *boolean = nextBoolean(iterator);
- updatePolarity(boolean, P_TRUE);
- updateMustValue(boolean, BV_MUSTBETRUE);
- computePolarityAndBooleanValue(boolean);
- }
- deleteIterBoolean(iterator);
-}
-
-void updatePolarity(Boolean *This, Polarity polarity) {
- This->polarity |= polarity;
-}
-
-void updateMustValue(Boolean *This, BooleanValue value) {
- This->boolVal |= value;
-}
-
-void computePolarityAndBooleanValue(Boolean *This) {
- switch (GETBOOLEANTYPE(This)) {
- case BOOLEANVAR:
- case ORDERCONST:
- return;
- case PREDICATEOP:
- return computePredicatePolarityAndBooleanValue((BooleanPredicate *)This);
- case LOGICOP:
- return computeLogicOpPolarityAndBooleanValue((BooleanLogic *)This);
- default:
- ASSERT(0);
- }
-}
-
-void computePredicatePolarityAndBooleanValue(BooleanPredicate *This) {
- updatePolarity(This->undefStatus, P_BOTHTRUEFALSE);
- computePolarityAndBooleanValue(This->undefStatus);
-}
-
-void computeLogicOpPolarityAndBooleanValue(BooleanLogic *This) {
- computeLogicOpBooleanValue(This);
- computeLogicOpPolarity(This);
- uint size = getSizeArrayBoolean(&This->inputs);
- for (uint i = 0; i < size; i++) {
- computePolarityAndBooleanValue(getArrayBoolean(&This->inputs, i));
- }
-}
-
-Polarity negatePolarity(Polarity This) {
- switch (This) {
- case P_UNDEFINED:
- case P_BOTHTRUEFALSE:
- return This;
- case P_TRUE:
- return P_FALSE;
- case P_FALSE:
- return P_TRUE;
- default:
- ASSERT(0);
- }
-}
-
-BooleanValue negateBooleanValue(BooleanValue This) {
- switch (This) {
- case BV_UNDEFINED:
- case BV_UNSAT:
- return This;
- case BV_MUSTBETRUE:
- return BV_MUSTBEFALSE;
- case BV_MUSTBEFALSE:
- return BV_MUSTBETRUE;
- default:
- ASSERT(0);
- }
-}
-
-void computeLogicOpPolarity(BooleanLogic *This) {
- Polarity parentpolarity = GETBOOLEANPOLARITY(This);
- switch (This->op) {
- case L_AND:
- case L_OR: {
- uint size = getSizeArrayBoolean(&This->inputs);
- for (uint i = 0; i < size; i++) {
- Boolean *tmp = getArrayBoolean(&This->inputs, i);
- updatePolarity(tmp, parentpolarity);
- }
- break;
- }
- case L_NOT: {
- Boolean *tmp = getArrayBoolean(&This->inputs, 0);
- updatePolarity(tmp, negatePolarity(parentpolarity));
- break;
- }
- case L_XOR: {
- updatePolarity(getArrayBoolean(&This->inputs, 0), P_BOTHTRUEFALSE);
- updatePolarity(getArrayBoolean(&This->inputs, 1), P_BOTHTRUEFALSE);
- break;
- }
- case L_IMPLIES: {
- Boolean *left = getArrayBoolean(&This->inputs, 0);
- updatePolarity(left, negatePolarity( parentpolarity));
- Boolean *right = getArrayBoolean(&This->inputs, 1);
- updatePolarity(right, parentpolarity);
- break;
- }
- default:
- ASSERT(0);
- }
-}
-
-void computeLogicOpBooleanValue(BooleanLogic *This) {
- BooleanValue parentbv = GETBOOLEANVALUE(This);
- switch (This->op) {
- case L_AND: {
- if (parentbv == BV_MUSTBETRUE || parentbv == BV_UNSAT) {
- uint size = getSizeArrayBoolean(&This->inputs);
- for (uint i = 0; i < size; i++) {
- updateMustValue(getArrayBoolean(&This->inputs, i), parentbv);
- }
- }
- return;
- }
- case L_OR: {
- if (parentbv == BV_MUSTBEFALSE || parentbv == BV_UNSAT) {
- uint size = getSizeArrayBoolean(&This->inputs);
- for (uint i = 0; i < size; i++) {
- updateMustValue(getArrayBoolean(&This->inputs, i), parentbv);
- }
- }
- return;
- }
- case L_NOT:
- updateMustValue(getArrayBoolean(&This->inputs, 0), negateBooleanValue(parentbv));
- return;
- case L_IMPLIES:
- //implies is really an or with the first term negated
- if (parentbv == BV_MUSTBEFALSE || parentbv == BV_UNSAT) {
- uint size = getSizeArrayBoolean(&This->inputs);
- updateMustValue(getArrayBoolean(&This->inputs, 0), negateBooleanValue(parentbv));
- updateMustValue(getArrayBoolean(&This->inputs, 1), parentbv);
- }
- return;
- case L_XOR:
- return;
- default:
- ASSERT(0);
- }
-}
--- /dev/null
+#include "polarityassignment.h"
+#include "csolver.h"
+
+void computePolarities(CSolver *This) {
+ HSIteratorBoolean *iterator=iteratorBoolean(This->constraints);
+ while(hasNextBoolean(iterator)) {
+ Boolean *boolean = nextBoolean(iterator);
+ updatePolarity(boolean, P_TRUE);
+ updateMustValue(boolean, BV_MUSTBETRUE);
+ computePolarityAndBooleanValue(boolean);
+ }
+ deleteIterBoolean(iterator);
+}
+
+void updatePolarity(Boolean *This, Polarity polarity) {
+ This->polarity = (Polarity) (This->polarity | polarity);
+}
+
+void updateMustValue(Boolean *This, BooleanValue value) {
+ This->boolVal = (BooleanValue) (This->boolVal | value);
+}
+
+void computePolarityAndBooleanValue(Boolean *This) {
+ switch (GETBOOLEANTYPE(This)) {
+ case BOOLEANVAR:
+ case ORDERCONST:
+ return;
+ case PREDICATEOP:
+ return computePredicatePolarityAndBooleanValue((BooleanPredicate *)This);
+ case LOGICOP:
+ return computeLogicOpPolarityAndBooleanValue((BooleanLogic *)This);
+ default:
+ ASSERT(0);
+ }
+}
+
+void computePredicatePolarityAndBooleanValue(BooleanPredicate *This) {
+ updatePolarity(This->undefStatus, P_BOTHTRUEFALSE);
+ computePolarityAndBooleanValue(This->undefStatus);
+}
+
+void computeLogicOpPolarityAndBooleanValue(BooleanLogic *This) {
+ computeLogicOpBooleanValue(This);
+ computeLogicOpPolarity(This);
+ uint size = getSizeArrayBoolean(&This->inputs);
+ for (uint i = 0; i < size; i++) {
+ computePolarityAndBooleanValue(getArrayBoolean(&This->inputs, i));
+ }
+}
+
+Polarity negatePolarity(Polarity This) {
+ switch (This) {
+ case P_UNDEFINED:
+ case P_BOTHTRUEFALSE:
+ return This;
+ case P_TRUE:
+ return P_FALSE;
+ case P_FALSE:
+ return P_TRUE;
+ default:
+ ASSERT(0);
+ }
+}
+
+BooleanValue negateBooleanValue(BooleanValue This) {
+ switch (This) {
+ case BV_UNDEFINED:
+ case BV_UNSAT:
+ return This;
+ case BV_MUSTBETRUE:
+ return BV_MUSTBEFALSE;
+ case BV_MUSTBEFALSE:
+ return BV_MUSTBETRUE;
+ default:
+ ASSERT(0);
+ }
+}
+
+void computeLogicOpPolarity(BooleanLogic *This) {
+ Polarity parentpolarity = GETBOOLEANPOLARITY(This);
+ switch (This->op) {
+ case L_AND:
+ case L_OR: {
+ uint size = getSizeArrayBoolean(&This->inputs);
+ for (uint i = 0; i < size; i++) {
+ Boolean *tmp = getArrayBoolean(&This->inputs, i);
+ updatePolarity(tmp, parentpolarity);
+ }
+ break;
+ }
+ case L_NOT: {
+ Boolean *tmp = getArrayBoolean(&This->inputs, 0);
+ updatePolarity(tmp, negatePolarity(parentpolarity));
+ break;
+ }
+ case L_XOR: {
+ updatePolarity(getArrayBoolean(&This->inputs, 0), P_BOTHTRUEFALSE);
+ updatePolarity(getArrayBoolean(&This->inputs, 1), P_BOTHTRUEFALSE);
+ break;
+ }
+ case L_IMPLIES: {
+ Boolean *left = getArrayBoolean(&This->inputs, 0);
+ updatePolarity(left, negatePolarity( parentpolarity));
+ Boolean *right = getArrayBoolean(&This->inputs, 1);
+ updatePolarity(right, parentpolarity);
+ break;
+ }
+ default:
+ ASSERT(0);
+ }
+}
+
+void computeLogicOpBooleanValue(BooleanLogic *This) {
+ BooleanValue parentbv = GETBOOLEANVALUE(This);
+ switch (This->op) {
+ case L_AND: {
+ if (parentbv == BV_MUSTBETRUE || parentbv == BV_UNSAT) {
+ uint size = getSizeArrayBoolean(&This->inputs);
+ for (uint i = 0; i < size; i++) {
+ updateMustValue(getArrayBoolean(&This->inputs, i), parentbv);
+ }
+ }
+ return;
+ }
+ case L_OR: {
+ if (parentbv == BV_MUSTBEFALSE || parentbv == BV_UNSAT) {
+ uint size = getSizeArrayBoolean(&This->inputs);
+ for (uint i = 0; i < size; i++) {
+ updateMustValue(getArrayBoolean(&This->inputs, i), parentbv);
+ }
+ }
+ return;
+ }
+ case L_NOT:
+ updateMustValue(getArrayBoolean(&This->inputs, 0), negateBooleanValue(parentbv));
+ return;
+ case L_IMPLIES:
+ //implies is really an or with the first term negated
+ if (parentbv == BV_MUSTBEFALSE || parentbv == BV_UNSAT) {
+ uint size = getSizeArrayBoolean(&This->inputs);
+ updateMustValue(getArrayBoolean(&This->inputs, 0), negateBooleanValue(parentbv));
+ updateMustValue(getArrayBoolean(&This->inputs, 1), parentbv);
+ }
+ return;
+ case L_XOR:
+ return;
+ default:
+ ASSERT(0);
+ }
+}
MKDIR_P = mkdir -p
OBJ_DIR = bin
-C_SOURCES := $(wildcard *.c) $(wildcard AST/*.c) $(wildcard Tuner/*.c) $(wildcard Collections/*.c) $(wildcard Backend/*.c) $(wildcard Encoders/*.c)
+CPP_SOURCES := $(wildcard *.cc) $(wildcard AST/*.cc) $(wildcard Tuner/*.cc) $(wildcard Collections/*.cc) $(wildcard Backend/*.cc) $(wildcard Encoders/*.cc)
HEADERS := $(wildcard *.h) $(wildcard AST/*.h) $(wildcard Tuner/*.h) $(wildcard Collections/*.h) $(wildcard Backend/*.h) $(wildcard Encoders/*.h)
-OBJECTS := $(CPP_SOURCES:%.cc=$(OBJ_DIR)/%.o) $(C_SOURCES:%.c=$(OBJ_DIR)/%.o)
+OBJECTS := $(CPP_SOURCES:%.cc=$(OBJ_DIR)/%.o)
CFLAGS := -Wall -g -O0
CFLAGS += -IAST -ICollections -IBackend -I. -IEncoders -ITuner
${OBJ_DIR}/$(LIB_SO): $(OBJECTS)
$(CC) -g $(SHARED) -o ${OBJ_DIR}/$(LIB_SO) $+ $(LDFLAGS)
-${OBJ_DIR}/%.o: %.c
+${OBJ_DIR}/%.o: %.cc
$(CC) -fPIC -c $< -o $@ $(CFLAGS) -Wno-unused-variable
-include $(OBJECTS:%=$OBJ_DIR/.%.d)
ctags -R
tabbing:
- uncrustify -c C.cfg --no-backup *.c */*.c
+ uncrustify -c C.cfg --no-backup *.cc */*.cc
uncrustify -c C.cfg --no-backup *.h */*.h
wc:
- wc */*.c */*.h *.c *.h
+ wc */*.cc */*.h *.cc *.h
.PHONY: $(PHONY)
BASE := ..
-OBJECTS := $(patsubst %.c, ../bin/%, $(wildcard *.c))
+OBJECTS := $(patsubst %.cc, ../bin/%, $(wildcard *.cc))
include $(BASE)/common.mk
-include $(DEPS)
-../bin/%: %.c
+../bin/%: %.cc
$(CC) -MMD -MF $(@D)/.$(@F).d -o ../bin/$@ $< $(CPPFLAGS) -L$(BASE)/bin/ -l_cons_comp
../bin/run.sh: run.sh
+++ /dev/null
-#include "csolver.h"
-
-/**
- * e1={0, 1, 2}
- * e2={0, 1, 2}
- * e1 == e2
- * e3= e1+e2 {0, 1, 2, 3, 4}
- * e4 = f(e1, e2)
- * 0 1 => 0
- * 1 1 => 0
- * 2 1 => 2
- * 2 2 => 2
- * e3 == e4
- * Result: UNSAT!
- */
-int main(int numargs, char **argv) {
- CSolver *solver = allocCSolver();
- uint64_t set1[] = {0, 1, 2};
- uint64_t setbigarray[] = {0, 1, 2, 3, 4};
-
- Set *s = createSet(solver, 0, set1, 3);
- Set *setbig = createSet(solver, 0, setbigarray, 5);
- Element *e1 = getElementVar(solver, s);
- Element *e2 = getElementVar(solver, s);
- Set *domain[] = {s, s};
- Predicate *equals = createPredicateOperator(solver, EQUALS, domain, 2);
- Element *inputs[] = {e1, e2};
- Boolean *b = applyPredicate(solver, equals, inputs, 2);
- addConstraint(solver, b);
-
- uint64_t set2[] = {2, 3};
- Set *rangef1 = createSet(solver, 1, set2, 2);
- Function *f1 = createFunctionOperator(solver, ADD, domain, 2, setbig, IGNORE);
-
- Table *table = createTable(solver, domain, 2, s);
- uint64_t row1[] = {0, 1};
- uint64_t row2[] = {1, 1};
- uint64_t row3[] = {2, 1};
- uint64_t row4[] = {2, 2};
- addTableEntry(solver, table, row1, 2, 0);
- addTableEntry(solver, table, row2, 2, 0);
- addTableEntry(solver, table, row3, 2, 2);
- addTableEntry(solver, table, row4, 2, 2);
- Function *f2 = completeTable(solver, table, IGNOREBEHAVIOR); //its range would be as same as s
- Boolean *overflow = getBooleanVar(solver, 2);
- Element *e3 = applyFunction(solver, f1, inputs, 2, overflow);
- Element *e4 = applyFunction(solver, f2, inputs, 2, overflow);
- Set *domain2[] = {s,rangef1};
- Predicate *equal2 = createPredicateOperator(solver, EQUALS, domain2, 2);
- Element *inputs2 [] = {e4, e3};
- Boolean *pred = applyPredicate(solver, equal2, inputs2, 2);
- addConstraint(solver, pred);
-
- if (startEncoding(solver) == 1)
- printf("e1=%llu e2=%llu\n", getElementValue(solver,e1), getElementValue(solver, e2));
- else
- printf("UNSAT\n");
- deleteSolver(solver);
-}
--- /dev/null
+#include "csolver.h"
+
+/**
+ * e1={0, 1, 2}
+ * e2={0, 1, 2}
+ * e1 == e2
+ * e3= e1+e2 {0, 1, 2, 3, 4}
+ * e4 = f(e1, e2)
+ * 0 1 => 0
+ * 1 1 => 0
+ * 2 1 => 2
+ * 2 2 => 2
+ * e3 == e4
+ * Result: UNSAT!
+ */
+int main(int numargs, char **argv) {
+ CSolver *solver = allocCSolver();
+ uint64_t set1[] = {0, 1, 2};
+ uint64_t setbigarray[] = {0, 1, 2, 3, 4};
+
+ Set *s = createSet(solver, 0, set1, 3);
+ Set *setbig = createSet(solver, 0, setbigarray, 5);
+ Element *e1 = getElementVar(solver, s);
+ Element *e2 = getElementVar(solver, s);
+ Set *domain[] = {s, s};
+ Predicate *equals = createPredicateOperator(solver, EQUALS, domain, 2);
+ Element *inputs[] = {e1, e2};
+ Boolean *b = applyPredicate(solver, equals, inputs, 2);
+ addConstraint(solver, b);
+
+ uint64_t set2[] = {2, 3};
+ Set *rangef1 = createSet(solver, 1, set2, 2);
+ Function *f1 = createFunctionOperator(solver, ADD, domain, 2, setbig, IGNORE);
+
+ Table *table = createTable(solver, domain, 2, s);
+ uint64_t row1[] = {0, 1};
+ uint64_t row2[] = {1, 1};
+ uint64_t row3[] = {2, 1};
+ uint64_t row4[] = {2, 2};
+ addTableEntry(solver, table, row1, 2, 0);
+ addTableEntry(solver, table, row2, 2, 0);
+ addTableEntry(solver, table, row3, 2, 2);
+ addTableEntry(solver, table, row4, 2, 2);
+ Function *f2 = completeTable(solver, table, IGNOREBEHAVIOR); //its range would be as same as s
+ Boolean *overflow = getBooleanVar(solver, 2);
+ Element *e3 = applyFunction(solver, f1, inputs, 2, overflow);
+ Element *e4 = applyFunction(solver, f2, inputs, 2, overflow);
+ Set *domain2[] = {s,rangef1};
+ Predicate *equal2 = createPredicateOperator(solver, EQUALS, domain2, 2);
+ Element *inputs2 [] = {e4, e3};
+ Boolean *pred = applyPredicate(solver, equal2, inputs2, 2);
+ addConstraint(solver, pred);
+
+ if (startEncoding(solver) == 1)
+ printf("e1=%llu e2=%llu\n", getElementValue(solver,e1), getElementValue(solver, e2));
+ else
+ printf("UNSAT\n");
+ deleteSolver(solver);
+}
+++ /dev/null
-#include "constraint.h"
-#include <stdio.h>
-
-int main(int numargs, char **argv) {
- CNF *cnf = createCNF();
- Edge v1 = constraintNewVar(cnf);
- Edge v2 = constraintNewVar(cnf);
- Edge v3 = constraintNewVar(cnf);
- Edge v4 = constraintNewVar(cnf);
-
- Edge nv1 = constraintNegate(v1);
- Edge nv2 = constraintNegate(v2);
- Edge nv3 = constraintNegate(v3);
- Edge nv4 = constraintNegate(v4);
-
- Edge c1 = constraintAND2(cnf, v1, nv2);
- Edge c2 = constraintAND2(cnf, v3, nv4);
- Edge c3 = constraintAND2(cnf, nv1, v2);
- Edge c4 = constraintAND2(cnf, nv3, v4);
- Edge cor = constraintOR2(cnf, constraintAND2(cnf, c1, c2), constraintAND2(cnf, c3, c4));
- printCNF(cor);
- printf("\n");
- addConstraintCNF(cnf, cor);
- int value = solveCNF(cnf);
- if (value == 1) {
- bool v1v = getValueCNF(cnf, v1);
- bool v2v = getValueCNF(cnf, v2);
- bool v3v = getValueCNF(cnf, v3);
- bool v4v = getValueCNF(cnf, v4);
- printf("%d %u %u %u %u\n", value, v1v, v2v, v3v, v4v);
- } else
- printf("%d\n",value);
- deleteCNF(cnf);
-}
--- /dev/null
+#include "constraint.h"
+#include <stdio.h>
+
+int main(int numargs, char **argv) {
+ CNF *cnf = createCNF();
+ Edge v1 = constraintNewVar(cnf);
+ Edge v2 = constraintNewVar(cnf);
+ Edge v3 = constraintNewVar(cnf);
+ Edge v4 = constraintNewVar(cnf);
+
+ Edge nv1 = constraintNegate(v1);
+ Edge nv2 = constraintNegate(v2);
+ Edge nv3 = constraintNegate(v3);
+ Edge nv4 = constraintNegate(v4);
+
+ Edge c1 = constraintAND2(cnf, v1, nv2);
+ Edge c2 = constraintAND2(cnf, v3, nv4);
+ Edge c3 = constraintAND2(cnf, nv1, v2);
+ Edge c4 = constraintAND2(cnf, nv3, v4);
+ Edge cor = constraintOR2(cnf, constraintAND2(cnf, c1, c2), constraintAND2(cnf, c3, c4));
+ printCNF(cor);
+ printf("\n");
+ addConstraintCNF(cnf, cor);
+ int value = solveCNF(cnf);
+ if (value == 1) {
+ bool v1v = getValueCNF(cnf, v1);
+ bool v2v = getValueCNF(cnf, v2);
+ bool v3v = getValueCNF(cnf, v3);
+ bool v4v = getValueCNF(cnf, v4);
+ printf("%d %u %u %u %u\n", value, v1v, v2v, v3v, v4v);
+ } else
+ printf("%d\n",value);
+ deleteCNF(cnf);
+}
+++ /dev/null
-#include "csolver.h"
-/**
- * e1 = {0, 1, 2}
- * e2 = {3, 1, 7}
- * e1 == e2
- *
- * Result (Enumeration):
- * e1=1 e2=1
- * Result (circuit):
- * e1=0 e2=3
- * e1=1 e2=1
- * e1=2 e2=7
- */
-int main(int numargs, char **argv) {
- CSolver *solver = allocCSolver();
- uint64_t set1[] = {0, 1, 2};
- uint64_t set2[] = {3, 1, 7};
- Set *s1 = createSet(solver, 0, set1, 3);
- Set *s2 = createSet(solver, 0, set2, 3);
- Element *e1 = getElementVar(solver, s1);
- Element *e2 = getElementVar(solver, s2);
- Set *domain[] = {s1, s2};
- Predicate *equals = createPredicateOperator(solver, EQUALS, domain, 2);
- Element *inputs[] = {e1, e2};
- Boolean *b = applyPredicate(solver, equals, inputs, 2);
- addConstraint(solver, b);
-
- if (startEncoding(solver) == 1)
- printf("e1=%llu e2=%llu\n", getElementValue(solver,e1), getElementValue(solver, e2));
- else
- printf("UNSAT\n");
- deleteSolver(solver);
-}
--- /dev/null
+#include "csolver.h"
+/**
+ * e1 = {0, 1, 2}
+ * e2 = {3, 1, 7}
+ * e1 == e2
+ *
+ * Result (Enumeration):
+ * e1=1 e2=1
+ * Result (circuit):
+ * e1=0 e2=3
+ * e1=1 e2=1
+ * e1=2 e2=7
+ */
+int main(int numargs, char **argv) {
+ CSolver *solver = allocCSolver();
+ uint64_t set1[] = {0, 1, 2};
+ uint64_t set2[] = {3, 1, 7};
+ Set *s1 = createSet(solver, 0, set1, 3);
+ Set *s2 = createSet(solver, 0, set2, 3);
+ Element *e1 = getElementVar(solver, s1);
+ Element *e2 = getElementVar(solver, s2);
+ Set *domain[] = {s1, s2};
+ Predicate *equals = createPredicateOperator(solver, EQUALS, domain, 2);
+ Element *inputs[] = {e1, e2};
+ Boolean *b = applyPredicate(solver, equals, inputs, 2);
+ addConstraint(solver, b);
+
+ if (startEncoding(solver) == 1)
+ printf("e1=%llu e2=%llu\n", getElementValue(solver,e1), getElementValue(solver, e2));
+ else
+ printf("UNSAT\n");
+ deleteSolver(solver);
+}
+++ /dev/null
-#include "csolver.h"
-/**
- * e1 = {0, 1, 2}
- * e2 = {3, 4}
- * e1 == e2
- *
- * Result: UNSAT
- */
-int main(int numargs, char **argv) {
- CSolver *solver = allocCSolver();
- uint64_t set1[] = {0, 1, 2};
- uint64_t set2[] = {3, 4};
- Set *s1 = createSet(solver, 0, set1, 3);
- Set *s2 = createSet(solver, 0, set2, 2);
- Element *e1 = getElementVar(solver, s1);
- Element *e2 = getElementVar(solver, s2);
- Set *domain[] = {s1, s2};
- Predicate *equals = createPredicateOperator(solver, EQUALS, domain, 2);
- Element *inputs[] = {e1, e2};
- Boolean *b = applyPredicate(solver, equals, inputs, 2);
- addConstraint(solver, b);
-
- if (startEncoding(solver) == 1)
- printf("e1=%llu e2=%llu\n", getElementValue(solver,e1), getElementValue(solver, e2));
- else
- printf("UNSAT\n");
- deleteSolver(solver);
-}
--- /dev/null
+#include "csolver.h"
+/**
+ * e1 = {0, 1, 2}
+ * e2 = {3, 4}
+ * e1 == e2
+ *
+ * Result: UNSAT
+ */
+int main(int numargs, char **argv) {
+ CSolver *solver = allocCSolver();
+ uint64_t set1[] = {0, 1, 2};
+ uint64_t set2[] = {3, 4};
+ Set *s1 = createSet(solver, 0, set1, 3);
+ Set *s2 = createSet(solver, 0, set2, 2);
+ Element *e1 = getElementVar(solver, s1);
+ Element *e2 = getElementVar(solver, s2);
+ Set *domain[] = {s1, s2};
+ Predicate *equals = createPredicateOperator(solver, EQUALS, domain, 2);
+ Element *inputs[] = {e1, e2};
+ Boolean *b = applyPredicate(solver, equals, inputs, 2);
+ addConstraint(solver, b);
+
+ if (startEncoding(solver) == 1)
+ printf("e1=%llu e2=%llu\n", getElementValue(solver,e1), getElementValue(solver, e2));
+ else
+ printf("UNSAT\n");
+ deleteSolver(solver);
+}
+++ /dev/null
-#include "csolver.h"
-/**
- * e1 = {6}
- * e2={4, 2}
- * e3=Fsub(e1,e2) {4, 2}
- * e4= f(e1, e2)
- * 6 2 => 3
- * 6 4 => 1
- * e5 = f(e1)=>e1 {6}
- * e6 = (e3, e4, e5) {2, 3, 1}
- * 4 3 6 => 3
- * 2 1 6 => 1
- * 2 3 6 => 2
- * 4 1 6 => 1
- * e7 = {2, 1, 0}
- * e7 > e6
- * Result: e1=6, e2=4, e7=2
- */
-int main(int numargs, char **argv) {
- CSolver *solver = allocCSolver();
- uint64_t set1[] = {6};
- uint64_t set2[] = {4, 2};
- uint64_t set3[] = {3, 1};
- uint64_t set4[] = {2, 3, 1};
- uint64_t set5[] = {2, 1, 0};
- Set *s1 = createSet(solver, 0, set1, 1);
- Set *s2 = createSet(solver, 0, set2, 2);
- Set *s3 = createSet(solver, 0, set3, 2);
- Set *s4 = createSet(solver, 0, set4, 3);
- Set *s5 = createSet(solver, 0, set5, 3);
- Element *e1 = getElementVar(solver, s1);
- Element *e2 = getElementVar(solver, s2);
- Element *e7 = getElementVar(solver, s5);
- Boolean *overflow = getBooleanVar(solver, 2);
- Set *d1[] = {s1, s2};
- //change the overflow flag
- Function *f1 = createFunctionOperator(solver, SUB, d1, 2, s2, IGNORE);
- Element *in1[] = {e1, e2};
- Element *e3 = applyFunction(solver, f1, in1, 2, overflow);
- Table *t1 = createTable(solver, d1, 2, s3);
- uint64_t row1[] = {6, 2};
- uint64_t row2[] = {6, 4};
- addTableEntry(solver, t1, row1, 2, 3);
- addTableEntry(solver, t1, row2, 2, 1);
- Function *f2 = completeTable(solver, t1, IGNOREBEHAVIOR);
- Element *e4 = applyFunction(solver, f2, in1, 2, overflow);
-
- Set *d2[] = {s1};
- Element *in2[] = {e1};
- Table *t2 = createTable(solver, d2, 1, s1);
- uint64_t row3[] = {6};
- addTableEntry(solver, t2, row3, 1, 6);
- Function *f3 = completeTable(solver, t2, IGNOREBEHAVIOR);
- Element *e5 = applyFunction(solver, f3, in2, 1, overflow);
-
- Set *d3[] = {s2, s3, s1};
- Element *in3[] = {e3, e4, e5};
- Table *t3 = createTable(solver, d3, 3, s4);
- uint64_t row4[] = {4, 3, 6};
- uint64_t row5[] = {2, 1, 6};
- uint64_t row6[] = {2, 3, 6};
- uint64_t row7[] = {4, 1, 6};
- addTableEntry(solver, t3, row4, 3, 3);
- addTableEntry(solver, t3, row5, 3, 1);
- addTableEntry(solver, t3, row6, 3, 2);
- addTableEntry(solver, t3, row7, 3, 1);
- Function *f4 = completeTable(solver, t3, IGNOREBEHAVIOR);
- Element *e6 = applyFunction(solver, f4, in3, 3, overflow);
-
- Set *deq[] = {s5,s4};
- Predicate *gt = createPredicateOperator(solver, GT, deq, 2);
- Element *inputs2 [] = {e7, e6};
- Boolean *pred = applyPredicate(solver, gt, inputs2, 2);
- addConstraint(solver, pred);
-
- if (startEncoding(solver) == 1)
- printf("e1=%llu e2=%llu e7=%llu\n",
- getElementValue(solver,e1), getElementValue(solver, e2), getElementValue(solver, e7));
- else
- printf("UNSAT\n");
- deleteSolver(solver);
-}
--- /dev/null
+#include "csolver.h"
+/**
+ * e1 = {6}
+ * e2={4, 2}
+ * e3=Fsub(e1,e2) {4, 2}
+ * e4= f(e1, e2)
+ * 6 2 => 3
+ * 6 4 => 1
+ * e5 = f(e1)=>e1 {6}
+ * e6 = (e3, e4, e5) {2, 3, 1}
+ * 4 3 6 => 3
+ * 2 1 6 => 1
+ * 2 3 6 => 2
+ * 4 1 6 => 1
+ * e7 = {2, 1, 0}
+ * e7 > e6
+ * Result: e1=6, e2=4, e7=2
+ */
+int main(int numargs, char **argv) {
+ CSolver *solver = allocCSolver();
+ uint64_t set1[] = {6};
+ uint64_t set2[] = {4, 2};
+ uint64_t set3[] = {3, 1};
+ uint64_t set4[] = {2, 3, 1};
+ uint64_t set5[] = {2, 1, 0};
+ Set *s1 = createSet(solver, 0, set1, 1);
+ Set *s2 = createSet(solver, 0, set2, 2);
+ Set *s3 = createSet(solver, 0, set3, 2);
+ Set *s4 = createSet(solver, 0, set4, 3);
+ Set *s5 = createSet(solver, 0, set5, 3);
+ Element *e1 = getElementVar(solver, s1);
+ Element *e2 = getElementVar(solver, s2);
+ Element *e7 = getElementVar(solver, s5);
+ Boolean *overflow = getBooleanVar(solver, 2);
+ Set *d1[] = {s1, s2};
+ //change the overflow flag
+ Function *f1 = createFunctionOperator(solver, SUB, d1, 2, s2, IGNORE);
+ Element *in1[] = {e1, e2};
+ Element *e3 = applyFunction(solver, f1, in1, 2, overflow);
+ Table *t1 = createTable(solver, d1, 2, s3);
+ uint64_t row1[] = {6, 2};
+ uint64_t row2[] = {6, 4};
+ addTableEntry(solver, t1, row1, 2, 3);
+ addTableEntry(solver, t1, row2, 2, 1);
+ Function *f2 = completeTable(solver, t1, IGNOREBEHAVIOR);
+ Element *e4 = applyFunction(solver, f2, in1, 2, overflow);
+
+ Set *d2[] = {s1};
+ Element *in2[] = {e1};
+ Table *t2 = createTable(solver, d2, 1, s1);
+ uint64_t row3[] = {6};
+ addTableEntry(solver, t2, row3, 1, 6);
+ Function *f3 = completeTable(solver, t2, IGNOREBEHAVIOR);
+ Element *e5 = applyFunction(solver, f3, in2, 1, overflow);
+
+ Set *d3[] = {s2, s3, s1};
+ Element *in3[] = {e3, e4, e5};
+ Table *t3 = createTable(solver, d3, 3, s4);
+ uint64_t row4[] = {4, 3, 6};
+ uint64_t row5[] = {2, 1, 6};
+ uint64_t row6[] = {2, 3, 6};
+ uint64_t row7[] = {4, 1, 6};
+ addTableEntry(solver, t3, row4, 3, 3);
+ addTableEntry(solver, t3, row5, 3, 1);
+ addTableEntry(solver, t3, row6, 3, 2);
+ addTableEntry(solver, t3, row7, 3, 1);
+ Function *f4 = completeTable(solver, t3, IGNOREBEHAVIOR);
+ Element *e6 = applyFunction(solver, f4, in3, 3, overflow);
+
+ Set *deq[] = {s5,s4};
+ Predicate *gt = createPredicateOperator(solver, GT, deq, 2);
+ Element *inputs2 [] = {e7, e6};
+ Boolean *pred = applyPredicate(solver, gt, inputs2, 2);
+ addConstraint(solver, pred);
+
+ if (startEncoding(solver) == 1)
+ printf("e1=%llu e2=%llu e7=%llu\n",
+ getElementValue(solver,e1), getElementValue(solver, e2), getElementValue(solver, e7));
+ else
+ printf("UNSAT\n");
+ deleteSolver(solver);
+}
+++ /dev/null
-#include "csolver.h"
-
-/**
- * b1 AND b2=>b3
- * !b3 OR b4
- * b1 XOR b4
- * Result: b1=1 b2=0 b3=0 b4=0
- */
-int main(int numargs, char **argv) {
- CSolver *solver = allocCSolver();
- Boolean *b1 = getBooleanVar(solver, 0);
- Boolean *b2 = getBooleanVar(solver, 0);
- Boolean *b3 = getBooleanVar(solver, 0);
- Boolean *b4 = getBooleanVar(solver, 0);
- //L_AND, L_OR, L_NOT, L_XOR, L_IMPLIES
- Boolean *andb1b2 = applyLogicalOperation(solver, L_AND,(Boolean *[]) {b1, b2}, 2);
- Boolean *imply = applyLogicalOperation(solver, L_IMPLIES, (Boolean *[]) {andb1b2, b3}, 2);
- addConstraint(solver, imply);
- Boolean *notb3 = applyLogicalOperation(solver, L_NOT, (Boolean *[]) {b3}, 1);
- addConstraint(solver, applyLogicalOperation(solver, L_OR, (Boolean *[]) {notb3, b4}, 2));
- addConstraint(solver, applyLogicalOperation(solver, L_XOR, (Boolean * []) {b1, b4}, 2));
- if (startEncoding(solver) == 1)
- printf("b1=%d b2=%d b3=%d b4=%d\n",
- getBooleanValue(solver,b1), getBooleanValue(solver, b2),
- getBooleanValue(solver, b3), getBooleanValue(solver, b4));
- else
- printf("UNSAT\n");
- deleteSolver(solver);
-}
\ No newline at end of file
--- /dev/null
+#include "csolver.h"
+
+/**
+ * b1 AND b2=>b3
+ * !b3 OR b4
+ * b1 XOR b4
+ * Result: b1=1 b2=0 b3=0 b4=0
+ */
+int main(int numargs, char **argv) {
+ CSolver *solver = allocCSolver();
+ Boolean *b1 = getBooleanVar(solver, 0);
+ Boolean *b2 = getBooleanVar(solver, 0);
+ Boolean *b3 = getBooleanVar(solver, 0);
+ Boolean *b4 = getBooleanVar(solver, 0);
+ //L_AND, L_OR, L_NOT, L_XOR, L_IMPLIES
+ Boolean *andb1b2 = applyLogicalOperation(solver, L_AND,(Boolean *[]) {b1, b2}, 2);
+ Boolean *imply = applyLogicalOperation(solver, L_IMPLIES, (Boolean *[]) {andb1b2, b3}, 2);
+ addConstraint(solver, imply);
+ Boolean *notb3 = applyLogicalOperation(solver, L_NOT, (Boolean *[]) {b3}, 1);
+ addConstraint(solver, applyLogicalOperation(solver, L_OR, (Boolean *[]) {notb3, b4}, 2));
+ addConstraint(solver, applyLogicalOperation(solver, L_XOR, (Boolean * []) {b1, b4}, 2));
+ if (startEncoding(solver) == 1)
+ printf("b1=%d b2=%d b3=%d b4=%d\n",
+ getBooleanValue(solver,b1), getBooleanValue(solver, b2),
+ getBooleanValue(solver, b3), getBooleanValue(solver, b4));
+ else
+ printf("UNSAT\n");
+ deleteSolver(solver);
+}
\ No newline at end of file
+++ /dev/null
-#include "csolver.h"
-/**
- * e1 = 5
- * e2 = {1, 3, 4, 6}
- * e1 < e2
- * Result: e1=5 e2=6
- */
-int main(int numargs, char **argv) {
- CSolver *solver = allocCSolver();
- uint64_t set1[] = {5};
- uint64_t set3[] = {1, 3, 4, 6};
- Set *s1 = createSet(solver, 0, set1, 3);
- Set *s3 = createSet(solver, 0, set3, 4);
- Element *e1 = getElementConst(solver, 4, 5);
- Element *e2 = getElementVar(solver, s3);
- Set *domain2[] = {s1, s3};
- Predicate *lt = createPredicateOperator(solver, LT, domain2, 2);
- Element *inputs2[] = {e1, e2};
- Boolean *b = applyPredicate(solver, lt, inputs2, 2);
- addConstraint(solver, b);
- if (startEncoding(solver) == 1)
- printf("e1=%llu e2=%llu\n", getElementValue(solver,e1), getElementValue(solver, e2));
- else
- printf("UNSAT\n");
- deleteSolver(solver);
-}
\ No newline at end of file
--- /dev/null
+#include "csolver.h"
+/**
+ * e1 = 5
+ * e2 = {1, 3, 4, 6}
+ * e1 < e2
+ * Result: e1=5 e2=6
+ */
+int main(int numargs, char **argv) {
+ CSolver *solver = allocCSolver();
+ uint64_t set1[] = {5};
+ uint64_t set3[] = {1, 3, 4, 6};
+ Set *s1 = createSet(solver, 0, set1, 3);
+ Set *s3 = createSet(solver, 0, set3, 4);
+ Element *e1 = getElementConst(solver, 4, 5);
+ Element *e2 = getElementVar(solver, s3);
+ Set *domain2[] = {s1, s3};
+ Predicate *lt = createPredicateOperator(solver, LT, domain2, 2);
+ Element *inputs2[] = {e1, e2};
+ Boolean *b = applyPredicate(solver, lt, inputs2, 2);
+ addConstraint(solver, b);
+ if (startEncoding(solver) == 1)
+ printf("e1=%llu e2=%llu\n", getElementValue(solver,e1), getElementValue(solver, e2));
+ else
+ printf("UNSAT\n");
+ deleteSolver(solver);
+}
\ No newline at end of file
+++ /dev/null
-#include "csolver.h"
-
-int main(int numargs, char **argv) {
- CSolver *solver = allocCSolver();
- uint64_t set1[] = {1, 2, 3, 4, 5, 6, 7, 8};
- Set *s = createSet(solver, 0, set1, 8);
- Order *order = createOrder(solver, TOTAL, s);
- Boolean *o12 = orderConstraint(solver, order, 1, 2);
- Boolean *o13 = orderConstraint(solver, order, 1, 3);
- Boolean *o24 = orderConstraint(solver, order, 2, 4);
- Boolean *o34 = orderConstraint(solver, order, 3, 4);
- Boolean *o41 = orderConstraint(solver, order, 4, 1);
- Boolean *o57 = orderConstraint(solver, order, 5, 7);
- Boolean *o76 = orderConstraint(solver, order, 7, 6);
- Boolean *o65 = orderConstraint(solver, order, 6, 5);
- Boolean *o58 = orderConstraint(solver, order, 5, 8);
- Boolean *o81 = orderConstraint(solver, order, 8, 1);
-
- addConstraint(solver, applyLogicalOperation(solver, L_OR,(Boolean *[]) {o12, o13, o24, o34}, 4) );
- Boolean *b1 = applyLogicalOperation(solver, L_XOR, (Boolean *[]) {o41, o57}, 2);
- Boolean *o34n = applyLogicalOperation(solver, L_NOT, (Boolean *[]) {o34}, 1);
- Boolean *o24n = applyLogicalOperation(solver, L_NOT, (Boolean *[]) {o24}, 1);
- Boolean *b2 = applyLogicalOperation(solver, L_OR, (Boolean *[]) {o34n, o24n}, 2);
- addConstraint(solver, applyLogicalOperation(solver, L_IMPLIES,(Boolean *[]) {b1, b2}, 2) );
- addConstraint(solver, applyLogicalOperation(solver, L_AND,(Boolean *[]) {o12, o13}, 2) );
- addConstraint(solver, applyLogicalOperation(solver, L_OR,(Boolean *[]) {o76, o65}, 2) );
- Boolean* b3= applyLogicalOperation(solver, L_AND,(Boolean *[]) {o76, o65}, 2) ;
- Boolean* o57n= applyLogicalOperation(solver, L_NOT,(Boolean *[]) {o57}, 1);
- addConstraint(solver, applyLogicalOperation(solver, L_IMPLIES,(Boolean *[]) {b3, o57n}, 2) );
- addConstraint(solver, applyLogicalOperation(solver, L_AND,(Boolean *[]) {o58, o81}, 2) );
-
- if (startEncoding(solver) == 1)
- printf("SAT\n");
- else
- printf("UNSAT\n");
- deleteSolver(solver);
-}
\ No newline at end of file
--- /dev/null
+#include "csolver.h"
+
+int main(int numargs, char **argv) {
+ CSolver *solver = allocCSolver();
+ uint64_t set1[] = {1, 2, 3, 4, 5, 6, 7, 8};
+ Set *s = createSet(solver, 0, set1, 8);
+ Order *order = createOrder(solver, TOTAL, s);
+ Boolean *o12 = orderConstraint(solver, order, 1, 2);
+ Boolean *o13 = orderConstraint(solver, order, 1, 3);
+ Boolean *o24 = orderConstraint(solver, order, 2, 4);
+ Boolean *o34 = orderConstraint(solver, order, 3, 4);
+ Boolean *o41 = orderConstraint(solver, order, 4, 1);
+ Boolean *o57 = orderConstraint(solver, order, 5, 7);
+ Boolean *o76 = orderConstraint(solver, order, 7, 6);
+ Boolean *o65 = orderConstraint(solver, order, 6, 5);
+ Boolean *o58 = orderConstraint(solver, order, 5, 8);
+ Boolean *o81 = orderConstraint(solver, order, 8, 1);
+
+ addConstraint(solver, applyLogicalOperation(solver, L_OR,(Boolean *[]) {o12, o13, o24, o34}, 4) );
+ Boolean *b1 = applyLogicalOperation(solver, L_XOR, (Boolean *[]) {o41, o57}, 2);
+ Boolean *o34n = applyLogicalOperation(solver, L_NOT, (Boolean *[]) {o34}, 1);
+ Boolean *o24n = applyLogicalOperation(solver, L_NOT, (Boolean *[]) {o24}, 1);
+ Boolean *b2 = applyLogicalOperation(solver, L_OR, (Boolean *[]) {o34n, o24n}, 2);
+ addConstraint(solver, applyLogicalOperation(solver, L_IMPLIES,(Boolean *[]) {b1, b2}, 2) );
+ addConstraint(solver, applyLogicalOperation(solver, L_AND,(Boolean *[]) {o12, o13}, 2) );
+ addConstraint(solver, applyLogicalOperation(solver, L_OR,(Boolean *[]) {o76, o65}, 2) );
+ Boolean* b3= applyLogicalOperation(solver, L_AND,(Boolean *[]) {o76, o65}, 2) ;
+ Boolean* o57n= applyLogicalOperation(solver, L_NOT,(Boolean *[]) {o57}, 1);
+ addConstraint(solver, applyLogicalOperation(solver, L_IMPLIES,(Boolean *[]) {b3, o57n}, 2) );
+ addConstraint(solver, applyLogicalOperation(solver, L_AND,(Boolean *[]) {o58, o81}, 2) );
+
+ if (startEncoding(solver) == 1)
+ printf("SAT\n");
+ else
+ printf("UNSAT\n");
+ deleteSolver(solver);
+}
\ No newline at end of file
+++ /dev/null
-
-#include "csolver.h"
-/**
- * TotalOrder(5, 1, 4)
- * 5 => 1
- * 1 => 4
- * Result: O(5,1)=0 O(1,4)=0 O(5,4)=0 O(1,5)=1 O(1111,5)=2
- */
-int main(int numargs, char **argv) {
- CSolver *solver = allocCSolver();
- uint64_t set1[] = {5, 1, 4};
- Set *s = createSet(solver, 0, set1, 3);
- Order *order = createOrder(solver, TOTAL, s);
- Boolean *b1 = orderConstraint(solver, order, 5, 1);
- Boolean *b2 = orderConstraint(solver, order, 1, 4);
- addConstraint(solver, b1);
- addConstraint(solver, b2);
- if (startEncoding(solver) == 1)
- printf("SAT\n");
- else
- printf("UNSAT\n");
- deleteSolver(solver);
-}
--- /dev/null
+
+#include "csolver.h"
+/**
+ * TotalOrder(5, 1, 4)
+ * 5 => 1
+ * 1 => 4
+ * Result: O(5,1)=0 O(1,4)=0 O(5,4)=0 O(1,5)=1 O(1111,5)=2
+ */
+int main(int numargs, char **argv) {
+ CSolver *solver = allocCSolver();
+ uint64_t set1[] = {5, 1, 4};
+ Set *s = createSet(solver, 0, set1, 3);
+ Order *order = createOrder(solver, TOTAL, s);
+ Boolean *b1 = orderConstraint(solver, order, 5, 1);
+ Boolean *b2 = orderConstraint(solver, order, 1, 4);
+ addConstraint(solver, b1);
+ addConstraint(solver, b2);
+ if (startEncoding(solver) == 1)
+ printf("SAT\n");
+ else
+ printf("UNSAT\n");
+ deleteSolver(solver);
+}
+++ /dev/null
-#include "csolver.h"
-/**
- * e1 = {1, 2}
- * e2={3, 5, 7}
- * e3= f(e1, e2)
- * 1 5 => 7
- * 2 3 => 5
- * 1 7 => 3
- * 2 7 => 5
- * 2 5 => 3
- * 1 3 => 5
- * e4 = {6, 10, 19}
- * e4 <= e3
- * Result: e1=1, e2=5, e3=7, e4=6, overflow=0
- */
-int main(int numargs, char **argv) {
- CSolver *solver = allocCSolver();
- uint64_t set1[] = {1, 2};
- uint64_t set2[] = {3, 5, 7};
- uint64_t set3[] = {6, 10, 19};
- Set *s1 = createSet(solver, 0, set1, 2);
- Set *s2 = createSet(solver, 0, set2, 3);
- Set *s3 = createSet(solver, 0, set3, 3);
- Element *e1 = getElementVar(solver, s1);
- Element *e2 = getElementVar(solver, s2);
- Element *e4 = getElementVar(solver, s3);
- Boolean *overflow = getBooleanVar(solver, 2);
- Set *d1[] = {s1, s2};
- //change the overflow flag
- Table *t1 = createTable(solver, d1, 2, s2);
- uint64_t row1[] = {1, 5};
- uint64_t row2[] = {2, 3};
- uint64_t row3[] = {1, 7};
- uint64_t row4[] = {2, 7};
- uint64_t row5[] = {2, 5};
- uint64_t row6[] = {1, 3};
- addTableEntry(solver, t1, row1, 2, 7);
- addTableEntry(solver, t1, row2, 2, 5);
- addTableEntry(solver, t1, row3, 2, 3);
- addTableEntry(solver, t1, row4, 2, 5);
- addTableEntry(solver, t1, row5, 2, 3);
- addTableEntry(solver, t1, row6, 2, 5);
- Function *f1 = completeTable(solver, t1, FLAGIFFUNDEFINED);
- Element *e3 = applyFunction(solver, f1, (Element * []) {e1,e2}, 2, overflow);
-
- Set *deq[] = {s3,s2};
- Predicate *lte = createPredicateOperator(solver, LTE, deq, 2);
- Element *inputs2 [] = {e4, e3};
- Boolean *pred = applyPredicate(solver, lte, inputs2, 2);
- addConstraint(solver, pred);
-
- if (startEncoding(solver) == 1)
- printf("e1=%llu e2=%llu e3=%llu e4=%llu overFlow:%d\n",
- getElementValue(solver,e1), getElementValue(solver, e2), getElementValue(solver, e3),
- getElementValue(solver, e4), getBooleanValue(solver, overflow));
- else
- printf("UNSAT\n");
- deleteSolver(solver);
-}
--- /dev/null
+#include "csolver.h"
+/**
+ * e1 = {1, 2}
+ * e2={3, 5, 7}
+ * e3= f(e1, e2)
+ * 1 5 => 7
+ * 2 3 => 5
+ * 1 7 => 3
+ * 2 7 => 5
+ * 2 5 => 3
+ * 1 3 => 5
+ * e4 = {6, 10, 19}
+ * e4 <= e3
+ * Result: e1=1, e2=5, e3=7, e4=6, overflow=0
+ */
+int main(int numargs, char **argv) {
+ CSolver *solver = allocCSolver();
+ uint64_t set1[] = {1, 2};
+ uint64_t set2[] = {3, 5, 7};
+ uint64_t set3[] = {6, 10, 19};
+ Set *s1 = createSet(solver, 0, set1, 2);
+ Set *s2 = createSet(solver, 0, set2, 3);
+ Set *s3 = createSet(solver, 0, set3, 3);
+ Element *e1 = getElementVar(solver, s1);
+ Element *e2 = getElementVar(solver, s2);
+ Element *e4 = getElementVar(solver, s3);
+ Boolean *overflow = getBooleanVar(solver, 2);
+ Set *d1[] = {s1, s2};
+ //change the overflow flag
+ Table *t1 = createTable(solver, d1, 2, s2);
+ uint64_t row1[] = {1, 5};
+ uint64_t row2[] = {2, 3};
+ uint64_t row3[] = {1, 7};
+ uint64_t row4[] = {2, 7};
+ uint64_t row5[] = {2, 5};
+ uint64_t row6[] = {1, 3};
+ addTableEntry(solver, t1, row1, 2, 7);
+ addTableEntry(solver, t1, row2, 2, 5);
+ addTableEntry(solver, t1, row3, 2, 3);
+ addTableEntry(solver, t1, row4, 2, 5);
+ addTableEntry(solver, t1, row5, 2, 3);
+ addTableEntry(solver, t1, row6, 2, 5);
+ Function *f1 = completeTable(solver, t1, FLAGIFFUNDEFINED);
+ Element *e3 = applyFunction(solver, f1, (Element * []) {e1,e2}, 2, overflow);
+
+ Set *deq[] = {s3,s2};
+ Predicate *lte = createPredicateOperator(solver, LTE, deq, 2);
+ Element *inputs2 [] = {e4, e3};
+ Boolean *pred = applyPredicate(solver, lte, inputs2, 2);
+ addConstraint(solver, pred);
+
+ if (startEncoding(solver) == 1)
+ printf("e1=%llu e2=%llu e3=%llu e4=%llu overFlow:%d\n",
+ getElementValue(solver,e1), getElementValue(solver, e2), getElementValue(solver, e3),
+ getElementValue(solver, e4), getBooleanValue(solver, overflow));
+ else
+ printf("UNSAT\n");
+ deleteSolver(solver);
+}
+++ /dev/null
-#include "csolver.h"
-/**
- * e1 = {1, 2}
- * e2={1, 3, 5, 7}
- * e3 = {6, 10, 19}
- * e4= p(e1, e2, e3)
- * 1 5 6 => T
- * 2 3 19 => T
- * 1 3 19 => F
- * 2 7 10 => F
- * 1 7 6 => F
- * 2 5 6 => T
- * e1 == e2
- * e3 >= e2
- * Result: e1=1, e2=1, e3=6 OR 10 OR 19, overflow=1
- */
-int main(int numargs, char **argv) {
- CSolver *solver = allocCSolver();
- uint64_t set1[] = {1, 2};
- uint64_t set2[] = {1, 3, 5, 7};
- uint64_t set3[] = {6, 10, 19};
- Set *s1 = createSet(solver, 0, set1, 2);
- Set *s2 = createSet(solver, 0, set2, 4);
- Set *s3 = createSet(solver, 0, set3, 3);
- Element *e1 = getElementVar(solver, s1);
- Element *e2 = getElementVar(solver, s2);
- Element *e3 = getElementVar(solver, s3);
- Set *d2[] = {s1, s2, s3};
- //change the overflow flag
- Table *t1 = createTableForPredicate(solver, d2, 3);
- uint64_t row1[] = {1, 5, 6};
- uint64_t row2[] = {2, 3, 19};
- uint64_t row3[] = {1, 3, 19};
- uint64_t row4[] = {2, 7, 10};
- uint64_t row5[] = {1, 7, 6};
- uint64_t row6[] = {2, 5, 6};
- addTableEntry(solver, t1, row1, 3, true);
- addTableEntry(solver, t1, row2, 3, true);
- addTableEntry(solver, t1, row3, 3, false);
- addTableEntry(solver, t1, row4, 3, false);
- addTableEntry(solver, t1, row5, 3, false);
- addTableEntry(solver, t1, row6, 3, true);
- Predicate *p1 = createPredicateTable(solver, t1, FLAGIFFUNDEFINED);
- Boolean *undef = getBooleanVar(solver, 2);
- Boolean *b1 = applyPredicateTable(solver, p1, (Element * []) {e1, e2, e3}, 3, undef);
- addConstraint(solver, b1);
-
- Set *deq[] = {s3,s2};
- Predicate *gte = createPredicateOperator(solver, GTE, deq, 2);
- Element *inputs2 [] = {e3, e2};
- Boolean *pred = applyPredicate(solver, gte, inputs2, 2);
- addConstraint(solver, pred);
-
- Set *d1[] = {s1, s2};
- Predicate *eq = createPredicateOperator(solver, EQUALS, d1, 2);
- Boolean *pred2 = applyPredicate(solver, eq,(Element *[]) {e1, e2}, 2);
- addConstraint(solver, pred2);
-
- if (startEncoding(solver) == 1)
- printf("e1=%llu e2=%llu e3=%llu undefFlag:%d\n",
- getElementValue(solver,e1), getElementValue(solver, e2),
- getElementValue(solver, e3), getBooleanValue(solver, undef));
- else
- printf("UNSAT\n");
- deleteSolver(solver);
-}
--- /dev/null
+#include "csolver.h"
+/**
+ * e1 = {1, 2}
+ * e2={1, 3, 5, 7}
+ * e3 = {6, 10, 19}
+ * e4= p(e1, e2, e3)
+ * 1 5 6 => T
+ * 2 3 19 => T
+ * 1 3 19 => F
+ * 2 7 10 => F
+ * 1 7 6 => F
+ * 2 5 6 => T
+ * e1 == e2
+ * e3 >= e2
+ * Result: e1=1, e2=1, e3=6 OR 10 OR 19, overflow=1
+ */
+int main(int numargs, char **argv) {
+ CSolver *solver = allocCSolver();
+ uint64_t set1[] = {1, 2};
+ uint64_t set2[] = {1, 3, 5, 7};
+ uint64_t set3[] = {6, 10, 19};
+ Set *s1 = createSet(solver, 0, set1, 2);
+ Set *s2 = createSet(solver, 0, set2, 4);
+ Set *s3 = createSet(solver, 0, set3, 3);
+ Element *e1 = getElementVar(solver, s1);
+ Element *e2 = getElementVar(solver, s2);
+ Element *e3 = getElementVar(solver, s3);
+ Set *d2[] = {s1, s2, s3};
+ //change the overflow flag
+ Table *t1 = createTableForPredicate(solver, d2, 3);
+ uint64_t row1[] = {1, 5, 6};
+ uint64_t row2[] = {2, 3, 19};
+ uint64_t row3[] = {1, 3, 19};
+ uint64_t row4[] = {2, 7, 10};
+ uint64_t row5[] = {1, 7, 6};
+ uint64_t row6[] = {2, 5, 6};
+ addTableEntry(solver, t1, row1, 3, true);
+ addTableEntry(solver, t1, row2, 3, true);
+ addTableEntry(solver, t1, row3, 3, false);
+ addTableEntry(solver, t1, row4, 3, false);
+ addTableEntry(solver, t1, row5, 3, false);
+ addTableEntry(solver, t1, row6, 3, true);
+ Predicate *p1 = createPredicateTable(solver, t1, FLAGIFFUNDEFINED);
+ Boolean *undef = getBooleanVar(solver, 2);
+ Boolean *b1 = applyPredicateTable(solver, p1, (Element * []) {e1, e2, e3}, 3, undef);
+ addConstraint(solver, b1);
+
+ Set *deq[] = {s3,s2};
+ Predicate *gte = createPredicateOperator(solver, GTE, deq, 2);
+ Element *inputs2 [] = {e3, e2};
+ Boolean *pred = applyPredicate(solver, gte, inputs2, 2);
+ addConstraint(solver, pred);
+
+ Set *d1[] = {s1, s2};
+ Predicate *eq = createPredicateOperator(solver, EQUALS, d1, 2);
+ Boolean *pred2 = applyPredicate(solver, eq,(Element *[]) {e1, e2}, 2);
+ addConstraint(solver, pred2);
+
+ if (startEncoding(solver) == 1)
+ printf("e1=%llu e2=%llu e3=%llu undefFlag:%d\n",
+ getElementValue(solver,e1), getElementValue(solver, e2),
+ getElementValue(solver, e3), getBooleanValue(solver, undef));
+ else
+ printf("UNSAT\n");
+ deleteSolver(solver);
+}
+++ /dev/null
-#include "tunable.h"
-
-Tuner * allocTuner() {
- return ourmalloc(sizeof(Tuner));
-}
-
-void deleteTuner(Tuner *This) {
- ourfree(This);
-}
-
-int getTunable(Tuner *This, TunableParam param, TunableDesc * descriptor) {
- return descriptor->defaultValue;
-}
-int getVarTunable(Tuner *This, VarType vartype, TunableParam param, TunableDesc * descriptor) {
- return descriptor->defaultValue;
-}
--- /dev/null
+#include "tunable.h"
+
+Tuner * allocTuner() {
+ return (Tuner *) ourmalloc(sizeof(Tuner));
+}
+
+void deleteTuner(Tuner *This) {
+ ourfree(This);
+}
+
+int getTunable(Tuner *This, TunableParam param, TunableDesc * descriptor) {
+ return descriptor->defaultValue;
+}
+int getVarTunable(Tuner *This, VarType vartype, TunableParam param, TunableDesc * descriptor) {
+ return descriptor->defaultValue;
+}
+++ /dev/null
-#include "common.h"
-
-void assert_hook(void)
-{
- model_print("Add breakpoint to line %u in file %s.\n", __LINE__, __FILE__);
-}
\ No newline at end of file
--- /dev/null
+#include "common.h"
+
+void assert_hook(void)
+{
+ model_print("Add breakpoint to line %u in file %s.\n", __LINE__, __FILE__);
+}
\ No newline at end of file
+++ /dev/null
-#include "csolver.h"
-#include "set.h"
-#include "mutableset.h"
-#include "element.h"
-#include "boolean.h"
-#include "predicate.h"
-#include "order.h"
-#include "table.h"
-#include "function.h"
-#include "satencoder.h"
-#include "sattranslator.h"
-#include "tunable.h"
-#include "orderencoder.h"
-#include "polarityassignment.h"
-
-CSolver *allocCSolver() {
- CSolver *This = (CSolver *) ourmalloc(sizeof(CSolver));
- This->unsat = false;
- This->constraints = allocDefHashSetBoolean();
- This->allBooleans = allocDefVectorBoolean();
- This->allSets = allocDefVectorSet();
- This->allElements = allocDefVectorElement();
- This->allPredicates = allocDefVectorPredicate();
- This->allTables = allocDefVectorTable();
- This->allOrders = allocDefVectorOrder();
- This->allFunctions = allocDefVectorFunction();
- This->tuner = allocTuner();
- This->satEncoder = allocSATEncoder(This);
- return This;
-}
-
-/** This function tears down the solver and the entire AST */
-
-void deleteSolver(CSolver *This) {
- deleteHashSetBoolean(This->constraints);
-
- uint size = getSizeVectorBoolean(This->allBooleans);
- for (uint i = 0; i < size; i++) {
- deleteBoolean(getVectorBoolean(This->allBooleans, i));
- }
- deleteVectorBoolean(This->allBooleans);
-
- size = getSizeVectorSet(This->allSets);
- for (uint i = 0; i < size; i++) {
- deleteSet(getVectorSet(This->allSets, i));
- }
- deleteVectorSet(This->allSets);
-
- size = getSizeVectorElement(This->allElements);
- for (uint i = 0; i < size; i++) {
- deleteElement(getVectorElement(This->allElements, i));
- }
- deleteVectorElement(This->allElements);
-
- size = getSizeVectorTable(This->allTables);
- for (uint i = 0; i < size; i++) {
- deleteTable(getVectorTable(This->allTables, i));
- }
- deleteVectorTable(This->allTables);
-
- size = getSizeVectorPredicate(This->allPredicates);
- for (uint i = 0; i < size; i++) {
- deletePredicate(getVectorPredicate(This->allPredicates, i));
- }
- deleteVectorPredicate(This->allPredicates);
-
- size = getSizeVectorOrder(This->allOrders);
- for (uint i = 0; i < size; i++) {
- deleteOrder(getVectorOrder(This->allOrders, i));
- }
- deleteVectorOrder(This->allOrders);
-
- size = getSizeVectorFunction(This->allFunctions);
- for (uint i = 0; i < size; i++) {
- deleteFunction(getVectorFunction(This->allFunctions, i));
- }
- deleteVectorFunction(This->allFunctions);
- deleteSATEncoder(This->satEncoder);
- deleteTuner(This->tuner);
- ourfree(This);
-}
-
-Set *createSet(CSolver *This, VarType type, uint64_t *elements, uint numelements) {
- Set *set = allocSet(type, elements, numelements);
- pushVectorSet(This->allSets, set);
- return set;
-}
-
-Set *createRangeSet(CSolver *This, VarType type, uint64_t lowrange, uint64_t highrange) {
- Set *set = allocSetRange(type, lowrange, highrange);
- pushVectorSet(This->allSets, set);
- return set;
-}
-
-MutableSet *createMutableSet(CSolver *This, VarType type) {
- MutableSet *set = allocMutableSet(type);
- pushVectorSet(This->allSets, set);
- return set;
-}
-
-void addItem(CSolver *This, MutableSet *set, uint64_t element) {
- addElementMSet(set, element);
-}
-
-uint64_t createUniqueItem(CSolver *This, MutableSet *set) {
- uint64_t element = set->low++;
- addElementMSet(set, element);
- return element;
-}
-
-Element *getElementVar(CSolver *This, Set *set) {
- Element *element = allocElementSet(set);
- pushVectorElement(This->allElements, element);
- return element;
-}
-
-Element *getElementConst(CSolver *This, VarType type, uint64_t value) {
- Element *element = allocElementConst(value, type);
- pushVectorElement(This->allElements, element);
- return element;
-}
-
-Boolean *getBooleanVar(CSolver *This, VarType type) {
- Boolean *boolean = allocBooleanVar(type);
- pushVectorBoolean(This->allBooleans, boolean);
- return boolean;
-}
-
-Function *createFunctionOperator(CSolver *This, ArithOp op, Set **domain, uint numDomain, Set *range,OverFlowBehavior overflowbehavior) {
- Function *function = allocFunctionOperator(op, domain, numDomain, range, overflowbehavior);
- pushVectorFunction(This->allFunctions, function);
- return function;
-}
-
-Predicate *createPredicateOperator(CSolver *This, CompOp op, Set **domain, uint numDomain) {
- Predicate *predicate = allocPredicateOperator(op, domain,numDomain);
- pushVectorPredicate(This->allPredicates, predicate);
- return predicate;
-}
-
-Predicate *createPredicateTable(CSolver *This, Table *table, UndefinedBehavior behavior) {
- Predicate *predicate = allocPredicateTable(table, behavior);
- pushVectorPredicate(This->allPredicates, predicate);
- return predicate;
-}
-
-Table *createTable(CSolver *This, Set **domains, uint numDomain, Set *range) {
- Table *table = allocTable(domains,numDomain,range);
- pushVectorTable(This->allTables, table);
- return table;
-}
-
-Table *createTableForPredicate(CSolver *solver, Set **domains, uint numDomain) {
- return createTable(solver, domains, numDomain, NULL);
-}
-
-void addTableEntry(CSolver *This, Table *table, uint64_t *inputs, uint inputSize, uint64_t result) {
- addNewTableEntry(table,inputs, inputSize,result);
-}
-
-Function *completeTable(CSolver *This, Table *table, UndefinedBehavior behavior) {
- Function *function = allocFunctionTable(table, behavior);
- pushVectorFunction(This->allFunctions,function);
- return function;
-}
-
-Element *applyFunction(CSolver *This, Function *function, Element **array, uint numArrays, Boolean *overflowstatus) {
- Element *element = allocElementFunction(function,array,numArrays,overflowstatus);
- pushVectorElement(This->allElements, element);
- return element;
-}
-
-Boolean *applyPredicate(CSolver *This, Predicate *predicate, Element **inputs, uint numInputs) {
- return applyPredicateTable(This, predicate, inputs, numInputs, NULL);
-}
-Boolean *applyPredicateTable(CSolver *This, Predicate *predicate, Element **inputs, uint numInputs, Boolean *undefinedStatus) {
- Boolean *boolean = allocBooleanPredicate(predicate, inputs, numInputs, undefinedStatus);
- pushVectorBoolean(This->allBooleans, boolean);
- return boolean;
-}
-
-Boolean *applyLogicalOperation(CSolver *This, LogicOp op, Boolean **array, uint asize) {
- return allocBooleanLogicArray(This, op, array, asize);
-}
-
-void addConstraint(CSolver *This, Boolean *constraint) {
- addHashSetBoolean(This->constraints, constraint);
-}
-
-Order *createOrder(CSolver *This, OrderType type, Set *set) {
- Order *order = allocOrder(type, set);
- pushVectorOrder(This->allOrders, order);
- return order;
-}
-
-Boolean *orderConstraint(CSolver *This, Order *order, uint64_t first, uint64_t second) {
- Boolean *constraint = allocBooleanOrder(order, first, second);
- pushVectorBoolean(This->allBooleans,constraint);
- return constraint;
-}
-
-int startEncoding(CSolver *This) {
- naiveEncodingDecision(This);
- SATEncoder *satEncoder = This->satEncoder;
- computePolarities(This);
- orderAnalysis(This);
- encodeAllSATEncoder(This, satEncoder);
- int result = solveCNF(satEncoder->cnf);
- model_print("sat_solver's result:%d\tsolutionSize=%d\n", result, satEncoder->cnf->solver->solutionsize);
- for (uint i = 1; i <= satEncoder->cnf->solver->solutionsize; i++) {
- model_print("%d, ", satEncoder->cnf->solver->solution[i]);
- }
- model_print("\n");
- return result;
-}
-
-uint64_t getElementValue(CSolver *This, Element *element) {
- switch (GETELEMENTTYPE(element)) {
- case ELEMSET:
- case ELEMCONST:
- case ELEMFUNCRETURN:
- return getElementValueSATTranslator(This, element);
- default:
- ASSERT(0);
- }
- exit(-1);
-}
-
-bool getBooleanValue( CSolver *This, Boolean *boolean) {
- switch (GETBOOLEANTYPE(boolean)) {
- case BOOLEANVAR:
- return getBooleanVariableValueSATTranslator(This, boolean);
- default:
- ASSERT(0);
- }
- exit(-1);
-}
-
-HappenedBefore getOrderConstraintValue(CSolver *This, Order *order, uint64_t first, uint64_t second) {
- return getOrderConstraintValueSATTranslator(This, order, first, second);
-}
-
--- /dev/null
+#include "csolver.h"
+#include "set.h"
+#include "mutableset.h"
+#include "element.h"
+#include "boolean.h"
+#include "predicate.h"
+#include "order.h"
+#include "table.h"
+#include "function.h"
+#include "satencoder.h"
+#include "sattranslator.h"
+#include "tunable.h"
+#include "orderencoder.h"
+#include "polarityassignment.h"
+
+CSolver *allocCSolver() {
+ CSolver *This = (CSolver *) ourmalloc(sizeof(CSolver));
+ This->unsat = false;
+ This->constraints = allocDefHashSetBoolean();
+ This->allBooleans = allocDefVectorBoolean();
+ This->allSets = allocDefVectorSet();
+ This->allElements = allocDefVectorElement();
+ This->allPredicates = allocDefVectorPredicate();
+ This->allTables = allocDefVectorTable();
+ This->allOrders = allocDefVectorOrder();
+ This->allFunctions = allocDefVectorFunction();
+ This->tuner = allocTuner();
+ This->satEncoder = allocSATEncoder(This);
+ return This;
+}
+
+/** This function tears down the solver and the entire AST */
+
+void deleteSolver(CSolver *This) {
+ deleteHashSetBoolean(This->constraints);
+
+ uint size = getSizeVectorBoolean(This->allBooleans);
+ for (uint i = 0; i < size; i++) {
+ deleteBoolean(getVectorBoolean(This->allBooleans, i));
+ }
+ deleteVectorBoolean(This->allBooleans);
+
+ size = getSizeVectorSet(This->allSets);
+ for (uint i = 0; i < size; i++) {
+ deleteSet(getVectorSet(This->allSets, i));
+ }
+ deleteVectorSet(This->allSets);
+
+ size = getSizeVectorElement(This->allElements);
+ for (uint i = 0; i < size; i++) {
+ deleteElement(getVectorElement(This->allElements, i));
+ }
+ deleteVectorElement(This->allElements);
+
+ size = getSizeVectorTable(This->allTables);
+ for (uint i = 0; i < size; i++) {
+ deleteTable(getVectorTable(This->allTables, i));
+ }
+ deleteVectorTable(This->allTables);
+
+ size = getSizeVectorPredicate(This->allPredicates);
+ for (uint i = 0; i < size; i++) {
+ deletePredicate(getVectorPredicate(This->allPredicates, i));
+ }
+ deleteVectorPredicate(This->allPredicates);
+
+ size = getSizeVectorOrder(This->allOrders);
+ for (uint i = 0; i < size; i++) {
+ deleteOrder(getVectorOrder(This->allOrders, i));
+ }
+ deleteVectorOrder(This->allOrders);
+
+ size = getSizeVectorFunction(This->allFunctions);
+ for (uint i = 0; i < size; i++) {
+ deleteFunction(getVectorFunction(This->allFunctions, i));
+ }
+ deleteVectorFunction(This->allFunctions);
+ deleteSATEncoder(This->satEncoder);
+ deleteTuner(This->tuner);
+ ourfree(This);
+}
+
+Set *createSet(CSolver *This, VarType type, uint64_t *elements, uint numelements) {
+ Set *set = allocSet(type, elements, numelements);
+ pushVectorSet(This->allSets, set);
+ return set;
+}
+
+Set *createRangeSet(CSolver *This, VarType type, uint64_t lowrange, uint64_t highrange) {
+ Set *set = allocSetRange(type, lowrange, highrange);
+ pushVectorSet(This->allSets, set);
+ return set;
+}
+
+MutableSet *createMutableSet(CSolver *This, VarType type) {
+ MutableSet *set = allocMutableSet(type);
+ pushVectorSet(This->allSets, set);
+ return set;
+}
+
+void addItem(CSolver *This, MutableSet *set, uint64_t element) {
+ addElementMSet(set, element);
+}
+
+uint64_t createUniqueItem(CSolver *This, MutableSet *set) {
+ uint64_t element = set->low++;
+ addElementMSet(set, element);
+ return element;
+}
+
+Element *getElementVar(CSolver *This, Set *set) {
+ Element *element = allocElementSet(set);
+ pushVectorElement(This->allElements, element);
+ return element;
+}
+
+Element *getElementConst(CSolver *This, VarType type, uint64_t value) {
+ Element *element = allocElementConst(value, type);
+ pushVectorElement(This->allElements, element);
+ return element;
+}
+
+Boolean *getBooleanVar(CSolver *This, VarType type) {
+ Boolean *boolean = allocBooleanVar(type);
+ pushVectorBoolean(This->allBooleans, boolean);
+ return boolean;
+}
+
+Function *createFunctionOperator(CSolver *This, ArithOp op, Set **domain, uint numDomain, Set *range,OverFlowBehavior overflowbehavior) {
+ Function *function = allocFunctionOperator(op, domain, numDomain, range, overflowbehavior);
+ pushVectorFunction(This->allFunctions, function);
+ return function;
+}
+
+Predicate *createPredicateOperator(CSolver *This, CompOp op, Set **domain, uint numDomain) {
+ Predicate *predicate = allocPredicateOperator(op, domain,numDomain);
+ pushVectorPredicate(This->allPredicates, predicate);
+ return predicate;
+}
+
+Predicate *createPredicateTable(CSolver *This, Table *table, UndefinedBehavior behavior) {
+ Predicate *predicate = allocPredicateTable(table, behavior);
+ pushVectorPredicate(This->allPredicates, predicate);
+ return predicate;
+}
+
+Table *createTable(CSolver *This, Set **domains, uint numDomain, Set *range) {
+ Table *table = allocTable(domains,numDomain,range);
+ pushVectorTable(This->allTables, table);
+ return table;
+}
+
+Table *createTableForPredicate(CSolver *solver, Set **domains, uint numDomain) {
+ return createTable(solver, domains, numDomain, NULL);
+}
+
+void addTableEntry(CSolver *This, Table *table, uint64_t *inputs, uint inputSize, uint64_t result) {
+ addNewTableEntry(table,inputs, inputSize,result);
+}
+
+Function *completeTable(CSolver *This, Table *table, UndefinedBehavior behavior) {
+ Function *function = allocFunctionTable(table, behavior);
+ pushVectorFunction(This->allFunctions,function);
+ return function;
+}
+
+Element *applyFunction(CSolver *This, Function *function, Element **array, uint numArrays, Boolean *overflowstatus) {
+ Element *element = allocElementFunction(function,array,numArrays,overflowstatus);
+ pushVectorElement(This->allElements, element);
+ return element;
+}
+
+Boolean *applyPredicate(CSolver *This, Predicate *predicate, Element **inputs, uint numInputs) {
+ return applyPredicateTable(This, predicate, inputs, numInputs, NULL);
+}
+Boolean *applyPredicateTable(CSolver *This, Predicate *predicate, Element **inputs, uint numInputs, Boolean *undefinedStatus) {
+ Boolean *boolean = allocBooleanPredicate(predicate, inputs, numInputs, undefinedStatus);
+ pushVectorBoolean(This->allBooleans, boolean);
+ return boolean;
+}
+
+Boolean *applyLogicalOperation(CSolver *This, LogicOp op, Boolean **array, uint asize) {
+ return allocBooleanLogicArray(This, op, array, asize);
+}
+
+void addConstraint(CSolver *This, Boolean *constraint) {
+ addHashSetBoolean(This->constraints, constraint);
+}
+
+Order *createOrder(CSolver *This, OrderType type, Set *set) {
+ Order *order = allocOrder(type, set);
+ pushVectorOrder(This->allOrders, order);
+ return order;
+}
+
+Boolean *orderConstraint(CSolver *This, Order *order, uint64_t first, uint64_t second) {
+ Boolean *constraint = allocBooleanOrder(order, first, second);
+ pushVectorBoolean(This->allBooleans,constraint);
+ return constraint;
+}
+
+int startEncoding(CSolver *This) {
+ naiveEncodingDecision(This);
+ SATEncoder *satEncoder = This->satEncoder;
+ computePolarities(This);
+ orderAnalysis(This);
+ encodeAllSATEncoder(This, satEncoder);
+ int result = solveCNF(satEncoder->cnf);
+ model_print("sat_solver's result:%d\tsolutionSize=%d\n", result, satEncoder->cnf->solver->solutionsize);
+ for (uint i = 1; i <= satEncoder->cnf->solver->solutionsize; i++) {
+ model_print("%d, ", satEncoder->cnf->solver->solution[i]);
+ }
+ model_print("\n");
+ return result;
+}
+
+uint64_t getElementValue(CSolver *This, Element *element) {
+ switch (GETELEMENTTYPE(element)) {
+ case ELEMSET:
+ case ELEMCONST:
+ case ELEMFUNCRETURN:
+ return getElementValueSATTranslator(This, element);
+ default:
+ ASSERT(0);
+ }
+ exit(-1);
+}
+
+bool getBooleanValue( CSolver *This, Boolean *boolean) {
+ switch (GETBOOLEANTYPE(boolean)) {
+ case BOOLEANVAR:
+ return getBooleanVariableValueSATTranslator(This, boolean);
+ default:
+ ASSERT(0);
+ }
+ exit(-1);
+}
+
+HappenedBefore getOrderConstraintValue(CSolver *This, Order *order, uint64_t first, uint64_t second) {
+ return getOrderConstraintValueSATTranslator(This, order, first, second);
+}
+