New Resolver Strategy
[satune.git] / src / ASTTransform / decomposeordertransform.cc
index 3791b100fe6358f0ee39b3e2cce90a4410408526..01a667d9eb0c32c83432e9eae083c4a275911698 100644 (file)
@@ -28,29 +28,30 @@ DecomposeOrderTransform::~DecomposeOrderTransform() {
 
 void DecomposeOrderTransform::doTransform() {
        HashsetOrder *orders = solver->getActiveOrders()->copy();
-       SetIteratorOrder * orderit=orders->iterator();
-       while(orderit->hasNext()) {
+       SetIteratorOrder *orderit = orders->iterator();
+       while (orderit->hasNext()) {
                Order *order = orderit->next();
 
                if (GETVARTUNABLE(solver->getTuner(), order->type, DECOMPOSEORDER, &onoff) == 0) {
                        continue;
                }
 
+               DecomposeOrderResolver *dor=new DecomposeOrderResolver(order);
+               order->setOrderResolver(dor);
+               
                OrderGraph *graph = buildOrderGraph(order);
                if (order->type == SATC_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);
+                       graph->completePartialOrderGraph();
                }
 
                bool mustReachGlobal = GETVARTUNABLE(solver->getTuner(), order->type, MUSTREACHGLOBAL, &onoff);
-
                if (mustReachGlobal)
                        reachMustAnalysis(solver, graph, false);
 
                bool mustReachLocal = GETVARTUNABLE(solver->getTuner(), order->type, MUSTREACHLOCAL, &onoff);
-
                if (mustReachLocal) {
                        //This pair of analysis is also optional
                        if (order->type == SATC_PARTIAL) {
@@ -60,35 +61,55 @@ void DecomposeOrderTransform::doTransform() {
                        }
                }
 
-               
                bool mustReachPrune = GETVARTUNABLE(solver->getTuner(), order->type, MUSTREACHPRUNE, &onoff);
+               HashsetOrderEdge *edgesRemoved = NULL;
+
+               if (mustReachPrune) {
+                       edgesRemoved = new HashsetOrderEdge();
+                       removeMustBeTrueNodes(graph, edgesRemoved);
+               }
 
-               if (mustReachPrune)
-                       removeMustBeTrueNodes(solver, graph);
-               
                //This is needed for splitorder
-               computeStronglyConnectedComponentGraph(graph);
-               decomposeOrder(order, graph);
+               graph->computeStronglyConnectedComponentGraph();
+               decomposeOrder(order, graph, edgesRemoved, dor);
+               if (edgesRemoved != NULL)
+                       delete edgesRemoved;
+               delete graph;
        }
        delete orderit;
        delete orders;
 }
 
 
-void DecomposeOrderTransform::decomposeOrder (Order *currOrder, OrderGraph *currGraph) {
-       Vector<Order *> ordervec;
+void DecomposeOrderTransform::decomposeOrder (Order *currOrder, OrderGraph *currGraph, HashsetOrderEdge *edgesRemoved, DecomposeOrderResolver *dor) {
        Vector<Order *> partialcandidatevec;
        uint size = currOrder->constraints.getSize();
        for (uint i = 0; i < size; i++) {
                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)) {
+                               dor->mustOrderEdge(from->getID(), to->getID());
+                               solver->replaceBooleanWithTrue(orderconstraint);
+                               continue;
+                       } else if (edgesRemoved->contains(invedge)) {
+                               dor->mustOrderEdge(to->getID(), from->getID());
+                               solver->replaceBooleanWithFalse(orderconstraint);
+                               continue;
+                       }
+               }
+
                if (from->sccNum != to->sccNum) {
-                       OrderEdge *edge = currGraph->lookupOrderEdgeFromOrderGraph(from, to);
                        if (edge != NULL) {
                                if (edge->polPos) {
+                                       dor->mustOrderEdge(from->getID(), to->getID());
                                        solver->replaceBooleanWithTrue(orderconstraint);
                                } else if (edge->polNeg) {
+                                       if (currOrder->type == SATC_TOTAL)                                      
+                                               dor->mustOrderEdge(to->getID(), from->getID());
                                        solver->replaceBooleanWithFalse(orderconstraint);
                                } else {
                                        //This case should only be possible if constraint isn't in AST
@@ -96,9 +117,9 @@ void DecomposeOrderTransform::decomposeOrder (Order *currOrder, OrderGraph *curr
                                        ;
                                }
                        } else {
-                               OrderEdge *invedge = currGraph->lookupOrderEdgeFromOrderGraph(to, from);
                                if (invedge != NULL) {
                                        if (invedge->polPos) {
+                                               dor->mustOrderEdge(to->getID(), from->getID());
                                                solver->replaceBooleanWithFalse(orderconstraint);
                                        } else if (edge->polNeg) {
                                                //This case shouldn't happen...  If we have a partial order,
@@ -115,12 +136,11 @@ void DecomposeOrderTransform::decomposeOrder (Order *currOrder, OrderGraph *curr
                } else {
                        //Build new order and change constraint's order
                        Order *neworder = NULL;
-                       if (ordervec.getSize() > from->sccNum)
-                               neworder = ordervec.get(from->sccNum);
+                       neworder = dor->getOrder(from->sccNum);
                        if (neworder == NULL) {
                                MutableSet *set = solver->createMutableSet(currOrder->set->getType());
                                neworder = solver->createOrder(currOrder->type, set);
-                               ordervec.setExpand(from->sccNum, neworder);
+                               dor->setOrder(from->sccNum, neworder);
                                if (currOrder->type == SATC_PARTIAL)
                                        partialcandidatevec.setExpand(from->sccNum, neworder);
                                else
@@ -135,15 +155,14 @@ void DecomposeOrderTransform::decomposeOrder (Order *currOrder, OrderGraph *curr
                                ((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);
                        }
                        orderconstraint->order = neworder;
+                       dor->setEdgeOrder(from->getID(), to->getID(), from->sccNum);
                        neworder->addOrderConstraint(orderconstraint);
                }
        }
-       currOrder->setOrderResolver( new DecomposeOrderResolver(currGraph, ordervec) );
        solver->getActiveOrders()->remove(currOrder);
        uint pcvsize = partialcandidatevec.getSize();
        for (uint i = 0; i < pcvsize; i++) {
@@ -153,3 +172,77 @@ void DecomposeOrderTransform::decomposeOrder (Order *currOrder, OrderGraph *curr
                }
        }
 }
+
+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) {
+       node->removed = true;
+       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;
+                               graph->removeNode(node);
+                               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;
+       graph->removeNode(node);
+}
+
+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;
+}