enum BooleanValue {BV_UNDEFINED=0, BV_MUSTBETRUE=1, BV_MUSTBEFALSE=2, BV_UNSAT=3};
typedef enum BooleanValue BooleanValue;
+extern const char *elemEncTypeNames[];
+
enum ElementEncodingType {
ELEM_UNASSIGNED, ONEHOT, UNARY, BINARYINDEX, BINARYVAL
};
}
void ElementSet::print() {
- model_print("{ElementSet:\n");
+ model_print("{ElementSet:");
set->print();
- model_print("}\n");
+ model_print(" %p ", this);
+ getElementEncoding()->print();
+ model_print("}");
}
void ElementConst::serialize(Serializer *serializer) {
}
void PredicateOperator::print() {
- model_print("{PredicateOperator: %s }\n", op == SATC_EQUALS ? "EQUAL" : "NOT-EQUAL");
+ const char *names[] = {"==", "<", ">", "<=", ">="};
+
+ model_print("PredicateOperator: %s\n", names[(int)op]);
}
void Set::print() {
model_print("{Set:");
if (isRange) {
- model_print("Range: low=%lu, high=%lu}\n\n", low, high);
+ model_print("Range: low=%lu, high=%lu}", low, high);
} else {
uint size = members->getSize();
model_print("Members: ");
uint64_t mem = members->get(i);
model_print("%lu, ", mem);
}
- model_print("}\n");
+ model_print("}");
}
}
if (!edge->mustPos)
continue;
} else
- if (!edge->polPos && !edge->pseudoPos) //Ignore edges that do not have positive polarity
+ if (!edge->polPos && !edge->pseudoPos) //Ignore edges that do not have positive polarity
continue;
OrderNode *child = isReverse ? edge->source : edge->sink;
child->status = VISITED;
DFSNodeVisit(child, finishNodes, isReverse, mustvisit, sccNum);
child->status = FINISHED;
- if (finishNodes != NULL)
+ if (finishNodes != NULL) {
finishNodes->push(child);
+ }
if (isReverse)
child->sccNum = sccNum;
}
resetNodeInfoStatusSCC(graph);
}
-bool isMustBeTrueNode(OrderNode *node) {
- SetIteratorOrderEdge *iterator = node->inEdges.iterator();
- while (iterator->hasNext()) {
- OrderEdge *edge = iterator->next();
- if (!edge->mustPos) {
- delete iterator;
- return false;
- }
- }
- delete iterator;
- iterator = node->outEdges.iterator();
- while (iterator->hasNext()) {
- OrderEdge *edge = iterator->next();
- if (!edge->mustPos) {
- delete iterator;
- return false;
- }
- }
- delete iterator;
- return true;
-}
-
-void bypassMustBeTrueNode(CSolver *This, OrderGraph *graph, OrderNode *node) {
- SetIteratorOrderEdge *iterin = node->inEdges.iterator();
- while (iterin->hasNext()) {
- OrderEdge *inEdge = iterin->next();
- OrderNode *srcNode = inEdge->source;
- srcNode->outEdges.remove(inEdge);
- SetIteratorOrderEdge *iterout = node->outEdges.iterator();
- while (iterout->hasNext()) {
- OrderEdge *outEdge = iterout->next();
- OrderNode *sinkNode = outEdge->sink;
- sinkNode->inEdges.remove(outEdge);
- //Adding new edge to new sink and src nodes ...
- if (srcNode == sinkNode) {
- This->setUnSAT();
- delete iterout;
- delete iterin;
- return;
- }
- OrderEdge *newEdge = graph->getOrderEdgeFromOrderGraph(srcNode, sinkNode);
- newEdge->mustPos = true;
- newEdge->polPos = true;
- if (newEdge->mustNeg)
- This->setUnSAT();
- srcNode->outEdges.add(newEdge);
- sinkNode->inEdges.add(newEdge);
- }
- delete iterout;
- }
- delete iterin;
-}
-void removeMustBeTrueNodes(CSolver *This, OrderGraph *graph) {
- SetIteratorOrderNode *iterator = graph->getNodes();
- while (iterator->hasNext()) {
- OrderNode *node = iterator->next();
- if (isMustBeTrueNode(node)) {
- bypassMustBeTrueNode(This, graph, node);
- }
- }
- delete iterator;
-}
/** This function computes a source set for every nodes, the set of
nodes that can reach that node via pospolarity edges. It then
void DFSReverse(OrderGraph *graph, Vector<OrderNode *> *finishNodes);
void completePartialOrderGraph(OrderGraph *graph);
void resetNodeInfoStatusSCC(OrderGraph *graph);
-bool isMustBeTrueNode(OrderNode *node);
-void bypassMustBeTrueNode(CSolver *This, OrderGraph *graph, OrderNode *node);
-void removeMustBeTrueNodes(CSolver *This, OrderGraph *graph);
void DFSMust(OrderGraph *graph, Vector<OrderNode *> *finishNodes);
void DFSClearContradictions(CSolver *solver, OrderGraph *graph, Vector<OrderNode *> *finishNodes, bool computeTransitiveClosure);
void reachMustAnalysis(CSolver *solver, OrderGraph *graph, bool computeTransitiveClosure);
OrderNode(uint64_t id);
void addNewIncomingEdge(OrderEdge *edge);
void addNewOutgoingEdge(OrderEdge *edge);
+ uint64_t getID() {return id;}
uint64_t id;
NodeStatus status;
bool mustReachPrune = GETVARTUNABLE(solver->getTuner(), order->type, MUSTREACHPRUNE, &onoff);
+ HashsetOrderEdge *edgesRemoved = NULL;
- if (mustReachPrune)
- removeMustBeTrueNodes(solver, graph);
+ if (mustReachPrune) {
+ edgesRemoved = new HashsetOrderEdge();
+ removeMustBeTrueNodes(graph, edgesRemoved);
+ }
//This is needed for splitorder
computeStronglyConnectedComponentGraph(graph);
- decomposeOrder(order, graph);
+ decomposeOrder(order, graph, edgesRemoved);
+ if (edgesRemoved != NULL)
+ delete edgesRemoved;
}
delete orderit;
delete orders;
}
-void DecomposeOrderTransform::decomposeOrder (Order *currOrder, OrderGraph *currGraph) {
+void DecomposeOrderTransform::decomposeOrder (Order *currOrder, OrderGraph *currGraph, HashsetOrderEdge *edgesRemoved) {
Vector<Order *> ordervec;
Vector<Order *> partialcandidatevec;
uint size = currOrder->constraints.getSize();
BooleanOrder *orderconstraint = currOrder->constraints.get(i);
OrderNode *from = currGraph->getOrderNodeFromOrderGraph(orderconstraint->first);
OrderNode *to = currGraph->getOrderNodeFromOrderGraph(orderconstraint->second);
+ OrderEdge *edge = currGraph->lookupOrderEdgeFromOrderGraph(from, to);
+ OrderEdge *invedge = currGraph->lookupOrderEdgeFromOrderGraph(to, from);
+ if (edgesRemoved != NULL) {
+ if (edgesRemoved->contains(edge)) {
+ solver->replaceBooleanWithTrue(orderconstraint);
+ continue;
+ } else if (edgesRemoved->contains(invedge)) {
+ solver->replaceBooleanWithFalse(orderconstraint);
+ continue;
+ }
+ }
+
if (from->sccNum != to->sccNum) {
- OrderEdge *edge = currGraph->lookupOrderEdgeFromOrderGraph(from, to);
if (edge != NULL) {
if (edge->polPos) {
solver->replaceBooleanWithTrue(orderconstraint);
;
}
} else {
- OrderEdge *invedge = currGraph->lookupOrderEdgeFromOrderGraph(to, from);
if (invedge != NULL) {
if (invedge->polPos) {
solver->replaceBooleanWithFalse(orderconstraint);
((MutableSet *)neworder->set)->addElementMSet(to->id);
}
if (currOrder->type == SATC_PARTIAL) {
- OrderEdge *edge = currGraph->getOrderEdgeFromOrderGraph(from, to);
if (edge->polNeg)
partialcandidatevec.setExpand(from->sccNum, NULL);
}
}
}
}
+
+bool DecomposeOrderTransform::isMustBeTrueNode(OrderNode *node) {
+ SetIteratorOrderEdge *iterator = node->inEdges.iterator();
+ while (iterator->hasNext()) {
+ OrderEdge *edge = iterator->next();
+ if (!edge->mustPos) {
+ delete iterator;
+ return false;
+ }
+ }
+ delete iterator;
+ iterator = node->outEdges.iterator();
+ while (iterator->hasNext()) {
+ OrderEdge *edge = iterator->next();
+ if (!edge->mustPos) {
+ delete iterator;
+ return false;
+ }
+ }
+ delete iterator;
+ return true;
+}
+
+void DecomposeOrderTransform::bypassMustBeTrueNode(OrderGraph *graph, OrderNode *node, HashsetOrderEdge *edgesRemoved) {
+ SetIteratorOrderEdge *iterin = node->inEdges.iterator();
+ while (iterin->hasNext()) {
+ OrderEdge *inEdge = iterin->next();
+ OrderNode *srcNode = inEdge->source;
+ srcNode->outEdges.remove(inEdge);
+ edgesRemoved->add(inEdge);
+ SetIteratorOrderEdge *iterout = node->outEdges.iterator();
+ while (iterout->hasNext()) {
+ OrderEdge *outEdge = iterout->next();
+ OrderNode *sinkNode = outEdge->sink;
+ sinkNode->inEdges.remove(outEdge);
+ edgesRemoved->add(outEdge);
+ //Adding new edge to new sink and src nodes ...
+ if (srcNode == sinkNode) {
+ solver->setUnSAT();
+ delete iterout;
+ delete iterin;
+ return;
+ }
+ //Add new order constraint
+ BooleanEdge orderconstraint = solver->orderConstraint(graph->getOrder(), srcNode->getID(), sinkNode->getID());
+ solver->addConstraint(orderconstraint);
+
+ //Add new edge
+ OrderEdge *newEdge = graph->getOrderEdgeFromOrderGraph(srcNode, sinkNode);
+ newEdge->mustPos = true;
+ newEdge->polPos = true;
+ if (newEdge->mustNeg)
+ solver->setUnSAT();
+ srcNode->outEdges.add(newEdge);
+ sinkNode->inEdges.add(newEdge);
+ }
+ delete iterout;
+ }
+ delete iterin;
+}
+
+void DecomposeOrderTransform::removeMustBeTrueNodes(OrderGraph *graph, HashsetOrderEdge *edgesRemoved) {
+ SetIteratorOrderNode *iterator = graph->getNodes();
+ while (iterator->hasNext()) {
+ OrderNode *node = iterator->next();
+ if (isMustBeTrueNode(node)) {
+ bypassMustBeTrueNode(graph, node, edgesRemoved);
+ }
+ }
+ delete iterator;
+}
DecomposeOrderTransform(CSolver *_solver);
~DecomposeOrderTransform();
void doTransform();
- void decomposeOrder (Order *currOrder, OrderGraph *currGraph);
CMEMALLOC;
private:
+ bool isMustBeTrueNode(OrderNode *node);
+ void bypassMustBeTrueNode(OrderGraph *graph, OrderNode *node, HashsetOrderEdge *edgesRemoved);
+ void decomposeOrder(Order *currOrder, OrderGraph *currGraph, HashsetOrderEdge *edgesRemoved);
+ void removeMustBeTrueNodes(OrderGraph *graph, HashsetOrderEdge *edgesRemoved);
};
+
+
#endif/* ORDERTRANSFORM_H */
#include "satencoder.h"
#include "set.h"
+const char *elemEncTypeNames[] = {"UNASSIGNED", "ONEHOT", "UNARY", "BINARYINDEX", "BINARYVAL"};
+
ElementEncoding::ElementEncoding(Element *_element) :
type(ELEM_UNASSIGNED),
element(_element),
setInUseElement(i);
}
}
+
+void ElementEncoding::print() {
+ model_print("%s ", elemEncTypeNames[type]);
+ if (type == BINARYINDEX) {
+ for (uint i = 0; i < encArraySize; i++) {
+ if (i != 0)
+ model_print(" ,");
+ if (isinUseElement(i))
+ model_print("%" PRIu64 "", encodingArray[i]);
+ else
+ model_print("_");
+ }
+ }
+}
}
return -1;
}
-
+ void print();
ElementEncodingType type;
Element *element;
BooleanEdge v3 = solver->getBooleanVar(0);
BooleanEdge v4 = solver->getBooleanVar(0);
BooleanEdge v5 = solver->getBooleanVar(0);
- solver->addConstraint(
- solver->applyLogicalOperation(SATC_OR,
- solver->applyLogicalOperation(SATC_IFF, v3, v4),
- v5));
+ BooleanEdge be = solver->applyLogicalOperation(SATC_IFF, v3, v4);
+ BooleanEdge sor = solver->applyLogicalOperation(SATC_OR, be, v5);
+ solver->addConstraint(sor);
solver->addConstraint(solver->applyLogicalOperation(SATC_NOT, v5));
BooleanEdge v6 = solver->getBooleanVar(0);
BooleanEdge v7 = solver->getBooleanVar(0);
solver->applyLogicalOperation(SATC_OR, v10, v11),
solver->applyLogicalOperation(SATC_IFF, v1, v12)));
BooleanEdge b48 = solver->orderConstraint(order, 4, 8);
- solver->addConstraint(
- solver->applyLogicalOperation(SATC_OR,
- solver->applyLogicalOperation(SATC_OR, v10, v11),
- b48));
+ BooleanEdge be1 = solver->applyLogicalOperation(SATC_OR, v10, v11);
+ BooleanEdge be2 = solver->applyLogicalOperation(SATC_OR, be1, b48);
+ solver->addConstraint(be2);
BooleanEdge v13 = solver->getBooleanVar(0);
BooleanEdge v14 = solver->getBooleanVar(0);
solver->addConstraint(
}
void CSolver::addConstraint(BooleanEdge constraint) {
- if (constraint.isNegated())
- model_print("!");
- constraint.getBoolean()->print();
if (isTrue(constraint))
return;
else if (isFalse(constraint)) {
long long startTime = getTimeNano();
computePolarities(this);
- //Preprocess pp(this);
- //pp.doTransform();
+ Preprocess pp(this);
+ pp.doTransform();
- //DecomposeOrderTransform dot(this);
- // dot.doTransform();
+ DecomposeOrderTransform dot(this);
+ dot.doTransform();
- //IntegerEncodingTransform iet(this);
- // iet.doTransform();
-
- //EncodingGraph eg(this);
- //eg.buildGraph();
- //eg.encode();
+ IntegerEncodingTransform iet(this);
+ iet.doTransform();
+ EncodingGraph eg(this);
+ eg.buildGraph();
+ eg.encode();
+ printConstraints();
naiveEncodingDecision(this);
satEncoder->encodeAllSATEncoder(this);
model_print("Is problem UNSAT after encoding: %d\n", unsat);
return result;
}
+void CSolver::printConstraints() {
+ SetIteratorBooleanEdge *it = getConstraints();
+ while (it->hasNext()) {
+ BooleanEdge b = it->next();
+ if (b.isNegated())
+ model_print("!");
+ b->print();
+ model_print("\n");
+ }
+ delete it;
+
+}
+
uint64_t CSolver::getElementValue(Element *element) {
switch (element->type) {
case ELEMSET:
bool isFalse(BooleanEdge b);
void setUnSAT() { model_print("Setting UNSAT %%%%%%\n"); unsat = true; }
-
bool isUnSAT() { return unsat; }
+ void printConstraints();
+
Vector<Order *> *getOrders() { return &allOrders;}
HashsetOrder *getActiveOrders() { return &activeOrders;}