Rename everything
authorbdemsky <bdemsky@uci.edu>
Thu, 24 Aug 2017 23:49:49 +0000 (16:49 -0700)
committerbdemsky <bdemsky@uci.edu>
Thu, 24 Aug 2017 23:49:49 +0000 (16:49 -0700)
92 files changed:
src/AST/boolean.c [deleted file]
src/AST/boolean.cc [new file with mode: 0644]
src/AST/element.c [deleted file]
src/AST/element.cc [new file with mode: 0644]
src/AST/function.c [deleted file]
src/AST/function.cc [new file with mode: 0644]
src/AST/mutableset.c [deleted file]
src/AST/mutableset.cc [new file with mode: 0644]
src/AST/order.c [deleted file]
src/AST/order.cc [new file with mode: 0644]
src/AST/predicate.c [deleted file]
src/AST/predicate.cc [new file with mode: 0644]
src/AST/rewriter.c [deleted file]
src/AST/rewriter.cc [new file with mode: 0644]
src/AST/set.c [deleted file]
src/AST/set.cc [new file with mode: 0644]
src/AST/table.c [deleted file]
src/AST/table.cc [new file with mode: 0644]
src/AST/tableentry.c [deleted file]
src/AST/tableentry.cc [new file with mode: 0644]
src/Backend/cnfexpr.c [deleted file]
src/Backend/cnfexpr.cc [new file with mode: 0644]
src/Backend/constraint.c [deleted file]
src/Backend/constraint.cc [new file with mode: 0644]
src/Backend/inc_solver.c [deleted file]
src/Backend/inc_solver.cc [new file with mode: 0644]
src/Backend/orderelement.c [deleted file]
src/Backend/orderelement.cc [new file with mode: 0644]
src/Backend/orderpair.c [deleted file]
src/Backend/orderpair.cc [new file with mode: 0644]
src/Backend/satelemencoder.c [deleted file]
src/Backend/satelemencoder.cc [new file with mode: 0644]
src/Backend/satencoder.c [deleted file]
src/Backend/satencoder.cc [new file with mode: 0644]
src/Backend/satfuncopencoder.c [deleted file]
src/Backend/satfuncopencoder.cc [new file with mode: 0644]
src/Backend/satfunctableencoder.c [deleted file]
src/Backend/satfunctableencoder.cc [new file with mode: 0644]
src/Backend/satorderencoder.c [deleted file]
src/Backend/satorderencoder.cc [new file with mode: 0644]
src/Backend/sattranslator.c [deleted file]
src/Backend/sattranslator.cc [new file with mode: 0644]
src/Collections/structs.c [deleted file]
src/Collections/structs.cc [new file with mode: 0644]
src/Encoders/elementencoding.c [deleted file]
src/Encoders/elementencoding.cc [new file with mode: 0644]
src/Encoders/functionencoding.c [deleted file]
src/Encoders/functionencoding.cc [new file with mode: 0644]
src/Encoders/naiveencoder.c [deleted file]
src/Encoders/naiveencoder.cc [new file with mode: 0644]
src/Encoders/orderedge.c [deleted file]
src/Encoders/orderedge.cc [new file with mode: 0644]
src/Encoders/orderencoder.c [deleted file]
src/Encoders/orderencoder.cc [new file with mode: 0644]
src/Encoders/orderencoding.c [deleted file]
src/Encoders/orderencoding.cc [new file with mode: 0644]
src/Encoders/ordergraph.c [deleted file]
src/Encoders/ordergraph.cc [new file with mode: 0644]
src/Encoders/ordernode.c [deleted file]
src/Encoders/ordernode.cc [new file with mode: 0644]
src/Encoders/polarityassignment.c [deleted file]
src/Encoders/polarityassignment.cc [new file with mode: 0644]
src/Makefile
src/Test/Makefile
src/Test/buildconstraintstest.c [deleted file]
src/Test/buildconstraintstest.cc [new file with mode: 0644]
src/Test/cnftest.c [deleted file]
src/Test/cnftest.cc [new file with mode: 0644]
src/Test/elemequalsattest.c [deleted file]
src/Test/elemequalsattest.cc [new file with mode: 0644]
src/Test/elemequalunsattest.c [deleted file]
src/Test/elemequalunsattest.cc [new file with mode: 0644]
src/Test/funcencodingtest.c [deleted file]
src/Test/funcencodingtest.cc [new file with mode: 0644]
src/Test/logicopstest.c [deleted file]
src/Test/logicopstest.cc [new file with mode: 0644]
src/Test/ltelemconsttest.c [deleted file]
src/Test/ltelemconsttest.cc [new file with mode: 0644]
src/Test/ordergraphtest.c [deleted file]
src/Test/ordergraphtest.cc [new file with mode: 0644]
src/Test/ordertest.c [deleted file]
src/Test/ordertest.cc [new file with mode: 0644]
src/Test/tablefuncencodetest.c [deleted file]
src/Test/tablefuncencodetest.cc [new file with mode: 0644]
src/Test/tablepredicencodetest.c [deleted file]
src/Test/tablepredicencodetest.cc [new file with mode: 0644]
src/Tuner/tunable.c [deleted file]
src/Tuner/tunable.cc [new file with mode: 0644]
src/common.c [deleted file]
src/common.cc [new file with mode: 0644]
src/csolver.c [deleted file]
src/csolver.cc [new file with mode: 0644]

diff --git a/src/AST/boolean.c b/src/AST/boolean.c
deleted file mode 100644 (file)
index 2987217..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#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);
-}
diff --git a/src/AST/boolean.cc b/src/AST/boolean.cc
new file mode 100644 (file)
index 0000000..256ab5a
--- /dev/null
@@ -0,0 +1,78 @@
+#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);
+}
diff --git a/src/AST/element.c b/src/AST/element.c
deleted file mode 100644 (file)
index 5d126c7..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#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);
-}
diff --git a/src/AST/element.cc b/src/AST/element.cc
new file mode 100644 (file)
index 0000000..5d126c7
--- /dev/null
@@ -0,0 +1,91 @@
+#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);
+}
diff --git a/src/AST/function.c b/src/AST/function.c
deleted file mode 100644 (file)
index 3a32139..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#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);
-}
diff --git a/src/AST/function.cc b/src/AST/function.cc
new file mode 100644 (file)
index 0000000..3a32139
--- /dev/null
@@ -0,0 +1,53 @@
+#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);
+}
diff --git a/src/AST/mutableset.c b/src/AST/mutableset.c
deleted file mode 100644 (file)
index 19552f6..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#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);
-}
diff --git a/src/AST/mutableset.cc b/src/AST/mutableset.cc
new file mode 100644 (file)
index 0000000..19552f6
--- /dev/null
@@ -0,0 +1,15 @@
+#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);
+}
diff --git a/src/AST/order.c b/src/AST/order.c
deleted file mode 100644 (file)
index 92bb557..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#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);
-}
diff --git a/src/AST/order.cc b/src/AST/order.cc
new file mode 100644 (file)
index 0000000..92bb557
--- /dev/null
@@ -0,0 +1,49 @@
+#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);
+}
diff --git a/src/AST/predicate.c b/src/AST/predicate.c
deleted file mode 100644 (file)
index 0e0238a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#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;
-}
diff --git a/src/AST/predicate.cc b/src/AST/predicate.cc
new file mode 100644 (file)
index 0000000..dfc8596
--- /dev/null
@@ -0,0 +1,53 @@
+#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;
+}
diff --git a/src/AST/rewriter.c b/src/AST/rewriter.c
deleted file mode 100644 (file)
index 5e24051..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-#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;
-               }
-       }
-}
diff --git a/src/AST/rewriter.cc b/src/AST/rewriter.cc
new file mode 100644 (file)
index 0000000..5e24051
--- /dev/null
@@ -0,0 +1,164 @@
+#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;
+               }
+       }
+}
diff --git a/src/AST/set.c b/src/AST/set.c
deleted file mode 100644 (file)
index 003379e..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#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);
-}
diff --git a/src/AST/set.cc b/src/AST/set.cc
new file mode 100644 (file)
index 0000000..003379e
--- /dev/null
@@ -0,0 +1,56 @@
+#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);
+}
diff --git a/src/AST/table.c b/src/AST/table.c
deleted file mode 100644 (file)
index b903744..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#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);
-}
-
diff --git a/src/AST/table.cc b/src/AST/table.cc
new file mode 100644 (file)
index 0000000..b903744
--- /dev/null
@@ -0,0 +1,45 @@
+#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);
+}
+
diff --git a/src/AST/tableentry.c b/src/AST/tableentry.c
deleted file mode 100644 (file)
index 64aae20..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#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);
-}
diff --git a/src/AST/tableentry.cc b/src/AST/tableentry.cc
new file mode 100644 (file)
index 0000000..64aae20
--- /dev/null
@@ -0,0 +1,14 @@
+#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);
+}
diff --git a/src/Backend/cnfexpr.c b/src/Backend/cnfexpr.c
deleted file mode 100644 (file)
index ae1104f..0000000
+++ /dev/null
@@ -1,465 +0,0 @@
-#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(")");
-       }
-}
diff --git a/src/Backend/cnfexpr.cc b/src/Backend/cnfexpr.cc
new file mode 100644 (file)
index 0000000..1aa6cf0
--- /dev/null
@@ -0,0 +1,465 @@
+#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(")");
+       }
+}
diff --git a/src/Backend/constraint.c b/src/Backend/constraint.c
deleted file mode 100644 (file)
index c7cac98..0000000
+++ /dev/null
@@ -1,906 +0,0 @@
-#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;
-}
diff --git a/src/Backend/constraint.cc b/src/Backend/constraint.cc
new file mode 100644 (file)
index 0000000..a339988
--- /dev/null
@@ -0,0 +1,906 @@
+#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;
+}
diff --git a/src/Backend/inc_solver.c b/src/Backend/inc_solver.c
deleted file mode 100644 (file)
index 85528dc..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/*      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;
-}
diff --git a/src/Backend/inc_solver.cc b/src/Backend/inc_solver.cc
new file mode 100644 (file)
index 0000000..85528dc
--- /dev/null
@@ -0,0 +1,209 @@
+/*      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;
+}
diff --git a/src/Backend/orderelement.c b/src/Backend/orderelement.c
deleted file mode 100644 (file)
index 1355011..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#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);
-}
diff --git a/src/Backend/orderelement.cc b/src/Backend/orderelement.cc
new file mode 100644 (file)
index 0000000..1355011
--- /dev/null
@@ -0,0 +1,13 @@
+#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);
+}
diff --git a/src/Backend/orderpair.c b/src/Backend/orderpair.c
deleted file mode 100644 (file)
index 9501af5..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#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);
-}
diff --git a/src/Backend/orderpair.cc b/src/Backend/orderpair.cc
new file mode 100644 (file)
index 0000000..9501af5
--- /dev/null
@@ -0,0 +1,14 @@
+#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);
+}
diff --git a/src/Backend/satelemencoder.c b/src/Backend/satelemencoder.c
deleted file mode 100644 (file)
index 5beae4f..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-#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);
-       }
-}
-
diff --git a/src/Backend/satelemencoder.cc b/src/Backend/satelemencoder.cc
new file mode 100644 (file)
index 0000000..5aaa162
--- /dev/null
@@ -0,0 +1,150 @@
+#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);
+       }
+}
+
diff --git a/src/Backend/satencoder.c b/src/Backend/satencoder.c
deleted file mode 100644 (file)
index f5362b8..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-#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);
-       }
-}
diff --git a/src/Backend/satencoder.cc b/src/Backend/satencoder.cc
new file mode 100644 (file)
index 0000000..73998a6
--- /dev/null
@@ -0,0 +1,166 @@
+#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);
+       }
+}
diff --git a/src/Backend/satfuncopencoder.c b/src/Backend/satfuncopencoder.c
deleted file mode 100644 (file)
index 8dd7532..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-#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);
-}
-
diff --git a/src/Backend/satfuncopencoder.cc b/src/Backend/satfuncopencoder.cc
new file mode 100644 (file)
index 0000000..8dd7532
--- /dev/null
@@ -0,0 +1,221 @@
+#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);
+}
+
diff --git a/src/Backend/satfunctableencoder.c b/src/Backend/satfunctableencoder.c
deleted file mode 100644 (file)
index d37e6dc..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-#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);
-
-}
diff --git a/src/Backend/satfunctableencoder.cc b/src/Backend/satfunctableencoder.cc
new file mode 100644 (file)
index 0000000..d37e6dc
--- /dev/null
@@ -0,0 +1,323 @@
+#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);
+
+}
diff --git a/src/Backend/satorderencoder.c b/src/Backend/satorderencoder.c
deleted file mode 100644 (file)
index 64f414c..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-#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;
-}
diff --git a/src/Backend/satorderencoder.cc b/src/Backend/satorderencoder.cc
new file mode 100644 (file)
index 0000000..64f414c
--- /dev/null
@@ -0,0 +1,208 @@
+#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;
+}
diff --git a/src/Backend/sattranslator.c b/src/Backend/sattranslator.c
deleted file mode 100644 (file)
index ca0fdae..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-#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;
-}
-
diff --git a/src/Backend/sattranslator.cc b/src/Backend/sattranslator.cc
new file mode 100644 (file)
index 0000000..ca0fdae
--- /dev/null
@@ -0,0 +1,96 @@
+#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;
+}
+
diff --git a/src/Collections/structs.c b/src/Collections/structs.c
deleted file mode 100644 (file)
index d6cdd16..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#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);
diff --git a/src/Collections/structs.cc b/src/Collections/structs.cc
new file mode 100644 (file)
index 0000000..d6cdd16
--- /dev/null
@@ -0,0 +1,91 @@
+#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);
diff --git a/src/Encoders/elementencoding.c b/src/Encoders/elementencoding.c
deleted file mode 100644 (file)
index 1b0c6b8..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#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;
-}
-
-
diff --git a/src/Encoders/elementencoding.cc b/src/Encoders/elementencoding.cc
new file mode 100644 (file)
index 0000000..dde2692
--- /dev/null
@@ -0,0 +1,40 @@
+#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;
+}
+
+
diff --git a/src/Encoders/functionencoding.c b/src/Encoders/functionencoding.c
deleted file mode 100644 (file)
index 75910cf..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#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;
-}
diff --git a/src/Encoders/functionencoding.cc b/src/Encoders/functionencoding.cc
new file mode 100644 (file)
index 0000000..75910cf
--- /dev/null
@@ -0,0 +1,18 @@
+#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;
+}
diff --git a/src/Encoders/naiveencoder.c b/src/Encoders/naiveencoder.c
deleted file mode 100644 (file)
index 71dc582..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-#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);
-       }
-}
diff --git a/src/Encoders/naiveencoder.cc b/src/Encoders/naiveencoder.cc
new file mode 100644 (file)
index 0000000..71dc582
--- /dev/null
@@ -0,0 +1,108 @@
+#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);
+       }
+}
diff --git a/src/Encoders/orderedge.c b/src/Encoders/orderedge.c
deleted file mode 100644 (file)
index c4632da..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#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);
-}
-
diff --git a/src/Encoders/orderedge.cc b/src/Encoders/orderedge.cc
new file mode 100644 (file)
index 0000000..c4632da
--- /dev/null
@@ -0,0 +1,19 @@
+#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);
+}
+
diff --git a/src/Encoders/orderencoder.c b/src/Encoders/orderencoder.c
deleted file mode 100644 (file)
index 99f826b..0000000
+++ /dev/null
@@ -1,442 +0,0 @@
-#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);
-       }
-}
diff --git a/src/Encoders/orderencoder.cc b/src/Encoders/orderencoder.cc
new file mode 100644 (file)
index 0000000..99f826b
--- /dev/null
@@ -0,0 +1,442 @@
+#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);
+       }
+}
diff --git a/src/Encoders/orderencoding.c b/src/Encoders/orderencoding.c
deleted file mode 100644 (file)
index 51dddcc..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "orderencoding.h"
-
-void initOrderEncoding(OrderEncoding *This, Order *order) {
-       This->type = ORDER_UNASSIGNED;
-       This->order = order;
-}
-
-void deleteOrderEncoding(OrderEncoding *This) {
-}
diff --git a/src/Encoders/orderencoding.cc b/src/Encoders/orderencoding.cc
new file mode 100644 (file)
index 0000000..51dddcc
--- /dev/null
@@ -0,0 +1,9 @@
+#include "orderencoding.h"
+
+void initOrderEncoding(OrderEncoding *This, Order *order) {
+       This->type = ORDER_UNASSIGNED;
+       This->order = order;
+}
+
+void deleteOrderEncoding(OrderEncoding *This) {
+}
diff --git a/src/Encoders/ordergraph.c b/src/Encoders/ordergraph.c
deleted file mode 100644 (file)
index 32e1350..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-#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);
-}
diff --git a/src/Encoders/ordergraph.cc b/src/Encoders/ordergraph.cc
new file mode 100644 (file)
index 0000000..a6728d6
--- /dev/null
@@ -0,0 +1,182 @@
+#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);
+}
diff --git a/src/Encoders/ordernode.c b/src/Encoders/ordernode.c
deleted file mode 100644 (file)
index c0bd096..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#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);
-}
diff --git a/src/Encoders/ordernode.cc b/src/Encoders/ordernode.cc
new file mode 100644 (file)
index 0000000..c0bd096
--- /dev/null
@@ -0,0 +1,28 @@
+#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);
+}
diff --git a/src/Encoders/polarityassignment.c b/src/Encoders/polarityassignment.c
deleted file mode 100644 (file)
index 3e41380..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-#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);
-       }
-}
diff --git a/src/Encoders/polarityassignment.cc b/src/Encoders/polarityassignment.cc
new file mode 100644 (file)
index 0000000..77d2a06
--- /dev/null
@@ -0,0 +1,150 @@
+#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);
+       }
+}
index 007705d0aa6682300bb40bb02b65db9b71c28b7c..7a455130a8a8ef11ccc4082d31baa3529720415a 100644 (file)
@@ -4,11 +4,11 @@ PHONY += directories
 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
@@ -48,7 +48,7 @@ docs: $(C_SOURCES) $(HEADERS)
 ${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)
@@ -67,10 +67,10 @@ tags:
        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)
index be27d60f132d810e23426861b5f5bf3f2b2a423b..2c24d58663f479045afef075712bf3fe6177c434 100644 (file)
@@ -1,6 +1,6 @@
 BASE := ..
 
-OBJECTS := $(patsubst %.c, ../bin/%, $(wildcard *.c))
+OBJECTS := $(patsubst %.cc, ../bin/%, $(wildcard *.cc))
 
 include $(BASE)/common.mk
 
@@ -12,7 +12,7 @@ all: $(OBJECTS) ../bin/run.sh
 
 -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
diff --git a/src/Test/buildconstraintstest.c b/src/Test/buildconstraintstest.c
deleted file mode 100644 (file)
index 71dbafd..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-#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);
-}
diff --git a/src/Test/buildconstraintstest.cc b/src/Test/buildconstraintstest.cc
new file mode 100644 (file)
index 0000000..71dbafd
--- /dev/null
@@ -0,0 +1,59 @@
+#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);
+}
diff --git a/src/Test/cnftest.c b/src/Test/cnftest.c
deleted file mode 100644 (file)
index b76af26..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#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);
-}
diff --git a/src/Test/cnftest.cc b/src/Test/cnftest.cc
new file mode 100644 (file)
index 0000000..b76af26
--- /dev/null
@@ -0,0 +1,34 @@
+#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);
+}
diff --git a/src/Test/elemequalsattest.c b/src/Test/elemequalsattest.c
deleted file mode 100644 (file)
index 7841a70..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#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);
-}
diff --git a/src/Test/elemequalsattest.cc b/src/Test/elemequalsattest.cc
new file mode 100644 (file)
index 0000000..7841a70
--- /dev/null
@@ -0,0 +1,33 @@
+#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);
+}
diff --git a/src/Test/elemequalunsattest.c b/src/Test/elemequalunsattest.c
deleted file mode 100644 (file)
index 5cbdd04..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#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);
-}
diff --git a/src/Test/elemequalunsattest.cc b/src/Test/elemequalunsattest.cc
new file mode 100644 (file)
index 0000000..5cbdd04
--- /dev/null
@@ -0,0 +1,28 @@
+#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);
+}
diff --git a/src/Test/funcencodingtest.c b/src/Test/funcencodingtest.c
deleted file mode 100644 (file)
index 24b652f..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-#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);
-}
diff --git a/src/Test/funcencodingtest.cc b/src/Test/funcencodingtest.cc
new file mode 100644 (file)
index 0000000..24b652f
--- /dev/null
@@ -0,0 +1,82 @@
+#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);
+}
diff --git a/src/Test/logicopstest.c b/src/Test/logicopstest.c
deleted file mode 100644 (file)
index 9d12a05..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#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
diff --git a/src/Test/logicopstest.cc b/src/Test/logicopstest.cc
new file mode 100644 (file)
index 0000000..9d12a05
--- /dev/null
@@ -0,0 +1,29 @@
+#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
diff --git a/src/Test/ltelemconsttest.c b/src/Test/ltelemconsttest.c
deleted file mode 100644 (file)
index 4818f24..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#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
diff --git a/src/Test/ltelemconsttest.cc b/src/Test/ltelemconsttest.cc
new file mode 100644 (file)
index 0000000..4818f24
--- /dev/null
@@ -0,0 +1,26 @@
+#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
diff --git a/src/Test/ordergraphtest.c b/src/Test/ordergraphtest.c
deleted file mode 100644 (file)
index 646b195..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#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
diff --git a/src/Test/ordergraphtest.cc b/src/Test/ordergraphtest.cc
new file mode 100644 (file)
index 0000000..646b195
--- /dev/null
@@ -0,0 +1,37 @@
+#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
diff --git a/src/Test/ordertest.c b/src/Test/ordertest.c
deleted file mode 100644 (file)
index eef8c36..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-
-#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);
-}
diff --git a/src/Test/ordertest.cc b/src/Test/ordertest.cc
new file mode 100644 (file)
index 0000000..eef8c36
--- /dev/null
@@ -0,0 +1,23 @@
+
+#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);
+}
diff --git a/src/Test/tablefuncencodetest.c b/src/Test/tablefuncencodetest.c
deleted file mode 100644 (file)
index a7b9412..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-#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);
-}
diff --git a/src/Test/tablefuncencodetest.cc b/src/Test/tablefuncencodetest.cc
new file mode 100644 (file)
index 0000000..a7b9412
--- /dev/null
@@ -0,0 +1,59 @@
+#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);
+}
diff --git a/src/Test/tablepredicencodetest.c b/src/Test/tablepredicencodetest.c
deleted file mode 100644 (file)
index ee9094b..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#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);
-}
diff --git a/src/Test/tablepredicencodetest.cc b/src/Test/tablepredicencodetest.cc
new file mode 100644 (file)
index 0000000..ee9094b
--- /dev/null
@@ -0,0 +1,66 @@
+#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);
+}
diff --git a/src/Tuner/tunable.c b/src/Tuner/tunable.c
deleted file mode 100644 (file)
index 237b91c..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#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;
-}
diff --git a/src/Tuner/tunable.cc b/src/Tuner/tunable.cc
new file mode 100644 (file)
index 0000000..e0a3201
--- /dev/null
@@ -0,0 +1,16 @@
+#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;
+}
diff --git a/src/common.c b/src/common.c
deleted file mode 100644 (file)
index 660472f..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#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
diff --git a/src/common.cc b/src/common.cc
new file mode 100644 (file)
index 0000000..660472f
--- /dev/null
@@ -0,0 +1,6 @@
+#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
diff --git a/src/csolver.c b/src/csolver.c
deleted file mode 100644 (file)
index e9c9526..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-#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);
-}
-
diff --git a/src/csolver.cc b/src/csolver.cc
new file mode 100644 (file)
index 0000000..e9c9526
--- /dev/null
@@ -0,0 +1,242 @@
+#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);
+}
+