removing true nodes from the OrderGraph
[satune.git] / src / Encoders / orderencoder.c
index 8f83906d1d9b70e5701346e52789bb22e1f3e2e8..32bd91092f16699200675b02911399527a2e6524 100644 (file)
@@ -5,24 +5,17 @@
 #include "ordergraph.h"
 #include "order.h"
 #include "ordernode.h"
-
-
-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;
-}
-
-void DFS(OrderGraph* graph, VectorOrderNode* finishNodes) {
-       HSIteratorOrderNode* iterator = iteratorOrderNode(graph->nodes);
-       while(hasNextOrderNode(iterator)){
-               OrderNode* node = nextOrderNode(iterator);
-               if(node->status == NOTVISITED){
+#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, 0);
+                       DFSNodeVisit(node, finishNodes, false, false, 0);
                        node->status = FINISHED;
                        pushVectorOrderNode(finishNodes, node);
                }
@@ -30,14 +23,14 @@ void DFS(OrderGraph* graph, VectorOrderNode* finishNodes) {
        deleteIterOrderNode(iterator);
 }
 
-void DFSReverse(OrderGraph* graph, VectorOrderNode* finishNodes) {
+void DFSReverse(OrderGraph *graph, VectorOrderNode *finishNodes) {
        uint size = getSizeVectorOrderNode(finishNodes);
-       uint sccNum=1;
-       for(int i=size-1; i>=0; i--){
-               OrderNodenode = getVectorOrderNode(finishNodes, i);
-               if(node->status == NOTVISITED){
+       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, sccNum);
+                       DFSNodeVisit(node, NULL, true, false, sccNum);
                        node->sccNum = sccNum;
                        node->status = FINISHED;
                        sccNum++;
@@ -45,39 +38,43 @@ void DFSReverse(OrderGraph* graph, VectorOrderNode* finishNodes) {
        }
 }
 
-void DFSNodeVisit(OrderNode* node, VectorOrderNode* finishNodes, bool isReverse, uint sccNum) {
-       HSIteratorOrderEdge* iterator = isReverse?iteratorOrderEdge(node->inEdges):iteratorOrderEdge(node->outEdges);
-       while(hasNextOrderEdge(iterator)){
-               OrderEdge* edge = nextOrderEdge(iterator);
-               if (!edge->polPos && !edge->pseudoPos) //Ignore edges that do not have positive polarity
-                       continue;
-               
-               OrderNode* child = isReverse? edge->source: edge->sink;
+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;
 
-               if(child->status == NOTVISITED) {
+               OrderNode *child = isReverse ? edge->source : edge->sink;
+
+               if (child->status == NOTVISITED) {
                        child->status = VISITED;
-                       DFSNodeVisit(child, finishNodes, isReverse, sccNum);
+                       DFSNodeVisit(child, finishNodes, isReverse, mustvisit, sccNum);
                        child->status = FINISHED;
-                       if(!isReverse)
-                               pushVectorOrderNode(finishNodes, child); 
-                       else
+                       if (finishNodes != NULL)
+                               pushVectorOrderNode(finishNodes, child);
+                       if (isReverse)
                                child->sccNum = sccNum;
                }
        }
        deleteIterOrderEdge(iterator);
 }
 
-void resetNodeInfoStatusSCC(OrderGraphgraph) {
-       HSIteratorOrderNodeiterator = iteratorOrderNode(graph->nodes);
-       while(hasNextOrderNode(iterator)){
+void resetNodeInfoStatusSCC(OrderGraph *graph) {
+       HSIteratorOrderNode *iterator = iteratorOrderNode(graph->nodes);
+       while (hasNextOrderNode(iterator)) {
                nextOrderNode(iterator)->status = NOTVISITED;
        }
        deleteIterOrderNode(iterator);
 }
 
-void computeStronglyConnectedComponentGraph(OrderGraphgraph) {
+void computeStronglyConnectedComponentGraph(OrderGraph *graph) {
        VectorOrderNode finishNodes;
-       initDefVectorOrderNode(& finishNodes);
+       initDefVectorOrderNode(&finishNodes);
        DFS(graph, &finishNodes);
        resetNodeInfoStatusSCC(graph);
        DFSReverse(graph, &finishNodes);
@@ -85,67 +82,147 @@ void computeStronglyConnectedComponentGraph(OrderGraph* graph) {
        deleteVectorArrayOrderNode(&finishNodes);
 }
 
-void removeMustBeTrueNodes(OrderGraph* graph) {
-       //TODO: Nodes that all the incoming/outgoing edges are MUST_BE_TRUE
-}
-
-void DFSPseudoNodeVisit(OrderGraph *graph, OrderNode* node) {
+bool isMustBeTrueNode(OrderNode* node){
        HSIteratorOrderEdge* iterator = iteratorOrderEdge(node->inEdges);
        while(hasNextOrderEdge(iterator)){
-               OrderEdge* inEdge = nextOrderEdge(iterator);
-               if (inEdge->polNeg) {
-                       OrderNode* src = inEdge->source;
-                       if (src->status==VISITED) {
-                               //Make a pseudoEdge to point backwards
-                               OrderEdge * newedge = getOrderEdgeFromOrderGraph(graph, inEdge->sink, inEdge->source);
-                               newedge->pseudoPos = true;
-                       }
-               }
+               OrderEdge* edge = nextOrderEdge(iterator);
+               if(!edge->mustPos)
+                       return false;
        }
        deleteIterOrderEdge(iterator);
        iterator = iteratorOrderEdge(node->outEdges);
        while(hasNextOrderEdge(iterator)){
                OrderEdge* edge = nextOrderEdge(iterator);
-               if (!edge->polPos) //Ignore edges that do not have positive polarity
-                       continue;
-               
-               OrderNode* child = edge->sink;
-               if(child->status == NOTVISITED){
-                       child->status = VISITED;
-                       DFSPseudoNodeVisit(graph, child);
-                       child->status = FINISHED;
-               }
+               if(!edge->mustPos)
+                       return false;
        }
        deleteIterOrderEdge(iterator);
+       return true;
+}
+
+void bypassMustBeTrueNode(CSolver *This, OrderGraph* graph, OrderNode* node){
+       HSIteratorOrderEdge* iterin = iteratorOrderEdge(node->inEdges);
+       while(hasNextOrderEdge(iterin)){
+               OrderEdge* inEdge = nextOrderEdge(iterin);
+               OrderNode* srcNode = inEdge->source;
+               removeHashSetOrderEdge(srcNode->outEdges, inEdge);
+               HSIteratorOrderEdge* iterout = iteratorOrderEdge(node->outEdges);
+               while(hasNextOrderEdge(iterout)){
+                       OrderEdge* outEdge = nextOrderEdge(iterout);
+                       OrderNode* sinkNode = outEdge->sink;
+                       removeHashSetOrderEdge(sinkNode->inEdges, outEdge);
+                       //Adding new edge to new sink and src nodes ...
+                       OrderEdge *newEdge =getOrderEdgeFromOrderGraph(graph, srcNode, sinkNode);
+                       newEdge->mustPos = true;
+                       newEdge->polPos = true;
+                       if (newEdge->mustNeg)
+                               This->unsat = true;
+                       addHashSetOrderEdge(srcNode->outEdges, newEdge);
+                       addHashSetOrderEdge(sinkNode->inEdges, newEdge);
+               }
+               deleteIterOrderEdge(iterout);
+       }
+       deleteIterOrderEdge(iterin);
+}
+
+void removeMustBeTrueNodes(CSolver *This, OrderGraph *graph) {
+       HSIteratorOrderNode* iterator = iteratorOrderNode(graph->nodes);
+       while(hasNextOrderNode(iterator)){
+               OrderNode* node = nextOrderNode(iterator);
+               if(isMustBeTrueNode(node)){
+                       bypassMustBeTrueNode(This,graph, node);
+               }
+       }
+       deleteIterOrderNode(iterator);
 }
 
-void completePartialOrderGraph(OrderGraph* graph) {
+/** 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);
+       initDefVectorOrderNode(&finishNodes);
        DFS(graph, &finishNodes);
        resetNodeInfoStatusSCC(graph);
+       HashTableNodeToNodeSet *table = allocHashTableNodeToNodeSet(128, 0.25);
 
+       VectorOrderNode sccNodes;
+       initDefVectorOrderNode(&sccNodes);
+       
        uint size = getSizeVectorOrderNode(&finishNodes);
-       for(int i=size-1; i>=0; i--){
-               OrderNode* node = getVectorOrderNode(&finishNodes, i);
-               if(node->status == NOTVISITED){
+       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;
-                       DFSPseudoNodeVisit(graph, node);
+                       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) {
-       HSIteratorOrderNodeiterator = iteratorOrderNode(graph->nodes);
-       while(hasNextOrderNode(iterator)){
-               OrderNodenode = nextOrderNode(iterator);
-               if(node->status == NOTVISITED){
+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;
-                       DFSMustNodeVisit(node, finishNodes, false);
+                       DFSNodeVisit(node, finishNodes, false, true, 0);
                        node->status = FINISHED;
                        pushVectorOrderNode(finishNodes, node);
                }
@@ -153,109 +230,145 @@ void DFSMust(OrderGraph* graph, VectorOrderNode* finishNodes) {
        deleteIterOrderNode(iterator);
 }
 
-void DFSMustNodeVisit(OrderNode* node, VectorOrderNode* finishNodes, bool clearBackEdges) {
-       //First compute implication of transitive closure on must pos edges
-       HSIteratorOrderEdge* iterator = iteratorOrderEdge(node->outEdges);
-       while(hasNextOrderEdge(iterator)){
-               OrderEdge* edge = nextOrderEdge(iterator);
-               OrderNode* parent = edge->source;
-               if (parent->status == VISITED) {
-                       edge->mustPos = true;
+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);
                }
-       }
-       deleteIterOrderEdge(iterator);
-
-       //Next compute implication of transitive closure on must neg edges
-       iterator = iteratorOrderEdge(node->outEdges);
-       while(hasNextOrderEdge(iterator)){
-               OrderEdge* edge = nextOrderEdge(iterator);
-               OrderNode* child = edge->sink;
-               
-               if (clearBackEdges && child->status==VISITED) {
-                       //We have a backedge, so note that this edge must be negative
-                       edge->mustNeg = true;
+               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);
                }
-
-               if (!edge->mustPos) //Ignore edges that are not must Positive edges
-                       continue;
-
-               if(child->status == NOTVISITED){
-                       child->status = VISITED;
-                       DFSMustNodeVisit(child, finishNodes, clearBackEdges);
-                       child->status = FINISHED;
-                       pushVectorOrderNode(finishNodes, child); 
+               {
+                       //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);
                }
-       }
-       deleteIterOrderEdge(iterator);
-}
-
-void DFSClearContradictions(OrderGraph* graph, VectorOrderNode* finishNodes) {
-       uint size=getSizeVectorOrderNode(finishNodes);
-       for(int i=size-1; i>=0; i--){
-               OrderNode* node=getVectorOrderNode(finishNodes, i);
-               if(node->status == NOTVISITED){
-                       node->status = VISITED;
-                       DFSMustNodeVisit(node, NULL, true);
-                       node->status = FINISHED;
+               {
+                       //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. */
+   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(OrderGraph *graph) {
+void reachMustAnalysis(CSolver * solver, OrderGraph *graph, bool computeTransitiveClosure) {
        VectorOrderNode finishNodes;
-       initDefVectorOrderNode(& 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(graph, &finishNodes);
+       DFSClearContradictions(solver, graph, &finishNodes, computeTransitiveClosure);
        deleteVectorArrayOrderNode(&finishNodes);
-       resetNodeInfoStatusSCC(graph);
 }
 
 /* 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). */
+   inverse edge to be negative (and clears its positive polarity if it
+   had one). */
 
-void localMustAnalysisTotal(OrderGraph *graph) {
-       HSIteratorOrderEdgeiterator = iteratorOrderEdge(graph->edges);
-       while(hasNextOrderEdge(iterator)) {
+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 && !invEdge -> mustPos && invEdge->polPos) {
-                               invEdge->polPos = false;
+               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;
                        }
-                       invEdge->mustNeg = 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. */
+    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(OrderGraph *graph) {
-       HSIteratorOrderEdgeiterator = iteratorOrderEdge(graph->edges);
-       while(hasNextOrderEdge(iterator)) {
+void localMustAnalysisPartial(CSolver *solver, OrderGraph *graph) {
+       HSIteratorOrderEdge *iterator = iteratorOrderEdge(graph->edges);
+       while (hasNextOrderEdge(iterator)) {
                OrderEdge *edge = nextOrderEdge(iterator);
-               if (edge -> mustPos) {
-                       if (edge->polNeg && !edge->mustNeg) {
+               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;
                        }
-                       OrderEdge *invEdge=getInverseOrderEdge(graph, edge);
-                       if (invEdge != NULL && !invEdge -> mustPos) {
-                               invEdge->polPos = false;
-                       }
-                       invEdge->mustNeg = true;
                }
                if (edge->mustNeg && !edge->mustPos) {
                        edge->polPos = false;
@@ -264,42 +377,116 @@ void localMustAnalysisPartial(OrderGraph *graph) {
        deleteIterOrderEdge(iterator);
 }
 
-void decomposeOrder(Order *order, OrderGraph *graph) {
-       uint size=getSizeVectorBooleanOrder(&order->constraints);
-       for(uint i=0;i<size;i++) {
+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(CSolverThis) {
+void orderAnalysis(CSolver *This) {
        uint size = getSizeVectorOrder(This->allOrders);
-       for(uint i=0; i<size; i++){
-               Order* order = getVectorOrder(This->allOrders, i);
-               OrderGraph* graph = buildOrderGraph(order);
-               if (order->type==PARTIAL) {
+       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);
                }
 
-               //This analysis is completely optional
-               reachMustAnalysis(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);
                
-               //This pair of analysis is also optional
-               if (order->type==PARTIAL) {
-                       localMustAnalysisPartial(graph);
-               } else {
-                       localMustAnalysisTotal(graph);
+               if (mustReachLocal) {
+                       //This pair of analysis is also optional
+                       if (order->type == PARTIAL) {
+                               localMustAnalysisPartial(This, graph);
+                       } else {
+                               localMustAnalysisTotal(This, graph);
+                       }
                }
 
-               //This optimization is completely optional
-               removeMustBeTrueNodes(graph);
-
+               bool mustReachPrune=GETVARTUNABLE(This->tuner, order->type, MUSTREACHPRUNE, &onoff);
+               
+               if (mustReachPrune)
+                       removeMustBeTrueNodes(This, graph);
+               
                //This is needed for splitorder
                computeStronglyConnectedComponentGraph(graph);
-
-               decomposeOrder(order, graph);
-                       
+               
+               decomposeOrder(This, order, graph);
+               
                deleteOrderGraph(graph);
        }
 }