예제 #1
0
int CFAnalysis::reduceNode(Flow& flow, Label lab) {
  Flow inFlow=flow.inEdges(lab);
  Flow outFlow=flow.outEdges(lab);
  // edge type cleanup
  // if true and false edge exist, remove both (merging true and false branches to a single branch)
  // if forward and backward exist, remove forward (we are not removing the cycle)
  
  /* description of essential operations:
   *   inedges: (n_i,b)
   *   outedge: (b,n2) 
   *   remove(n_i,b)
   *   remove(b,n2)
   *   insert(n1,n2)
   */
  if(inFlow.size()==0 && outFlow.size()==0) {
    return 0;
  } else if(inFlow.size()>0 && outFlow.size()>0) {
    set<Edge> toErase;
    set<Edge> toInsert;
    for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
      for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
        Edge e1=*initer;
        Edge e2=*outiter;
        // preserve edge annotations of ingoing and outgoing edges
        EdgeTypeSet unionEdgeTypeSet;
        EdgeTypeSet edgeTypeSet1=(*initer).types();
        unionEdgeTypeSet.insert(edgeTypeSet1.begin(),edgeTypeSet1.end());
        EdgeTypeSet edgeTypeSet2=(*outiter).types();
        // only copy an edge annotation in the outgoing edge if it is
        // not a true-annotation or a false-annotation
        for(EdgeTypeSet::iterator i=edgeTypeSet2.begin();i!=edgeTypeSet2.end();++i) {
          if(*i!=EDGE_TRUE && *i!=EDGE_FALSE) {
            unionEdgeTypeSet.insert(*i);
          }
        }
        if(unionEdgeTypeSet.find(EDGE_TRUE)!=unionEdgeTypeSet.end()
           && unionEdgeTypeSet.find(EDGE_FALSE)!=unionEdgeTypeSet.end()) {
          unionEdgeTypeSet.erase(EDGE_TRUE);
          unionEdgeTypeSet.erase(EDGE_FALSE);
        }
        if(unionEdgeTypeSet.find(EDGE_FORWARD)!=unionEdgeTypeSet.end()
           && unionEdgeTypeSet.find(EDGE_BACKWARD)!=unionEdgeTypeSet.end()) {
          unionEdgeTypeSet.erase(EDGE_FORWARD);
          // keep backward edge annotation
        }
        
        Edge newEdge=Edge(e1.source(),unionEdgeTypeSet,e2.target());
        toErase.insert(e1);
        toErase.insert(e2);
        if(e1.source()!=e2.target()) {
          toInsert.insert(newEdge);
        }
      }
    }
    for(set<Edge>::iterator i=toErase.begin();i!=toErase.end();++i) {
      flow.erase(*i);
    }
    for(set<Edge>::iterator i=toInsert.begin();i!=toInsert.end();++i) {
      flow.insert(*i);
    }
    return 1;
  } else if(inFlow.size()>0) {
    for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
      Edge e1=*initer;
      flow.erase(e1);
    }
    return 1;
  } else if(outFlow.size()>0) {
    for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
      Edge e2=*outiter;
      flow.erase(e2);
    }
    return 1;
  }
  return 0;
}
예제 #2
0
int CFAnalysis::reduceNode(Flow& flow, Label lab) {
  Flow inFlow=flow.inEdges(lab);
  Flow outFlow=flow.outEdges(lab);
  EdgeTypeSet unionEdgeTypeSets;
  for(Flow::iterator i=inFlow.begin();i!=inFlow.end();++i) {
    EdgeTypeSet edgeTypeSet=(*i).types();
    unionEdgeTypeSets.insert(edgeTypeSet.begin(),edgeTypeSet.end());
  }
  for(Flow::iterator i=outFlow.begin();i!=outFlow.end();++i) {
    EdgeTypeSet edgeTypeSet=(*i).types();
    unionEdgeTypeSets.insert(edgeTypeSet.begin(),edgeTypeSet.end());
  }
  // edge type cleanup
  // if true and false edge exist, remove both (merging true and false branches to a single branch)
  // if forward and backward exist, remove backward (we are removing a cycle)
  if(unionEdgeTypeSets.find(EDGE_TRUE)!=unionEdgeTypeSets.end()
     && unionEdgeTypeSets.find(EDGE_FALSE)!=unionEdgeTypeSets.end()) {
    unionEdgeTypeSets.erase(EDGE_TRUE);
    unionEdgeTypeSets.erase(EDGE_FALSE);
  }
  if(unionEdgeTypeSets.find(EDGE_FORWARD)!=unionEdgeTypeSets.end()
     && unionEdgeTypeSets.find(EDGE_BACKWARD)!=unionEdgeTypeSets.end()) {
    unionEdgeTypeSets.erase(EDGE_FORWARD);
    unionEdgeTypeSets.erase(EDGE_BACKWARD);
  }
  
  /* description of essential operations:
   *   inedges: (n_i,b)
   *   outedge: (b,n2) 
   *   remove(n_i,b)
   *   remove(b,n2)
   *   insert(n1,n2)
   */
  if(inFlow.size()==0 && outFlow.size()==0) {
    return 0;
  } else if(inFlow.size()>0 && outFlow.size()>0) {
    for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
      for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
        Edge e1=*initer;
        Edge e2=*outiter;
        // preserve edge annotations of ingoing and outgoing edges
        Edge newEdge=Edge(e1.source,unionEdgeTypeSets,e2.target);
        flow.erase(e1);
        flow.erase(e2);
        flow.insert(newEdge);
      }
      return 1;
    }
  } else if(inFlow.size()>0) {
    for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
      Edge e1=*initer;
      flow.erase(e1);
    }
    return 1;
  } else if(outFlow.size()>0) {
    for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
      Edge e2=*outiter;
      flow.erase(e2);
    }
    return 1;
  }
  return 0;
}