Пример #1
0
int 
main(int argc, char *argv[]) 
{

  int i,j,n;
  Solver      S;
  unsigned atractor_count=0;
  unsigned atractor_stats_count=0;
  std::vector<Lit> lits;
  char command[100];
  float avg_length = 0;

  std::vector< std::vector<Lit> > orig_clauses;
  global_var.orig_clauses = &orig_clauses;

  ReadNET(argv[1], S); //ckhong: read networks and then make transition relations with depth 2 by using update functions
    
  //PRINT(orig_clauses.size());

  vec<Clause*>* orig_clauses_pr = S.Clauses();

  lits.clear();  

  i=(*orig_clauses_pr).size();
  //PRINT(i);
  
  while(i--){
    int j=(*((*orig_clauses_pr)[i])).size(); //ckhong: j has the number of literals in each clause

    while(j--){
      lits.push_back((*((*orig_clauses_pr)[i]))[j]);
    }

    orig_clauses.push_back( lits ); 
    lits.clear();
  }

  /*Handle assignments of variables made in solver*/ 
  /*ckhong: what is this for ?*/ 
  /*ckhong: initial state value setting ?*/
  i=number_of_var;
  while(i--){
    if(S.value(i)!= l_Undef){
      lits.push_back((S.value(i)==l_True)? Lit(i) : ~Lit(i));
      orig_clauses.push_back( lits );
      lits.clear();
    }
  }
 
  //PRINT(orig_clauses.size());

  global_var.S = &S;
  global_var.number_of_var = number_of_var;
  global_var.depth=2;


  if(number_of_var<100){ //ckhong: make n-length formula
    construct_depth(number_of_var);
  }else{
    construct_depth(100);
  }

  //puts("Start searching...");
  while(1){

    if (!S.solve()) break;
    /*ckhong: found valid path*/

    for( i=1; i<global_var.depth; i++ ){
      if(compare_states(0,i,number_of_var,S.model )){
    	atractor_count++;
    	atractor_stats_count+=i;
    	//PRINT(atractor_stats_count);
    	//constrain all states of atractor sequence on 0 index variable
        
        //char temp_attr[i*number_of_var];
    	char tState[number_of_var];
        Attractor tAttr; 
        tAttr.length = i;

        for( j = 0; j < i; j++ ){
	      constrain_state(j, S.model, 0, S, number_of_var );
#ifdef PRINT_STATE 
          /*ckhong: attractor state print out*/
    	  int a_tmp=j*number_of_var;	  
          int b_tmp=0;
	      int counter=number_of_var;
	      while(counter--){
	        if(S.model[a_tmp] != l_Undef){
		      //printf( "%s", (S.model[a_tmp]==l_True)?"1":"0");
              //sprintf(temp_attr+a_tmp, "%s", (S.model[a_tmp]==l_True)?"1":"0");
              sprintf(tState+b_tmp, "%s", (S.model[a_tmp]==l_True)?"1":"0");
	        }else{
		      //printf("-");
              //sprintf(temp_attr+a_tmp, "-");
              sprintf(tState+b_tmp, "-");
	        }
	        a_tmp++;
            b_tmp++;
	      }
          tAttr.states.push_back(tState);
          //printf("\n");
#endif 
	    }
        //results.push_back(temp_attr);
        //results.push_back("\n");
        global_var.Attractors.push_back(tAttr);
	    //printf("Attractor %d is of length %d\n\n",atractor_count,i);
	    //avg_length = avg_length + i;
	    break;
      }
    }

    if(global_var.depth == i){
      construct_depth( global_var.depth << 1 ); //ckhong: depth = depth * 2
      printf("Depth of unfolding transition relation is increased to %d\n",global_var.depth);
    }
  }

  printf("Total number of attractors is %d\n",atractor_count);
  printf("Average length of attractors is %0.2f\n",avg_length/(float)atractor_count);

  for (int i=0; i<global_var.Attractors.size(); i++) {
    std::cout << "Attractor " << i << "\n";
    for (int j=0; j<global_var.Attractors[i].length; j++)
        std::cout << global_var.Attractors[i].states[j] << " " ;
    std::cout << "\n";
  }

  int MAX_DEPTH = global_var.depth;

/* ####### Basin Analysis ####### */
  
  int total_basin_size = 1;
  int curr_depth = 0;
  int attr_num = 0;
  
  for (curr_depth=2; curr_depth<MAX_DEPTH; curr_depth++) {
    Solver S_;
    orig_clauses.clear();
    lits.clear();

    ReadNET(argv[1], S_);
    
    //PRINT(S_.nClauses());

    orig_clauses_pr = S_.Clauses();
    
    i=(*orig_clauses_pr).size();
    //PRINT(i);

    while(i--){
        int j=(*((*orig_clauses_pr)[i])).size();

        while(j--){
          lits.push_back((*((*orig_clauses_pr)[i]))[j]);
        }
        orig_clauses.push_back( lits ); 
        lits.clear();
    }
    //PRINT(orig_clauses.size());

    int count = 0;
    i=number_of_var;
    while(i--){
        if(S_.value(i)!= l_Undef){
            count++;
            lits.push_back((S_.value(i)==l_True)? Lit(i) : ~Lit(i));
            orig_clauses.push_back( lits );
            lits.clear();
        }
    }

    global_var.S = &S_;
    global_var.depth = 2;
    global_var.number_of_var = number_of_var;
    //global_var.orig_clauses = &orig_clauses;

    construct_depth(curr_depth);
    int tSize = getPredecessors(S_, attr_num, number_of_var, curr_depth);
    //printf("level %d: %d\n", curr_depth, tSize);
    total_basin_size = total_basin_size + tSize;
    
    if (tSize == 0) {
        break;
    }
  }
  
  printf("Basin size for attractor %d: %d\n", attr_num, total_basin_size);

  return 0;
}
Пример #2
0
//int getPredecessors(Solver& S, const char *state, int num_var, int curr_depth) {
int getPredecessors( std::vector< std::vector<Lit> > &orig_clauses, const char *state, int num_var, int curr_depth) {
    vec<Lit> lits;
    //global_var.basins.push_back(state);

    int number_of_predecessors = 1;

    /*
    if (curr_depth == 12){ 
        //printf("\n");
        return number_of_predecessors;
    }*/

    Solver S;
    int i = num_var;
    while (i--){
        S.newVar(); S.newVar();
    }
    add_clauses_with_variable_shift(orig_clauses, S, 0);
    
    //char state_[] = "000001000000";

    i = num_var;
    while (i--){
      lits.push((state[i]=='1')? Lit(i) : ~Lit(i));
      S.addClause(lits);
      lits.clear();
    }

    i = num_var;
    while (i--){
        lits.push((state[i]=='1')? ~Lit(i+num_var) : Lit(i+num_var));
    }
    S.addClause(lits);
    lits.clear();

    int nDirectPredecessors = 0;

    while (1){
      if (!S.solve()) break;

      int a_tmp=num_var;
      int b_tmp=0;
      int counter=num_var;

      char tState[num_var];

      while(counter--){
        if(S.model[a_tmp] != l_Undef){
          //printf("%s", (S.model[a_tmp]==l_True)? "1":"0");
          sprintf(tState+b_tmp, "%s", (S.model[a_tmp]==l_True)? "1":"0"); 
        } else{
          //printf("-");
          sprintf(tState+b_tmp, "-");
        }
        a_tmp++;
        b_tmp++;
      }
      //printf("%s <- %s, ", state, tState);
      //PRINT(curr_depth);
      number_of_predecessors = number_of_predecessors + getPredecessors(orig_clauses, tState, num_var, curr_depth + 1);
      
      //constrain_state(curr_depth, S.model, curr_depth, S, num_var);
      
      i = num_var;
      while (i--){
          if (strcmp(tState, "-")) {
            lits.push((tState[i]=='1')? ~Lit(i+num_var) : Lit(i+num_var));
          }
          else {
          }
      }
      S.addClause(lits);
      lits.clear();
      nDirectPredecessors++;
    }

    

    /*
    if (nDirectPredecessors > MAX_NUMBER_OF_HUBS) {
        global_var.hubs.push_back(state);    
    }*/

    return number_of_predecessors;
}
void ReversePostOrderTraversal::analyze(Function& function)
{
	typedef util::LargeSet<BasicBlock*> BlockSet;
	typedef std::stack<BasicBlock*>     BlockStack;

	order.clear();
	
	BlockSet   visited;
	BlockStack stack;
	
	auto cfgAnalysis = getAnalysis("ControlFlowGraph");
	auto cfg         = static_cast<ControlFlowGraph*>(cfgAnalysis);	

	report("Creating reverse post order traversal over function '" +
		function.name() + "'");

	// reverse post order is reversed topological order
	stack.push(&*function.entry_block());
	
	while(order.size() != function.size())
	{
		if(stack.empty())
		{
			for(auto block : order)
			{
				auto successors = cfg->getSuccessors(*block);
				
				for(auto successor : successors)
				{
					if(visited.insert(successor).second)
					{
						stack.push(successor);
						break;
					}
				}
				
				if(!stack.empty()) break;
			}
		}
		
		assertM(!stack.empty(), (function.size() - order.size())
			<< " blocks are not connected.");
		
		while(!stack.empty())
		{
			BasicBlock* top = stack.top();
			stack.pop();
		
			auto successors = cfg->getSuccessors(*top);
			
			for(auto successor : successors)
			{
				assert(successor != nullptr);
				
				auto predecessors = cfg->getPredecessors(*successor);
				
				bool allPredecessorsVisited = true;
		
				for(auto predecessor : predecessors)
				{
					if(visited.count(predecessor) == 0)
					{
						allPredecessorsVisited = false;
						break;
					}
				}
				
				if(!allPredecessorsVisited) continue;
				
				if(visited.insert(successor).second)
				{
					stack.push(successor);
				}
			}

			order.push_back(top);
		
			report(" " << top->name());
		}
	}
	
	// reverse the order
	std::reverse(order.begin(), order.end());
}
Пример #4
0
void DataflowAnalyzer::analyze(const CFG &cfg) {
    /*
     * Returns true if the given term does not cover given memory location.
     */
    auto notCovered = [this](const MemoryLocation &mloc, const Term *term) -> bool {
        return !dataflow().getMemoryLocation(term).covers(mloc);
    };

    /* Mapping of a basic block to the definitions reaching its end. */
    boost::unordered_map<const BasicBlock *, ReachingDefinitions> outDefinitions;

    /*
     * Running abstract interpretation until reaching a fixpoint several times in a row.
     */
    int niterations = 0;
    int nfixpoints = 0;

    while (nfixpoints++ < 3) {
        /*
         * Run abstract interpretation on all basic blocks.
         */
        foreach (auto basicBlock, cfg.basicBlocks()) {
            ReachingDefinitions definitions;

            /* Merge reaching definitions from predecessors. */
            foreach (const BasicBlock *predecessor, cfg.getPredecessors(basicBlock)) {
                definitions.merge(outDefinitions[predecessor]);
            }

            /* Remove definitions that do not cover the memory location that they define. */
            definitions.filterOut(notCovered);

            /* Execute all the statements in the basic block. */
            foreach (auto statement, basicBlock->statements()) {
                execute(statement, definitions);
            }

            /* Something has changed? */
            ReachingDefinitions &oldDefinitions(outDefinitions[basicBlock]);
            if (oldDefinitions != definitions) {
                oldDefinitions = std::move(definitions);
                nfixpoints = 0;
            }
        }

        /*
         * Some terms might have changed their addresses. Filter again.
         */
        foreach (auto &termAndDefinitions, dataflow().term2definitions()) {
            termAndDefinitions.second.filterOut(notCovered);
        }

        /*
         * Do we loop infinitely?
         */
        if (++niterations >= 30) {
            log_.warning(tr("%1: Fixpoint was not reached after %2 iterations.").arg(Q_FUNC_INFO).arg(niterations));
            break;
        }

        canceled_.poll();
    }

    /*
     * Remove information about terms that disappeared.
     * Terms can disappear if e.g. a call is deinstrumented during the analysis.
     */
    auto disappeared = [](const Term *term){ return term->statement()->basicBlock() == nullptr; };

    std::vector<const Term *> disappearedTerms;
    foreach (auto &termAndDefinitions, dataflow().term2definitions()) {
        termAndDefinitions.second.filterOut([disappeared](const MemoryLocation &, const Term *term) { return disappeared(term); } );
    }

    remove_if(dataflow().term2value(), disappeared);
    remove_if(dataflow().term2location(), disappeared);
    remove_if(dataflow().term2definitions(), disappeared);
}