1 #include "orderencoder.h"
5 #include "ordergraph.h"
10 OrderGraph* buildOrderGraph(Order *order) {
11 OrderGraph* orderGraph = allocOrderGraph(order);
12 uint constrSize = getSizeVectorBooleanOrder(&order->constraints);
13 for(uint j=0; j<constrSize; j++){
14 addOrderConstraintToOrderGraph(orderGraph, getVectorBooleanOrder(&order->constraints, j));
19 void DFS(OrderGraph* graph, VectorOrderNode* finishNodes) {
20 HSIteratorOrderNode* iterator = iteratorOrderNode(graph->nodes);
21 while(hasNextOrderNode(iterator)){
22 OrderNode* node = nextOrderNode(iterator);
23 if(node->status == NOTVISITED){
24 node->status = VISITED;
25 DFSNodeVisit(node, finishNodes, false, 0);
26 node->status = FINISHED;
27 pushVectorOrderNode(finishNodes, node);
30 deleteIterOrderNode(iterator);
33 void DFSReverse(OrderGraph* graph, VectorOrderNode* finishNodes) {
34 uint size = getSizeVectorOrderNode(finishNodes);
36 for(int i=size-1; i>=0; i--){
37 OrderNode* node = getVectorOrderNode(finishNodes, i);
38 if(node->status == NOTVISITED){
39 node->status = VISITED;
40 DFSNodeVisit(node, NULL, true, sccNum);
41 node->sccNum = sccNum;
42 node->status = FINISHED;
48 void DFSNodeVisit(OrderNode* node, VectorOrderNode* finishNodes, bool isReverse, uint sccNum) {
49 HSIteratorOrderEdge* iterator = isReverse?iteratorOrderEdge(node->inEdges):iteratorOrderEdge(node->outEdges);
50 while(hasNextOrderEdge(iterator)){
51 OrderEdge* edge = nextOrderEdge(iterator);
52 if (!edge->polPos && !edge->pseudoPos) //Ignore edges that do not have positive polarity
55 OrderNode* child = isReverse? edge->source: edge->sink;
57 if(child->status == NOTVISITED) {
58 child->status = VISITED;
59 DFSNodeVisit(child, finishNodes, isReverse, sccNum);
60 child->status = FINISHED;
62 pushVectorOrderNode(finishNodes, child);
64 child->sccNum = sccNum;
67 deleteIterOrderEdge(iterator);
70 void resetNodeInfoStatusSCC(OrderGraph* graph) {
71 HSIteratorOrderNode* iterator = iteratorOrderNode(graph->nodes);
72 while(hasNextOrderNode(iterator)){
73 nextOrderNode(iterator)->status = NOTVISITED;
75 deleteIterOrderNode(iterator);
78 void computeStronglyConnectedComponentGraph(OrderGraph* graph) {
79 VectorOrderNode finishNodes;
80 initDefVectorOrderNode(& finishNodes);
81 DFS(graph, &finishNodes);
82 resetNodeInfoStatusSCC(graph);
83 DFSReverse(graph, &finishNodes);
84 resetNodeInfoStatusSCC(graph);
85 deleteVectorArrayOrderNode(&finishNodes);
88 void removeMustBeTrueNodes(OrderGraph* graph) {
89 //TODO: Nodes that all the incoming/outgoing edges are MUST_BE_TRUE
92 void DFSPseudoNodeVisit(OrderGraph *graph, OrderNode* node) {
93 HSIteratorOrderEdge* iterator = iteratorOrderEdge(node->inEdges);
94 while(hasNextOrderEdge(iterator)){
95 OrderEdge* inEdge = nextOrderEdge(iterator);
97 OrderNode* src = inEdge->source;
98 if (src->status==VISITED) {
99 //Make a pseudoEdge to point backwards
100 OrderEdge * newedge = getOrderEdgeFromOrderGraph(graph, inEdge->sink, inEdge->source);
101 newedge->pseudoPos = true;
105 deleteIterOrderEdge(iterator);
106 iterator = iteratorOrderEdge(node->outEdges);
107 while(hasNextOrderEdge(iterator)){
108 OrderEdge* edge = nextOrderEdge(iterator);
109 if (!edge->polPos) //Ignore edges that do not have positive polarity
112 OrderNode* child = edge->sink;
113 if(child->status == NOTVISITED){
114 child->status = VISITED;
115 DFSPseudoNodeVisit(graph, child);
116 child->status = FINISHED;
119 deleteIterOrderEdge(iterator);
122 void completePartialOrderGraph(OrderGraph* graph) {
123 VectorOrderNode finishNodes;
124 initDefVectorOrderNode(& finishNodes);
125 DFS(graph, &finishNodes);
126 resetNodeInfoStatusSCC(graph);
128 uint size = getSizeVectorOrderNode(&finishNodes);
129 for(int i=size-1; i>=0; i--){
130 OrderNode* node = getVectorOrderNode(&finishNodes, i);
131 if(node->status == NOTVISITED){
132 node->status = VISITED;
133 DFSPseudoNodeVisit(graph, node);
134 node->status = FINISHED;
138 resetNodeInfoStatusSCC(graph);
139 deleteVectorArrayOrderNode(&finishNodes);
142 void DFSMust(OrderGraph* graph, VectorOrderNode* finishNodes) {
143 HSIteratorOrderNode* iterator = iteratorOrderNode(graph->nodes);
144 while(hasNextOrderNode(iterator)){
145 OrderNode* node = nextOrderNode(iterator);
146 if(node->status == NOTVISITED){
147 node->status = VISITED;
148 DFSMustNodeVisit(node, finishNodes, false);
149 node->status = FINISHED;
150 pushVectorOrderNode(finishNodes, node);
153 deleteIterOrderNode(iterator);
156 void DFSMustNodeVisit(OrderNode* node, VectorOrderNode* finishNodes, bool clearBackEdges) {
157 HSIteratorOrderEdge* iterator = iteratorOrderEdge(node->outEdges);
158 while(hasNextOrderEdge(iterator)){
159 OrderEdge* edge = nextOrderEdge(iterator);
160 OrderNode* child = edge->sink;
162 if (clearBackEdges && child->status==VISITED) {
163 //We have a backedge, so note that this edge must be negative
164 edge->mustNeg = true;
167 if (!edge->mustPos) //Ignore edges that are not must Positive edges
170 if(child->status == NOTVISITED){
171 child->status = VISITED;
172 DFSMustNodeVisit(child, finishNodes, clearBackEdges);
173 child->status = FINISHED;
174 pushVectorOrderNode(finishNodes, child);
177 deleteIterOrderEdge(iterator);
180 void DFSClearContradictions(OrderGraph* graph, VectorOrderNode* finishNodes) {
181 uint size=getSizeVectorOrderNode(finishNodes);
182 for(int i=size-1; i>=0; i--){
183 OrderNode* node=getVectorOrderNode(finishNodes, i);
184 if(node->status == NOTVISITED){
185 node->status = VISITED;
186 DFSMustNodeVisit(node, NULL, true);
187 node->status = FINISHED;
192 /* This function finds edges that would form a cycle with must edges
193 and forces them to be mustNeg. */
195 void reachMustAnalysis(OrderGraph *graph) {
196 VectorOrderNode finishNodes;
197 initDefVectorOrderNode(& finishNodes);
198 //Topologically sort the mustPos edge graph
199 DFSMust(graph, &finishNodes);
200 resetNodeInfoStatusSCC(graph);
202 //Find any backwards edges that complete cycles and force them to be mustNeg
203 DFSClearContradictions(graph, &finishNodes);
204 deleteVectorArrayOrderNode(&finishNodes);
205 resetNodeInfoStatusSCC(graph);
208 /* This function finds edges that must be positive and forces the
209 inverse edge to be negative (and clears its positive polarity if it
212 void localMustAnalysisTotal(OrderGraph *graph) {
213 HSIteratorOrderEdge* iterator = iteratorOrderEdge(graph->edges);
214 while(hasNextOrderEdge(iterator)) {
215 OrderEdge *edge = nextOrderEdge(iterator);
216 if (edge -> mustPos) {
217 OrderEdge *invEdge=getInverseOrderEdge(graph, edge);
218 if (invEdge!= NULL && !invEdge -> mustPos && invEdge->polPos) {
219 invEdge->polPos = false;
221 invEdge->mustNeg = true;
224 deleteIterOrderEdge(iterator);
227 /** This finds edges that must be positive and forces the inverse edge
228 to be negative. It also clears the negative flag of this edge.
229 It also finds edges that must be negative and clears the positive
232 void localMustAnalysisPartial(OrderGraph *graph) {
233 HSIteratorOrderEdge* iterator = iteratorOrderEdge(graph->edges);
234 while(hasNextOrderEdge(iterator)) {
235 OrderEdge *edge = nextOrderEdge(iterator);
236 if (edge -> mustPos) {
237 if (edge->polNeg && !edge->mustNeg) {
238 edge->polNeg = false;
240 OrderEdge *invEdge=getInverseOrderEdge(graph, edge);
241 if (invEdge != NULL && !invEdge -> mustPos) {
242 invEdge->polPos = false;
244 invEdge->mustNeg = true;
246 if (edge->mustNeg && !edge->mustPos) {
247 edge->polPos = false;
250 deleteIterOrderEdge(iterator);
253 void decomposeOrder(Order *order, OrderGraph *graph) {
254 uint size=getSizeVectorBooleanOrder(&order->constraints);
255 for(uint i=0;i<size;i++) {
259 void orderAnalysis(CSolver* This) {
260 uint size = getSizeVectorOrder(This->allOrders);
261 for(uint i=0; i<size; i++){
262 Order* order = getVectorOrder(This->allOrders, i);
263 OrderGraph* graph = buildOrderGraph(order);
264 if (order->type==PARTIAL) {
265 //Required to do SCC analysis for partial order graphs. It
266 //makes sure we don't incorrectly optimize graphs with negative
268 completePartialOrderGraph(graph);
271 //This analysis is completely optional
272 reachMustAnalysis(graph);
274 //This pair of analysis is also optional
275 if (order->type==PARTIAL) {
276 localMustAnalysisPartial(graph);
278 localMustAnalysisTotal(graph);
281 //This optimization is completely optional
282 removeMustBeTrueNodes(graph);
284 //This is needed for splitorder
285 computeStronglyConnectedComponentGraph(graph);
287 decomposeOrder(order, graph);
289 deleteOrderGraph(graph);