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; }
//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()); }
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); }